From 849369d6c66d3054688672f97d31fceb8e8230fb Mon Sep 17 00:00:00 2001 From: root Date: Fri, 25 Dec 2015 04:40:36 +0000 Subject: initial_commit --- arch/arm/include/asm/Kbuild | 3 + arch/arm/include/asm/a.out-core.h | 45 ++ arch/arm/include/asm/a.out.h | 34 + arch/arm/include/asm/asm-offsets.h | 1 + arch/arm/include/asm/assembler.h | 310 ++++++++ arch/arm/include/asm/atomic.h | 468 +++++++++++ arch/arm/include/asm/auxvec.h | 4 + arch/arm/include/asm/bitops.h | 320 ++++++++ arch/arm/include/asm/bitsperlong.h | 1 + arch/arm/include/asm/bug.h | 24 + arch/arm/include/asm/bugs.h | 21 + arch/arm/include/asm/byteorder.h | 25 + arch/arm/include/asm/cache.h | 28 + arch/arm/include/asm/cacheflush.h | 347 ++++++++ arch/arm/include/asm/cachetype.h | 56 ++ arch/arm/include/asm/checksum.h | 139 ++++ arch/arm/include/asm/clkdev.h | 24 + arch/arm/include/asm/cpu.h | 26 + arch/arm/include/asm/cputime.h | 6 + arch/arm/include/asm/cputype.h | 99 +++ arch/arm/include/asm/current.h | 15 + arch/arm/include/asm/delay.h | 44 ++ arch/arm/include/asm/device.h | 18 + arch/arm/include/asm/div64.h | 227 ++++++ arch/arm/include/asm/dma-mapping.h | 568 +++++++++++++ arch/arm/include/asm/dma.h | 151 ++++ arch/arm/include/asm/domain.h | 105 +++ arch/arm/include/asm/ecard.h | 219 ++++++ arch/arm/include/asm/elf.h | 137 ++++ arch/arm/include/asm/emergency-restart.h | 6 + arch/arm/include/asm/entry-macro-multi.S | 46 ++ arch/arm/include/asm/entry-macro-vic2.S | 57 ++ arch/arm/include/asm/errno.h | 6 + arch/arm/include/asm/fb.h | 19 + arch/arm/include/asm/fcntl.h | 11 + arch/arm/include/asm/fiq.h | 56 ++ arch/arm/include/asm/fiq_debugger.h | 64 ++ arch/arm/include/asm/fiq_glue.h | 30 + arch/arm/include/asm/fixmap.h | 41 + arch/arm/include/asm/flat.h | 16 + arch/arm/include/asm/floppy.h | 148 ++++ arch/arm/include/asm/fncpy.h | 94 +++ arch/arm/include/asm/fpstate.h | 93 +++ arch/arm/include/asm/ftrace.h | 67 ++ arch/arm/include/asm/futex.h | 168 ++++ arch/arm/include/asm/glue-cache.h | 146 ++++ arch/arm/include/asm/glue-df.h | 110 +++ arch/arm/include/asm/glue-pf.h | 57 ++ arch/arm/include/asm/glue-proc.h | 264 +++++++ arch/arm/include/asm/glue.h | 25 + arch/arm/include/asm/gpio.h | 7 + arch/arm/include/asm/hardirq.h | 52 ++ arch/arm/include/asm/hardware/arm_timer.h | 30 + arch/arm/include/asm/hardware/cache-l2x0.h | 82 ++ arch/arm/include/asm/hardware/cache-tauros2.h | 11 + arch/arm/include/asm/hardware/clps7111.h | 184 +++++ arch/arm/include/asm/hardware/coresight.h | 185 +++++ arch/arm/include/asm/hardware/cs89712.h | 49 ++ arch/arm/include/asm/hardware/debug-8250.S | 29 + arch/arm/include/asm/hardware/debug-pl01x.S | 29 + arch/arm/include/asm/hardware/dec21285.h | 147 ++++ arch/arm/include/asm/hardware/entry-macro-gic.S | 75 ++ arch/arm/include/asm/hardware/entry-macro-iomd.S | 139 ++++ arch/arm/include/asm/hardware/ep7211.h | 40 + arch/arm/include/asm/hardware/ep7212.h | 83 ++ arch/arm/include/asm/hardware/gic.h | 77 ++ arch/arm/include/asm/hardware/icst.h | 59 ++ arch/arm/include/asm/hardware/ioc.h | 72 ++ arch/arm/include/asm/hardware/iomd.h | 185 +++++ arch/arm/include/asm/hardware/iop3xx-adma.h | 962 +++++++++++++++++++++++ arch/arm/include/asm/hardware/iop3xx-gpio.h | 73 ++ arch/arm/include/asm/hardware/iop3xx.h | 329 ++++++++ arch/arm/include/asm/hardware/iop_adma.h | 125 +++ arch/arm/include/asm/hardware/it8152.h | 112 +++ arch/arm/include/asm/hardware/linkup-l1110.h | 48 ++ arch/arm/include/asm/hardware/locomo.h | 221 ++++++ arch/arm/include/asm/hardware/memc.h | 26 + arch/arm/include/asm/hardware/pci_v3.h | 186 +++++ arch/arm/include/asm/hardware/pl080.h | 140 ++++ arch/arm/include/asm/hardware/pl330.h | 217 +++++ arch/arm/include/asm/hardware/sa1111.h | 585 ++++++++++++++ arch/arm/include/asm/hardware/scoop.h | 72 ++ arch/arm/include/asm/hardware/sp810.h | 68 ++ arch/arm/include/asm/hardware/ssp.h | 28 + arch/arm/include/asm/hardware/timer-sp.h | 2 + arch/arm/include/asm/hardware/uengine.h | 62 ++ arch/arm/include/asm/hardware/vic.h | 47 ++ arch/arm/include/asm/highmem.h | 66 ++ arch/arm/include/asm/hw_breakpoint.h | 133 ++++ arch/arm/include/asm/hw_irq.h | 21 + arch/arm/include/asm/hwcap.h | 33 + arch/arm/include/asm/i8253.h | 15 + arch/arm/include/asm/ide.h | 23 + arch/arm/include/asm/io.h | 317 ++++++++ arch/arm/include/asm/ioctl.h | 1 + arch/arm/include/asm/ioctls.h | 8 + arch/arm/include/asm/ipcbuf.h | 29 + arch/arm/include/asm/irq.h | 35 + arch/arm/include/asm/irq_regs.h | 1 + arch/arm/include/asm/irqflags.h | 155 ++++ arch/arm/include/asm/kdebug.h | 1 + arch/arm/include/asm/kexec.h | 60 ++ arch/arm/include/asm/kgdb.h | 105 +++ arch/arm/include/asm/kmap_types.h | 33 + arch/arm/include/asm/kprobes.h | 81 ++ arch/arm/include/asm/leds.h | 50 ++ arch/arm/include/asm/limits.h | 11 + arch/arm/include/asm/linkage.h | 11 + arch/arm/include/asm/local.h | 1 + arch/arm/include/asm/local64.h | 1 + arch/arm/include/asm/localtimer.h | 57 ++ arch/arm/include/asm/locks.h | 274 +++++++ arch/arm/include/asm/mach-types.h | 1 + arch/arm/include/asm/mach/arch.h | 73 ++ arch/arm/include/asm/mach/dma.h | 54 ++ arch/arm/include/asm/mach/flash.h | 39 + arch/arm/include/asm/mach/irda.h | 20 + arch/arm/include/asm/mach/irq.h | 68 ++ arch/arm/include/asm/mach/map.h | 45 ++ arch/arm/include/asm/mach/mmc.h | 28 + arch/arm/include/asm/mach/pci.h | 84 ++ arch/arm/include/asm/mach/serial_at91.h | 33 + arch/arm/include/asm/mach/serial_sa1100.h | 31 + arch/arm/include/asm/mach/sharpsl_param.h | 37 + arch/arm/include/asm/mach/time.h | 47 ++ arch/arm/include/asm/mach/udc_pxa2xx.h | 26 + arch/arm/include/asm/mc146818rtc.h | 28 + arch/arm/include/asm/memblock.h | 9 + arch/arm/include/asm/memory.h | 306 +++++++ arch/arm/include/asm/mman.h | 4 + arch/arm/include/asm/mmu.h | 37 + arch/arm/include/asm/mmu_context.h | 164 ++++ arch/arm/include/asm/module.h | 55 ++ arch/arm/include/asm/msgbuf.h | 31 + arch/arm/include/asm/mtd-xip.h | 23 + arch/arm/include/asm/mutex.h | 127 +++ arch/arm/include/asm/nwflash.h | 9 + arch/arm/include/asm/outercache.h | 102 +++ arch/arm/include/asm/page-nommu.h | 46 ++ arch/arm/include/asm/page.h | 214 +++++ arch/arm/include/asm/param.h | 31 + arch/arm/include/asm/parport.h | 18 + arch/arm/include/asm/pci.h | 80 ++ arch/arm/include/asm/percpu.h | 6 + arch/arm/include/asm/perf_event.h | 36 + arch/arm/include/asm/pgalloc.h | 140 ++++ arch/arm/include/asm/pgtable-hwdef.h | 90 +++ arch/arm/include/asm/pgtable-nommu.h | 119 +++ arch/arm/include/asm/pgtable.h | 487 ++++++++++++ arch/arm/include/asm/pmu.h | 91 +++ arch/arm/include/asm/poll.h | 1 + arch/arm/include/asm/posix_types.h | 77 ++ arch/arm/include/asm/proc-fns.h | 115 +++ arch/arm/include/asm/processor.h | 128 +++ arch/arm/include/asm/procinfo.h | 49 ++ arch/arm/include/asm/prom.h | 37 + arch/arm/include/asm/ptrace.h | 243 ++++++ arch/arm/include/asm/resource.h | 6 + arch/arm/include/asm/scatterlist.h | 8 + arch/arm/include/asm/sched_clock.h | 120 +++ arch/arm/include/asm/seccomp.h | 11 + arch/arm/include/asm/sections.h | 1 + arch/arm/include/asm/segment.h | 11 + arch/arm/include/asm/sembuf.h | 25 + arch/arm/include/asm/serial.h | 19 + arch/arm/include/asm/setup.h | 226 ++++++ arch/arm/include/asm/shmbuf.h | 42 + arch/arm/include/asm/shmparam.h | 16 + arch/arm/include/asm/sigcontext.h | 34 + arch/arm/include/asm/siginfo.h | 6 + arch/arm/include/asm/signal.h | 164 ++++ arch/arm/include/asm/sizes.h | 21 + arch/arm/include/asm/smp.h | 98 +++ arch/arm/include/asm/smp_plat.h | 46 ++ arch/arm/include/asm/smp_scu.h | 14 + arch/arm/include/asm/smp_twd.h | 28 + arch/arm/include/asm/socket.h | 65 ++ arch/arm/include/asm/sockios.h | 13 + arch/arm/include/asm/sparsemem.h | 24 + arch/arm/include/asm/spinlock.h | 268 +++++++ arch/arm/include/asm/spinlock_types.h | 20 + arch/arm/include/asm/stackprotector.h | 38 + arch/arm/include/asm/stacktrace.h | 15 + arch/arm/include/asm/stat.h | 87 ++ arch/arm/include/asm/statfs.h | 12 + arch/arm/include/asm/string.h | 41 + arch/arm/include/asm/swab.h | 69 ++ arch/arm/include/asm/system.h | 542 +++++++++++++ arch/arm/include/asm/tcm.h | 31 + arch/arm/include/asm/termbits.h | 198 +++++ arch/arm/include/asm/termios.h | 92 +++ arch/arm/include/asm/therm.h | 28 + arch/arm/include/asm/thread_info.h | 165 ++++ arch/arm/include/asm/thread_notify.h | 49 ++ arch/arm/include/asm/timex.h | 24 + arch/arm/include/asm/tlb.h | 211 +++++ arch/arm/include/asm/tlbflush.h | 587 ++++++++++++++ arch/arm/include/asm/tls.h | 49 ++ arch/arm/include/asm/topology.h | 6 + arch/arm/include/asm/traps.h | 52 ++ arch/arm/include/asm/types.h | 22 + arch/arm/include/asm/uaccess.h | 450 +++++++++++ arch/arm/include/asm/ucontext.h | 102 +++ arch/arm/include/asm/unaligned.h | 19 + arch/arm/include/asm/unified.h | 130 +++ arch/arm/include/asm/unistd.h | 485 ++++++++++++ arch/arm/include/asm/unwind.h | 69 ++ arch/arm/include/asm/user.h | 103 +++ arch/arm/include/asm/vfp.h | 84 ++ arch/arm/include/asm/vfpmacros.h | 65 ++ arch/arm/include/asm/vga.h | 12 + arch/arm/include/asm/xor.h | 141 ++++ 212 files changed, 20102 insertions(+) create mode 100644 arch/arm/include/asm/Kbuild create mode 100644 arch/arm/include/asm/a.out-core.h create mode 100644 arch/arm/include/asm/a.out.h create mode 100644 arch/arm/include/asm/asm-offsets.h create mode 100644 arch/arm/include/asm/assembler.h create mode 100644 arch/arm/include/asm/atomic.h create mode 100644 arch/arm/include/asm/auxvec.h create mode 100644 arch/arm/include/asm/bitops.h create mode 100644 arch/arm/include/asm/bitsperlong.h create mode 100644 arch/arm/include/asm/bug.h create mode 100644 arch/arm/include/asm/bugs.h create mode 100644 arch/arm/include/asm/byteorder.h create mode 100644 arch/arm/include/asm/cache.h create mode 100644 arch/arm/include/asm/cacheflush.h create mode 100644 arch/arm/include/asm/cachetype.h create mode 100644 arch/arm/include/asm/checksum.h create mode 100644 arch/arm/include/asm/clkdev.h create mode 100644 arch/arm/include/asm/cpu.h create mode 100644 arch/arm/include/asm/cputime.h create mode 100644 arch/arm/include/asm/cputype.h create mode 100644 arch/arm/include/asm/current.h create mode 100644 arch/arm/include/asm/delay.h create mode 100644 arch/arm/include/asm/device.h create mode 100644 arch/arm/include/asm/div64.h create mode 100644 arch/arm/include/asm/dma-mapping.h create mode 100644 arch/arm/include/asm/dma.h create mode 100644 arch/arm/include/asm/domain.h create mode 100644 arch/arm/include/asm/ecard.h create mode 100644 arch/arm/include/asm/elf.h create mode 100644 arch/arm/include/asm/emergency-restart.h create mode 100644 arch/arm/include/asm/entry-macro-multi.S create mode 100644 arch/arm/include/asm/entry-macro-vic2.S create mode 100644 arch/arm/include/asm/errno.h create mode 100644 arch/arm/include/asm/fb.h create mode 100644 arch/arm/include/asm/fcntl.h create mode 100644 arch/arm/include/asm/fiq.h create mode 100644 arch/arm/include/asm/fiq_debugger.h create mode 100644 arch/arm/include/asm/fiq_glue.h create mode 100644 arch/arm/include/asm/fixmap.h create mode 100644 arch/arm/include/asm/flat.h create mode 100644 arch/arm/include/asm/floppy.h create mode 100644 arch/arm/include/asm/fncpy.h create mode 100644 arch/arm/include/asm/fpstate.h create mode 100644 arch/arm/include/asm/ftrace.h create mode 100644 arch/arm/include/asm/futex.h create mode 100644 arch/arm/include/asm/glue-cache.h create mode 100644 arch/arm/include/asm/glue-df.h create mode 100644 arch/arm/include/asm/glue-pf.h create mode 100644 arch/arm/include/asm/glue-proc.h create mode 100644 arch/arm/include/asm/glue.h create mode 100644 arch/arm/include/asm/gpio.h create mode 100644 arch/arm/include/asm/hardirq.h create mode 100644 arch/arm/include/asm/hardware/arm_timer.h create mode 100644 arch/arm/include/asm/hardware/cache-l2x0.h create mode 100644 arch/arm/include/asm/hardware/cache-tauros2.h create mode 100644 arch/arm/include/asm/hardware/clps7111.h create mode 100644 arch/arm/include/asm/hardware/coresight.h create mode 100644 arch/arm/include/asm/hardware/cs89712.h create mode 100644 arch/arm/include/asm/hardware/debug-8250.S create mode 100644 arch/arm/include/asm/hardware/debug-pl01x.S create mode 100644 arch/arm/include/asm/hardware/dec21285.h create mode 100644 arch/arm/include/asm/hardware/entry-macro-gic.S create mode 100644 arch/arm/include/asm/hardware/entry-macro-iomd.S create mode 100644 arch/arm/include/asm/hardware/ep7211.h create mode 100644 arch/arm/include/asm/hardware/ep7212.h create mode 100644 arch/arm/include/asm/hardware/gic.h create mode 100644 arch/arm/include/asm/hardware/icst.h create mode 100644 arch/arm/include/asm/hardware/ioc.h create mode 100644 arch/arm/include/asm/hardware/iomd.h create mode 100644 arch/arm/include/asm/hardware/iop3xx-adma.h create mode 100644 arch/arm/include/asm/hardware/iop3xx-gpio.h create mode 100644 arch/arm/include/asm/hardware/iop3xx.h create mode 100644 arch/arm/include/asm/hardware/iop_adma.h create mode 100644 arch/arm/include/asm/hardware/it8152.h create mode 100644 arch/arm/include/asm/hardware/linkup-l1110.h create mode 100644 arch/arm/include/asm/hardware/locomo.h create mode 100644 arch/arm/include/asm/hardware/memc.h create mode 100644 arch/arm/include/asm/hardware/pci_v3.h create mode 100644 arch/arm/include/asm/hardware/pl080.h create mode 100644 arch/arm/include/asm/hardware/pl330.h create mode 100644 arch/arm/include/asm/hardware/sa1111.h create mode 100644 arch/arm/include/asm/hardware/scoop.h create mode 100644 arch/arm/include/asm/hardware/sp810.h create mode 100644 arch/arm/include/asm/hardware/ssp.h create mode 100644 arch/arm/include/asm/hardware/timer-sp.h create mode 100644 arch/arm/include/asm/hardware/uengine.h create mode 100644 arch/arm/include/asm/hardware/vic.h create mode 100644 arch/arm/include/asm/highmem.h create mode 100644 arch/arm/include/asm/hw_breakpoint.h create mode 100644 arch/arm/include/asm/hw_irq.h create mode 100644 arch/arm/include/asm/hwcap.h create mode 100644 arch/arm/include/asm/i8253.h create mode 100644 arch/arm/include/asm/ide.h create mode 100644 arch/arm/include/asm/io.h create mode 100644 arch/arm/include/asm/ioctl.h create mode 100644 arch/arm/include/asm/ioctls.h create mode 100644 arch/arm/include/asm/ipcbuf.h create mode 100644 arch/arm/include/asm/irq.h create mode 100644 arch/arm/include/asm/irq_regs.h create mode 100644 arch/arm/include/asm/irqflags.h create mode 100644 arch/arm/include/asm/kdebug.h create mode 100644 arch/arm/include/asm/kexec.h create mode 100644 arch/arm/include/asm/kgdb.h create mode 100644 arch/arm/include/asm/kmap_types.h create mode 100644 arch/arm/include/asm/kprobes.h create mode 100644 arch/arm/include/asm/leds.h create mode 100644 arch/arm/include/asm/limits.h create mode 100644 arch/arm/include/asm/linkage.h create mode 100644 arch/arm/include/asm/local.h create mode 100644 arch/arm/include/asm/local64.h create mode 100644 arch/arm/include/asm/localtimer.h create mode 100644 arch/arm/include/asm/locks.h create mode 100644 arch/arm/include/asm/mach-types.h create mode 100644 arch/arm/include/asm/mach/arch.h create mode 100644 arch/arm/include/asm/mach/dma.h create mode 100644 arch/arm/include/asm/mach/flash.h create mode 100644 arch/arm/include/asm/mach/irda.h create mode 100644 arch/arm/include/asm/mach/irq.h create mode 100644 arch/arm/include/asm/mach/map.h create mode 100644 arch/arm/include/asm/mach/mmc.h create mode 100644 arch/arm/include/asm/mach/pci.h create mode 100644 arch/arm/include/asm/mach/serial_at91.h create mode 100644 arch/arm/include/asm/mach/serial_sa1100.h create mode 100644 arch/arm/include/asm/mach/sharpsl_param.h create mode 100644 arch/arm/include/asm/mach/time.h create mode 100644 arch/arm/include/asm/mach/udc_pxa2xx.h create mode 100644 arch/arm/include/asm/mc146818rtc.h create mode 100644 arch/arm/include/asm/memblock.h create mode 100644 arch/arm/include/asm/memory.h create mode 100644 arch/arm/include/asm/mman.h create mode 100644 arch/arm/include/asm/mmu.h create mode 100644 arch/arm/include/asm/mmu_context.h create mode 100644 arch/arm/include/asm/module.h create mode 100644 arch/arm/include/asm/msgbuf.h create mode 100644 arch/arm/include/asm/mtd-xip.h create mode 100644 arch/arm/include/asm/mutex.h create mode 100644 arch/arm/include/asm/nwflash.h create mode 100644 arch/arm/include/asm/outercache.h create mode 100644 arch/arm/include/asm/page-nommu.h create mode 100644 arch/arm/include/asm/page.h create mode 100644 arch/arm/include/asm/param.h create mode 100644 arch/arm/include/asm/parport.h create mode 100644 arch/arm/include/asm/pci.h create mode 100644 arch/arm/include/asm/percpu.h create mode 100644 arch/arm/include/asm/perf_event.h create mode 100644 arch/arm/include/asm/pgalloc.h create mode 100644 arch/arm/include/asm/pgtable-hwdef.h create mode 100644 arch/arm/include/asm/pgtable-nommu.h create mode 100644 arch/arm/include/asm/pgtable.h create mode 100644 arch/arm/include/asm/pmu.h create mode 100644 arch/arm/include/asm/poll.h create mode 100644 arch/arm/include/asm/posix_types.h create mode 100644 arch/arm/include/asm/proc-fns.h create mode 100644 arch/arm/include/asm/processor.h create mode 100644 arch/arm/include/asm/procinfo.h create mode 100644 arch/arm/include/asm/prom.h create mode 100644 arch/arm/include/asm/ptrace.h create mode 100644 arch/arm/include/asm/resource.h create mode 100644 arch/arm/include/asm/scatterlist.h create mode 100644 arch/arm/include/asm/sched_clock.h create mode 100644 arch/arm/include/asm/seccomp.h create mode 100644 arch/arm/include/asm/sections.h create mode 100644 arch/arm/include/asm/segment.h create mode 100644 arch/arm/include/asm/sembuf.h create mode 100644 arch/arm/include/asm/serial.h create mode 100644 arch/arm/include/asm/setup.h create mode 100644 arch/arm/include/asm/shmbuf.h create mode 100644 arch/arm/include/asm/shmparam.h create mode 100644 arch/arm/include/asm/sigcontext.h create mode 100644 arch/arm/include/asm/siginfo.h create mode 100644 arch/arm/include/asm/signal.h create mode 100644 arch/arm/include/asm/sizes.h create mode 100644 arch/arm/include/asm/smp.h create mode 100644 arch/arm/include/asm/smp_plat.h create mode 100644 arch/arm/include/asm/smp_scu.h create mode 100644 arch/arm/include/asm/smp_twd.h create mode 100644 arch/arm/include/asm/socket.h create mode 100644 arch/arm/include/asm/sockios.h create mode 100644 arch/arm/include/asm/sparsemem.h create mode 100644 arch/arm/include/asm/spinlock.h create mode 100644 arch/arm/include/asm/spinlock_types.h create mode 100644 arch/arm/include/asm/stackprotector.h create mode 100644 arch/arm/include/asm/stacktrace.h create mode 100644 arch/arm/include/asm/stat.h create mode 100644 arch/arm/include/asm/statfs.h create mode 100644 arch/arm/include/asm/string.h create mode 100644 arch/arm/include/asm/swab.h create mode 100644 arch/arm/include/asm/system.h create mode 100644 arch/arm/include/asm/tcm.h create mode 100644 arch/arm/include/asm/termbits.h create mode 100644 arch/arm/include/asm/termios.h create mode 100644 arch/arm/include/asm/therm.h create mode 100644 arch/arm/include/asm/thread_info.h create mode 100644 arch/arm/include/asm/thread_notify.h create mode 100644 arch/arm/include/asm/timex.h create mode 100644 arch/arm/include/asm/tlb.h create mode 100644 arch/arm/include/asm/tlbflush.h create mode 100644 arch/arm/include/asm/tls.h create mode 100644 arch/arm/include/asm/topology.h create mode 100644 arch/arm/include/asm/traps.h create mode 100644 arch/arm/include/asm/types.h create mode 100644 arch/arm/include/asm/uaccess.h create mode 100644 arch/arm/include/asm/ucontext.h create mode 100644 arch/arm/include/asm/unaligned.h create mode 100644 arch/arm/include/asm/unified.h create mode 100644 arch/arm/include/asm/unistd.h create mode 100644 arch/arm/include/asm/unwind.h create mode 100644 arch/arm/include/asm/user.h create mode 100644 arch/arm/include/asm/vfp.h create mode 100644 arch/arm/include/asm/vfpmacros.h create mode 100644 arch/arm/include/asm/vga.h create mode 100644 arch/arm/include/asm/xor.h (limited to 'arch/arm/include/asm') diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild new file mode 100644 index 00000000..6550db3a --- /dev/null +++ b/arch/arm/include/asm/Kbuild @@ -0,0 +1,3 @@ +include include/asm-generic/Kbuild.asm + +header-y += hwcap.h diff --git a/arch/arm/include/asm/a.out-core.h b/arch/arm/include/asm/a.out-core.h new file mode 100644 index 00000000..92f10cb5 --- /dev/null +++ b/arch/arm/include/asm/a.out-core.h @@ -0,0 +1,45 @@ +/* a.out coredump register dumper + * + * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +#ifndef _ASM_A_OUT_CORE_H +#define _ASM_A_OUT_CORE_H + +#ifdef __KERNEL__ + +#include +#include + +/* + * fill in the user structure for an a.out core dump + */ +static inline void aout_dump_thread(struct pt_regs *regs, struct user *dump) +{ + struct task_struct *tsk = current; + + dump->magic = CMAGIC; + dump->start_code = tsk->mm->start_code; + dump->start_stack = regs->ARM_sp & ~(PAGE_SIZE - 1); + + dump->u_tsize = (tsk->mm->end_code - tsk->mm->start_code) >> PAGE_SHIFT; + dump->u_dsize = (tsk->mm->brk - tsk->mm->start_data + PAGE_SIZE - 1) >> PAGE_SHIFT; + dump->u_ssize = 0; + + memset(dump->u_debugreg, 0, sizeof(dump->u_debugreg)); + + if (dump->start_stack < 0x04000000) + dump->u_ssize = (0x04000000 - dump->start_stack) >> PAGE_SHIFT; + + dump->regs = *regs; + dump->u_fpvalid = dump_fpu (regs, &dump->u_fp); +} + +#endif /* __KERNEL__ */ +#endif /* _ASM_A_OUT_CORE_H */ diff --git a/arch/arm/include/asm/a.out.h b/arch/arm/include/asm/a.out.h new file mode 100644 index 00000000..083894b2 --- /dev/null +++ b/arch/arm/include/asm/a.out.h @@ -0,0 +1,34 @@ +#ifndef __ARM_A_OUT_H__ +#define __ARM_A_OUT_H__ + +#include +#include + +struct exec +{ + __u32 a_info; /* Use macros N_MAGIC, etc for access */ + __u32 a_text; /* length of text, in bytes */ + __u32 a_data; /* length of data, in bytes */ + __u32 a_bss; /* length of uninitialized data area for file, in bytes */ + __u32 a_syms; /* length of symbol table data in file, in bytes */ + __u32 a_entry; /* start address */ + __u32 a_trsize; /* length of relocation info for text, in bytes */ + __u32 a_drsize; /* length of relocation info for data, in bytes */ +}; + +/* + * This is always the same + */ +#define N_TXTADDR(a) (0x00008000) + +#define N_TRSIZE(a) ((a).a_trsize) +#define N_DRSIZE(a) ((a).a_drsize) +#define N_SYMSIZE(a) ((a).a_syms) + +#define M_ARM 103 + +#ifndef LIBRARY_START_TEXT +#define LIBRARY_START_TEXT (0x00c00000) +#endif + +#endif /* __A_OUT_GNU_H__ */ diff --git a/arch/arm/include/asm/asm-offsets.h b/arch/arm/include/asm/asm-offsets.h new file mode 100644 index 00000000..d370ee36 --- /dev/null +++ b/arch/arm/include/asm/asm-offsets.h @@ -0,0 +1 @@ +#include diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h new file mode 100644 index 00000000..fed335ef --- /dev/null +++ b/arch/arm/include/asm/assembler.h @@ -0,0 +1,310 @@ +/* + * arch/arm/include/asm/assembler.h + * + * Copyright (C) 1996-2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This file contains arm architecture specific defines + * for the different processors. + * + * Do not include any C declarations in this file - it is included by + * assembler source. + */ +#ifndef __ASM_ASSEMBLER_H__ +#define __ASM_ASSEMBLER_H__ + +#ifndef __ASSEMBLY__ +#error "Only include this from assembly code" +#endif + +#include +#include + +/* + * Endian independent macros for shifting bytes within registers. + */ +#ifndef __ARMEB__ +#define pull lsr +#define push lsl +#define get_byte_0 lsl #0 +#define get_byte_1 lsr #8 +#define get_byte_2 lsr #16 +#define get_byte_3 lsr #24 +#define put_byte_0 lsl #0 +#define put_byte_1 lsl #8 +#define put_byte_2 lsl #16 +#define put_byte_3 lsl #24 +#else +#define pull lsl +#define push lsr +#define get_byte_0 lsr #24 +#define get_byte_1 lsr #16 +#define get_byte_2 lsr #8 +#define get_byte_3 lsl #0 +#define put_byte_0 lsl #24 +#define put_byte_1 lsl #16 +#define put_byte_2 lsl #8 +#define put_byte_3 lsl #0 +#endif + +/* + * Data preload for architectures that support it + */ +#if __LINUX_ARM_ARCH__ >= 5 +#define PLD(code...) code +#else +#define PLD(code...) +#endif + +/* + * This can be used to enable code to cacheline align the destination + * pointer when bulk writing to memory. Experiments on StrongARM and + * XScale didn't show this a worthwhile thing to do when the cache is not + * set to write-allocate (this would need further testing on XScale when WA + * is used). + * + * On Feroceon there is much to gain however, regardless of cache mode. + */ +#ifdef CONFIG_CPU_FEROCEON +#define CALGN(code...) code +#else +#define CALGN(code...) +#endif + +/* + * Enable and disable interrupts + */ +#if __LINUX_ARM_ARCH__ >= 6 + .macro disable_irq_notrace + cpsid i + .endm + + .macro enable_irq_notrace + cpsie i + .endm +#else + .macro disable_irq_notrace + msr cpsr_c, #PSR_I_BIT | SVC_MODE + .endm + + .macro enable_irq_notrace + msr cpsr_c, #SVC_MODE + .endm +#endif + + .macro asm_trace_hardirqs_off +#if defined(CONFIG_TRACE_IRQFLAGS) + stmdb sp!, {r0-r3, ip, lr} + bl trace_hardirqs_off + ldmia sp!, {r0-r3, ip, lr} +#endif + .endm + + .macro asm_trace_hardirqs_on_cond, cond +#if defined(CONFIG_TRACE_IRQFLAGS) + /* + * actually the registers should be pushed and pop'd conditionally, but + * after bl the flags are certainly clobbered + */ + stmdb sp!, {r0-r3, ip, lr} + bl\cond trace_hardirqs_on + ldmia sp!, {r0-r3, ip, lr} +#endif + .endm + + .macro asm_trace_hardirqs_on + asm_trace_hardirqs_on_cond al + .endm + + .macro disable_irq + disable_irq_notrace + asm_trace_hardirqs_off + .endm + + .macro enable_irq + asm_trace_hardirqs_on + enable_irq_notrace + .endm +/* + * Save the current IRQ state and disable IRQs. Note that this macro + * assumes FIQs are enabled, and that the processor is in SVC mode. + */ + .macro save_and_disable_irqs, oldcpsr + mrs \oldcpsr, cpsr + disable_irq + .endm + + .macro save_and_disable_irqs_notrace, oldcpsr + mrs \oldcpsr, cpsr + disable_irq_notrace + .endm + +/* + * Restore interrupt state previously stored in a register. We don't + * guarantee that this will preserve the flags. + */ + .macro restore_irqs_notrace, oldcpsr + msr cpsr_c, \oldcpsr + .endm + + .macro restore_irqs, oldcpsr + tst \oldcpsr, #PSR_I_BIT + asm_trace_hardirqs_on_cond eq + restore_irqs_notrace \oldcpsr + .endm + +#define USER(x...) \ +9999: x; \ + .pushsection __ex_table,"a"; \ + .align 3; \ + .long 9999b,9001f; \ + .popsection + +#ifdef CONFIG_SMP +#define ALT_SMP(instr...) \ +9998: instr +/* + * Note: if you get assembler errors from ALT_UP() when building with + * CONFIG_THUMB2_KERNEL, you almost certainly need to use + * ALT_SMP( W(instr) ... ) + */ +#define ALT_UP(instr...) \ + .pushsection ".alt.smp.init", "a" ;\ + .long 9998b ;\ +9997: instr ;\ + .if . - 9997b != 4 ;\ + .error "ALT_UP() content must assemble to exactly 4 bytes";\ + .endif ;\ + .popsection +#define ALT_UP_B(label) \ + .equ up_b_offset, label - 9998b ;\ + .pushsection ".alt.smp.init", "a" ;\ + .long 9998b ;\ + W(b) . + up_b_offset ;\ + .popsection +#else +#define ALT_SMP(instr...) +#define ALT_UP(instr...) instr +#define ALT_UP_B(label) b label +#endif + +/* + * SMP data memory barrier + */ + .macro smp_dmb mode +#ifdef CONFIG_SMP +#if __LINUX_ARM_ARCH__ >= 7 + .ifeqs "\mode","arm" + ALT_SMP(dmb) + .else + ALT_SMP(W(dmb)) + .endif +#elif __LINUX_ARM_ARCH__ == 6 + ALT_SMP(mcr p15, 0, r0, c7, c10, 5) @ dmb +#else +#error Incompatible SMP platform +#endif + .ifeqs "\mode","arm" + ALT_UP(nop) + .else + ALT_UP(W(nop)) + .endif +#endif + .endm + +#ifdef CONFIG_THUMB2_KERNEL + .macro setmode, mode, reg + mov \reg, #\mode + msr cpsr_c, \reg + .endm +#else + .macro setmode, mode, reg + msr cpsr_c, #\mode + .endm +#endif + +/* + * STRT/LDRT access macros with ARM and Thumb-2 variants + */ +#ifdef CONFIG_THUMB2_KERNEL + + .macro usraccoff, instr, reg, ptr, inc, off, cond, abort, t=TUSER() +9999: + .if \inc == 1 + \instr\cond\()b\()\t\().w \reg, [\ptr, #\off] + .elseif \inc == 4 + \instr\cond\()\t\().w \reg, [\ptr, #\off] + .else + .error "Unsupported inc macro argument" + .endif + + .pushsection __ex_table,"a" + .align 3 + .long 9999b, \abort + .popsection + .endm + + .macro usracc, instr, reg, ptr, inc, cond, rept, abort + @ explicit IT instruction needed because of the label + @ introduced by the USER macro + .ifnc \cond,al + .if \rept == 1 + itt \cond + .elseif \rept == 2 + ittt \cond + .else + .error "Unsupported rept macro argument" + .endif + .endif + + @ Slightly optimised to avoid incrementing the pointer twice + usraccoff \instr, \reg, \ptr, \inc, 0, \cond, \abort + .if \rept == 2 + usraccoff \instr, \reg, \ptr, \inc, \inc, \cond, \abort + .endif + + add\cond \ptr, #\rept * \inc + .endm + +#else /* !CONFIG_THUMB2_KERNEL */ + + .macro usracc, instr, reg, ptr, inc, cond, rept, abort, t=TUSER() + .rept \rept +9999: + .if \inc == 1 + \instr\cond\()b\()\t \reg, [\ptr], #\inc + .elseif \inc == 4 + \instr\cond\()\t \reg, [\ptr], #\inc + .else + .error "Unsupported inc macro argument" + .endif + + .pushsection __ex_table,"a" + .align 3 + .long 9999b, \abort + .popsection + .endr + .endm + +#endif /* CONFIG_THUMB2_KERNEL */ + + .macro strusr, reg, ptr, inc, cond=al, rept=1, abort=9001f + usracc str, \reg, \ptr, \inc, \cond, \rept, \abort + .endm + + .macro ldrusr, reg, ptr, inc, cond=al, rept=1, abort=9001f + usracc ldr, \reg, \ptr, \inc, \cond, \rept, \abort + .endm + +/* Utility macro for declaring string literals */ + .macro string name:req, string + .type \name , #object +\name: + .asciz "\string" + .size \name , . - \name + .endm + +#endif /* __ASM_ASSEMBLER_H__ */ diff --git a/arch/arm/include/asm/atomic.h b/arch/arm/include/asm/atomic.h new file mode 100644 index 00000000..7e79503a --- /dev/null +++ b/arch/arm/include/asm/atomic.h @@ -0,0 +1,468 @@ +/* + * arch/arm/include/asm/atomic.h + * + * Copyright (C) 1996 Russell King. + * Copyright (C) 2002 Deep Blue Solutions Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __ASM_ARM_ATOMIC_H +#define __ASM_ARM_ATOMIC_H + +#include +#include +#include + +#define ATOMIC_INIT(i) { (i) } + +#ifdef __KERNEL__ + +/* + * On ARM, ordinary assignment (str instruction) doesn't clear the local + * strex/ldrex monitor on some implementations. The reason we can use it for + * atomic_set() is the clrex or dummy strex done on every exception return. + */ +#define atomic_read(v) (*(volatile int *)&(v)->counter) +#define atomic_set(v,i) (((v)->counter) = (i)) + +#if __LINUX_ARM_ARCH__ >= 6 + +/* + * ARMv6 UP and SMP safe atomic ops. We use load exclusive and + * store exclusive to ensure that these are atomic. We may loop + * to ensure that the update happens. + */ +static inline void atomic_add(int i, atomic_t *v) +{ + unsigned long tmp; + int result; + + __asm__ __volatile__("@ atomic_add\n" +"1: ldrex %0, [%3]\n" +" add %0, %0, %4\n" +" strex %1, %0, [%3]\n" +" teq %1, #0\n" +" bne 1b" + : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) + : "r" (&v->counter), "Ir" (i) + : "cc"); +} + +static inline int atomic_add_return(int i, atomic_t *v) +{ + unsigned long tmp; + int result; + + smp_mb(); + + __asm__ __volatile__("@ atomic_add_return\n" +"1: ldrex %0, [%3]\n" +" add %0, %0, %4\n" +" strex %1, %0, [%3]\n" +" teq %1, #0\n" +" bne 1b" + : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) + : "r" (&v->counter), "Ir" (i) + : "cc"); + + smp_mb(); + + return result; +} + +static inline void atomic_sub(int i, atomic_t *v) +{ + unsigned long tmp; + int result; + + __asm__ __volatile__("@ atomic_sub\n" +"1: ldrex %0, [%3]\n" +" sub %0, %0, %4\n" +" strex %1, %0, [%3]\n" +" teq %1, #0\n" +" bne 1b" + : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) + : "r" (&v->counter), "Ir" (i) + : "cc"); +} + +static inline int atomic_sub_return(int i, atomic_t *v) +{ + unsigned long tmp; + int result; + + smp_mb(); + + __asm__ __volatile__("@ atomic_sub_return\n" +"1: ldrex %0, [%3]\n" +" sub %0, %0, %4\n" +" strex %1, %0, [%3]\n" +" teq %1, #0\n" +" bne 1b" + : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) + : "r" (&v->counter), "Ir" (i) + : "cc"); + + smp_mb(); + + return result; +} + +static inline int atomic_cmpxchg(atomic_t *ptr, int old, int new) +{ + unsigned long oldval, res; + + smp_mb(); + + do { + __asm__ __volatile__("@ atomic_cmpxchg\n" + "ldrex %1, [%3]\n" + "mov %0, #0\n" + "teq %1, %4\n" + "strexeq %0, %5, [%3]\n" + : "=&r" (res), "=&r" (oldval), "+Qo" (ptr->counter) + : "r" (&ptr->counter), "Ir" (old), "r" (new) + : "cc"); + } while (res); + + smp_mb(); + + return oldval; +} + +static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr) +{ + unsigned long tmp, tmp2; + + __asm__ __volatile__("@ atomic_clear_mask\n" +"1: ldrex %0, [%3]\n" +" bic %0, %0, %4\n" +" strex %1, %0, [%3]\n" +" teq %1, #0\n" +" bne 1b" + : "=&r" (tmp), "=&r" (tmp2), "+Qo" (*addr) + : "r" (addr), "Ir" (mask) + : "cc"); +} + +#else /* ARM_ARCH_6 */ + +#ifdef CONFIG_SMP +#error SMP not supported on pre-ARMv6 CPUs +#endif + +static inline int atomic_add_return(int i, atomic_t *v) +{ + unsigned long flags; + int val; + + raw_local_irq_save(flags); + val = v->counter; + v->counter = val += i; + raw_local_irq_restore(flags); + + return val; +} +#define atomic_add(i, v) (void) atomic_add_return(i, v) + +static inline int atomic_sub_return(int i, atomic_t *v) +{ + unsigned long flags; + int val; + + raw_local_irq_save(flags); + val = v->counter; + v->counter = val -= i; + raw_local_irq_restore(flags); + + return val; +} +#define atomic_sub(i, v) (void) atomic_sub_return(i, v) + +static inline int atomic_cmpxchg(atomic_t *v, int old, int new) +{ + int ret; + unsigned long flags; + + raw_local_irq_save(flags); + ret = v->counter; + if (likely(ret == old)) + v->counter = new; + raw_local_irq_restore(flags); + + return ret; +} + +static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr) +{ + unsigned long flags; + + raw_local_irq_save(flags); + *addr &= ~mask; + raw_local_irq_restore(flags); +} + +#endif /* __LINUX_ARM_ARCH__ */ + +#define atomic_xchg(v, new) (xchg(&((v)->counter), new)) + +static inline int atomic_add_unless(atomic_t *v, int a, int u) +{ + int c, old; + + c = atomic_read(v); + while (c != u && (old = atomic_cmpxchg((v), c, c + a)) != c) + c = old; + return c != u; +} +#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) + +#define atomic_inc(v) atomic_add(1, v) +#define atomic_dec(v) atomic_sub(1, v) + +#define atomic_inc_and_test(v) (atomic_add_return(1, v) == 0) +#define atomic_dec_and_test(v) (atomic_sub_return(1, v) == 0) +#define atomic_inc_return(v) (atomic_add_return(1, v)) +#define atomic_dec_return(v) (atomic_sub_return(1, v)) +#define atomic_sub_and_test(i, v) (atomic_sub_return(i, v) == 0) + +#define atomic_add_negative(i,v) (atomic_add_return(i, v) < 0) + +#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() + +#ifndef CONFIG_GENERIC_ATOMIC64 +typedef struct { + u64 __aligned(8) counter; +} atomic64_t; + +#define ATOMIC64_INIT(i) { (i) } + +static inline u64 atomic64_read(atomic64_t *v) +{ + u64 result; + + __asm__ __volatile__("@ atomic64_read\n" +" ldrexd %0, %H0, [%1]" + : "=&r" (result) + : "r" (&v->counter), "Qo" (v->counter) + ); + + return result; +} + +static inline void atomic64_set(atomic64_t *v, u64 i) +{ + u64 tmp; + + __asm__ __volatile__("@ atomic64_set\n" +"1: ldrexd %0, %H0, [%2]\n" +" strexd %0, %3, %H3, [%2]\n" +" teq %0, #0\n" +" bne 1b" + : "=&r" (tmp), "=Qo" (v->counter) + : "r" (&v->counter), "r" (i) + : "cc"); +} + +static inline void atomic64_add(u64 i, atomic64_t *v) +{ + u64 result; + unsigned long tmp; + + __asm__ __volatile__("@ atomic64_add\n" +"1: ldrexd %0, %H0, [%3]\n" +" adds %0, %0, %4\n" +" adc %H0, %H0, %H4\n" +" strexd %1, %0, %H0, [%3]\n" +" teq %1, #0\n" +" bne 1b" + : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) + : "r" (&v->counter), "r" (i) + : "cc"); +} + +static inline u64 atomic64_add_return(u64 i, atomic64_t *v) +{ + u64 result; + unsigned long tmp; + + smp_mb(); + + __asm__ __volatile__("@ atomic64_add_return\n" +"1: ldrexd %0, %H0, [%3]\n" +" adds %0, %0, %4\n" +" adc %H0, %H0, %H4\n" +" strexd %1, %0, %H0, [%3]\n" +" teq %1, #0\n" +" bne 1b" + : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) + : "r" (&v->counter), "r" (i) + : "cc"); + + smp_mb(); + + return result; +} + +static inline void atomic64_sub(u64 i, atomic64_t *v) +{ + u64 result; + unsigned long tmp; + + __asm__ __volatile__("@ atomic64_sub\n" +"1: ldrexd %0, %H0, [%3]\n" +" subs %0, %0, %4\n" +" sbc %H0, %H0, %H4\n" +" strexd %1, %0, %H0, [%3]\n" +" teq %1, #0\n" +" bne 1b" + : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) + : "r" (&v->counter), "r" (i) + : "cc"); +} + +static inline u64 atomic64_sub_return(u64 i, atomic64_t *v) +{ + u64 result; + unsigned long tmp; + + smp_mb(); + + __asm__ __volatile__("@ atomic64_sub_return\n" +"1: ldrexd %0, %H0, [%3]\n" +" subs %0, %0, %4\n" +" sbc %H0, %H0, %H4\n" +" strexd %1, %0, %H0, [%3]\n" +" teq %1, #0\n" +" bne 1b" + : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) + : "r" (&v->counter), "r" (i) + : "cc"); + + smp_mb(); + + return result; +} + +static inline u64 atomic64_cmpxchg(atomic64_t *ptr, u64 old, u64 new) +{ + u64 oldval; + unsigned long res; + + smp_mb(); + + do { + __asm__ __volatile__("@ atomic64_cmpxchg\n" + "ldrexd %1, %H1, [%3]\n" + "mov %0, #0\n" + "teq %1, %4\n" + "teqeq %H1, %H4\n" + "strexdeq %0, %5, %H5, [%3]" + : "=&r" (res), "=&r" (oldval), "+Qo" (ptr->counter) + : "r" (&ptr->counter), "r" (old), "r" (new) + : "cc"); + } while (res); + + smp_mb(); + + return oldval; +} + +static inline u64 atomic64_xchg(atomic64_t *ptr, u64 new) +{ + u64 result; + unsigned long tmp; + + smp_mb(); + + __asm__ __volatile__("@ atomic64_xchg\n" +"1: ldrexd %0, %H0, [%3]\n" +" strexd %1, %4, %H4, [%3]\n" +" teq %1, #0\n" +" bne 1b" + : "=&r" (result), "=&r" (tmp), "+Qo" (ptr->counter) + : "r" (&ptr->counter), "r" (new) + : "cc"); + + smp_mb(); + + return result; +} + +static inline u64 atomic64_dec_if_positive(atomic64_t *v) +{ + u64 result; + unsigned long tmp; + + smp_mb(); + + __asm__ __volatile__("@ atomic64_dec_if_positive\n" +"1: ldrexd %0, %H0, [%3]\n" +" subs %0, %0, #1\n" +" sbc %H0, %H0, #0\n" +" teq %H0, #0\n" +" bmi 2f\n" +" strexd %1, %0, %H0, [%3]\n" +" teq %1, #0\n" +" bne 1b\n" +"2:" + : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) + : "r" (&v->counter) + : "cc"); + + smp_mb(); + + return result; +} + +static inline int atomic64_add_unless(atomic64_t *v, u64 a, u64 u) +{ + u64 val; + unsigned long tmp; + int ret = 1; + + smp_mb(); + + __asm__ __volatile__("@ atomic64_add_unless\n" +"1: ldrexd %0, %H0, [%4]\n" +" teq %0, %5\n" +" teqeq %H0, %H5\n" +" moveq %1, #0\n" +" beq 2f\n" +" adds %0, %0, %6\n" +" adc %H0, %H0, %H6\n" +" strexd %2, %0, %H0, [%4]\n" +" teq %2, #0\n" +" bne 1b\n" +"2:" + : "=&r" (val), "+r" (ret), "=&r" (tmp), "+Qo" (v->counter) + : "r" (&v->counter), "r" (u), "r" (a) + : "cc"); + + if (ret) + smp_mb(); + + return ret; +} + +#define atomic64_add_negative(a, v) (atomic64_add_return((a), (v)) < 0) +#define atomic64_inc(v) atomic64_add(1LL, (v)) +#define atomic64_inc_return(v) atomic64_add_return(1LL, (v)) +#define atomic64_inc_and_test(v) (atomic64_inc_return(v) == 0) +#define atomic64_sub_and_test(a, v) (atomic64_sub_return((a), (v)) == 0) +#define atomic64_dec(v) atomic64_sub(1LL, (v)) +#define atomic64_dec_return(v) atomic64_sub_return(1LL, (v)) +#define atomic64_dec_and_test(v) (atomic64_dec_return((v)) == 0) +#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1LL, 0LL) + +#else /* !CONFIG_GENERIC_ATOMIC64 */ +#include +#endif +#include +#endif +#endif diff --git a/arch/arm/include/asm/auxvec.h b/arch/arm/include/asm/auxvec.h new file mode 100644 index 00000000..c0536f6b --- /dev/null +++ b/arch/arm/include/asm/auxvec.h @@ -0,0 +1,4 @@ +#ifndef __ASMARM_AUXVEC_H +#define __ASMARM_AUXVEC_H + +#endif diff --git a/arch/arm/include/asm/bitops.h b/arch/arm/include/asm/bitops.h new file mode 100644 index 00000000..b4892a06 --- /dev/null +++ b/arch/arm/include/asm/bitops.h @@ -0,0 +1,320 @@ +/* + * Copyright 1995, Russell King. + * Various bits and pieces copyrights include: + * Linus Torvalds (test_bit). + * Big endian support: Copyright 2001, Nicolas Pitre + * reworked by rmk. + * + * bit 0 is the LSB of an "unsigned long" quantity. + * + * Please note that the code in this file should never be included + * from user space. Many of these are not implemented in assembler + * since they would be too costly. Also, they require privileged + * instructions (which are not available from user mode) to ensure + * that they are atomic. + */ + +#ifndef __ASM_ARM_BITOPS_H +#define __ASM_ARM_BITOPS_H + +#ifdef __KERNEL__ + +#ifndef _LINUX_BITOPS_H +#error only can be included directly +#endif + +#include +#include + +#define smp_mb__before_clear_bit() mb() +#define smp_mb__after_clear_bit() mb() + +/* + * These functions are the basis of our bit ops. + * + * First, the atomic bitops. These use native endian. + */ +static inline void ____atomic_set_bit(unsigned int bit, volatile unsigned long *p) +{ + unsigned long flags; + unsigned long mask = 1UL << (bit & 31); + + p += bit >> 5; + + raw_local_irq_save(flags); + *p |= mask; + raw_local_irq_restore(flags); +} + +static inline void ____atomic_clear_bit(unsigned int bit, volatile unsigned long *p) +{ + unsigned long flags; + unsigned long mask = 1UL << (bit & 31); + + p += bit >> 5; + + raw_local_irq_save(flags); + *p &= ~mask; + raw_local_irq_restore(flags); +} + +static inline void ____atomic_change_bit(unsigned int bit, volatile unsigned long *p) +{ + unsigned long flags; + unsigned long mask = 1UL << (bit & 31); + + p += bit >> 5; + + raw_local_irq_save(flags); + *p ^= mask; + raw_local_irq_restore(flags); +} + +static inline int +____atomic_test_and_set_bit(unsigned int bit, volatile unsigned long *p) +{ + unsigned long flags; + unsigned int res; + unsigned long mask = 1UL << (bit & 31); + + p += bit >> 5; + + raw_local_irq_save(flags); + res = *p; + *p = res | mask; + raw_local_irq_restore(flags); + + return (res & mask) != 0; +} + +static inline int +____atomic_test_and_clear_bit(unsigned int bit, volatile unsigned long *p) +{ + unsigned long flags; + unsigned int res; + unsigned long mask = 1UL << (bit & 31); + + p += bit >> 5; + + raw_local_irq_save(flags); + res = *p; + *p = res & ~mask; + raw_local_irq_restore(flags); + + return (res & mask) != 0; +} + +static inline int +____atomic_test_and_change_bit(unsigned int bit, volatile unsigned long *p) +{ + unsigned long flags; + unsigned int res; + unsigned long mask = 1UL << (bit & 31); + + p += bit >> 5; + + raw_local_irq_save(flags); + res = *p; + *p = res ^ mask; + raw_local_irq_restore(flags); + + return (res & mask) != 0; +} + +#include + +/* + * A note about Endian-ness. + * ------------------------- + * + * When the ARM is put into big endian mode via CR15, the processor + * merely swaps the order of bytes within words, thus: + * + * ------------ physical data bus bits ----------- + * D31 ... D24 D23 ... D16 D15 ... D8 D7 ... D0 + * little byte 3 byte 2 byte 1 byte 0 + * big byte 0 byte 1 byte 2 byte 3 + * + * This means that reading a 32-bit word at address 0 returns the same + * value irrespective of the endian mode bit. + * + * Peripheral devices should be connected with the data bus reversed in + * "Big Endian" mode. ARM Application Note 61 is applicable, and is + * available from http://www.arm.com/. + * + * The following assumes that the data bus connectivity for big endian + * mode has been followed. + * + * Note that bit 0 is defined to be 32-bit word bit 0, not byte 0 bit 0. + */ + +/* + * Native endian assembly bitops. nr = 0 -> word 0 bit 0. + */ +extern void _set_bit(int nr, volatile unsigned long * p); +extern void _clear_bit(int nr, volatile unsigned long * p); +extern void _change_bit(int nr, volatile unsigned long * p); +extern int _test_and_set_bit(int nr, volatile unsigned long * p); +extern int _test_and_clear_bit(int nr, volatile unsigned long * p); +extern int _test_and_change_bit(int nr, volatile unsigned long * p); + +/* + * Little endian assembly bitops. nr = 0 -> byte 0 bit 0. + */ +extern int _find_first_zero_bit_le(const void * p, unsigned size); +extern int _find_next_zero_bit_le(const void * p, int size, int offset); +extern int _find_first_bit_le(const unsigned long *p, unsigned size); +extern int _find_next_bit_le(const unsigned long *p, int size, int offset); + +/* + * Big endian assembly bitops. nr = 0 -> byte 3 bit 0. + */ +extern int _find_first_zero_bit_be(const void * p, unsigned size); +extern int _find_next_zero_bit_be(const void * p, int size, int offset); +extern int _find_first_bit_be(const unsigned long *p, unsigned size); +extern int _find_next_bit_be(const unsigned long *p, int size, int offset); + +#ifndef CONFIG_SMP +/* + * The __* form of bitops are non-atomic and may be reordered. + */ +#define ATOMIC_BITOP(name,nr,p) \ + (__builtin_constant_p(nr) ? ____atomic_##name(nr, p) : _##name(nr,p)) +#else +#define ATOMIC_BITOP(name,nr,p) _##name(nr,p) +#endif + +/* + * Native endian atomic definitions. + */ +#define set_bit(nr,p) ATOMIC_BITOP(set_bit,nr,p) +#define clear_bit(nr,p) ATOMIC_BITOP(clear_bit,nr,p) +#define change_bit(nr,p) ATOMIC_BITOP(change_bit,nr,p) +#define test_and_set_bit(nr,p) ATOMIC_BITOP(test_and_set_bit,nr,p) +#define test_and_clear_bit(nr,p) ATOMIC_BITOP(test_and_clear_bit,nr,p) +#define test_and_change_bit(nr,p) ATOMIC_BITOP(test_and_change_bit,nr,p) + +#ifndef __ARMEB__ +/* + * These are the little endian, atomic definitions. + */ +#define find_first_zero_bit(p,sz) _find_first_zero_bit_le(p,sz) +#define find_next_zero_bit(p,sz,off) _find_next_zero_bit_le(p,sz,off) +#define find_first_bit(p,sz) _find_first_bit_le(p,sz) +#define find_next_bit(p,sz,off) _find_next_bit_le(p,sz,off) + +#else +/* + * These are the big endian, atomic definitions. + */ +#define find_first_zero_bit(p,sz) _find_first_zero_bit_be(p,sz) +#define find_next_zero_bit(p,sz,off) _find_next_zero_bit_be(p,sz,off) +#define find_first_bit(p,sz) _find_first_bit_be(p,sz) +#define find_next_bit(p,sz,off) _find_next_bit_be(p,sz,off) + +#endif + +#if __LINUX_ARM_ARCH__ < 5 + +#include +#include +#include +#include +#include + +#else + +static inline int constant_fls(int x) +{ + int r = 32; + + if (!x) + return 0; + if (!(x & 0xffff0000u)) { + x <<= 16; + r -= 16; + } + if (!(x & 0xff000000u)) { + x <<= 8; + r -= 8; + } + if (!(x & 0xf0000000u)) { + x <<= 4; + r -= 4; + } + if (!(x & 0xc0000000u)) { + x <<= 2; + r -= 2; + } + if (!(x & 0x80000000u)) { + x <<= 1; + r -= 1; + } + return r; +} + +/* + * On ARMv5 and above those functions can be implemented around + * the clz instruction for much better code efficiency. + */ + +static inline int fls(int x) +{ + int ret; + + if (__builtin_constant_p(x)) + return constant_fls(x); + + asm("clz\t%0, %1" : "=r" (ret) : "r" (x)); + ret = 32 - ret; + return ret; +} + +#define __fls(x) (fls(x) - 1) +#define ffs(x) ({ unsigned long __t = (x); fls(__t & -__t); }) +#define __ffs(x) (ffs(x) - 1) +#define ffz(x) __ffs( ~(x) ) + +#endif + +#include + +#include +#include +#include + +#ifdef __ARMEB__ + +static inline int find_first_zero_bit_le(const void *p, unsigned size) +{ + return _find_first_zero_bit_le(p, size); +} +#define find_first_zero_bit_le find_first_zero_bit_le + +static inline int find_next_zero_bit_le(const void *p, int size, int offset) +{ + return _find_next_zero_bit_le(p, size, offset); +} +#define find_next_zero_bit_le find_next_zero_bit_le + +static inline int find_next_bit_le(const void *p, int size, int offset) +{ + return _find_next_bit_le(p, size, offset); +} +#define find_next_bit_le find_next_bit_le + +#endif + +#include + +/* + * Ext2 is defined to use little-endian byte ordering. + */ +#define ext2_set_bit_atomic(lock, nr, p) \ + test_and_set_bit_le(nr, p) +#define ext2_clear_bit_atomic(lock, nr, p) \ + test_and_clear_bit_le(nr, p) + +#endif /* __KERNEL__ */ + +#endif /* _ARM_BITOPS_H */ diff --git a/arch/arm/include/asm/bitsperlong.h b/arch/arm/include/asm/bitsperlong.h new file mode 100644 index 00000000..6dc0bb0c --- /dev/null +++ b/arch/arm/include/asm/bitsperlong.h @@ -0,0 +1 @@ +#include diff --git a/arch/arm/include/asm/bug.h b/arch/arm/include/asm/bug.h new file mode 100644 index 00000000..4d88425a --- /dev/null +++ b/arch/arm/include/asm/bug.h @@ -0,0 +1,24 @@ +#ifndef _ASMARM_BUG_H +#define _ASMARM_BUG_H + + +#ifdef CONFIG_BUG +#ifdef CONFIG_DEBUG_BUGVERBOSE +extern void __bug(const char *file, int line) __attribute__((noreturn)); + +/* give file/line information */ +#define BUG() __bug(__FILE__, __LINE__) + +#else + +/* this just causes an oops */ +#define BUG() do { *(int *)0 = 0; } while (1) + +#endif + +#define HAVE_ARCH_BUG +#endif + +#include + +#endif diff --git a/arch/arm/include/asm/bugs.h b/arch/arm/include/asm/bugs.h new file mode 100644 index 00000000..a97f1ea7 --- /dev/null +++ b/arch/arm/include/asm/bugs.h @@ -0,0 +1,21 @@ +/* + * arch/arm/include/asm/bugs.h + * + * Copyright (C) 1995-2003 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __ASM_BUGS_H +#define __ASM_BUGS_H + +#ifdef CONFIG_MMU +extern void check_writebuffer_bugs(void); + +#define check_bugs() check_writebuffer_bugs() +#else +#define check_bugs() do { } while (0) +#endif + +#endif diff --git a/arch/arm/include/asm/byteorder.h b/arch/arm/include/asm/byteorder.h new file mode 100644 index 00000000..77379748 --- /dev/null +++ b/arch/arm/include/asm/byteorder.h @@ -0,0 +1,25 @@ +/* + * arch/arm/include/asm/byteorder.h + * + * ARM Endian-ness. In little endian mode, the data bus is connected such + * that byte accesses appear as: + * 0 = d0...d7, 1 = d8...d15, 2 = d16...d23, 3 = d24...d31 + * and word accesses (data or instruction) appear as: + * d0...d31 + * + * When in big endian mode, byte accesses appear as: + * 0 = d24...d31, 1 = d16...d23, 2 = d8...d15, 3 = d0...d7 + * and word accesses (data or instruction) appear as: + * d0...d31 + */ +#ifndef __ASM_ARM_BYTEORDER_H +#define __ASM_ARM_BYTEORDER_H + +#ifdef __ARMEB__ +#include +#else +#include +#endif + +#endif + diff --git a/arch/arm/include/asm/cache.h b/arch/arm/include/asm/cache.h new file mode 100644 index 00000000..75fe66bc --- /dev/null +++ b/arch/arm/include/asm/cache.h @@ -0,0 +1,28 @@ +/* + * arch/arm/include/asm/cache.h + */ +#ifndef __ASMARM_CACHE_H +#define __ASMARM_CACHE_H + +#define L1_CACHE_SHIFT CONFIG_ARM_L1_CACHE_SHIFT +#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) + +/* + * Memory returned by kmalloc() may be used for DMA, so we must make + * sure that all such allocations are cache aligned. Otherwise, + * unrelated code may cause parts of the buffer to be read into the + * cache before the transfer is done, causing old data to be seen by + * the CPU. + */ +#define ARCH_DMA_MINALIGN L1_CACHE_BYTES + +/* + * With EABI on ARMv5 and above we must have 64-bit aligned slab pointers. + */ +#if defined(CONFIG_AEABI) && (__LINUX_ARM_ARCH__ >= 5) +#define ARCH_SLAB_MINALIGN 8 +#endif + +#define __read_mostly __attribute__((__section__(".data..read_mostly"))) + +#endif diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h new file mode 100644 index 00000000..1252a267 --- /dev/null +++ b/arch/arm/include/asm/cacheflush.h @@ -0,0 +1,347 @@ +/* + * arch/arm/include/asm/cacheflush.h + * + * Copyright (C) 1999-2002 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef _ASMARM_CACHEFLUSH_H +#define _ASMARM_CACHEFLUSH_H + +#include + +#include +#include +#include +#include + +#define CACHE_COLOUR(vaddr) ((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT) + +/* + * This flag is used to indicate that the page pointed to by a pte is clean + * and does not require cleaning before returning it to the user. + */ +#define PG_dcache_clean PG_arch_1 + +/* + * MM Cache Management + * =================== + * + * The arch/arm/mm/cache-*.S and arch/arm/mm/proc-*.S files + * implement these methods. + * + * Start addresses are inclusive and end addresses are exclusive; + * start addresses should be rounded down, end addresses up. + * + * See Documentation/cachetlb.txt for more information. + * Please note that the implementation of these, and the required + * effects are cache-type (VIVT/VIPT/PIPT) specific. + * + * flush_icache_all() + * + * Unconditionally clean and invalidate the entire icache. + * Currently only needed for cache-v6.S and cache-v7.S, see + * __flush_icache_all for the generic implementation. + * + * flush_kern_all() + * + * Unconditionally clean and invalidate the entire cache. + * + * flush_user_all() + * + * Clean and invalidate all user space cache entries + * before a change of page tables. + * + * flush_user_range(start, end, flags) + * + * Clean and invalidate a range of cache entries in the + * specified address space before a change of page tables. + * - start - user start address (inclusive, page aligned) + * - end - user end address (exclusive, page aligned) + * - flags - vma->vm_flags field + * + * coherent_kern_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start, end. If you have non-snooping + * Harvard caches, you need to implement this function. + * - start - virtual start address + * - end - virtual end address + * + * coherent_user_range(start, end) + * + * Ensure coherency between the Icache and the Dcache in the + * region described by start, end. If you have non-snooping + * Harvard caches, you need to implement this function. + * - start - virtual start address + * - end - virtual end address + * + * flush_kern_dcache_area(kaddr, size) + * + * Ensure that the data held in page is written back. + * - kaddr - page address + * - size - region size + * + * DMA Cache Coherency + * =================== + * + * dma_flush_range(start, end) + * + * Clean and invalidate the specified virtual address range. + * - start - virtual start address + * - end - virtual end address + */ + +struct cpu_cache_fns { + void (*flush_icache_all)(void); + void (*flush_kern_all)(void); + void (*flush_user_all)(void); + void (*flush_user_range)(unsigned long, unsigned long, unsigned int); + + void (*coherent_kern_range)(unsigned long, unsigned long); + void (*coherent_user_range)(unsigned long, unsigned long); + void (*flush_kern_dcache_area)(void *, size_t); + + void (*dma_map_area)(const void *, size_t, int); + void (*dma_unmap_area)(const void *, size_t, int); + + void (*dma_flush_range)(const void *, const void *); +}; + +/* + * Select the calling method + */ +#ifdef MULTI_CACHE + +extern struct cpu_cache_fns cpu_cache; + +#define __cpuc_flush_icache_all cpu_cache.flush_icache_all +#define __cpuc_flush_kern_all cpu_cache.flush_kern_all +#define __cpuc_flush_user_all cpu_cache.flush_user_all +#define __cpuc_flush_user_range cpu_cache.flush_user_range +#define __cpuc_coherent_kern_range cpu_cache.coherent_kern_range +#define __cpuc_coherent_user_range cpu_cache.coherent_user_range +#define __cpuc_flush_dcache_area cpu_cache.flush_kern_dcache_area + +/* + * These are private to the dma-mapping API. Do not use directly. + * Their sole purpose is to ensure that data held in the cache + * is visible to DMA, or data written by DMA to system memory is + * visible to the CPU. + */ +#define dmac_map_area cpu_cache.dma_map_area +#define dmac_unmap_area cpu_cache.dma_unmap_area +#define dmac_flush_range cpu_cache.dma_flush_range + +#else + +extern void __cpuc_flush_icache_all(void); +extern void __cpuc_flush_kern_all(void); +extern void __cpuc_flush_user_all(void); +extern void __cpuc_flush_user_range(unsigned long, unsigned long, unsigned int); +extern void __cpuc_coherent_kern_range(unsigned long, unsigned long); +extern void __cpuc_coherent_user_range(unsigned long, unsigned long); +extern void __cpuc_flush_dcache_area(void *, size_t); + +/* + * These are private to the dma-mapping API. Do not use directly. + * Their sole purpose is to ensure that data held in the cache + * is visible to DMA, or data written by DMA to system memory is + * visible to the CPU. + */ +extern void dmac_map_area(const void *, size_t, int); +extern void dmac_unmap_area(const void *, size_t, int); +extern void dmac_flush_range(const void *, const void *); + +#endif + +/* + * Copy user data from/to a page which is mapped into a different + * processes address space. Really, we want to allow our "user + * space" model to handle this. + */ +extern void copy_to_user_page(struct vm_area_struct *, struct page *, + unsigned long, void *, const void *, unsigned long); +#define copy_from_user_page(vma, page, vaddr, dst, src, len) \ + do { \ + memcpy(dst, src, len); \ + } while (0) + +/* + * Convert calls to our calling convention. + */ + +/* Invalidate I-cache */ +#define __flush_icache_all_generic() \ + asm("mcr p15, 0, %0, c7, c5, 0" \ + : : "r" (0)); + +/* Invalidate I-cache inner shareable */ +#define __flush_icache_all_v7_smp() \ + asm("mcr p15, 0, %0, c7, c1, 0" \ + : : "r" (0)); + +/* + * Optimized __flush_icache_all for the common cases. Note that UP ARMv7 + * will fall through to use __flush_icache_all_generic. + */ +#if (defined(CONFIG_CPU_V7) && \ + (defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K))) || \ + defined(CONFIG_SMP_ON_UP) +#define __flush_icache_preferred __cpuc_flush_icache_all +#elif __LINUX_ARM_ARCH__ >= 7 && defined(CONFIG_SMP) +#define __flush_icache_preferred __flush_icache_all_v7_smp +#elif __LINUX_ARM_ARCH__ == 6 && defined(CONFIG_ARM_ERRATA_411920) +#define __flush_icache_preferred __cpuc_flush_icache_all +#else +#define __flush_icache_preferred __flush_icache_all_generic +#endif + +static inline void __flush_icache_all(void) +{ + __flush_icache_preferred(); +} + +#define flush_cache_all() __cpuc_flush_kern_all() + +static inline void vivt_flush_cache_mm(struct mm_struct *mm) +{ + if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(mm))) + __cpuc_flush_user_all(); +} + +static inline void +vivt_flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) +{ + if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) + __cpuc_flush_user_range(start & PAGE_MASK, PAGE_ALIGN(end), + vma->vm_flags); +} + +static inline void +vivt_flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn) +{ + if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) { + unsigned long addr = user_addr & PAGE_MASK; + __cpuc_flush_user_range(addr, addr + PAGE_SIZE, vma->vm_flags); + } +} + +#ifndef CONFIG_CPU_CACHE_VIPT +#define flush_cache_mm(mm) \ + vivt_flush_cache_mm(mm) +#define flush_cache_range(vma,start,end) \ + vivt_flush_cache_range(vma,start,end) +#define flush_cache_page(vma,addr,pfn) \ + vivt_flush_cache_page(vma,addr,pfn) +#else +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 user_addr, unsigned long pfn); +#endif + +#define flush_cache_dup_mm(mm) flush_cache_mm(mm) + +/* + * flush_cache_user_range is used when we want to ensure that the + * Harvard caches are synchronised for the user space address range. + * This is used for the ARM private sys_cacheflush system call. + */ +#define flush_cache_user_range(start,end) \ + __cpuc_coherent_user_range((start) & PAGE_MASK, PAGE_ALIGN(end)) + +/* + * Perform necessary cache operations to ensure that data previously + * stored within this range of addresses can be executed by the CPU. + */ +#define flush_icache_range(s,e) __cpuc_coherent_kern_range(s,e) + +/* + * Perform necessary cache operations to ensure that the TLB will + * see data written in the specified area. + */ +#define clean_dcache_area(start,size) cpu_dcache_clean_area(start, size) + +/* + * flush_dcache_page is used when the kernel has written to the page + * cache page at virtual address page->virtual. + * + * If this page isn't mapped (ie, page_mapping == NULL), or it might + * have userspace mappings, then we _must_ always clean + invalidate + * the dcache entries associated with the kernel mapping. + * + * Otherwise we can defer the operation, and clean the cache when we are + * about to change to user space. This is the same method as used on SPARC64. + * See update_mmu_cache for the user space part. + */ +#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 +extern void flush_dcache_page(struct page *); + +static inline void flush_kernel_vmap_range(void *addr, int size) +{ + if ((cache_is_vivt() || cache_is_vipt_aliasing())) + __cpuc_flush_dcache_area(addr, (size_t)size); +} +static inline void invalidate_kernel_vmap_range(void *addr, int size) +{ + if ((cache_is_vivt() || cache_is_vipt_aliasing())) + __cpuc_flush_dcache_area(addr, (size_t)size); +} + +#define ARCH_HAS_FLUSH_ANON_PAGE +static inline void flush_anon_page(struct vm_area_struct *vma, + struct page *page, unsigned long vmaddr) +{ + extern void __flush_anon_page(struct vm_area_struct *vma, + struct page *, unsigned long); + if (PageAnon(page)) + __flush_anon_page(vma, page, vmaddr); +} + +#define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE +static inline void flush_kernel_dcache_page(struct page *page) +{ +} + +#define flush_dcache_mmap_lock(mapping) \ + spin_lock_irq(&(mapping)->tree_lock) +#define flush_dcache_mmap_unlock(mapping) \ + spin_unlock_irq(&(mapping)->tree_lock) + +#define flush_icache_user_range(vma,page,addr,len) \ + flush_dcache_page(page) + +/* + * We don't appear to need to do anything here. In fact, if we did, we'd + * duplicate cache flushing elsewhere performed by flush_dcache_page(). + */ +#define flush_icache_page(vma,page) do { } while (0) + +/* + * flush_cache_vmap() is used when creating mappings (eg, via vmap, + * vmalloc, ioremap etc) in kernel space for pages. On non-VIPT + * caches, since the direct-mappings of these pages may contain cached + * data, we need to do a full cache flush to ensure that writebacks + * don't corrupt data placed into these pages via the new mappings. + */ +static inline void flush_cache_vmap(unsigned long start, unsigned long end) +{ + if (!cache_is_vipt_nonaliasing()) + flush_cache_all(); + else + /* + * set_pte_at() called from vmap_pte_range() does not + * have a DSB after cleaning the cache line. + */ + dsb(); +} + +static inline void flush_cache_vunmap(unsigned long start, unsigned long end) +{ + if (!cache_is_vipt_nonaliasing()) + flush_cache_all(); +} + +#endif diff --git a/arch/arm/include/asm/cachetype.h b/arch/arm/include/asm/cachetype.h new file mode 100644 index 00000000..c023db09 --- /dev/null +++ b/arch/arm/include/asm/cachetype.h @@ -0,0 +1,56 @@ +#ifndef __ASM_ARM_CACHETYPE_H +#define __ASM_ARM_CACHETYPE_H + +#define CACHEID_VIVT (1 << 0) +#define CACHEID_VIPT_NONALIASING (1 << 1) +#define CACHEID_VIPT_ALIASING (1 << 2) +#define CACHEID_VIPT (CACHEID_VIPT_ALIASING|CACHEID_VIPT_NONALIASING) +#define CACHEID_ASID_TAGGED (1 << 3) +#define CACHEID_VIPT_I_ALIASING (1 << 4) + +extern unsigned int cacheid; + +#define cache_is_vivt() cacheid_is(CACHEID_VIVT) +#define cache_is_vipt() cacheid_is(CACHEID_VIPT) +#define cache_is_vipt_nonaliasing() cacheid_is(CACHEID_VIPT_NONALIASING) +#define cache_is_vipt_aliasing() cacheid_is(CACHEID_VIPT_ALIASING) +#define icache_is_vivt_asid_tagged() cacheid_is(CACHEID_ASID_TAGGED) +#define icache_is_vipt_aliasing() cacheid_is(CACHEID_VIPT_I_ALIASING) + +/* + * __LINUX_ARM_ARCH__ is the minimum supported CPU architecture + * Mask out support which will never be present on newer CPUs. + * - v6+ is never VIVT + * - v7+ VIPT never aliases on D-side + */ +#if __LINUX_ARM_ARCH__ >= 7 +#define __CACHEID_ARCH_MIN (CACHEID_VIPT_NONALIASING |\ + CACHEID_ASID_TAGGED |\ + CACHEID_VIPT_I_ALIASING) +#elif __LINUX_ARM_ARCH__ >= 6 +#define __CACHEID_ARCH_MIN (~CACHEID_VIVT) +#else +#define __CACHEID_ARCH_MIN (~0) +#endif + +/* + * Mask out support which isn't configured + */ +#if defined(CONFIG_CPU_CACHE_VIVT) && !defined(CONFIG_CPU_CACHE_VIPT) +#define __CACHEID_ALWAYS (CACHEID_VIVT) +#define __CACHEID_NEVER (~CACHEID_VIVT) +#elif !defined(CONFIG_CPU_CACHE_VIVT) && defined(CONFIG_CPU_CACHE_VIPT) +#define __CACHEID_ALWAYS (0) +#define __CACHEID_NEVER (CACHEID_VIVT) +#else +#define __CACHEID_ALWAYS (0) +#define __CACHEID_NEVER (0) +#endif + +static inline unsigned int __attribute__((pure)) cacheid_is(unsigned int mask) +{ + return (__CACHEID_ALWAYS & mask) | + (~__CACHEID_NEVER & __CACHEID_ARCH_MIN & mask & cacheid); +} + +#endif diff --git a/arch/arm/include/asm/checksum.h b/arch/arm/include/asm/checksum.h new file mode 100644 index 00000000..6dcc1643 --- /dev/null +++ b/arch/arm/include/asm/checksum.h @@ -0,0 +1,139 @@ +/* + * arch/arm/include/asm/checksum.h + * + * IP checksum routines + * + * Copyright (C) Original authors of ../asm-i386/checksum.h + * Copyright (C) 1996-1999 Russell King + */ +#ifndef __ASM_ARM_CHECKSUM_H +#define __ASM_ARM_CHECKSUM_H + +#include + +/* + * computes the checksum of a memory block at buff, length len, + * and adds in "sum" (32-bit) + * + * returns a 32-bit number suitable for feeding into itself + * or csum_tcpudp_magic + * + * this function must be called with even lengths, except + * for the last fragment, which may be odd + * + * it's best to have buff aligned on a 32-bit boundary + */ +__wsum csum_partial(const void *buff, int len, __wsum sum); + +/* + * the same as csum_partial, but copies from src while it + * checksums, and handles user-space pointer exceptions correctly, when needed. + * + * here even more important to align src and dst on a 32-bit (or even + * better 64-bit) boundary + */ + +__wsum +csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum); + +__wsum +csum_partial_copy_from_user(const void __user *src, void *dst, int len, __wsum sum, int *err_ptr); + +/* + * Fold a partial checksum without adding pseudo headers + */ +static inline __sum16 csum_fold(__wsum sum) +{ + __asm__( + "add %0, %1, %1, ror #16 @ csum_fold" + : "=r" (sum) + : "r" (sum) + : "cc"); + return (__force __sum16)(~(__force u32)sum >> 16); +} + +/* + * This is a version of ip_compute_csum() optimized for IP headers, + * which always checksum on 4 octet boundaries. + */ +static inline __sum16 +ip_fast_csum(const void *iph, unsigned int ihl) +{ + unsigned int tmp1; + __wsum sum; + + __asm__ __volatile__( + "ldr %0, [%1], #4 @ ip_fast_csum \n\ + ldr %3, [%1], #4 \n\ + sub %2, %2, #5 \n\ + adds %0, %0, %3 \n\ + ldr %3, [%1], #4 \n\ + adcs %0, %0, %3 \n\ + ldr %3, [%1], #4 \n\ +1: adcs %0, %0, %3 \n\ + ldr %3, [%1], #4 \n\ + tst %2, #15 @ do this carefully \n\ + subne %2, %2, #1 @ without destroying \n\ + bne 1b @ the carry flag \n\ + adcs %0, %0, %3 \n\ + adc %0, %0, #0" + : "=r" (sum), "=r" (iph), "=r" (ihl), "=r" (tmp1) + : "1" (iph), "2" (ihl) + : "cc", "memory"); + return csum_fold(sum); +} + +static inline __wsum +csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, + unsigned short proto, __wsum sum) +{ + __asm__( + "adds %0, %1, %2 @ csum_tcpudp_nofold \n\ + adcs %0, %0, %3 \n" +#ifdef __ARMEB__ + "adcs %0, %0, %4 \n" +#else + "adcs %0, %0, %4, lsl #8 \n" +#endif + "adcs %0, %0, %5 \n\ + adc %0, %0, #0" + : "=&r"(sum) + : "r" (sum), "r" (daddr), "r" (saddr), "r" (len), "Ir" (htons(proto)) + : "cc"); + return sum; +} +/* + * computes the checksum of the TCP/UDP pseudo-header + * returns a 16-bit checksum, already complemented + */ +static inline __sum16 +csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len, + unsigned short proto, __wsum sum) +{ + return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum)); +} + + +/* + * this routine is used for miscellaneous IP-like checksums, mainly + * in icmp.c + */ +static inline __sum16 +ip_compute_csum(const void *buff, int len) +{ + return csum_fold(csum_partial(buff, len, 0)); +} + +#define _HAVE_ARCH_IPV6_CSUM +extern __wsum +__csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, __be32 len, + __be32 proto, __wsum sum); + +static inline __sum16 +csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, __u32 len, + unsigned short proto, __wsum sum) +{ + return csum_fold(__csum_ipv6_magic(saddr, daddr, htonl(len), + htonl(proto), sum)); +} +#endif diff --git a/arch/arm/include/asm/clkdev.h b/arch/arm/include/asm/clkdev.h new file mode 100644 index 00000000..765d3322 --- /dev/null +++ b/arch/arm/include/asm/clkdev.h @@ -0,0 +1,24 @@ +/* + * arch/arm/include/asm/clkdev.h + * + * Copyright (C) 2008 Russell King. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Helper for the clk API to assist looking up a struct clk. + */ +#ifndef __ASM_CLKDEV_H +#define __ASM_CLKDEV_H + +#include + +#include + +static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size) +{ + return kzalloc(size, GFP_KERNEL); +} + +#endif diff --git a/arch/arm/include/asm/cpu.h b/arch/arm/include/asm/cpu.h new file mode 100644 index 00000000..79396817 --- /dev/null +++ b/arch/arm/include/asm/cpu.h @@ -0,0 +1,26 @@ +/* + * arch/arm/include/asm/cpu.h + * + * Copyright (C) 2004-2005 ARM Ltd. + * + * 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. + */ +#ifndef __ASM_ARM_CPU_H +#define __ASM_ARM_CPU_H + +#include +#include + +struct cpuinfo_arm { + struct cpu cpu; +#ifdef CONFIG_SMP + struct task_struct *idle; + unsigned int loops_per_jiffy; +#endif +}; + +DECLARE_PER_CPU(struct cpuinfo_arm, cpu_data); + +#endif diff --git a/arch/arm/include/asm/cputime.h b/arch/arm/include/asm/cputime.h new file mode 100644 index 00000000..3a8002a5 --- /dev/null +++ b/arch/arm/include/asm/cputime.h @@ -0,0 +1,6 @@ +#ifndef __ARM_CPUTIME_H +#define __ARM_CPUTIME_H + +#include + +#endif /* __ARM_CPUTIME_H */ diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h new file mode 100644 index 00000000..cd4458f6 --- /dev/null +++ b/arch/arm/include/asm/cputype.h @@ -0,0 +1,99 @@ +#ifndef __ASM_ARM_CPUTYPE_H +#define __ASM_ARM_CPUTYPE_H + +#include +#include + +#define CPUID_ID 0 +#define CPUID_CACHETYPE 1 +#define CPUID_TCM 2 +#define CPUID_TLBTYPE 3 + +#define CPUID_EXT_PFR0 "c1, 0" +#define CPUID_EXT_PFR1 "c1, 1" +#define CPUID_EXT_DFR0 "c1, 2" +#define CPUID_EXT_AFR0 "c1, 3" +#define CPUID_EXT_MMFR0 "c1, 4" +#define CPUID_EXT_MMFR1 "c1, 5" +#define CPUID_EXT_MMFR2 "c1, 6" +#define CPUID_EXT_MMFR3 "c1, 7" +#define CPUID_EXT_ISAR0 "c2, 0" +#define CPUID_EXT_ISAR1 "c2, 1" +#define CPUID_EXT_ISAR2 "c2, 2" +#define CPUID_EXT_ISAR3 "c2, 3" +#define CPUID_EXT_ISAR4 "c2, 4" +#define CPUID_EXT_ISAR5 "c2, 5" + +extern unsigned int processor_id; + +#ifdef CONFIG_CPU_CP15 +#define read_cpuid(reg) \ + ({ \ + unsigned int __val; \ + asm("mrc p15, 0, %0, c0, c0, " __stringify(reg) \ + : "=r" (__val) \ + : \ + : "cc"); \ + __val; \ + }) +#define read_cpuid_ext(ext_reg) \ + ({ \ + unsigned int __val; \ + asm("mrc p15, 0, %0, c0, " ext_reg \ + : "=r" (__val) \ + : \ + : "cc"); \ + __val; \ + }) +#else +#define read_cpuid(reg) (processor_id) +#define read_cpuid_ext(reg) 0 +#endif + +/* + * The CPU ID never changes at run time, so we might as well tell the + * compiler that it's constant. Use this function to read the CPU ID + * rather than directly reading processor_id or read_cpuid() directly. + */ +static inline unsigned int __attribute_const__ read_cpuid_id(void) +{ + return read_cpuid(CPUID_ID); +} + +static inline unsigned int __attribute_const__ read_cpuid_cachetype(void) +{ + return read_cpuid(CPUID_CACHETYPE); +} + +static inline unsigned int __attribute_const__ read_cpuid_tcmstatus(void) +{ + return read_cpuid(CPUID_TCM); +} + +/* + * Intel's XScale3 core supports some v6 features (supersections, L2) + * but advertises itself as v5 as it does not support the v6 ISA. For + * this reason, we need a way to explicitly test for this type of CPU. + */ +#ifndef CONFIG_CPU_XSC3 +#define cpu_is_xsc3() 0 +#else +static inline int cpu_is_xsc3(void) +{ + unsigned int id; + id = read_cpuid_id() & 0xffffe000; + /* It covers both Intel ID and Marvell ID */ + if ((id == 0x69056000) || (id == 0x56056000)) + return 1; + + return 0; +} +#endif + +#if !defined(CONFIG_CPU_XSCALE) && !defined(CONFIG_CPU_XSC3) +#define cpu_is_xscale() 0 +#else +#define cpu_is_xscale() 1 +#endif + +#endif diff --git a/arch/arm/include/asm/current.h b/arch/arm/include/asm/current.h new file mode 100644 index 00000000..75d21e2a --- /dev/null +++ b/arch/arm/include/asm/current.h @@ -0,0 +1,15 @@ +#ifndef _ASMARM_CURRENT_H +#define _ASMARM_CURRENT_H + +#include + +static inline struct task_struct *get_current(void) __attribute_const__; + +static inline struct task_struct *get_current(void) +{ + return current_thread_info()->task; +} + +#define current (get_current()) + +#endif /* _ASMARM_CURRENT_H */ diff --git a/arch/arm/include/asm/delay.h b/arch/arm/include/asm/delay.h new file mode 100644 index 00000000..b2deda18 --- /dev/null +++ b/arch/arm/include/asm/delay.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 1995-2004 Russell King + * + * Delay routines, using a pre-computed "loops_per_second" value. + */ +#ifndef __ASM_ARM_DELAY_H +#define __ASM_ARM_DELAY_H + +#include /* HZ */ + +extern void __delay(int loops); + +/* + * This function intentionally does not exist; if you see references to + * it, it means that you're calling udelay() with an out of range value. + * + * With currently imposed limits, this means that we support a max delay + * of 2000us. Further limits: HZ<=1000 and bogomips<=3355 + */ +extern void __bad_udelay(void); + +/* + * 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 + * lookup table, really, as the multiplications take much too long with + * short delays. This is a "reasonable" implementation, though (and the + * first constant multiplications gets optimized away if the delay is + * a constant) + */ +extern void __udelay(unsigned long usecs); +extern void __const_udelay(unsigned long); + +#define MAX_UDELAY_MS 2 + +#define udelay(n) \ + (__builtin_constant_p(n) ? \ + ((n) > (MAX_UDELAY_MS * 1000) ? __bad_udelay() : \ + __const_udelay((n) * ((2199023U*HZ)>>11))) : \ + __udelay(n)) + +#endif /* defined(_ARM_DELAY_H) */ + diff --git a/arch/arm/include/asm/device.h b/arch/arm/include/asm/device.h new file mode 100644 index 00000000..9f390ce3 --- /dev/null +++ b/arch/arm/include/asm/device.h @@ -0,0 +1,18 @@ +/* + * Arch specific extensions to struct device + * + * This file is released under the GPLv2 + */ +#ifndef ASMARM_DEVICE_H +#define ASMARM_DEVICE_H + +struct dev_archdata { +#ifdef CONFIG_DMABOUNCE + struct dmabounce_device_info *dmabounce; +#endif +}; + +struct pdev_archdata { +}; + +#endif diff --git a/arch/arm/include/asm/div64.h b/arch/arm/include/asm/div64.h new file mode 100644 index 00000000..d3f0a9ee --- /dev/null +++ b/arch/arm/include/asm/div64.h @@ -0,0 +1,227 @@ +#ifndef __ASM_ARM_DIV64 +#define __ASM_ARM_DIV64 + +#include +#include + +/* + * The semantics of do_div() are: + * + * uint32_t do_div(uint64_t *n, uint32_t base) + * { + * uint32_t remainder = *n % base; + * *n = *n / base; + * return remainder; + * } + * + * In other words, a 64-bit dividend with a 32-bit divisor producing + * a 64-bit result and a 32-bit remainder. To accomplish this optimally + * we call a special __do_div64 helper with completely non standard + * calling convention for arguments and results (beware). + */ + +#ifdef __ARMEB__ +#define __xh "r0" +#define __xl "r1" +#else +#define __xl "r0" +#define __xh "r1" +#endif + +#define __do_div_asm(n, base) \ +({ \ + register unsigned int __base asm("r4") = base; \ + register unsigned long long __n asm("r0") = n; \ + register unsigned long long __res asm("r2"); \ + register unsigned int __rem asm(__xh); \ + asm( __asmeq("%0", __xh) \ + __asmeq("%1", "r2") \ + __asmeq("%2", "r0") \ + __asmeq("%3", "r4") \ + "bl __do_div64" \ + : "=r" (__rem), "=r" (__res) \ + : "r" (__n), "r" (__base) \ + : "ip", "lr", "cc"); \ + n = __res; \ + __rem; \ +}) + +#if __GNUC__ < 4 + +/* + * gcc versions earlier than 4.0 are simply too problematic for the + * optimized implementation below. First there is gcc PR 15089 that + * tend to trig on more complex constructs, spurious .global __udivsi3 + * are inserted even if none of those symbols are referenced in the + * generated code, and those gcc versions are not able to do constant + * propagation on long long values anyway. + */ +#define do_div(n, base) __do_div_asm(n, base) + +#elif __GNUC__ >= 4 + +#include + +/* + * If the divisor happens to be constant, we determine the appropriate + * inverse at compile time to turn the division into a few inline + * multiplications instead which is much faster. And yet only if compiling + * for ARMv4 or higher (we need umull/umlal) and if the gcc version is + * sufficiently recent to perform proper long long constant propagation. + * (It is unfortunate that gcc doesn't perform all this internally.) + */ +#define do_div(n, base) \ +({ \ + unsigned int __r, __b = (base); \ + if (!__builtin_constant_p(__b) || __b == 0 || \ + (__LINUX_ARM_ARCH__ < 4 && (__b & (__b - 1)) != 0)) { \ + /* non-constant divisor (or zero): slow path */ \ + __r = __do_div_asm(n, __b); \ + } else if ((__b & (__b - 1)) == 0) { \ + /* Trivial: __b is constant and a power of 2 */ \ + /* gcc does the right thing with this code. */ \ + __r = n; \ + __r &= (__b - 1); \ + n /= __b; \ + } else { \ + /* Multiply by inverse of __b: n/b = n*(p/b)/p */ \ + /* We rely on the fact that most of this code gets */ \ + /* optimized away at compile time due to constant */ \ + /* propagation and only a couple inline assembly */ \ + /* instructions should remain. Better avoid any */ \ + /* code construct that might prevent that. */ \ + unsigned long long __res, __x, __t, __m, __n = n; \ + unsigned int __c, __p, __z = 0; \ + /* preserve low part of n for reminder computation */ \ + __r = __n; \ + /* determine number of bits to represent __b */ \ + __p = 1 << __div64_fls(__b); \ + /* compute __m = ((__p << 64) + __b - 1) / __b */ \ + __m = (~0ULL / __b) * __p; \ + __m += (((~0ULL % __b + 1) * __p) + __b - 1) / __b; \ + /* compute __res = __m*(~0ULL/__b*__b-1)/(__p << 64) */ \ + __x = ~0ULL / __b * __b - 1; \ + __res = (__m & 0xffffffff) * (__x & 0xffffffff); \ + __res >>= 32; \ + __res += (__m & 0xffffffff) * (__x >> 32); \ + __t = __res; \ + __res += (__x & 0xffffffff) * (__m >> 32); \ + __t = (__res < __t) ? (1ULL << 32) : 0; \ + __res = (__res >> 32) + __t; \ + __res += (__m >> 32) * (__x >> 32); \ + __res /= __p; \ + /* Now sanitize and optimize what we've got. */ \ + if (~0ULL % (__b / (__b & -__b)) == 0) { \ + /* those cases can be simplified with: */ \ + __n /= (__b & -__b); \ + __m = ~0ULL / (__b / (__b & -__b)); \ + __p = 1; \ + __c = 1; \ + } else if (__res != __x / __b) { \ + /* We can't get away without a correction */ \ + /* to compensate for bit truncation errors. */ \ + /* To avoid it we'd need an additional bit */ \ + /* to represent __m which would overflow it. */ \ + /* Instead we do m=p/b and n/b=(n*m+m)/p. */ \ + __c = 1; \ + /* Compute __m = (__p << 64) / __b */ \ + __m = (~0ULL / __b) * __p; \ + __m += ((~0ULL % __b + 1) * __p) / __b; \ + } else { \ + /* Reduce __m/__p, and try to clear bit 31 */ \ + /* of __m when possible otherwise that'll */ \ + /* need extra overflow handling later. */ \ + unsigned int __bits = -(__m & -__m); \ + __bits |= __m >> 32; \ + __bits = (~__bits) << 1; \ + /* If __bits == 0 then setting bit 31 is */ \ + /* unavoidable. Simply apply the maximum */ \ + /* possible reduction in that case. */ \ + /* Otherwise the MSB of __bits indicates the */ \ + /* best reduction we should apply. */ \ + if (!__bits) { \ + __p /= (__m & -__m); \ + __m /= (__m & -__m); \ + } else { \ + __p >>= __div64_fls(__bits); \ + __m >>= __div64_fls(__bits); \ + } \ + /* No correction needed. */ \ + __c = 0; \ + } \ + /* Now we have a combination of 2 conditions: */ \ + /* 1) whether or not we need a correction (__c), and */ \ + /* 2) whether or not there might be an overflow in */ \ + /* the cross product (__m & ((1<<63) | (1<<31))) */ \ + /* Select the best insn combination to perform the */ \ + /* actual __m * __n / (__p << 64) operation. */ \ + if (!__c) { \ + asm ( "umull %Q0, %R0, %1, %Q2\n\t" \ + "mov %Q0, #0" \ + : "=&r" (__res) \ + : "r" (__m), "r" (__n) \ + : "cc" ); \ + } else if (!(__m & ((1ULL << 63) | (1ULL << 31)))) { \ + __res = __m; \ + asm ( "umlal %Q0, %R0, %Q1, %Q2\n\t" \ + "mov %Q0, #0" \ + : "+&r" (__res) \ + : "r" (__m), "r" (__n) \ + : "cc" ); \ + } else { \ + asm ( "umull %Q0, %R0, %Q1, %Q2\n\t" \ + "cmn %Q0, %Q1\n\t" \ + "adcs %R0, %R0, %R1\n\t" \ + "adc %Q0, %3, #0" \ + : "=&r" (__res) \ + : "r" (__m), "r" (__n), "r" (__z) \ + : "cc" ); \ + } \ + if (!(__m & ((1ULL << 63) | (1ULL << 31)))) { \ + asm ( "umlal %R0, %Q0, %R1, %Q2\n\t" \ + "umlal %R0, %Q0, %Q1, %R2\n\t" \ + "mov %R0, #0\n\t" \ + "umlal %Q0, %R0, %R1, %R2" \ + : "+&r" (__res) \ + : "r" (__m), "r" (__n) \ + : "cc" ); \ + } else { \ + asm ( "umlal %R0, %Q0, %R2, %Q3\n\t" \ + "umlal %R0, %1, %Q2, %R3\n\t" \ + "mov %R0, #0\n\t" \ + "adds %Q0, %1, %Q0\n\t" \ + "adc %R0, %R0, #0\n\t" \ + "umlal %Q0, %R0, %R2, %R3" \ + : "+&r" (__res), "+&r" (__z) \ + : "r" (__m), "r" (__n) \ + : "cc" ); \ + } \ + __res /= __p; \ + /* The reminder can be computed with 32-bit regs */ \ + /* only, and gcc is good at that. */ \ + { \ + unsigned int __res0 = __res; \ + unsigned int __b0 = __b; \ + __r -= __res0 * __b0; \ + } \ + /* BUG_ON(__r >= __b || __res * __b + __r != n); */ \ + n = __res; \ + } \ + __r; \ +}) + +/* our own fls implementation to make sure constant propagation is fine */ +#define __div64_fls(bits) \ +({ \ + unsigned int __left = (bits), __nr = 0; \ + if (__left & 0xffff0000) __nr += 16, __left >>= 16; \ + if (__left & 0x0000ff00) __nr += 8, __left >>= 8; \ + if (__left & 0x000000f0) __nr += 4, __left >>= 4; \ + if (__left & 0x0000000c) __nr += 2, __left >>= 2; \ + if (__left & 0x00000002) __nr += 1; \ + __nr; \ +}) + +#endif + +#endif diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h new file mode 100644 index 00000000..5eaa7a2f --- /dev/null +++ b/arch/arm/include/asm/dma-mapping.h @@ -0,0 +1,568 @@ +#ifndef ASMARM_DMA_MAPPING_H +#define ASMARM_DMA_MAPPING_H + +#ifdef __KERNEL__ + +#include +#include +#include + +#include +#include + +#ifdef __arch_page_to_dma +#error Please update to __arch_pfn_to_dma +#endif + +/* + * dma_to_pfn/pfn_to_dma/dma_to_virt/virt_to_dma are architecture private + * functions used internally by the DMA-mapping API to provide DMA + * addresses. They must not be used by drivers. + */ +#ifndef __arch_pfn_to_dma +static inline dma_addr_t pfn_to_dma(struct device *dev, unsigned long pfn) +{ + return (dma_addr_t)__pfn_to_bus(pfn); +} + +static inline unsigned long dma_to_pfn(struct device *dev, dma_addr_t addr) +{ + return __bus_to_pfn(addr); +} + +static inline void *dma_to_virt(struct device *dev, dma_addr_t addr) +{ + return (void *)__bus_to_virt(addr); +} + +static inline dma_addr_t virt_to_dma(struct device *dev, void *addr) +{ + return (dma_addr_t)__virt_to_bus((unsigned long)(addr)); +} +#else +static inline dma_addr_t pfn_to_dma(struct device *dev, unsigned long pfn) +{ + return __arch_pfn_to_dma(dev, pfn); +} + +static inline unsigned long dma_to_pfn(struct device *dev, dma_addr_t addr) +{ + return __arch_dma_to_pfn(dev, addr); +} + +static inline void *dma_to_virt(struct device *dev, dma_addr_t addr) +{ + return __arch_dma_to_virt(dev, addr); +} + +static inline dma_addr_t virt_to_dma(struct device *dev, void *addr) +{ + return __arch_virt_to_dma(dev, addr); +} +#endif + +/* + * The DMA API is built upon the notion of "buffer ownership". A buffer + * is either exclusively owned by the CPU (and therefore may be accessed + * by it) or exclusively owned by the DMA device. These helper functions + * represent the transitions between these two ownership states. + * + * Note, however, that on later ARMs, this notion does not work due to + * speculative prefetches. We model our approach on the assumption that + * the CPU does do speculative prefetches, which means we clean caches + * before transfers and delay cache invalidation until transfer completion. + * + * Private support functions: these are not part of the API and are + * liable to change. Drivers must not use these. + */ +static inline void __dma_single_cpu_to_dev(const void *kaddr, size_t size, + enum dma_data_direction dir) +{ + extern void ___dma_single_cpu_to_dev(const void *, size_t, + enum dma_data_direction); + + if (!arch_is_coherent()) + ___dma_single_cpu_to_dev(kaddr, size, dir); +} + +static inline void __dma_single_dev_to_cpu(const void *kaddr, size_t size, + enum dma_data_direction dir) +{ + extern void ___dma_single_dev_to_cpu(const void *, size_t, + enum dma_data_direction); + + if (!arch_is_coherent()) + ___dma_single_dev_to_cpu(kaddr, size, dir); +} + +static inline void __dma_page_cpu_to_dev(struct page *page, unsigned long off, + size_t size, enum dma_data_direction dir) +{ + extern void ___dma_page_cpu_to_dev(struct page *, unsigned long, + size_t, enum dma_data_direction); + + if (!arch_is_coherent()) + ___dma_page_cpu_to_dev(page, off, size, dir); +} + +static inline void __dma_page_dev_to_cpu(struct page *page, unsigned long off, + size_t size, enum dma_data_direction dir) +{ + extern void ___dma_page_dev_to_cpu(struct page *, unsigned long, + size_t, enum dma_data_direction); + + if (!arch_is_coherent()) + ___dma_page_dev_to_cpu(page, off, size, dir); +} + +/* + * Return whether the given device DMA address mask can be supported + * properly. For example, if your device can only drive the low 24-bits + * during bus mastering, then you would pass 0x00ffffff as the mask + * to this function. + * + * FIXME: This should really be a platform specific issue - we should + * return false if GFP_DMA allocations may not satisfy the supplied 'mask'. + */ +static inline int dma_supported(struct device *dev, u64 mask) +{ + if (mask < ISA_DMA_THRESHOLD) + return 0; + return 1; +} + +static inline int dma_set_mask(struct device *dev, u64 dma_mask) +{ +#ifdef CONFIG_DMABOUNCE + if (dev->archdata.dmabounce) { + if (dma_mask >= ISA_DMA_THRESHOLD) + return 0; + else + return -EIO; + } +#endif + if (!dev->dma_mask || !dma_supported(dev, dma_mask)) + return -EIO; + + *dev->dma_mask = dma_mask; + + return 0; +} + +/* + * DMA errors are defined by all-bits-set in the DMA address. + */ +static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) +{ + return dma_addr == ~0; +} + +/* + * Dummy noncoherent implementation. We don't provide a dma_cache_sync + * function so drivers using this API are highlighted with build warnings. + */ +static inline void *dma_alloc_noncoherent(struct device *dev, size_t size, + dma_addr_t *handle, gfp_t gfp) +{ + return NULL; +} + +static inline void dma_free_noncoherent(struct device *dev, size_t size, + void *cpu_addr, dma_addr_t handle) +{ +} + +/** + * dma_alloc_noncached - allocate consistent memory for DMA + * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices + * @size: required memory size + * @handle: bus-specific DMA address + * + * Allocate some uncached, unbuffered memory for a device for + * performing DMA. This function allocates pages, and will + * return the CPU-viewed address, and sets @handle to be the + * device-viewed address. + */ +extern void *dma_alloc_noncached(struct device *, size_t, dma_addr_t *, gfp_t); + +/** + * dma_alloc_coherent - allocate consistent memory for DMA + * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices + * @size: required memory size + * @handle: bus-specific DMA address + * + * Allocate some uncached, unbuffered memory for a device for + * performing DMA. This function allocates pages, and will + * return the CPU-viewed address, and sets @handle to be the + * device-viewed address. + */ +extern void *dma_alloc_coherent(struct device *, size_t, dma_addr_t *, gfp_t); + +/** + * dma_alloc_writethrough - allocate consistent memory for DMA + * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices + * @size: required memory size + * @handle: bus-specific DMA address + * + * Allocate some writethrough cached, for a device for + * performing DMA. This function allocates pages, and will + * return the CPU-viewed address, and sets @handle to be the + * device-viewed address. + */ +extern void *dma_alloc_writethrough(struct device *, size_t, dma_addr_t *, gfp_t); + +/** + * dma_alloc_noncacheable - allocate consistent memory for DMA + * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices + * @size: required memory size + * @handle: bus-specific DMA address + * + * Allocate some noncacheable memory, for a device for + * performing DMA. This function allocates pages, and will + * return the CPU-viewed address, and sets @handle to be the + * device-viewed address. + */ +extern void *dma_alloc_noncacheable(struct device *, size_t, dma_addr_t *, gfp_t); + +/** + * dma_free_coherent - free memory allocated by dma_alloc_coherent + * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices + * @size: size of memory originally requested in dma_alloc_coherent + * @cpu_addr: CPU-view address returned from dma_alloc_coherent + * @handle: device-view address returned from dma_alloc_coherent + * + * Free (and unmap) a DMA buffer previously allocated by + * dma_alloc_coherent(). + * + * References to memory and mappings associated with cpu_addr/handle + * during and after this call executing are illegal. + */ +extern void dma_free_coherent(struct device *, size_t, void *, dma_addr_t); + +/** + * dma_mmap_coherent - map a coherent DMA allocation into user space + * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices + * @vma: vm_area_struct describing requested user mapping + * @cpu_addr: kernel CPU-view address returned from dma_alloc_coherent + * @handle: device-view address returned from dma_alloc_coherent + * @size: size of memory originally requested in dma_alloc_coherent + * + * Map a coherent DMA buffer previously allocated by dma_alloc_coherent + * into user space. The coherent DMA buffer must not be freed by the + * driver until the user space mapping has been released. + */ +int dma_mmap_coherent(struct device *, struct vm_area_struct *, + void *, dma_addr_t, size_t); + + +/** + * dma_alloc_writecombine - allocate writecombining memory for DMA + * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices + * @size: required memory size + * @handle: bus-specific DMA address + * + * Allocate some uncached, buffered memory for a device for + * performing DMA. This function allocates pages, and will + * return the CPU-viewed address, and sets @handle to be the + * device-viewed address. + */ +extern void *dma_alloc_writecombine(struct device *, size_t, dma_addr_t *, + gfp_t); + +#define dma_free_writecombine(dev,size,cpu_addr,handle) \ + dma_free_coherent(dev,size,cpu_addr,handle) + +int dma_mmap_writecombine(struct device *, struct vm_area_struct *, + void *, dma_addr_t, size_t); + + +#ifdef CONFIG_DMABOUNCE +/* + * For SA-1111, IXP425, and ADI systems the dma-mapping functions are "magic" + * and utilize bounce buffers as needed to work around limited DMA windows. + * + * On the SA-1111, a bug limits DMA to only certain regions of RAM. + * On the IXP425, the PCI inbound window is 64MB (256MB total RAM) + * On some ADI engineering systems, PCI inbound window is 32MB (12MB total RAM) + * + * The following are helper functions used by the dmabounce subystem + * + */ + +/** + * dmabounce_register_dev + * + * @dev: valid struct device pointer + * @small_buf_size: size of buffers to use with small buffer pool + * @large_buf_size: size of buffers to use with large buffer pool (can be 0) + * + * This function should be called by low-level platform code to register + * a device as requireing DMA buffer bouncing. The function will allocate + * appropriate DMA pools for the device. + * + */ +extern int dmabounce_register_dev(struct device *, unsigned long, + unsigned long); + +/** + * dmabounce_unregister_dev + * + * @dev: valid struct device pointer + * + * This function should be called by low-level platform code when device + * that was previously registered with dmabounce_register_dev is removed + * from the system. + * + */ +extern void dmabounce_unregister_dev(struct device *); + +/** + * dma_needs_bounce + * + * @dev: valid struct device pointer + * @dma_handle: dma_handle of unbounced buffer + * @size: size of region being mapped + * + * Platforms that utilize the dmabounce mechanism must implement + * this function. + * + * The dmabounce routines call this function whenever a dma-mapping + * is requested to determine whether a given buffer needs to be bounced + * or not. The function must return 0 if the buffer is OK for + * DMA access and 1 if the buffer needs to be bounced. + * + */ +extern int dma_needs_bounce(struct device*, dma_addr_t, size_t); + +/* + * The DMA API, implemented by dmabounce.c. See below for descriptions. + */ +extern dma_addr_t __dma_map_single(struct device *, void *, size_t, + enum dma_data_direction); +extern void __dma_unmap_single(struct device *, dma_addr_t, size_t, + enum dma_data_direction); +extern dma_addr_t __dma_map_page(struct device *, struct page *, + unsigned long, size_t, enum dma_data_direction); +extern void __dma_unmap_page(struct device *, dma_addr_t, size_t, + enum dma_data_direction); + +/* + * Private functions + */ +int dmabounce_sync_for_cpu(struct device *, dma_addr_t, unsigned long, + size_t, enum dma_data_direction); +int dmabounce_sync_for_device(struct device *, dma_addr_t, unsigned long, + size_t, enum dma_data_direction); +#else +static inline int dmabounce_sync_for_cpu(struct device *d, dma_addr_t addr, + unsigned long offset, size_t size, enum dma_data_direction dir) +{ + return 1; +} + +static inline int dmabounce_sync_for_device(struct device *d, dma_addr_t addr, + unsigned long offset, size_t size, enum dma_data_direction dir) +{ + return 1; +} + + +static inline dma_addr_t __dma_map_single(struct device *dev, void *cpu_addr, + size_t size, enum dma_data_direction dir) +{ + __dma_single_cpu_to_dev(cpu_addr, size, dir); + return virt_to_dma(dev, cpu_addr); +} + +static inline dma_addr_t __dma_map_page(struct device *dev, struct page *page, + unsigned long offset, size_t size, enum dma_data_direction dir) +{ + __dma_page_cpu_to_dev(page, offset, size, dir); + return pfn_to_dma(dev, page_to_pfn(page)) + offset; +} + +static inline void __dma_unmap_single(struct device *dev, dma_addr_t handle, + size_t size, enum dma_data_direction dir) +{ + __dma_single_dev_to_cpu(dma_to_virt(dev, handle), size, dir); +} + +static inline void __dma_unmap_page(struct device *dev, dma_addr_t handle, + size_t size, enum dma_data_direction dir) +{ + __dma_page_dev_to_cpu(pfn_to_page(dma_to_pfn(dev, handle)), + handle & ~PAGE_MASK, size, dir); +} +#endif /* CONFIG_DMABOUNCE */ + +/** + * dma_map_single - map a single buffer for streaming DMA + * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices + * @cpu_addr: CPU direct mapped address of buffer + * @size: size of buffer to map + * @dir: DMA transfer direction + * + * Ensure that any data held in the cache is appropriately discarded + * or written back. + * + * The device owns this memory once this call has completed. The CPU + * can regain ownership by calling dma_unmap_single() or + * dma_sync_single_for_cpu(). + */ +static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, + size_t size, enum dma_data_direction dir) +{ + dma_addr_t addr; + + BUG_ON(!valid_dma_direction(dir)); + + addr = __dma_map_single(dev, cpu_addr, size, dir); + debug_dma_map_page(dev, virt_to_page(cpu_addr), + (unsigned long)cpu_addr & ~PAGE_MASK, size, + dir, addr, true); + + return addr; +} + +/** + * dma_map_page - map a portion of a page for streaming DMA + * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices + * @page: page that buffer resides in + * @offset: offset into page for start of buffer + * @size: size of buffer to map + * @dir: DMA transfer direction + * + * Ensure that any data held in the cache is appropriately discarded + * or written back. + * + * The device owns this memory once this call has completed. The CPU + * can regain ownership by calling dma_unmap_page(). + */ +static inline dma_addr_t dma_map_page(struct device *dev, struct page *page, + unsigned long offset, size_t size, enum dma_data_direction dir) +{ + dma_addr_t addr; + + BUG_ON(!valid_dma_direction(dir)); + + addr = __dma_map_page(dev, page, offset, size, dir); + debug_dma_map_page(dev, page, offset, size, dir, addr, false); + + return addr; +} + +/** + * dma_unmap_single - unmap a single buffer previously mapped + * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices + * @handle: DMA address of buffer + * @size: size of buffer (same as passed to dma_map_single) + * @dir: DMA transfer direction (same as passed to dma_map_single) + * + * Unmap a single streaming mode DMA translation. The handle and size + * must match what was provided in the previous dma_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. + */ +static inline void dma_unmap_single(struct device *dev, dma_addr_t handle, + size_t size, enum dma_data_direction dir) +{ + debug_dma_unmap_page(dev, handle, size, dir, true); + __dma_unmap_single(dev, handle, size, dir); +} + +/** + * dma_unmap_page - unmap a buffer previously mapped through dma_map_page() + * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices + * @handle: DMA address of buffer + * @size: size of buffer (same as passed to dma_map_page) + * @dir: DMA transfer direction (same as passed to dma_map_page) + * + * Unmap a page streaming mode DMA translation. The handle and size + * must match what was provided in the previous dma_map_page() 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. + */ +static inline void dma_unmap_page(struct device *dev, dma_addr_t handle, + size_t size, enum dma_data_direction dir) +{ + debug_dma_unmap_page(dev, handle, size, dir, false); + __dma_unmap_page(dev, handle, size, dir); +} + +/** + * dma_sync_single_range_for_cpu + * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices + * @handle: DMA address of buffer + * @offset: offset of region to start sync + * @size: size of region to sync + * @dir: DMA transfer direction (same as passed to dma_map_single) + * + * Make physical memory consistent for a single streaming mode DMA + * translation after a transfer. + * + * If you perform a dma_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, you + * must first the perform a dma_sync_for_device, and then the + * device again owns the buffer. + */ +static inline void dma_sync_single_range_for_cpu(struct device *dev, + dma_addr_t handle, unsigned long offset, size_t size, + enum dma_data_direction dir) +{ + BUG_ON(!valid_dma_direction(dir)); + + debug_dma_sync_single_for_cpu(dev, handle + offset, size, dir); + + if (!dmabounce_sync_for_cpu(dev, handle, offset, size, dir)) + return; + + __dma_single_dev_to_cpu(dma_to_virt(dev, handle) + offset, size, dir); +} + +static inline void dma_sync_single_range_for_device(struct device *dev, + dma_addr_t handle, unsigned long offset, size_t size, + enum dma_data_direction dir) +{ + BUG_ON(!valid_dma_direction(dir)); + + debug_dma_sync_single_for_device(dev, handle + offset, size, dir); + + if (!dmabounce_sync_for_device(dev, handle, offset, size, dir)) + return; + + __dma_single_cpu_to_dev(dma_to_virt(dev, handle) + offset, size, dir); +} + +static inline void dma_sync_single_for_cpu(struct device *dev, + dma_addr_t handle, size_t size, enum dma_data_direction dir) +{ + dma_sync_single_range_for_cpu(dev, handle, 0, size, dir); +} + +static inline void dma_sync_single_for_device(struct device *dev, + dma_addr_t handle, size_t size, enum dma_data_direction dir) +{ + dma_sync_single_range_for_device(dev, handle, 0, size, dir); +} + +/* + * The scatter list versions of the above methods. + */ +extern int dma_map_sg(struct device *, struct scatterlist *, int, + enum dma_data_direction); +extern void dma_unmap_sg(struct device *, struct scatterlist *, int, + enum dma_data_direction); +extern void dma_sync_sg_for_cpu(struct device *, struct scatterlist *, int, + enum dma_data_direction); +extern void dma_sync_sg_for_device(struct device *, struct scatterlist *, int, + enum dma_data_direction); + + +#endif /* __KERNEL__ */ +#endif diff --git a/arch/arm/include/asm/dma.h b/arch/arm/include/asm/dma.h new file mode 100644 index 00000000..42005542 --- /dev/null +++ b/arch/arm/include/asm/dma.h @@ -0,0 +1,151 @@ +#ifndef __ASM_ARM_DMA_H +#define __ASM_ARM_DMA_H + +#include + +/* + * This is the maximum virtual address which can be DMA'd from. + */ +#ifndef ARM_DMA_ZONE_SIZE +#define MAX_DMA_ADDRESS 0xffffffff +#else +#define MAX_DMA_ADDRESS (PAGE_OFFSET + ARM_DMA_ZONE_SIZE) +#endif + +#ifdef CONFIG_ISA_DMA_API +/* + * This is used to support drivers written for the x86 ISA DMA API. + * It should not be re-used except for that purpose. + */ +#include +#include +#include + +#include + +/* + * The DMA modes reflect the settings for the ISA DMA controller + */ +#define DMA_MODE_MASK 0xcc + +#define DMA_MODE_READ 0x44 +#define DMA_MODE_WRITE 0x48 +#define DMA_MODE_CASCADE 0xc0 +#define DMA_AUTOINIT 0x10 + +extern spinlock_t dma_spin_lock; + +static inline unsigned long claim_dma_lock(void) +{ + unsigned long flags; + spin_lock_irqsave(&dma_spin_lock, flags); + return flags; +} + +static inline void release_dma_lock(unsigned long flags) +{ + spin_unlock_irqrestore(&dma_spin_lock, flags); +} + +/* Clear the 'DMA Pointer Flip Flop'. + * Write 0 for LSB/MSB, 1 for MSB/LSB access. + */ +#define clear_dma_ff(chan) + +/* Set only the page register bits of the transfer address. + * + * NOTE: This is an architecture specific function, and should + * be hidden from the drivers + */ +extern void set_dma_page(unsigned int chan, char pagenr); + +/* Request a DMA channel + * + * Some architectures may need to do allocate an interrupt + */ +extern int request_dma(unsigned int chan, const char * device_id); + +/* Free a DMA channel + * + * Some architectures may need to do free an interrupt + */ +extern void free_dma(unsigned int chan); + +/* Enable DMA for this channel + * + * On some architectures, this may have other side effects like + * enabling an interrupt and setting the DMA registers. + */ +extern void enable_dma(unsigned int chan); + +/* Disable DMA for this channel + * + * On some architectures, this may have other side effects like + * disabling an interrupt or whatever. + */ +extern void disable_dma(unsigned int chan); + +/* Test whether the specified channel has an active DMA transfer + */ +extern int dma_channel_active(unsigned int chan); + +/* Set the DMA scatter gather list for this channel + * + * This should not be called if a DMA channel is enabled, + * especially since some DMA architectures don't update the + * DMA address immediately, but defer it to the enable_dma(). + */ +extern void set_dma_sg(unsigned int chan, struct scatterlist *sg, int nr_sg); + +/* Set the DMA address for this channel + * + * This should not be called if a DMA channel is enabled, + * especially since some DMA architectures don't update the + * DMA address immediately, but defer it to the enable_dma(). + */ +extern void __set_dma_addr(unsigned int chan, void *addr); +#define set_dma_addr(chan, addr) \ + __set_dma_addr(chan, bus_to_virt(addr)) + +/* Set the DMA byte count for this channel + * + * This should not be called if a DMA channel is enabled, + * especially since some DMA architectures don't update the + * DMA count immediately, but defer it to the enable_dma(). + */ +extern void set_dma_count(unsigned int chan, unsigned long count); + +/* Set the transfer direction for this channel + * + * This should not be called if a DMA channel is enabled, + * especially since some DMA architectures don't update the + * DMA transfer direction immediately, but defer it to the + * enable_dma(). + */ +extern void set_dma_mode(unsigned int chan, unsigned int mode); + +/* Set the transfer speed for this channel + */ +extern void set_dma_speed(unsigned int chan, int cycle_ns); + +/* Get DMA residue count. After a DMA transfer, this + * should return zero. Reading this while a DMA transfer is + * still in progress will return unpredictable results. + * If called before the channel has been used, it may return 1. + * Otherwise, it returns the number of _bytes_ left to transfer. + */ +extern int get_dma_residue(unsigned int chan); + +#ifndef NO_DMA +#define NO_DMA 255 +#endif + +#endif /* CONFIG_ISA_DMA_API */ + +#ifdef CONFIG_PCI +extern int isa_dma_bridge_buggy; +#else +#define isa_dma_bridge_buggy (0) +#endif + +#endif /* __ASM_ARM_DMA_H */ diff --git a/arch/arm/include/asm/domain.h b/arch/arm/include/asm/domain.h new file mode 100644 index 00000000..b5dc173d --- /dev/null +++ b/arch/arm/include/asm/domain.h @@ -0,0 +1,105 @@ +/* + * arch/arm/include/asm/domain.h + * + * Copyright (C) 1999 Russell King. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __ASM_PROC_DOMAIN_H +#define __ASM_PROC_DOMAIN_H + +/* + * Domain numbers + * + * DOMAIN_IO - domain 2 includes all IO only + * DOMAIN_USER - domain 1 includes all user memory only + * DOMAIN_KERNEL - domain 0 includes all kernel memory only + * + * The domain numbering depends on whether we support 36 physical + * address for I/O or not. Addresses above the 32 bit boundary can + * only be mapped using supersections and supersections can only + * be set for domain 0. We could just default to DOMAIN_IO as zero, + * but there may be systems with supersection support and no 36-bit + * addressing. In such cases, we want to map system memory with + * supersections to reduce TLB misses and footprint. + * + * 36-bit addressing and supersections are only available on + * CPUs based on ARMv6+ or the Intel XSC3 core. + */ +#ifndef CONFIG_IO_36 +#define DOMAIN_KERNEL 0 +#define DOMAIN_TABLE 0 +#define DOMAIN_USER 1 +#define DOMAIN_IO 2 +#else +#define DOMAIN_KERNEL 2 +#define DOMAIN_TABLE 2 +#define DOMAIN_USER 1 +#define DOMAIN_IO 0 +#endif + +/* + * Domain types + */ +#define DOMAIN_NOACCESS 0 +#define DOMAIN_CLIENT 1 +#ifdef CONFIG_CPU_USE_DOMAINS +#define DOMAIN_MANAGER 3 +#else +#define DOMAIN_MANAGER 1 +#endif + +#define domain_val(dom,type) ((type) << (2*(dom))) + +#ifndef __ASSEMBLY__ + +#ifdef CONFIG_CPU_USE_DOMAINS +#define set_domain(x) \ + do { \ + __asm__ __volatile__( \ + "mcr p15, 0, %0, c3, c0 @ set domain" \ + : : "r" (x)); \ + isb(); \ + } while (0) + +#define modify_domain(dom,type) \ + do { \ + struct thread_info *thread = current_thread_info(); \ + unsigned int domain = thread->cpu_domain; \ + domain &= ~domain_val(dom, DOMAIN_MANAGER); \ + thread->cpu_domain = domain | domain_val(dom, type); \ + set_domain(thread->cpu_domain); \ + } while (0) + +#else +#define set_domain(x) do { } while (0) +#define modify_domain(dom,type) do { } while (0) +#endif + +/* + * Generate the T (user) versions of the LDR/STR and related + * instructions (inline assembly) + */ +#ifdef CONFIG_CPU_USE_DOMAINS +#define TUSER(instr) #instr "t" +#else +#define TUSER(instr) #instr +#endif + +#else /* __ASSEMBLY__ */ + +/* + * Generate the T (user) versions of the LDR/STR and related + * instructions + */ +#ifdef CONFIG_CPU_USE_DOMAINS +#define TUSER(instr) instr ## t +#else +#define TUSER(instr) instr +#endif + +#endif /* __ASSEMBLY__ */ + +#endif /* !__ASM_PROC_DOMAIN_H */ diff --git a/arch/arm/include/asm/ecard.h b/arch/arm/include/asm/ecard.h new file mode 100644 index 00000000..29f2610e --- /dev/null +++ b/arch/arm/include/asm/ecard.h @@ -0,0 +1,219 @@ +/* + * arch/arm/include/asm/ecard.h + * + * definitions for expansion cards + * + * This is a new system as from Linux 1.2.3 + * + * Changelog: + * 11-12-1996 RMK Further minor improvements + * 12-09-1997 RMK Added interrupt enable/disable for card level + * + * Reference: Acorns Risc OS 3 Programmers Reference Manuals. + */ + +#ifndef __ASM_ECARD_H +#define __ASM_ECARD_H + +/* + * Currently understood cards (but not necessarily + * supported): + * Manufacturer Product ID + */ +#define MANU_ACORN 0x0000 +#define PROD_ACORN_SCSI 0x0002 +#define PROD_ACORN_ETHER1 0x0003 +#define PROD_ACORN_MFM 0x000b + +#define MANU_ANT2 0x0011 +#define PROD_ANT_ETHER3 0x00a4 + +#define MANU_ATOMWIDE 0x0017 +#define PROD_ATOMWIDE_3PSERIAL 0x0090 + +#define MANU_IRLAM_INSTRUMENTS 0x001f +#define MANU_IRLAM_INSTRUMENTS_ETHERN 0x5678 + +#define MANU_OAK 0x0021 +#define PROD_OAK_SCSI 0x0058 + +#define MANU_MORLEY 0x002b +#define PROD_MORLEY_SCSI_UNCACHED 0x0067 + +#define MANU_CUMANA 0x003a +#define PROD_CUMANA_SCSI_2 0x003a +#define PROD_CUMANA_SCSI_1 0x00a0 + +#define MANU_ICS 0x003c +#define PROD_ICS_IDE 0x00ae + +#define MANU_ICS2 0x003d +#define PROD_ICS2_IDE 0x00ae + +#define MANU_SERPORT 0x003f +#define PROD_SERPORT_DSPORT 0x00b9 + +#define MANU_ARXE 0x0041 +#define PROD_ARXE_SCSI 0x00be + +#define MANU_I3 0x0046 +#define PROD_I3_ETHERLAN500 0x00d4 +#define PROD_I3_ETHERLAN600 0x00ec +#define PROD_I3_ETHERLAN600A 0x011e + +#define MANU_ANT 0x0053 +#define PROD_ANT_ETHERM 0x00d8 +#define PROD_ANT_ETHERB 0x00e4 + +#define MANU_ALSYSTEMS 0x005b +#define PROD_ALSYS_SCSIATAPI 0x0107 + +#define MANU_MCS 0x0063 +#define PROD_MCS_CONNECT32 0x0125 + +#define MANU_EESOX 0x0064 +#define PROD_EESOX_SCSI2 0x008c + +#define MANU_YELLOWSTONE 0x0096 +#define PROD_YELLOWSTONE_RAPIDE32 0x0120 + +#ifdef ECARD_C +#define CONST +#else +#define CONST const +#endif + +#define MAX_ECARDS 9 + +struct ecard_id { /* Card ID structure */ + unsigned short manufacturer; + unsigned short product; + void *data; +}; + +struct in_ecid { /* Packed card ID information */ + unsigned short product; /* Product code */ + unsigned short manufacturer; /* Manufacturer code */ + unsigned char id:4; /* Simple ID */ + unsigned char cd:1; /* Chunk dir present */ + unsigned char is:1; /* Interrupt status pointers */ + unsigned char w:2; /* Width */ + unsigned char country; /* Country */ + unsigned char irqmask; /* IRQ mask */ + unsigned char fiqmask; /* FIQ mask */ + unsigned long irqoff; /* IRQ offset */ + unsigned long fiqoff; /* FIQ offset */ +}; + +typedef struct expansion_card ecard_t; +typedef unsigned long *loader_t; + +typedef struct expansion_card_ops { /* Card handler routines */ + void (*irqenable)(ecard_t *ec, int irqnr); + void (*irqdisable)(ecard_t *ec, int irqnr); + int (*irqpending)(ecard_t *ec); + void (*fiqenable)(ecard_t *ec, int fiqnr); + void (*fiqdisable)(ecard_t *ec, int fiqnr); + int (*fiqpending)(ecard_t *ec); +} expansioncard_ops_t; + +#define ECARD_NUM_RESOURCES (6) + +#define ECARD_RES_IOCSLOW (0) +#define ECARD_RES_IOCMEDIUM (1) +#define ECARD_RES_IOCFAST (2) +#define ECARD_RES_IOCSYNC (3) +#define ECARD_RES_MEMC (4) +#define ECARD_RES_EASI (5) + +#define ecard_resource_start(ec,nr) ((ec)->resource[nr].start) +#define ecard_resource_end(ec,nr) ((ec)->resource[nr].end) +#define ecard_resource_len(ec,nr) ((ec)->resource[nr].end - \ + (ec)->resource[nr].start + 1) +#define ecard_resource_flags(ec,nr) ((ec)->resource[nr].flags) + +/* + * This contains all the info needed on an expansion card + */ +struct expansion_card { + struct expansion_card *next; + + struct device dev; + struct resource resource[ECARD_NUM_RESOURCES]; + + /* Public data */ + void __iomem *irqaddr; /* address of IRQ register */ + void __iomem *fiqaddr; /* address of FIQ register */ + unsigned char irqmask; /* IRQ mask */ + unsigned char fiqmask; /* FIQ mask */ + unsigned char claimed; /* Card claimed? */ + unsigned char easi; /* EASI card */ + + void *irq_data; /* Data for use for IRQ by card */ + void *fiq_data; /* Data for use for FIQ by card */ + const expansioncard_ops_t *ops; /* Enable/Disable Ops for card */ + + CONST unsigned int slot_no; /* Slot number */ + CONST unsigned int dma; /* DMA number (for request_dma) */ + CONST unsigned int irq; /* IRQ number (for request_irq) */ + CONST unsigned int fiq; /* FIQ number (for request_irq) */ + CONST struct in_ecid cid; /* Card Identification */ + + /* Private internal data */ + const char *card_desc; /* Card description */ + CONST unsigned int podaddr; /* Base Linux address for card */ + CONST loader_t loader; /* loader program */ + u64 dma_mask; +}; + +void ecard_setirq(struct expansion_card *ec, const struct expansion_card_ops *ops, void *irq_data); + +struct in_chunk_dir { + unsigned int start_offset; + union { + unsigned char string[256]; + unsigned char data[1]; + } d; +}; + +/* + * Read a chunk from an expansion card + * cd : where to put read data + * ec : expansion card info struct + * id : id number to find + * num: (n+1)'th id to find. + */ +extern int ecard_readchunk (struct in_chunk_dir *cd, struct expansion_card *ec, int id, int num); + +/* + * Request and release ecard resources + */ +extern int ecard_request_resources(struct expansion_card *ec); +extern void ecard_release_resources(struct expansion_card *ec); + +void __iomem *ecardm_iomap(struct expansion_card *ec, unsigned int res, + unsigned long offset, unsigned long maxsize); +#define ecardm_iounmap(__ec, __addr) devm_iounmap(&(__ec)->dev, __addr) + +extern struct bus_type ecard_bus_type; + +#define ECARD_DEV(_d) container_of((_d), struct expansion_card, dev) + +struct ecard_driver { + int (*probe)(struct expansion_card *, const struct ecard_id *id); + void (*remove)(struct expansion_card *); + void (*shutdown)(struct expansion_card *); + const struct ecard_id *id_table; + unsigned int id; + struct device_driver drv; +}; + +#define ECARD_DRV(_d) container_of((_d), struct ecard_driver, drv) + +#define ecard_set_drvdata(ec,data) dev_set_drvdata(&(ec)->dev, (data)) +#define ecard_get_drvdata(ec) dev_get_drvdata(&(ec)->dev) + +int ecard_register_driver(struct ecard_driver *); +void ecard_remove_driver(struct ecard_driver *); + +#endif diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h new file mode 100644 index 00000000..0e9ce8d9 --- /dev/null +++ b/arch/arm/include/asm/elf.h @@ -0,0 +1,137 @@ +#ifndef __ASMARM_ELF_H +#define __ASMARM_ELF_H + +#include + +/* + * ELF register definitions.. + */ +#include +#include + +struct task_struct; + +typedef unsigned long elf_greg_t; +typedef unsigned long elf_freg_t[3]; + +#define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t)) +typedef elf_greg_t elf_gregset_t[ELF_NGREG]; + +typedef struct user_fp elf_fpregset_t; + +#define EM_ARM 40 + +#define EF_ARM_EABI_MASK 0xff000000 +#define EF_ARM_EABI_UNKNOWN 0x00000000 +#define EF_ARM_EABI_VER1 0x01000000 +#define EF_ARM_EABI_VER2 0x02000000 +#define EF_ARM_EABI_VER3 0x03000000 +#define EF_ARM_EABI_VER4 0x04000000 +#define EF_ARM_EABI_VER5 0x05000000 + +#define EF_ARM_BE8 0x00800000 /* ABI 4,5 */ +#define EF_ARM_LE8 0x00400000 /* ABI 4,5 */ +#define EF_ARM_MAVERICK_FLOAT 0x00000800 /* ABI 0 */ +#define EF_ARM_VFP_FLOAT 0x00000400 /* ABI 0 */ +#define EF_ARM_SOFT_FLOAT 0x00000200 /* ABI 0 */ +#define EF_ARM_OLD_ABI 0x00000100 /* ABI 0 */ +#define EF_ARM_NEW_ABI 0x00000080 /* ABI 0 */ +#define EF_ARM_ALIGN8 0x00000040 /* ABI 0 */ +#define EF_ARM_PIC 0x00000020 /* ABI 0 */ +#define EF_ARM_MAPSYMSFIRST 0x00000010 /* ABI 2 */ +#define EF_ARM_APCS_FLOAT 0x00000010 /* ABI 0, floats in fp regs */ +#define EF_ARM_DYNSYMSUSESEGIDX 0x00000008 /* ABI 2 */ +#define EF_ARM_APCS_26 0x00000008 /* ABI 0 */ +#define EF_ARM_SYMSARESORTED 0x00000004 /* ABI 1,2 */ +#define EF_ARM_INTERWORK 0x00000004 /* ABI 0 */ +#define EF_ARM_HASENTRY 0x00000002 /* All */ +#define EF_ARM_RELEXEC 0x00000001 /* All */ + +#define R_ARM_NONE 0 +#define R_ARM_PC24 1 +#define R_ARM_ABS32 2 +#define R_ARM_CALL 28 +#define R_ARM_JUMP24 29 +#define R_ARM_V4BX 40 +#define R_ARM_PREL31 42 +#define R_ARM_MOVW_ABS_NC 43 +#define R_ARM_MOVT_ABS 44 + +#define R_ARM_THM_CALL 10 +#define R_ARM_THM_JUMP24 30 +#define R_ARM_THM_MOVW_ABS_NC 47 +#define R_ARM_THM_MOVT_ABS 48 + +/* + * These are used to set parameters in the core dumps. + */ +#define ELF_CLASS ELFCLASS32 +#ifdef __ARMEB__ +#define ELF_DATA ELFDATA2MSB +#else +#define ELF_DATA ELFDATA2LSB +#endif +#define ELF_ARCH EM_ARM + +/* + * This yields a string that ld.so will use to load implementation + * specific libraries for optimization. This is more specific in + * intent than poking at uname or /proc/cpuinfo. + * + * For now we just provide a fairly general string that describes the + * processor family. This could be made more specific later if someone + * implemented optimisations that require it. 26-bit CPUs give you + * "v1l" for ARM2 (no SWP) and "v2l" for anything else (ARM1 isn't + * supported). 32-bit CPUs give you "v3[lb]" for anything based on an + * ARM6 or ARM7 core and "armv4[lb]" for anything based on a StrongARM-1 + * core. + */ +#define ELF_PLATFORM_SIZE 8 +#define ELF_PLATFORM (elf_platform) + +extern char elf_platform[]; + +struct elf32_hdr; + +/* + * This is used to ensure we don't load something for the wrong architecture. + */ +extern int elf_check_arch(const struct elf32_hdr *); +#define elf_check_arch elf_check_arch + +#define vmcore_elf64_check_arch(x) (0) + +extern int arm_elf_read_implies_exec(const struct elf32_hdr *, int); +#define elf_read_implies_exec(ex,stk) arm_elf_read_implies_exec(&(ex), stk) + +struct task_struct; +int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs); +#define ELF_CORE_COPY_TASK_REGS dump_task_regs + +#define CORE_DUMP_USE_REGSET +#define ELF_EXEC_PAGESIZE 4096 + +/* This is the location that an ET_DYN program is loaded if exec'ed. Typical + use of this is to invoke "./ld.so someprog" to test out a new version of + the loader. We need to make sure that it is out of the way of the program + that it will "exec", and that there is sufficient room for the brk. */ + +#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3) + +/* When the program starts, a1 contains a pointer to a function to be + registered with atexit, as per the SVR4 ABI. A value of 0 means we + have no such handler. */ +#define ELF_PLAT_INIT(_r, load_addr) (_r)->ARM_r0 = 0 + +extern void elf_set_personality(const struct elf32_hdr *); +#define SET_PERSONALITY(ex) elf_set_personality(&(ex)) + +struct mm_struct; +extern unsigned long arch_randomize_brk(struct mm_struct *mm); +#define arch_randomize_brk arch_randomize_brk + +extern int vectors_user_mapping(void); +#define arch_setup_additional_pages(bprm, uses_interp) vectors_user_mapping() +#define ARCH_HAS_SETUP_ADDITIONAL_PAGES + +#endif diff --git a/arch/arm/include/asm/emergency-restart.h b/arch/arm/include/asm/emergency-restart.h new file mode 100644 index 00000000..108d8c48 --- /dev/null +++ b/arch/arm/include/asm/emergency-restart.h @@ -0,0 +1,6 @@ +#ifndef _ASM_EMERGENCY_RESTART_H +#define _ASM_EMERGENCY_RESTART_H + +#include + +#endif /* _ASM_EMERGENCY_RESTART_H */ diff --git a/arch/arm/include/asm/entry-macro-multi.S b/arch/arm/include/asm/entry-macro-multi.S new file mode 100644 index 00000000..2da8547d --- /dev/null +++ b/arch/arm/include/asm/entry-macro-multi.S @@ -0,0 +1,46 @@ +#include + +/* + * Interrupt handling. Preserves r7, r8, r9 + */ + .macro arch_irq_handler_default + get_irqnr_preamble r5, lr +1: get_irqnr_and_base r0, r6, r5, lr + movne r1, sp + @ + @ routine called with r0 = irq number, r1 = struct pt_regs * + @ + adrne lr, BSYM(1b) + bne asm_do_IRQ + +#ifdef CONFIG_SMP + /* + * XXX + * + * this macro assumes that irqstat (r6) and base (r5) are + * preserved from get_irqnr_and_base above + */ + ALT_SMP(test_for_ipi r0, r6, r5, lr) + ALT_UP_B(9997f) + movne r1, sp + adrne lr, BSYM(1b) + bne do_IPI + +#ifdef CONFIG_LOCAL_TIMERS + test_for_ltirq r0, r6, r5, lr + movne r0, sp + adrne lr, BSYM(1b) + bne do_local_timer +#endif +#endif +9997: + .endm + + .macro arch_irq_handler, symbol_name + .align 5 + .global \symbol_name +\symbol_name: + mov r4, lr + arch_irq_handler_default + mov pc, r4 + .endm diff --git a/arch/arm/include/asm/entry-macro-vic2.S b/arch/arm/include/asm/entry-macro-vic2.S new file mode 100644 index 00000000..3ceb85e4 --- /dev/null +++ b/arch/arm/include/asm/entry-macro-vic2.S @@ -0,0 +1,57 @@ +/* arch/arm/include/asm/entry-macro-vic2.S + * + * Originally arch/arm/mach-s3c6400/include/mach/entry-macro.S + * + * Copyright 2008 Openmoko, Inc. + * Copyright 2008 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * + * Low-level IRQ helper macros for a device with two VICs + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. +*/ + +/* This should be included from with the necessary + * defines for virtual addresses and IRQ bases for the two vics. + * + * The code needs the following defined: + * IRQ_VIC0_BASE IRQ number of VIC0's first IRQ + * IRQ_VIC1_BASE IRQ number of VIC1's first IRQ + * VA_VIC0 Virtual address of VIC0 + * VA_VIC1 Virtual address of VIC1 + * + * Note, code assumes VIC0's virtual address is an ARM immediate constant + * away from VIC1. +*/ + +#include + + .macro disable_fiq + .endm + + .macro get_irqnr_preamble, base, tmp + ldr \base, =VA_VIC0 + .endm + + .macro arch_ret_to_user, tmp1, tmp2 + .endm + + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + + @ check the vic0 + mov \irqnr, #IRQ_VIC0_BASE + 31 + ldr \irqstat, [ \base, # VIC_IRQ_STATUS ] + teq \irqstat, #0 + + @ otherwise try vic1 + addeq \tmp, \base, #(VA_VIC1 - VA_VIC0) + addeq \irqnr, \irqnr, #(IRQ_VIC1_BASE - IRQ_VIC0_BASE) + ldreq \irqstat, [ \tmp, # VIC_IRQ_STATUS ] + teqeq \irqstat, #0 + + clzne \irqstat, \irqstat + subne \irqnr, \irqnr, \irqstat + .endm diff --git a/arch/arm/include/asm/errno.h b/arch/arm/include/asm/errno.h new file mode 100644 index 00000000..6e60f061 --- /dev/null +++ b/arch/arm/include/asm/errno.h @@ -0,0 +1,6 @@ +#ifndef _ARM_ERRNO_H +#define _ARM_ERRNO_H + +#include + +#endif diff --git a/arch/arm/include/asm/fb.h b/arch/arm/include/asm/fb.h new file mode 100644 index 00000000..d92e99cd --- /dev/null +++ b/arch/arm/include/asm/fb.h @@ -0,0 +1,19 @@ +#ifndef _ASM_FB_H_ +#define _ASM_FB_H_ + +#include +#include +#include + +static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma, + unsigned long off) +{ + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); +} + +static inline int fb_is_primary_device(struct fb_info *info) +{ + return 0; +} + +#endif /* _ASM_FB_H_ */ diff --git a/arch/arm/include/asm/fcntl.h b/arch/arm/include/asm/fcntl.h new file mode 100644 index 00000000..a80b6607 --- /dev/null +++ b/arch/arm/include/asm/fcntl.h @@ -0,0 +1,11 @@ +#ifndef _ARM_FCNTL_H +#define _ARM_FCNTL_H + +#define O_DIRECTORY 040000 /* must be a directory */ +#define O_NOFOLLOW 0100000 /* don't follow links */ +#define O_DIRECT 0200000 /* direct disk access hint - currently ignored */ +#define O_LARGEFILE 0400000 + +#include + +#endif diff --git a/arch/arm/include/asm/fiq.h b/arch/arm/include/asm/fiq.h new file mode 100644 index 00000000..d493d0b7 --- /dev/null +++ b/arch/arm/include/asm/fiq.h @@ -0,0 +1,56 @@ +/* + * arch/arm/include/asm/fiq.h + * + * Support for FIQ on ARM architectures. + * Written by Philip Blundell , 1998 + * Re-written by Russell King + * + * NOTE: The FIQ mode registers are not magically preserved across + * suspend/resume. + * + * Drivers which require these registers to be preserved across power + * management operations must implement appropriate suspend/resume handlers to + * save and restore them. + */ + +#ifndef __ASM_FIQ_H +#define __ASM_FIQ_H + +#include + +struct fiq_handler { + struct fiq_handler *next; + /* Name + */ + const char *name; + /* Called to ask driver to relinquish/ + * reacquire FIQ + * return zero to accept, or - + */ + int (*fiq_op)(void *, int relinquish); + /* data for the relinquish/reacquire functions + */ + void *dev_id; +}; + +extern int claim_fiq(struct fiq_handler *f); +extern void release_fiq(struct fiq_handler *f); +extern void set_fiq_handler(void *start, unsigned int length); +extern void enable_fiq(int fiq); +extern void disable_fiq(int fiq); + +/* helpers defined in fiqasm.S: */ +extern void __set_fiq_regs(unsigned long const *regs); +extern void __get_fiq_regs(unsigned long *regs); + +static inline void set_fiq_regs(struct pt_regs const *regs) +{ + __set_fiq_regs(®s->ARM_r8); +} + +static inline void get_fiq_regs(struct pt_regs *regs) +{ + __get_fiq_regs(®s->ARM_r8); +} + +#endif diff --git a/arch/arm/include/asm/fiq_debugger.h b/arch/arm/include/asm/fiq_debugger.h new file mode 100644 index 00000000..4d274883 --- /dev/null +++ b/arch/arm/include/asm/fiq_debugger.h @@ -0,0 +1,64 @@ +/* + * arch/arm/include/asm/fiq_debugger.h + * + * Copyright (C) 2010 Google, Inc. + * Author: Colin Cross + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#ifndef _ARCH_ARM_MACH_TEGRA_FIQ_DEBUGGER_H_ +#define _ARCH_ARM_MACH_TEGRA_FIQ_DEBUGGER_H_ + +#include + +#define FIQ_DEBUGGER_NO_CHAR NO_POLL_CHAR +#define FIQ_DEBUGGER_BREAK 0x00ff0100 + +#define FIQ_DEBUGGER_FIQ_IRQ_NAME "fiq" +#define FIQ_DEBUGGER_SIGNAL_IRQ_NAME "signal" +#define FIQ_DEBUGGER_WAKEUP_IRQ_NAME "wakeup" + +/** + * struct fiq_debugger_pdata - fiq debugger platform data + * @uart_resume: used to restore uart state right before enabling + * the fiq. + * @uart_enable: Do the work necessary to communicate with the uart + * hw (enable clocks, etc.). This must be ref-counted. + * @uart_disable: Do the work necessary to disable the uart hw + * (disable clocks, etc.). This must be ref-counted. + * @uart_dev_suspend: called during PM suspend, generally not needed + * for real fiq mode debugger. + * @uart_dev_resume: called during PM resume, generally not needed + * for real fiq mode debugger. + */ +struct fiq_debugger_pdata { + int (*uart_init)(struct platform_device *pdev); + void (*uart_free)(struct platform_device *pdev); + int (*uart_resume)(struct platform_device *pdev); + int (*uart_getc)(struct platform_device *pdev); + void (*uart_putc)(struct platform_device *pdev, unsigned int c); + void (*uart_flush)(struct platform_device *pdev); + void (*uart_enable)(struct platform_device *pdev); + void (*uart_disable)(struct platform_device *pdev); + + int (*uart_dev_suspend)(struct platform_device *pdev); + int (*uart_dev_resume)(struct platform_device *pdev); + + void (*fiq_enable)(struct platform_device *pdev, unsigned int fiq, + bool enable); + void (*fiq_ack)(struct platform_device *pdev, unsigned int fiq); + + void (*force_irq)(struct platform_device *pdev, unsigned int irq); + void (*force_irq_ack)(struct platform_device *pdev, unsigned int irq); +}; + +#endif diff --git a/arch/arm/include/asm/fiq_glue.h b/arch/arm/include/asm/fiq_glue.h new file mode 100644 index 00000000..d54c29db --- /dev/null +++ b/arch/arm/include/asm/fiq_glue.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2010 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + */ + +#ifndef __ASM_FIQ_GLUE_H +#define __ASM_FIQ_GLUE_H + +struct fiq_glue_handler { + void (*fiq)(struct fiq_glue_handler *h, void *regs, void *svc_sp); + void (*resume)(struct fiq_glue_handler *h); +}; + +int fiq_glue_register_handler(struct fiq_glue_handler *handler); + +#ifdef CONFIG_FIQ_GLUE +void fiq_glue_resume(void); +#else +static inline void fiq_glue_resume(void) {} +#endif + +#endif diff --git a/arch/arm/include/asm/fixmap.h b/arch/arm/include/asm/fixmap.h new file mode 100644 index 00000000..bbae919b --- /dev/null +++ b/arch/arm/include/asm/fixmap.h @@ -0,0 +1,41 @@ +#ifndef _ASM_FIXMAP_H +#define _ASM_FIXMAP_H + +/* + * Nothing too fancy for now. + * + * On ARM we already have well known fixed virtual addresses imposed by + * the architecture such as the vector page which is located at 0xffff0000, + * therefore a second level page table is already allocated covering + * 0xfff00000 upwards. + * + * The cache flushing code in proc-xscale.S uses the virtual area between + * 0xfffe0000 and 0xfffeffff. + */ + +#define FIXADDR_START 0xfff00000UL +#define FIXADDR_TOP 0xfffe0000UL +#define FIXADDR_SIZE (FIXADDR_TOP - FIXADDR_START) + +#define FIX_KMAP_BEGIN 0 +#define FIX_KMAP_END (FIXADDR_SIZE >> PAGE_SHIFT) + +#define __fix_to_virt(x) (FIXADDR_START + ((x) << PAGE_SHIFT)) +#define __virt_to_fix(x) (((x) - FIXADDR_START) >> PAGE_SHIFT) + +extern void __this_fixmap_does_not_exist(void); + +static inline unsigned long fix_to_virt(const unsigned int idx) +{ + if (idx >= FIX_KMAP_END) + __this_fixmap_does_not_exist(); + return __fix_to_virt(idx); +} + +static inline unsigned int virt_to_fix(const unsigned long vaddr) +{ + BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START); + return __virt_to_fix(vaddr); +} + +#endif diff --git a/arch/arm/include/asm/flat.h b/arch/arm/include/asm/flat.h new file mode 100644 index 00000000..59426a45 --- /dev/null +++ b/arch/arm/include/asm/flat.h @@ -0,0 +1,16 @@ +/* + * arch/arm/include/asm/flat.h -- uClinux flat-format executables + */ + +#ifndef __ARM_FLAT_H__ +#define __ARM_FLAT_H__ + +#define flat_argvp_envp_on_stack() 1 +#define flat_old_ram_flag(flags) (flags) +#define flat_reloc_valid(reloc, size) ((reloc) <= (size)) +#define flat_get_addr_from_rp(rp, relval, flags, persistent) get_unaligned(rp) +#define flat_put_addr_at_rp(rp, val, relval) put_unaligned(val,rp) +#define flat_get_relocate_addr(rel) (rel) +#define flat_set_persistent(relval, p) 0 + +#endif /* __ARM_FLAT_H__ */ diff --git a/arch/arm/include/asm/floppy.h b/arch/arm/include/asm/floppy.h new file mode 100644 index 00000000..c9f03ecc --- /dev/null +++ b/arch/arm/include/asm/floppy.h @@ -0,0 +1,148 @@ +/* + * arch/arm/include/asm/floppy.h + * + * Copyright (C) 1996-2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Note that we don't touch FLOPPY_DMA nor FLOPPY_IRQ here + */ +#ifndef __ASM_ARM_FLOPPY_H +#define __ASM_ARM_FLOPPY_H +#if 0 +#include +#endif + +#define fd_outb(val,port) \ + do { \ + if ((port) == FD_DOR) \ + fd_setdor((val)); \ + else \ + outb((val),(port)); \ + } while(0) + +#define fd_inb(port) inb((port)) +#define fd_request_irq() request_irq(IRQ_FLOPPYDISK,floppy_interrupt,\ + IRQF_DISABLED,"floppy",NULL) +#define fd_free_irq() free_irq(IRQ_FLOPPYDISK,NULL) +#define fd_disable_irq() disable_irq(IRQ_FLOPPYDISK) +#define fd_enable_irq() enable_irq(IRQ_FLOPPYDISK) + +static inline int fd_dma_setup(void *data, unsigned int length, + unsigned int mode, unsigned long addr) +{ + set_dma_mode(DMA_FLOPPY, mode); + __set_dma_addr(DMA_FLOPPY, data); + set_dma_count(DMA_FLOPPY, length); + virtual_dma_port = addr; + enable_dma(DMA_FLOPPY); + return 0; +} +#define fd_dma_setup fd_dma_setup + +#define fd_request_dma() request_dma(DMA_FLOPPY,"floppy") +#define fd_free_dma() free_dma(DMA_FLOPPY) +#define fd_disable_dma() disable_dma(DMA_FLOPPY) + +/* need to clean up dma.h */ +#define DMA_FLOPPYDISK DMA_FLOPPY + +/* Floppy_selects is the list of DOR's to select drive fd + * + * On initialisation, the floppy list is scanned, and the drives allocated + * in the order that they are found. This is done by seeking the drive + * to a non-zero track, and then restoring it to track 0. If an error occurs, + * then there is no floppy drive present. [to be put back in again] + */ +static unsigned char floppy_selects[2][4] = +{ + { 0x10, 0x21, 0x23, 0x33 }, + { 0x10, 0x21, 0x23, 0x33 } +}; + +#define fd_setdor(dor) \ +do { \ + int new_dor = (dor); \ + if (new_dor & 0xf0) \ + new_dor = (new_dor & 0x0c) | floppy_selects[fdc][new_dor & 3]; \ + else \ + new_dor &= 0x0c; \ + outb(new_dor, FD_DOR); \ +} while (0) + +/* + * Someday, we'll automatically detect which drives are present... + */ +static inline void fd_scandrives (void) +{ +#if 0 + int floppy, drive_count; + + fd_disable_irq(); + raw_cmd = &default_raw_cmd; + raw_cmd->flags = FD_RAW_SPIN | FD_RAW_NEED_SEEK; + raw_cmd->track = 0; + raw_cmd->rate = ?; + drive_count = 0; + for (floppy = 0; floppy < 4; floppy ++) { + current_drive = drive_count; + /* + * Turn on floppy motor + */ + if (start_motor(redo_fd_request)) + continue; + /* + * Set up FDC + */ + fdc_specify(); + /* + * Tell FDC to recalibrate + */ + output_byte(FD_RECALIBRATE); + LAST_OUT(UNIT(floppy)); + /* wait for command to complete */ + if (!successful) { + int i; + for (i = drive_count; i < 3; i--) + floppy_selects[fdc][i] = floppy_selects[fdc][i + 1]; + floppy_selects[fdc][3] = 0; + floppy -= 1; + } else + drive_count++; + } +#else + floppy_selects[0][0] = 0x10; + floppy_selects[0][1] = 0x21; + floppy_selects[0][2] = 0x23; + floppy_selects[0][3] = 0x33; +#endif +} + +#define FDC1 (0x3f0) + +#define FLOPPY0_TYPE 4 +#define FLOPPY1_TYPE 4 + +#define N_FDC 1 +#define N_DRIVE 4 + +#define CROSS_64KB(a,s) (0) + +/* + * This allows people to reverse the order of + * fd0 and fd1, in case their hardware is + * strangely connected (as some RiscPCs + * and A5000s seem to be). + */ +static void driveswap(int *ints, int dummy, int dummy2) +{ + floppy_selects[0][0] ^= floppy_selects[0][1]; + floppy_selects[0][1] ^= floppy_selects[0][0]; + floppy_selects[0][0] ^= floppy_selects[0][1]; +} + +#define EXTRA_FLOPPY_PARAMS ,{ "driveswap", &driveswap, NULL, 0, 0 } + +#endif diff --git a/arch/arm/include/asm/fncpy.h b/arch/arm/include/asm/fncpy.h new file mode 100644 index 00000000..de535474 --- /dev/null +++ b/arch/arm/include/asm/fncpy.h @@ -0,0 +1,94 @@ +/* + * arch/arm/include/asm/fncpy.h - helper macros for function body copying + * + * Copyright (C) 2011 Linaro Limited + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This 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 macros are intended for use when there is a need to copy a low-level + * function body into special memory. + * + * For example, when reconfiguring the SDRAM controller, the code doing the + * reconfiguration may need to run from SRAM. + * + * NOTE: that the copied function body must be entirely self-contained and + * position-independent in order for this to work properly. + * + * NOTE: in order for embedded literals and data to get referenced correctly, + * the alignment of functions must be preserved when copying. To ensure this, + * the source and destination addresses for fncpy() must be aligned to a + * multiple of 8 bytes: you will be get a BUG() if this condition is not met. + * You will typically need a ".align 3" directive in the assembler where the + * function to be copied is defined, and ensure that your allocator for the + * destination buffer returns 8-byte-aligned pointers. + * + * Typical usage example: + * + * extern int f(args); + * extern uint32_t size_of_f; + * int (*copied_f)(args); + * void *sram_buffer; + * + * copied_f = fncpy(sram_buffer, &f, size_of_f); + * + * ... later, call the function: ... + * + * copied_f(args); + * + * The size of the function to be copied can't be determined from C: + * this must be determined by other means, such as adding assmbler directives + * in the file where f is defined. + */ + +#ifndef __ASM_FNCPY_H +#define __ASM_FNCPY_H + +#include +#include + +#include +#include + +/* + * Minimum alignment requirement for the source and destination addresses + * for function copying. + */ +#define FNCPY_ALIGN 8 + +#define fncpy(dest_buf, funcp, size) ({ \ + uintptr_t __funcp_address; \ + typeof(funcp) __result; \ + \ + asm("" : "=r" (__funcp_address) : "0" (funcp)); \ + \ + /* \ + * Ensure alignment of source and destination addresses, \ + * disregarding the function's Thumb bit: \ + */ \ + BUG_ON((uintptr_t)(dest_buf) & (FNCPY_ALIGN - 1) || \ + (__funcp_address & ~(uintptr_t)1 & (FNCPY_ALIGN - 1))); \ + \ + memcpy(dest_buf, (void const *)(__funcp_address & ~1), size); \ + flush_icache_range((unsigned long)(dest_buf), \ + (unsigned long)(dest_buf) + (size)); \ + \ + asm("" : "=r" (__result) \ + : "0" ((uintptr_t)(dest_buf) | (__funcp_address & 1))); \ + \ + __result; \ +}) + +#endif /* !__ASM_FNCPY_H */ diff --git a/arch/arm/include/asm/fpstate.h b/arch/arm/include/asm/fpstate.h new file mode 100644 index 00000000..3ad4c10d --- /dev/null +++ b/arch/arm/include/asm/fpstate.h @@ -0,0 +1,93 @@ +/* + * arch/arm/include/asm/fpstate.h + * + * Copyright (C) 1995 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ASM_ARM_FPSTATE_H +#define __ASM_ARM_FPSTATE_H + + +#ifndef __ASSEMBLY__ + +/* + * VFP storage area has: + * - FPEXC, FPSCR, FPINST and FPINST2. + * - 16 or 32 double precision data registers + * - an implementation-dependent word of state for FLDMX/FSTMX (pre-ARMv6) + * + * FPEXC will always be non-zero once the VFP has been used in this process. + */ + +struct vfp_hard_struct { +#ifdef CONFIG_VFPv3 + __u64 fpregs[32]; +#else + __u64 fpregs[16]; +#endif +#if __LINUX_ARM_ARCH__ < 6 + __u32 fpmx_state; +#endif + __u32 fpexc; + __u32 fpscr; + /* + * VFP implementation specific state + */ + __u32 fpinst; + __u32 fpinst2; + +#ifdef CONFIG_SMP + __u32 cpu; +#endif +}; + +union vfp_state { + struct vfp_hard_struct hard; +}; + +extern void vfp_flush_thread(union vfp_state *); +extern void vfp_release_thread(union vfp_state *); + +#define FP_HARD_SIZE 35 + +struct fp_hard_struct { + unsigned int save[FP_HARD_SIZE]; /* as yet undefined */ +}; + +#define FP_SOFT_SIZE 35 + +struct fp_soft_struct { + unsigned int save[FP_SOFT_SIZE]; /* undefined information */ +}; + +#define IWMMXT_SIZE 0x98 + +struct iwmmxt_struct { + unsigned int save[IWMMXT_SIZE / sizeof(unsigned int)]; +}; + +union fp_state { + struct fp_hard_struct hard; + struct fp_soft_struct soft; +#ifdef CONFIG_IWMMXT + struct iwmmxt_struct iwmmxt; +#endif +}; + +#define FP_SIZE (sizeof(union fp_state) / sizeof(int)) + +struct crunch_state { + unsigned int mvdx[16][2]; + unsigned int mvax[4][3]; + unsigned int dspsc[2]; +}; + +#define CRUNCH_SIZE sizeof(struct crunch_state) + +#endif + +#endif diff --git a/arch/arm/include/asm/ftrace.h b/arch/arm/include/asm/ftrace.h new file mode 100644 index 00000000..f89515ad --- /dev/null +++ b/arch/arm/include/asm/ftrace.h @@ -0,0 +1,67 @@ +#ifndef _ASM_ARM_FTRACE +#define _ASM_ARM_FTRACE + +#ifdef CONFIG_FUNCTION_TRACER +#define MCOUNT_ADDR ((unsigned long)(__gnu_mcount_nc)) +#define MCOUNT_INSN_SIZE 4 /* sizeof mcount call */ + +#ifndef __ASSEMBLY__ +extern void mcount(void); +extern void __gnu_mcount_nc(void); + +#ifdef CONFIG_DYNAMIC_FTRACE +struct dyn_arch_ftrace { +#ifdef CONFIG_OLD_MCOUNT + bool old_mcount; +#endif +}; + +static inline unsigned long ftrace_call_adjust(unsigned long addr) +{ + /* With Thumb-2, the recorded addresses have the lsb set */ + return addr & ~1; +} + +extern void ftrace_caller_old(void); +extern void ftrace_call_old(void); +#endif + +#endif + +#endif + +#ifndef __ASSEMBLY__ + +#if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND) +/* + * return_address uses walk_stackframe to do it's work. If both + * CONFIG_FRAME_POINTER=y and CONFIG_ARM_UNWIND=y walk_stackframe uses unwind + * information. For this to work in the function tracer many functions would + * have to be marked with __notrace. So for now just depend on + * !CONFIG_ARM_UNWIND. + */ + +void *return_address(unsigned int); + +#else + +extern inline void *return_address(unsigned int level) +{ + return NULL; +} + +#endif + +#define HAVE_ARCH_CALLER_ADDR + +#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0)) +#define CALLER_ADDR1 ((unsigned long)return_address(1)) +#define CALLER_ADDR2 ((unsigned long)return_address(2)) +#define CALLER_ADDR3 ((unsigned long)return_address(3)) +#define CALLER_ADDR4 ((unsigned long)return_address(4)) +#define CALLER_ADDR5 ((unsigned long)return_address(5)) +#define CALLER_ADDR6 ((unsigned long)return_address(6)) + +#endif /* ifndef __ASSEMBLY__ */ + +#endif /* _ASM_ARM_FTRACE */ diff --git a/arch/arm/include/asm/futex.h b/arch/arm/include/asm/futex.h new file mode 100644 index 00000000..7be54690 --- /dev/null +++ b/arch/arm/include/asm/futex.h @@ -0,0 +1,168 @@ +#ifndef _ASM_ARM_FUTEX_H +#define _ASM_ARM_FUTEX_H + +#ifdef __KERNEL__ + +#if defined(CONFIG_CPU_USE_DOMAINS) && defined(CONFIG_SMP) +/* ARM doesn't provide unprivileged exclusive memory accessors */ +#include +#else + +#include +#include +#include + +#define __futex_atomic_ex_table(err_reg) \ + "3:\n" \ + " .pushsection __ex_table,\"a\"\n" \ + " .align 3\n" \ + " .long 1b, 4f, 2b, 4f\n" \ + " .popsection\n" \ + " .pushsection .fixup,\"ax\"\n" \ + "4: mov %0, " err_reg "\n" \ + " b 3b\n" \ + " .popsection" + +#ifdef CONFIG_SMP + +#define __futex_atomic_op(insn, ret, oldval, tmp, uaddr, oparg) \ + smp_mb(); \ + __asm__ __volatile__( \ + "1: ldrex %1, [%3]\n" \ + " " insn "\n" \ + "2: strex %2, %0, [%3]\n" \ + " teq %2, #0\n" \ + " bne 1b\n" \ + " mov %0, #0\n" \ + __futex_atomic_ex_table("%5") \ + : "=&r" (ret), "=&r" (oldval), "=&r" (tmp) \ + : "r" (uaddr), "r" (oparg), "Ir" (-EFAULT) \ + : "cc", "memory") + +static inline int +futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, + u32 oldval, u32 newval) +{ + int ret; + u32 val; + + if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) + return -EFAULT; + + smp_mb(); + __asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n" + "1: ldrex %1, [%4]\n" + " teq %1, %2\n" + " ite eq @ explicit IT needed for the 2b label\n" + "2: strexeq %0, %3, [%4]\n" + " movne %0, #0\n" + " teq %0, #0\n" + " bne 1b\n" + __futex_atomic_ex_table("%5") + : "=&r" (ret), "=&r" (val) + : "r" (oldval), "r" (newval), "r" (uaddr), "Ir" (-EFAULT) + : "cc", "memory"); + smp_mb(); + + *uval = val; + return ret; +} + +#else /* !SMP, we can work around lack of atomic ops by disabling preemption */ + +#include +#include + +#define __futex_atomic_op(insn, ret, oldval, tmp, uaddr, oparg) \ + __asm__ __volatile__( \ + "1: " TUSER(ldr) " %1, [%3]\n" \ + " " insn "\n" \ + "2: " TUSER(str) " %0, [%3]\n" \ + " mov %0, #0\n" \ + __futex_atomic_ex_table("%5") \ + : "=&r" (ret), "=&r" (oldval), "=&r" (tmp) \ + : "r" (uaddr), "r" (oparg), "Ir" (-EFAULT) \ + : "cc", "memory") + +static inline int +futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, + u32 oldval, u32 newval) +{ + int ret = 0; + u32 val; + + if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) + return -EFAULT; + + __asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n" + "1: " TUSER(ldr) " %1, [%4]\n" + " teq %1, %2\n" + " it eq @ explicit IT needed for the 2b label\n" + "2: " TUSER(streq) " %3, [%4]\n" + __futex_atomic_ex_table("%5") + : "+r" (ret), "=&r" (val) + : "r" (oldval), "r" (newval), "r" (uaddr), "Ir" (-EFAULT) + : "cc", "memory"); + + *uval = val; + return ret; +} + +#endif /* !SMP */ + +static inline int +futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) +{ + int op = (encoded_op >> 28) & 7; + int cmp = (encoded_op >> 24) & 15; + int oparg = (encoded_op << 8) >> 20; + int cmparg = (encoded_op << 20) >> 20; + int oldval = 0, ret, tmp; + + if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) + oparg = 1 << oparg; + + if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) + return -EFAULT; + + pagefault_disable(); /* implies preempt_disable() */ + + switch (op) { + case FUTEX_OP_SET: + __futex_atomic_op("mov %0, %4", ret, oldval, tmp, uaddr, oparg); + break; + case FUTEX_OP_ADD: + __futex_atomic_op("add %0, %1, %4", ret, oldval, tmp, uaddr, oparg); + break; + case FUTEX_OP_OR: + __futex_atomic_op("orr %0, %1, %4", ret, oldval, tmp, uaddr, oparg); + break; + case FUTEX_OP_ANDN: + __futex_atomic_op("and %0, %1, %4", ret, oldval, tmp, uaddr, ~oparg); + break; + case FUTEX_OP_XOR: + __futex_atomic_op("eor %0, %1, %4", ret, oldval, tmp, uaddr, oparg); + break; + default: + ret = -ENOSYS; + } + + pagefault_enable(); /* subsumes preempt_enable() */ + + if (!ret) { + switch (cmp) { + case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; + case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; + case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; + case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; + case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; + case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; + default: ret = -ENOSYS; + } + } + return ret; +} + +#endif /* !(CPU_USE_DOMAINS && SMP) */ +#endif /* __KERNEL__ */ +#endif /* _ASM_ARM_FUTEX_H */ diff --git a/arch/arm/include/asm/glue-cache.h b/arch/arm/include/asm/glue-cache.h new file mode 100644 index 00000000..7e308743 --- /dev/null +++ b/arch/arm/include/asm/glue-cache.h @@ -0,0 +1,146 @@ +/* + * arch/arm/include/asm/glue-cache.h + * + * Copyright (C) 1999-2002 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef ASM_GLUE_CACHE_H +#define ASM_GLUE_CACHE_H + +#include + +/* + * Cache Model + * =========== + */ +#undef _CACHE +#undef MULTI_CACHE + +#if defined(CONFIG_CPU_CACHE_V3) +# ifdef _CACHE +# define MULTI_CACHE 1 +# else +# define _CACHE v3 +# endif +#endif + +#if defined(CONFIG_CPU_CACHE_V4) +# ifdef _CACHE +# define MULTI_CACHE 1 +# else +# define _CACHE v4 +# endif +#endif + +#if defined(CONFIG_CPU_ARM920T) || defined(CONFIG_CPU_ARM922T) || \ + defined(CONFIG_CPU_ARM925T) || defined(CONFIG_CPU_ARM1020) || \ + defined(CONFIG_CPU_ARM1026) +# define MULTI_CACHE 1 +#endif + +#if defined(CONFIG_CPU_FA526) +# ifdef _CACHE +# define MULTI_CACHE 1 +# else +# define _CACHE fa +# endif +#endif + +#if defined(CONFIG_CPU_ARM926T) +# ifdef _CACHE +# define MULTI_CACHE 1 +# else +# define _CACHE arm926 +# endif +#endif + +#if defined(CONFIG_CPU_ARM940T) +# ifdef _CACHE +# define MULTI_CACHE 1 +# else +# define _CACHE arm940 +# endif +#endif + +#if defined(CONFIG_CPU_ARM946E) +# ifdef _CACHE +# define MULTI_CACHE 1 +# else +# define _CACHE arm946 +# endif +#endif + +#if defined(CONFIG_CPU_CACHE_V4WB) +# ifdef _CACHE +# define MULTI_CACHE 1 +# else +# define _CACHE v4wb +# endif +#endif + +#if defined(CONFIG_CPU_XSCALE) +# ifdef _CACHE +# define MULTI_CACHE 1 +# else +# define _CACHE xscale +# endif +#endif + +#if defined(CONFIG_CPU_XSC3) +# ifdef _CACHE +# define MULTI_CACHE 1 +# else +# define _CACHE xsc3 +# endif +#endif + +#if defined(CONFIG_CPU_MOHAWK) +# ifdef _CACHE +# define MULTI_CACHE 1 +# else +# define _CACHE mohawk +# endif +#endif + +#if defined(CONFIG_CPU_FEROCEON) +# define MULTI_CACHE 1 +#endif + +#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) +//# ifdef _CACHE +# define MULTI_CACHE 1 +//# else +//# define _CACHE v6 +//# endif +#endif + +#if defined(CONFIG_CPU_V7) +//# ifdef _CACHE +# define MULTI_CACHE 1 +//# else +//# define _CACHE v7 +//# endif +#endif + +#if !defined(_CACHE) && !defined(MULTI_CACHE) +#error Unknown cache maintenance model +#endif + +#ifndef MULTI_CACHE +#define __cpuc_flush_icache_all __glue(_CACHE,_flush_icache_all) +#define __cpuc_flush_kern_all __glue(_CACHE,_flush_kern_cache_all) +#define __cpuc_flush_user_all __glue(_CACHE,_flush_user_cache_all) +#define __cpuc_flush_user_range __glue(_CACHE,_flush_user_cache_range) +#define __cpuc_coherent_kern_range __glue(_CACHE,_coherent_kern_range) +#define __cpuc_coherent_user_range __glue(_CACHE,_coherent_user_range) +#define __cpuc_flush_dcache_area __glue(_CACHE,_flush_kern_dcache_area) + +#define dmac_map_area __glue(_CACHE,_dma_map_area) +#define dmac_unmap_area __glue(_CACHE,_dma_unmap_area) +#define dmac_flush_range __glue(_CACHE,_dma_flush_range) +#endif + +#endif diff --git a/arch/arm/include/asm/glue-df.h b/arch/arm/include/asm/glue-df.h new file mode 100644 index 00000000..354d571e --- /dev/null +++ b/arch/arm/include/asm/glue-df.h @@ -0,0 +1,110 @@ +/* + * arch/arm/include/asm/glue-df.h + * + * Copyright (C) 1997-1999 Russell King + * Copyright (C) 2000-2002 Deep Blue Solutions Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef ASM_GLUE_DF_H +#define ASM_GLUE_DF_H + +#include + +/* + * Data Abort Model + * ================ + * + * We have the following to choose from: + * arm6 - ARM6 style + * arm7 - ARM7 style + * v4_early - ARMv4 without Thumb early abort handler + * v4t_late - ARMv4 with Thumb late abort handler + * v4t_early - ARMv4 with Thumb early abort handler + * v5tej_early - ARMv5 with Thumb and Java early abort handler + * xscale - ARMv5 with Thumb with Xscale extensions + * v6_early - ARMv6 generic early abort handler + * v7_early - ARMv7 generic early abort handler + */ +#undef CPU_DABORT_HANDLER +#undef MULTI_DABORT + +#if defined(CONFIG_CPU_ARM610) +# ifdef CPU_DABORT_HANDLER +# define MULTI_DABORT 1 +# else +# define CPU_DABORT_HANDLER cpu_arm6_data_abort +# endif +#endif + +#if defined(CONFIG_CPU_ARM710) +# ifdef CPU_DABORT_HANDLER +# define MULTI_DABORT 1 +# else +# define CPU_DABORT_HANDLER cpu_arm7_data_abort +# endif +#endif + +#ifdef CONFIG_CPU_ABRT_LV4T +# ifdef CPU_DABORT_HANDLER +# define MULTI_DABORT 1 +# else +# define CPU_DABORT_HANDLER v4t_late_abort +# endif +#endif + +#ifdef CONFIG_CPU_ABRT_EV4 +# ifdef CPU_DABORT_HANDLER +# define MULTI_DABORT 1 +# else +# define CPU_DABORT_HANDLER v4_early_abort +# endif +#endif + +#ifdef CONFIG_CPU_ABRT_EV4T +# ifdef CPU_DABORT_HANDLER +# define MULTI_DABORT 1 +# else +# define CPU_DABORT_HANDLER v4t_early_abort +# endif +#endif + +#ifdef CONFIG_CPU_ABRT_EV5TJ +# ifdef CPU_DABORT_HANDLER +# define MULTI_DABORT 1 +# else +# define CPU_DABORT_HANDLER v5tj_early_abort +# endif +#endif + +#ifdef CONFIG_CPU_ABRT_EV5T +# ifdef CPU_DABORT_HANDLER +# define MULTI_DABORT 1 +# else +# define CPU_DABORT_HANDLER v5t_early_abort +# endif +#endif + +#ifdef CONFIG_CPU_ABRT_EV6 +# ifdef CPU_DABORT_HANDLER +# define MULTI_DABORT 1 +# else +# define CPU_DABORT_HANDLER v6_early_abort +# endif +#endif + +#ifdef CONFIG_CPU_ABRT_EV7 +# ifdef CPU_DABORT_HANDLER +# define MULTI_DABORT 1 +# else +# define CPU_DABORT_HANDLER v7_early_abort +# endif +#endif + +#ifndef CPU_DABORT_HANDLER +#error Unknown data abort handler type +#endif + +#endif diff --git a/arch/arm/include/asm/glue-pf.h b/arch/arm/include/asm/glue-pf.h new file mode 100644 index 00000000..d385f37c --- /dev/null +++ b/arch/arm/include/asm/glue-pf.h @@ -0,0 +1,57 @@ +/* + * arch/arm/include/asm/glue-pf.h + * + * Copyright (C) 1997-1999 Russell King + * Copyright (C) 2000-2002 Deep Blue Solutions Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef ASM_GLUE_PF_H +#define ASM_GLUE_PF_H + +#include + +/* + * Prefetch Abort Model + * ================ + * + * We have the following to choose from: + * legacy - no IFSR, no IFAR + * v6 - ARMv6: IFSR, no IFAR + * v7 - ARMv7: IFSR and IFAR + */ + +#undef CPU_PABORT_HANDLER +#undef MULTI_PABORT + +#ifdef CONFIG_CPU_PABRT_LEGACY +# ifdef CPU_PABORT_HANDLER +# define MULTI_PABORT 1 +# else +# define CPU_PABORT_HANDLER legacy_pabort +# endif +#endif + +#ifdef CONFIG_CPU_PABRT_V6 +# ifdef CPU_PABORT_HANDLER +# define MULTI_PABORT 1 +# else +# define CPU_PABORT_HANDLER v6_pabort +# endif +#endif + +#ifdef CONFIG_CPU_PABRT_V7 +# ifdef CPU_PABORT_HANDLER +# define MULTI_PABORT 1 +# else +# define CPU_PABORT_HANDLER v7_pabort +# endif +#endif + +#ifndef CPU_PABORT_HANDLER +#error Unknown prefetch abort handler type +#endif + +#endif diff --git a/arch/arm/include/asm/glue-proc.h b/arch/arm/include/asm/glue-proc.h new file mode 100644 index 00000000..e2be7f14 --- /dev/null +++ b/arch/arm/include/asm/glue-proc.h @@ -0,0 +1,264 @@ +/* + * arch/arm/include/asm/glue-proc.h + * + * Copyright (C) 1997-1999 Russell King + * Copyright (C) 2000 Deep Blue Solutions Ltd + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef ASM_GLUE_PROC_H +#define ASM_GLUE_PROC_H + +#include + +/* + * Work out if we need multiple CPU support + */ +#undef MULTI_CPU +#undef CPU_NAME + +/* + * CPU_NAME - the prefix for CPU related functions + */ + +#ifdef CONFIG_CPU_ARM610 +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm6 +# endif +#endif + +#ifdef CONFIG_CPU_ARM7TDMI +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm7tdmi +# endif +#endif + +#ifdef CONFIG_CPU_ARM710 +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm7 +# endif +#endif + +#ifdef CONFIG_CPU_ARM720T +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm720 +# endif +#endif + +#ifdef CONFIG_CPU_ARM740T +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm740 +# endif +#endif + +#ifdef CONFIG_CPU_ARM9TDMI +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm9tdmi +# endif +#endif + +#ifdef CONFIG_CPU_ARM920T +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm920 +# endif +#endif + +#ifdef CONFIG_CPU_ARM922T +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm922 +# endif +#endif + +#ifdef CONFIG_CPU_FA526 +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_fa526 +# endif +#endif + +#ifdef CONFIG_CPU_ARM925T +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm925 +# endif +#endif + +#ifdef CONFIG_CPU_ARM926T +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm926 +# endif +#endif + +#ifdef CONFIG_CPU_ARM940T +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm940 +# endif +#endif + +#ifdef CONFIG_CPU_ARM946E +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm946 +# endif +#endif + +#ifdef CONFIG_CPU_SA110 +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_sa110 +# endif +#endif + +#ifdef CONFIG_CPU_SA1100 +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_sa1100 +# endif +#endif + +#ifdef CONFIG_CPU_ARM1020 +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm1020 +# endif +#endif + +#ifdef CONFIG_CPU_ARM1020E +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm1020e +# endif +#endif + +#ifdef CONFIG_CPU_ARM1022 +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm1022 +# endif +#endif + +#ifdef CONFIG_CPU_ARM1026 +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_arm1026 +# endif +#endif + +#ifdef CONFIG_CPU_XSCALE +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_xscale +# endif +#endif + +#ifdef CONFIG_CPU_XSC3 +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_xsc3 +# endif +#endif + +#ifdef CONFIG_CPU_MOHAWK +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_mohawk +# endif +#endif + +#ifdef CONFIG_CPU_FEROCEON +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_feroceon +# endif +#endif + +#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_v6 +# endif +#endif + +#ifdef CONFIG_CPU_V7 +# ifdef CPU_NAME +# undef MULTI_CPU +# define MULTI_CPU +# else +# define CPU_NAME cpu_v7 +# endif +#endif + +#ifndef MULTI_CPU +#define cpu_proc_init __glue(CPU_NAME,_proc_init) +#define cpu_proc_fin __glue(CPU_NAME,_proc_fin) +#define cpu_reset __glue(CPU_NAME,_reset) +#define cpu_do_idle __glue(CPU_NAME,_do_idle) +#define cpu_dcache_clean_area __glue(CPU_NAME,_dcache_clean_area) +#define cpu_do_switch_mm __glue(CPU_NAME,_switch_mm) +#define cpu_set_pte_ext __glue(CPU_NAME,_set_pte_ext) +#define cpu_suspend_size __glue(CPU_NAME,_suspend_size) +#define cpu_do_suspend __glue(CPU_NAME,_do_suspend) +#define cpu_do_resume __glue(CPU_NAME,_do_resume) +#endif + +#endif diff --git a/arch/arm/include/asm/glue.h b/arch/arm/include/asm/glue.h new file mode 100644 index 00000000..fbf71d75 --- /dev/null +++ b/arch/arm/include/asm/glue.h @@ -0,0 +1,25 @@ +/* + * arch/arm/include/asm/glue.h + * + * Copyright (C) 1997-1999 Russell King + * Copyright (C) 2000-2002 Deep Blue Solutions Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This file provides the glue to stick the processor-specific bits + * into the kernel in an efficient manner. The idea is to use branches + * when we're only targeting one class of TLB, or indirect calls + * when we're targeting multiple classes of TLBs. + */ +#ifdef __KERNEL__ + +#ifdef __STDC__ +#define ____glue(name,fn) name##fn +#else +#define ____glue(name,fn) name/**/fn +#endif +#define __glue(name,fn) ____glue(name,fn) + +#endif diff --git a/arch/arm/include/asm/gpio.h b/arch/arm/include/asm/gpio.h new file mode 100644 index 00000000..166a7a3e --- /dev/null +++ b/arch/arm/include/asm/gpio.h @@ -0,0 +1,7 @@ +#ifndef _ARCH_ARM_GPIO_H +#define _ARCH_ARM_GPIO_H + +/* not all ARM platforms necessarily support this API ... */ +#include + +#endif /* _ARCH_ARM_GPIO_H */ diff --git a/arch/arm/include/asm/hardirq.h b/arch/arm/include/asm/hardirq.h new file mode 100644 index 00000000..2635c8b5 --- /dev/null +++ b/arch/arm/include/asm/hardirq.h @@ -0,0 +1,52 @@ +#ifndef __ASM_HARDIRQ_H +#define __ASM_HARDIRQ_H + +#include +#include +#include + +#define NR_IPI 6 + +typedef struct { + unsigned int __softirq_pending; +#ifdef CONFIG_LOCAL_TIMERS + unsigned int local_timer_irqs; +#endif +#ifdef CONFIG_SMP + unsigned int ipi_irqs[NR_IPI]; +#endif +} ____cacheline_aligned irq_cpustat_t; + +#include /* Standard mappings for irq_cpustat_t above */ + +#define __inc_irq_stat(cpu, member) __IRQ_STAT(cpu, member)++ +#define __get_irq_stat(cpu, member) __IRQ_STAT(cpu, member) + +#ifdef CONFIG_SMP +u64 smp_irq_stat_cpu(unsigned int cpu); +#else +#define smp_irq_stat_cpu(cpu) 0 +#endif + +#define arch_irq_stat_cpu smp_irq_stat_cpu + +#if NR_IRQS > 512 +#define HARDIRQ_BITS 10 +#elif NR_IRQS > 256 +#define HARDIRQ_BITS 9 +#else +#define HARDIRQ_BITS 8 +#endif + +/* + * 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 + +#define __ARCH_IRQ_EXIT_IRQS_DISABLED 1 + +#endif /* __ASM_HARDIRQ_H */ diff --git a/arch/arm/include/asm/hardware/arm_timer.h b/arch/arm/include/asm/hardware/arm_timer.h new file mode 100644 index 00000000..c0f4e7bf --- /dev/null +++ b/arch/arm/include/asm/hardware/arm_timer.h @@ -0,0 +1,30 @@ +#ifndef __ASM_ARM_HARDWARE_ARM_TIMER_H +#define __ASM_ARM_HARDWARE_ARM_TIMER_H + +/* + * ARM timer implementation, found in Integrator, Versatile and Realview + * platforms. Not all platforms support all registers and bits in these + * registers, so we mark them with A for Integrator AP, C for Integrator + * CP, V for Versatile and R for Realview. + * + * Integrator AP has 16-bit timers, Integrator CP, Versatile and Realview + * can have 16-bit or 32-bit selectable via a bit in the control register. + */ +#define TIMER_LOAD 0x00 /* ACVR rw */ +#define TIMER_VALUE 0x04 /* ACVR ro */ +#define TIMER_CTRL 0x08 /* ACVR rw */ +#define TIMER_CTRL_ONESHOT (1 << 0) /* CVR */ +#define TIMER_CTRL_32BIT (1 << 1) /* CVR */ +#define TIMER_CTRL_DIV1 (0 << 2) /* ACVR */ +#define TIMER_CTRL_DIV16 (1 << 2) /* ACVR */ +#define TIMER_CTRL_DIV256 (2 << 2) /* ACVR */ +#define TIMER_CTRL_IE (1 << 5) /* VR */ +#define TIMER_CTRL_PERIODIC (1 << 6) /* ACVR */ +#define TIMER_CTRL_ENABLE (1 << 7) /* ACVR */ + +#define TIMER_INTCLR 0x0c /* ACVR wo */ +#define TIMER_RIS 0x10 /* CVR ro */ +#define TIMER_MIS 0x14 /* CVR ro */ +#define TIMER_BGLOAD 0x18 /* CVR rw */ + +#endif diff --git a/arch/arm/include/asm/hardware/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h new file mode 100644 index 00000000..2a20876e --- /dev/null +++ b/arch/arm/include/asm/hardware/cache-l2x0.h @@ -0,0 +1,82 @@ +/* + * arch/arm/include/asm/hardware/cache-l2x0.h + * + * Copyright (C) 2007 ARM Limited + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This 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_ARM_HARDWARE_L2X0_H +#define __ASM_ARM_HARDWARE_L2X0_H + +#define L2X0_CACHE_ID 0x000 +#define L2X0_CACHE_TYPE 0x004 +#define L2X0_CTRL 0x100 +#define L2X0_AUX_CTRL 0x104 +#define L2X0_TAG_LATENCY_CTRL 0x108 +#define L2X0_DATA_LATENCY_CTRL 0x10C +#define L2X0_EVENT_CNT_CTRL 0x200 +#define L2X0_EVENT_CNT1_CFG 0x204 +#define L2X0_EVENT_CNT0_CFG 0x208 +#define L2X0_EVENT_CNT1_VAL 0x20C +#define L2X0_EVENT_CNT0_VAL 0x210 +#define L2X0_INTR_MASK 0x214 +#define L2X0_MASKED_INTR_STAT 0x218 +#define L2X0_RAW_INTR_STAT 0x21C +#define L2X0_INTR_CLEAR 0x220 +#define L2X0_CACHE_SYNC 0x730 +#define L2X0_DUMMY_REG 0x740 +#define L2X0_INV_LINE_PA 0x770 +#define L2X0_INV_WAY 0x77C +#define L2X0_CLEAN_LINE_PA 0x7B0 +#define L2X0_CLEAN_LINE_IDX 0x7B8 +#define L2X0_CLEAN_WAY 0x7BC +#define L2X0_CLEAN_INV_LINE_PA 0x7F0 +#define L2X0_CLEAN_INV_LINE_IDX 0x7F8 +#define L2X0_CLEAN_INV_WAY 0x7FC +#define L2X0_LOCKDOWN_WAY_D 0x900 +#define L2X0_LOCKDOWN_WAY_I 0x904 +#define L2X0_TEST_OPERATION 0xF00 +#define L2X0_LINE_DATA 0xF10 +#define L2X0_LINE_TAG 0xF30 +#define L2X0_DEBUG_CTRL 0xF40 +#define L2X0_PREFETCH_CTRL 0xF60 +#define L2X0_POWER_CTRL 0xF80 +#define L2X0_DYNAMIC_CLK_GATING_EN (1 << 1) +#define L2X0_STNDBY_MODE_EN (1 << 0) + +/* Registers shifts and masks */ +#define L2X0_CACHE_ID_REV_MASK (0x3f) +#define L2X0_CACHE_ID_PART_MASK (0xf << 6) +#define L2X0_CACHE_ID_PART_L210 (1 << 6) +#define L2X0_CACHE_ID_PART_L310 (3 << 6) + +#define L2X0_AUX_CTRL_MASK 0xc0000fff +#define L2X0_AUX_CTRL_ASSOCIATIVITY_SHIFT 16 +#define L2X0_AUX_CTRL_WAY_SIZE_SHIFT 17 +#define L2X0_AUX_CTRL_WAY_SIZE_MASK (0x7 << 17) +#define L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT 22 +#define L2X0_AUX_CTRL_NS_LOCKDOWN_SHIFT 26 +#define L2X0_AUX_CTRL_NS_INT_CTRL_SHIFT 27 +#define L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT 28 +#define L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT 29 +#define L2X0_AUX_CTRL_EARLY_BRESP_SHIFT 30 + +#define REV_PL310_R2P0 4 + +#ifndef __ASSEMBLY__ +extern void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask); +#endif + +#endif diff --git a/arch/arm/include/asm/hardware/cache-tauros2.h b/arch/arm/include/asm/hardware/cache-tauros2.h new file mode 100644 index 00000000..538f17ca --- /dev/null +++ b/arch/arm/include/asm/hardware/cache-tauros2.h @@ -0,0 +1,11 @@ +/* + * arch/arm/include/asm/hardware/cache-tauros2.h + * + * Copyright (C) 2008 Marvell Semiconductor + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +extern void __init tauros2_init(void); diff --git a/arch/arm/include/asm/hardware/clps7111.h b/arch/arm/include/asm/hardware/clps7111.h new file mode 100644 index 00000000..44477225 --- /dev/null +++ b/arch/arm/include/asm/hardware/clps7111.h @@ -0,0 +1,184 @@ +/* + * arch/arm/include/asm/hardware/clps7111.h + * + * This file contains the hardware definitions of the CLPS7111 internal + * registers. + * + * Copyright (C) 2000 Deep Blue Solutions Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __ASM_HARDWARE_CLPS7111_H +#define __ASM_HARDWARE_CLPS7111_H + +#define CLPS7111_PHYS_BASE (0x80000000) + +#ifndef __ASSEMBLY__ +#define clps_readb(off) __raw_readb(CLPS7111_BASE + (off)) +#define clps_readw(off) __raw_readw(CLPS7111_BASE + (off)) +#define clps_readl(off) __raw_readl(CLPS7111_BASE + (off)) +#define clps_writeb(val,off) __raw_writeb(val, CLPS7111_BASE + (off)) +#define clps_writew(val,off) __raw_writew(val, CLPS7111_BASE + (off)) +#define clps_writel(val,off) __raw_writel(val, CLPS7111_BASE + (off)) +#endif + +#define PADR (0x0000) +#define PBDR (0x0001) +#define PDDR (0x0003) +#define PADDR (0x0040) +#define PBDDR (0x0041) +#define PDDDR (0x0043) +#define PEDR (0x0080) +#define PEDDR (0x00c0) +#define SYSCON1 (0x0100) +#define SYSFLG1 (0x0140) +#define MEMCFG1 (0x0180) +#define MEMCFG2 (0x01c0) +#define DRFPR (0x0200) +#define INTSR1 (0x0240) +#define INTMR1 (0x0280) +#define LCDCON (0x02c0) +#define TC1D (0x0300) +#define TC2D (0x0340) +#define RTCDR (0x0380) +#define RTCMR (0x03c0) +#define PMPCON (0x0400) +#define CODR (0x0440) +#define UARTDR1 (0x0480) +#define UBRLCR1 (0x04c0) +#define SYNCIO (0x0500) +#define PALLSW (0x0540) +#define PALMSW (0x0580) +#define STFCLR (0x05c0) +#define BLEOI (0x0600) +#define MCEOI (0x0640) +#define TEOI (0x0680) +#define TC1EOI (0x06c0) +#define TC2EOI (0x0700) +#define RTCEOI (0x0740) +#define UMSEOI (0x0780) +#define COEOI (0x07c0) +#define HALT (0x0800) +#define STDBY (0x0840) + +#define FBADDR (0x1000) +#define SYSCON2 (0x1100) +#define SYSFLG2 (0x1140) +#define INTSR2 (0x1240) +#define INTMR2 (0x1280) +#define UARTDR2 (0x1480) +#define UBRLCR2 (0x14c0) +#define SS2DR (0x1500) +#define SRXEOF (0x1600) +#define SS2POP (0x16c0) +#define KBDEOI (0x1700) + +/* common bits: SYSCON1 / SYSCON2 */ +#define SYSCON_UARTEN (1 << 8) + +#define SYSCON1_KBDSCAN(x) ((x) & 15) +#define SYSCON1_KBDSCANMASK (15) +#define SYSCON1_TC1M (1 << 4) +#define SYSCON1_TC1S (1 << 5) +#define SYSCON1_TC2M (1 << 6) +#define SYSCON1_TC2S (1 << 7) +#define SYSCON1_UART1EN SYSCON_UARTEN +#define SYSCON1_BZTOG (1 << 9) +#define SYSCON1_BZMOD (1 << 10) +#define SYSCON1_DBGEN (1 << 11) +#define SYSCON1_LCDEN (1 << 12) +#define SYSCON1_CDENTX (1 << 13) +#define SYSCON1_CDENRX (1 << 14) +#define SYSCON1_SIREN (1 << 15) +#define SYSCON1_ADCKSEL(x) (((x) & 3) << 16) +#define SYSCON1_ADCKSEL_MASK (3 << 16) +#define SYSCON1_EXCKEN (1 << 18) +#define SYSCON1_WAKEDIS (1 << 19) +#define SYSCON1_IRTXM (1 << 20) + +/* common bits: SYSFLG1 / SYSFLG2 */ +#define SYSFLG_UBUSY (1 << 11) +#define SYSFLG_URXFE (1 << 22) +#define SYSFLG_UTXFF (1 << 23) + +#define SYSFLG1_MCDR (1 << 0) +#define SYSFLG1_DCDET (1 << 1) +#define SYSFLG1_WUDR (1 << 2) +#define SYSFLG1_WUON (1 << 3) +#define SYSFLG1_CTS (1 << 8) +#define SYSFLG1_DSR (1 << 9) +#define SYSFLG1_DCD (1 << 10) +#define SYSFLG1_UBUSY SYSFLG_UBUSY +#define SYSFLG1_NBFLG (1 << 12) +#define SYSFLG1_RSTFLG (1 << 13) +#define SYSFLG1_PFFLG (1 << 14) +#define SYSFLG1_CLDFLG (1 << 15) +#define SYSFLG1_URXFE SYSFLG_URXFE +#define SYSFLG1_UTXFF SYSFLG_UTXFF +#define SYSFLG1_CRXFE (1 << 24) +#define SYSFLG1_CTXFF (1 << 25) +#define SYSFLG1_SSIBUSY (1 << 26) +#define SYSFLG1_ID (1 << 29) + +#define SYSFLG2_SSRXOF (1 << 0) +#define SYSFLG2_RESVAL (1 << 1) +#define SYSFLG2_RESFRM (1 << 2) +#define SYSFLG2_SS2RXFE (1 << 3) +#define SYSFLG2_SS2TXFF (1 << 4) +#define SYSFLG2_SS2TXUF (1 << 5) +#define SYSFLG2_CKMODE (1 << 6) +#define SYSFLG2_UBUSY SYSFLG_UBUSY +#define SYSFLG2_URXFE SYSFLG_URXFE +#define SYSFLG2_UTXFF SYSFLG_UTXFF + +#define LCDCON_GSEN (1 << 30) +#define LCDCON_GSMD (1 << 31) + +#define SYSCON2_SERSEL (1 << 0) +#define SYSCON2_KBD6 (1 << 1) +#define SYSCON2_DRAMZ (1 << 2) +#define SYSCON2_KBWEN (1 << 3) +#define SYSCON2_SS2TXEN (1 << 4) +#define SYSCON2_PCCARD1 (1 << 5) +#define SYSCON2_PCCARD2 (1 << 6) +#define SYSCON2_SS2RXEN (1 << 7) +#define SYSCON2_UART2EN SYSCON_UARTEN +#define SYSCON2_SS2MAEN (1 << 9) +#define SYSCON2_OSTB (1 << 12) +#define SYSCON2_CLKENSL (1 << 13) +#define SYSCON2_BUZFREQ (1 << 14) + +/* common bits: UARTDR1 / UARTDR2 */ +#define UARTDR_FRMERR (1 << 8) +#define UARTDR_PARERR (1 << 9) +#define UARTDR_OVERR (1 << 10) + +/* common bits: UBRLCR1 / UBRLCR2 */ +#define UBRLCR_BAUD_MASK ((1 << 12) - 1) +#define UBRLCR_BREAK (1 << 12) +#define UBRLCR_PRTEN (1 << 13) +#define UBRLCR_EVENPRT (1 << 14) +#define UBRLCR_XSTOP (1 << 15) +#define UBRLCR_FIFOEN (1 << 16) +#define UBRLCR_WRDLEN5 (0 << 17) +#define UBRLCR_WRDLEN6 (1 << 17) +#define UBRLCR_WRDLEN7 (2 << 17) +#define UBRLCR_WRDLEN8 (3 << 17) +#define UBRLCR_WRDLEN_MASK (3 << 17) + +#define SYNCIO_SMCKEN (1 << 13) +#define SYNCIO_TXFRMEN (1 << 14) + +#endif /* __ASM_HARDWARE_CLPS7111_H */ diff --git a/arch/arm/include/asm/hardware/coresight.h b/arch/arm/include/asm/hardware/coresight.h new file mode 100644 index 00000000..dcf74d71 --- /dev/null +++ b/arch/arm/include/asm/hardware/coresight.h @@ -0,0 +1,185 @@ +/* + * linux/arch/arm/include/asm/hardware/coresight.h + * + * CoreSight components' registers + * + * Copyright (C) 2009 Nokia Corporation. + * Alexander Shishkin + * + * 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. + */ + +#ifndef __ASM_HARDWARE_CORESIGHT_H +#define __ASM_HARDWARE_CORESIGHT_H + +#define TRACER_ACCESSED_BIT 0 +#define TRACER_RUNNING_BIT 1 +#define TRACER_CYCLE_ACC_BIT 2 +#define TRACER_TRACE_DATA_BIT 3 +#define TRACER_TIMESTAMP_BIT 4 +#define TRACER_BRANCHOUTPUT_BIT 5 +#define TRACER_RETURN_STACK_BIT 6 +#define TRACER_ACCESSED BIT(TRACER_ACCESSED_BIT) +#define TRACER_RUNNING BIT(TRACER_RUNNING_BIT) +#define TRACER_CYCLE_ACC BIT(TRACER_CYCLE_ACC_BIT) +#define TRACER_TRACE_DATA BIT(TRACER_TRACE_DATA_BIT) +#define TRACER_TIMESTAMP BIT(TRACER_TIMESTAMP_BIT) +#define TRACER_BRANCHOUTPUT BIT(TRACER_BRANCHOUTPUT_BIT) +#define TRACER_RETURN_STACK BIT(TRACER_RETURN_STACK_BIT) + +#define TRACER_TIMEOUT 10000 + +#define etm_writel(t, id, v, x) \ + (__raw_writel((v), (t)->etm_regs[(id)] + (x))) +#define etm_readl(t, id, x) (__raw_readl((t)->etm_regs[(id)] + (x))) + +/* CoreSight Management Registers */ +#define CSMR_LOCKACCESS 0xfb0 +#define CSMR_LOCKSTATUS 0xfb4 +#define CSMR_AUTHSTATUS 0xfb8 +#define CSMR_DEVID 0xfc8 +#define CSMR_DEVTYPE 0xfcc +/* CoreSight Component Registers */ +#define CSCR_CLASS 0xff4 + +#define UNLOCK_MAGIC 0xc5acce55 + +/* ETM control register, "ETM Architecture", 3.3.1 */ +#define ETMR_CTRL 0 +#define ETMCTRL_POWERDOWN 1 +#define ETMCTRL_PROGRAM (1 << 10) +#define ETMCTRL_PORTSEL (1 << 11) +#define ETMCTRL_CONTEXTIDSIZE(x) (((x) & 3) << 14) +#define ETMCTRL_PORTMASK1 (7 << 4) +#define ETMCTRL_PORTMASK2 (1 << 21) +#define ETMCTRL_PORTMASK (ETMCTRL_PORTMASK1 | ETMCTRL_PORTMASK2) +#define ETMCTRL_PORTSIZE(x) ((((x) & 7) << 4) | (!!((x) & 8)) << 21) +#define ETMCTRL_DO_CPRT (1 << 1) +#define ETMCTRL_DATAMASK (3 << 2) +#define ETMCTRL_DATA_DO_DATA (1 << 2) +#define ETMCTRL_DATA_DO_ADDR (1 << 3) +#define ETMCTRL_DATA_DO_BOTH (ETMCTRL_DATA_DO_DATA | ETMCTRL_DATA_DO_ADDR) +#define ETMCTRL_BRANCH_OUTPUT (1 << 8) +#define ETMCTRL_CYCLEACCURATE (1 << 12) +#define ETMCTRL_TIMESTAMP_EN (1 << 28) +#define ETMCTRL_RETURN_STACK_EN (1 << 29) + +/* ETM configuration code register */ +#define ETMR_CONFCODE (0x04) +#define ETMCCR_ETMIDR_PRESENT BIT(31) + +/* ETM trace start/stop resource control register */ +#define ETMR_TRACESSCTRL (0x18) + +/* ETM trigger event register */ +#define ETMR_TRIGEVT (0x08) + +/* address access type register bits, "ETM architecture", + * table 3-27 */ +/* - access type */ +#define ETMAAT_IFETCH 0 +#define ETMAAT_IEXEC 1 +#define ETMAAT_IEXECPASS 2 +#define ETMAAT_IEXECFAIL 3 +#define ETMAAT_DLOADSTORE 4 +#define ETMAAT_DLOAD 5 +#define ETMAAT_DSTORE 6 +/* - comparison access size */ +#define ETMAAT_JAVA (0 << 3) +#define ETMAAT_THUMB (1 << 3) +#define ETMAAT_ARM (3 << 3) +/* - data value comparison control */ +#define ETMAAT_NOVALCMP (0 << 5) +#define ETMAAT_VALMATCH (1 << 5) +#define ETMAAT_VALNOMATCH (3 << 5) +/* - exact match */ +#define ETMAAT_EXACTMATCH (1 << 7) +/* - context id comparator control */ +#define ETMAAT_IGNCONTEXTID (0 << 8) +#define ETMAAT_VALUE1 (1 << 8) +#define ETMAAT_VALUE2 (2 << 8) +#define ETMAAT_VALUE3 (3 << 8) +/* - security level control */ +#define ETMAAT_IGNSECURITY (0 << 10) +#define ETMAAT_NSONLY (1 << 10) +#define ETMAAT_SONLY (2 << 10) + +#define ETMR_COMP_VAL(x) (0x40 + (x) * 4) +#define ETMR_COMP_ACC_TYPE(x) (0x80 + (x) * 4) + +/* ETM status register, "ETM Architecture", 3.3.2 */ +#define ETMR_STATUS (0x10) +#define ETMST_OVERFLOW BIT(0) +#define ETMST_PROGBIT BIT(1) +#define ETMST_STARTSTOP BIT(2) +#define ETMST_TRIGGER BIT(3) + +#define etm_progbit(t) (etm_readl((t), ETMR_STATUS) & ETMST_PROGBIT) +#define etm_started(t) (etm_readl((t), ETMR_STATUS) & ETMST_STARTSTOP) +#define etm_triggered(t) (etm_readl((t), ETMR_STATUS) & ETMST_TRIGGER) + +#define ETMR_TRACEENCTRL2 0x1c +#define ETMR_TRACEENCTRL 0x24 +#define ETMTE_INCLEXCL BIT(24) +#define ETMR_TRACEENEVT 0x20 + +#define ETMR_VIEWDATAEVT 0x30 +#define ETMR_VIEWDATACTRL1 0x34 +#define ETMR_VIEWDATACTRL2 0x38 +#define ETMR_VIEWDATACTRL3 0x3c +#define ETMVDC3_EXCLONLY BIT(16) + +#define ETMCTRL_OPTS (ETMCTRL_DO_CPRT) + +#define ETMR_ID 0x1e4 +#define ETMIDR_VERSION(x) (((x) >> 4) & 0xff) +#define ETMIDR_VERSION_3_1 0x21 +#define ETMIDR_VERSION_PFT_1_0 0x30 + +#define ETMR_CCE 0x1e8 +#define ETMCCER_RETURN_STACK_IMPLEMENTED BIT(23) +#define ETMCCER_TIMESTAMPING_IMPLEMENTED BIT(22) + +#define ETMR_TRACEIDR 0x200 + +/* ETM management registers, "ETM Architecture", 3.5.24 */ +#define ETMMR_OSLAR 0x300 +#define ETMMR_OSLSR 0x304 +#define ETMMR_OSSRR 0x308 +#define ETMMR_PDSR 0x314 + +/* ETB registers, "CoreSight Components TRM", 9.3 */ +#define ETBR_DEPTH 0x04 +#define ETBR_STATUS 0x0c +#define ETBR_READMEM 0x10 +#define ETBR_READADDR 0x14 +#define ETBR_WRITEADDR 0x18 +#define ETBR_TRIGGERCOUNT 0x1c +#define ETBR_CTRL 0x20 +#define ETBR_FORMATTERCTRL 0x304 +#define ETBFF_ENFTC 1 +#define ETBFF_ENFCONT BIT(1) +#define ETBFF_FONFLIN BIT(4) +#define ETBFF_MANUAL_FLUSH BIT(6) +#define ETBFF_TRIGIN BIT(8) +#define ETBFF_TRIGEVT BIT(9) +#define ETBFF_TRIGFL BIT(10) +#define ETBFF_STOPFL BIT(12) + +#define etb_writel(t, v, x) \ + (__raw_writel((v), (t)->etb_regs + (x))) +#define etb_readl(t, x) (__raw_readl((t)->etb_regs + (x))) + +#define etm_lock(t, id) \ + do { etm_writel((t), (id), 0, CSMR_LOCKACCESS); } while (0) +#define etm_unlock(t, id) \ + do { etm_writel((t), (id), UNLOCK_MAGIC, CSMR_LOCKACCESS); } while (0) + +#define etb_lock(t) do { etb_writel((t), 0, CSMR_LOCKACCESS); } while (0) +#define etb_unlock(t) \ + do { etb_writel((t), UNLOCK_MAGIC, CSMR_LOCKACCESS); } while (0) + +#endif /* __ASM_HARDWARE_CORESIGHT_H */ + diff --git a/arch/arm/include/asm/hardware/cs89712.h b/arch/arm/include/asm/hardware/cs89712.h new file mode 100644 index 00000000..f7562693 --- /dev/null +++ b/arch/arm/include/asm/hardware/cs89712.h @@ -0,0 +1,49 @@ +/* + * arch/arm/include/asm/hardware/cs89712.h + * + * This file contains the hardware definitions of the CS89712 + * additional internal registers. + * + * Copyright (C) 2001 Thomas Gleixner autronix automation + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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_HARDWARE_CS89712_H +#define __ASM_HARDWARE_CS89712_H + +/* +* CS89712 additional registers +*/ + +#define PCDR 0x0002 /* Port C Data register ---------------------------- */ +#define PCDDR 0x0042 /* Port C Data Direction register ------------------ */ +#define SDCONF 0x2300 /* SDRAM Configuration register ---------------------*/ +#define SDRFPR 0x2340 /* SDRAM Refresh period register --------------------*/ + +#define SDCONF_ACTIVE (1 << 10) +#define SDCONF_CLKCTL (1 << 9) +#define SDCONF_WIDTH_4 (0 << 7) +#define SDCONF_WIDTH_8 (1 << 7) +#define SDCONF_WIDTH_16 (2 << 7) +#define SDCONF_WIDTH_32 (3 << 7) +#define SDCONF_SIZE_16 (0 << 5) +#define SDCONF_SIZE_64 (1 << 5) +#define SDCONF_SIZE_128 (2 << 5) +#define SDCONF_SIZE_256 (3 << 5) +#define SDCONF_CASLAT_2 (2) +#define SDCONF_CASLAT_3 (3) + +#endif /* __ASM_HARDWARE_CS89712_H */ diff --git a/arch/arm/include/asm/hardware/debug-8250.S b/arch/arm/include/asm/hardware/debug-8250.S new file mode 100644 index 00000000..22c68925 --- /dev/null +++ b/arch/arm/include/asm/hardware/debug-8250.S @@ -0,0 +1,29 @@ +/* + * arch/arm/include/asm/hardware/debug-8250.S + * + * Copyright (C) 1994-1999 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include + + .macro senduart,rd,rx + strb \rd, [\rx, #UART_TX << UART_SHIFT] + .endm + + .macro busyuart,rd,rx +1002: ldrb \rd, [\rx, #UART_LSR << UART_SHIFT] + and \rd, \rd, #UART_LSR_TEMT | UART_LSR_THRE + teq \rd, #UART_LSR_TEMT | UART_LSR_THRE + bne 1002b + .endm + + .macro waituart,rd,rx +#ifdef FLOW_CONTROL +1001: ldrb \rd, [\rx, #UART_MSR << UART_SHIFT] + tst \rd, #UART_MSR_CTS + beq 1001b +#endif + .endm diff --git a/arch/arm/include/asm/hardware/debug-pl01x.S b/arch/arm/include/asm/hardware/debug-pl01x.S new file mode 100644 index 00000000..f9fd083e --- /dev/null +++ b/arch/arm/include/asm/hardware/debug-pl01x.S @@ -0,0 +1,29 @@ +/* arch/arm/include/asm/hardware/debug-pl01x.S + * + * Debugging macro include header + * + * Copyright (C) 1994-1999 Russell King + * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * +*/ +#include + + .macro senduart,rd,rx + strb \rd, [\rx, #UART01x_DR] + .endm + + .macro waituart,rd,rx +1001: ldr \rd, [\rx, #UART01x_FR] + tst \rd, #UART01x_FR_TXFF + bne 1001b + .endm + + .macro busyuart,rd,rx +1001: ldr \rd, [\rx, #UART01x_FR] + tst \rd, #UART01x_FR_BUSY + bne 1001b + .endm diff --git a/arch/arm/include/asm/hardware/dec21285.h b/arch/arm/include/asm/hardware/dec21285.h new file mode 100644 index 00000000..0d755275 --- /dev/null +++ b/arch/arm/include/asm/hardware/dec21285.h @@ -0,0 +1,147 @@ +/* + * arch/arm/include/asm/hardware/dec21285.h + * + * Copyright (C) 1998 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * DC21285 registers + */ +#define DC21285_PCI_IACK 0x79000000 +#define DC21285_ARMCSR_BASE 0x42000000 +#define DC21285_PCI_TYPE_0_CONFIG 0x7b000000 +#define DC21285_PCI_TYPE_1_CONFIG 0x7a000000 +#define DC21285_OUTBOUND_WRITE_FLUSH 0x78000000 +#define DC21285_FLASH 0x41000000 +#define DC21285_PCI_IO 0x7c000000 +#define DC21285_PCI_MEM 0x80000000 + +#ifndef __ASSEMBLY__ +#include +#define DC21285_IO(x) ((volatile unsigned long *)(ARMCSR_BASE+(x))) +#else +#define DC21285_IO(x) (x) +#endif + +#define CSR_PCICMD DC21285_IO(0x0004) +#define CSR_CLASSREV DC21285_IO(0x0008) +#define CSR_PCICACHELINESIZE DC21285_IO(0x000c) +#define CSR_PCICSRBASE DC21285_IO(0x0010) +#define CSR_PCICSRIOBASE DC21285_IO(0x0014) +#define CSR_PCISDRAMBASE DC21285_IO(0x0018) +#define CSR_PCIROMBASE DC21285_IO(0x0030) +#define CSR_MBOX0 DC21285_IO(0x0050) +#define CSR_MBOX1 DC21285_IO(0x0054) +#define CSR_MBOX2 DC21285_IO(0x0058) +#define CSR_MBOX3 DC21285_IO(0x005c) +#define CSR_DOORBELL DC21285_IO(0x0060) +#define CSR_DOORBELL_SETUP DC21285_IO(0x0064) +#define CSR_ROMWRITEREG DC21285_IO(0x0068) +#define CSR_CSRBASEMASK DC21285_IO(0x00f8) +#define CSR_CSRBASEOFFSET DC21285_IO(0x00fc) +#define CSR_SDRAMBASEMASK DC21285_IO(0x0100) +#define CSR_SDRAMBASEOFFSET DC21285_IO(0x0104) +#define CSR_ROMBASEMASK DC21285_IO(0x0108) +#define CSR_SDRAMTIMING DC21285_IO(0x010c) +#define CSR_SDRAMADDRSIZE0 DC21285_IO(0x0110) +#define CSR_SDRAMADDRSIZE1 DC21285_IO(0x0114) +#define CSR_SDRAMADDRSIZE2 DC21285_IO(0x0118) +#define CSR_SDRAMADDRSIZE3 DC21285_IO(0x011c) +#define CSR_I2O_INFREEHEAD DC21285_IO(0x0120) +#define CSR_I2O_INPOSTTAIL DC21285_IO(0x0124) +#define CSR_I2O_OUTPOSTHEAD DC21285_IO(0x0128) +#define CSR_I2O_OUTFREETAIL DC21285_IO(0x012c) +#define CSR_I2O_INFREECOUNT DC21285_IO(0x0130) +#define CSR_I2O_OUTPOSTCOUNT DC21285_IO(0x0134) +#define CSR_I2O_INPOSTCOUNT DC21285_IO(0x0138) +#define CSR_SA110_CNTL DC21285_IO(0x013c) +#define SA110_CNTL_INITCMPLETE (1 << 0) +#define SA110_CNTL_ASSERTSERR (1 << 1) +#define SA110_CNTL_RXSERR (1 << 3) +#define SA110_CNTL_SA110DRAMPARITY (1 << 4) +#define SA110_CNTL_PCISDRAMPARITY (1 << 5) +#define SA110_CNTL_DMASDRAMPARITY (1 << 6) +#define SA110_CNTL_DISCARDTIMER (1 << 8) +#define SA110_CNTL_PCINRESET (1 << 9) +#define SA110_CNTL_I2O_256 (0 << 10) +#define SA110_CNTL_I20_512 (1 << 10) +#define SA110_CNTL_I2O_1024 (2 << 10) +#define SA110_CNTL_I2O_2048 (3 << 10) +#define SA110_CNTL_I2O_4096 (4 << 10) +#define SA110_CNTL_I2O_8192 (5 << 10) +#define SA110_CNTL_I2O_16384 (6 << 10) +#define SA110_CNTL_I2O_32768 (7 << 10) +#define SA110_CNTL_WATCHDOG (1 << 13) +#define SA110_CNTL_ROMWIDTH_UNDEF (0 << 14) +#define SA110_CNTL_ROMWIDTH_16 (1 << 14) +#define SA110_CNTL_ROMWIDTH_32 (2 << 14) +#define SA110_CNTL_ROMWIDTH_8 (3 << 14) +#define SA110_CNTL_ROMACCESSTIME(x) ((x)<<16) +#define SA110_CNTL_ROMBURSTTIME(x) ((x)<<20) +#define SA110_CNTL_ROMTRISTATETIME(x) ((x)<<24) +#define SA110_CNTL_XCSDIR(x) ((x)<<28) +#define SA110_CNTL_PCICFN (1 << 31) + +/* + * footbridge_cfn_mode() is used when we want + * to check whether we are the central function + */ +#define __footbridge_cfn_mode() (*CSR_SA110_CNTL & SA110_CNTL_PCICFN) +#if defined(CONFIG_FOOTBRIDGE_HOST) && defined(CONFIG_FOOTBRIDGE_ADDIN) +#define footbridge_cfn_mode() __footbridge_cfn_mode() +#elif defined(CONFIG_FOOTBRIDGE_HOST) +#define footbridge_cfn_mode() (1) +#else +#define footbridge_cfn_mode() (0) +#endif + +#define CSR_PCIADDR_EXTN DC21285_IO(0x0140) +#define CSR_PREFETCHMEMRANGE DC21285_IO(0x0144) +#define CSR_XBUS_CYCLE DC21285_IO(0x0148) +#define CSR_XBUS_IOSTROBE DC21285_IO(0x014c) +#define CSR_DOORBELL_PCI DC21285_IO(0x0150) +#define CSR_DOORBELL_SA110 DC21285_IO(0x0154) +#define CSR_UARTDR DC21285_IO(0x0160) +#define CSR_RXSTAT DC21285_IO(0x0164) +#define CSR_H_UBRLCR DC21285_IO(0x0168) +#define CSR_M_UBRLCR DC21285_IO(0x016c) +#define CSR_L_UBRLCR DC21285_IO(0x0170) +#define CSR_UARTCON DC21285_IO(0x0174) +#define CSR_UARTFLG DC21285_IO(0x0178) +#define CSR_IRQ_STATUS DC21285_IO(0x0180) +#define CSR_IRQ_RAWSTATUS DC21285_IO(0x0184) +#define CSR_IRQ_ENABLE DC21285_IO(0x0188) +#define CSR_IRQ_DISABLE DC21285_IO(0x018c) +#define CSR_IRQ_SOFT DC21285_IO(0x0190) +#define CSR_FIQ_STATUS DC21285_IO(0x0280) +#define CSR_FIQ_RAWSTATUS DC21285_IO(0x0284) +#define CSR_FIQ_ENABLE DC21285_IO(0x0288) +#define CSR_FIQ_DISABLE DC21285_IO(0x028c) +#define CSR_FIQ_SOFT DC21285_IO(0x0290) +#define CSR_TIMER1_LOAD DC21285_IO(0x0300) +#define CSR_TIMER1_VALUE DC21285_IO(0x0304) +#define CSR_TIMER1_CNTL DC21285_IO(0x0308) +#define CSR_TIMER1_CLR DC21285_IO(0x030c) +#define CSR_TIMER2_LOAD DC21285_IO(0x0320) +#define CSR_TIMER2_VALUE DC21285_IO(0x0324) +#define CSR_TIMER2_CNTL DC21285_IO(0x0328) +#define CSR_TIMER2_CLR DC21285_IO(0x032c) +#define CSR_TIMER3_LOAD DC21285_IO(0x0340) +#define CSR_TIMER3_VALUE DC21285_IO(0x0344) +#define CSR_TIMER3_CNTL DC21285_IO(0x0348) +#define CSR_TIMER3_CLR DC21285_IO(0x034c) +#define CSR_TIMER4_LOAD DC21285_IO(0x0360) +#define CSR_TIMER4_VALUE DC21285_IO(0x0364) +#define CSR_TIMER4_CNTL DC21285_IO(0x0368) +#define CSR_TIMER4_CLR DC21285_IO(0x036c) + +#define TIMER_CNTL_ENABLE (1 << 7) +#define TIMER_CNTL_AUTORELOAD (1 << 6) +#define TIMER_CNTL_DIV1 (0) +#define TIMER_CNTL_DIV16 (1 << 2) +#define TIMER_CNTL_DIV256 (2 << 2) +#define TIMER_CNTL_CNTEXT (3 << 2) + + diff --git a/arch/arm/include/asm/hardware/entry-macro-gic.S b/arch/arm/include/asm/hardware/entry-macro-gic.S new file mode 100644 index 00000000..c115b82f --- /dev/null +++ b/arch/arm/include/asm/hardware/entry-macro-gic.S @@ -0,0 +1,75 @@ +/* + * arch/arm/include/asm/hardware/entry-macro-gic.S + * + * Low-level IRQ helper macros for GIC + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include + +#ifndef HAVE_GET_IRQNR_PREAMBLE + .macro get_irqnr_preamble, base, tmp + ldr \base, =gic_cpu_base_addr + ldr \base, [\base] + .endm +#endif + +/* + * The interrupt numbering scheme is defined in the + * interrupt controller spec. To wit: + * + * Interrupts 0-15 are IPI + * 16-28 are reserved + * 29-31 are local. We allow 30 to be used for the watchdog. + * 32-1020 are global + * 1021-1022 are reserved + * 1023 is "spurious" (no interrupt) + * + * For now, we ignore all local interrupts so only return an interrupt if it's + * between 30 and 1020. The test_for_ipi routine below will pick up on IPIs. + * + * A simple read from the controller will tell us the number of the highest + * priority enabled interrupt. We then just need to check whether it is in the + * valid range for an IRQ (30-1020 inclusive). + */ + + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + + ldr \irqstat, [\base, #GIC_CPU_INTACK] + /* bits 12-10 = src CPU, 9-0 = int # */ + + ldr \tmp, =1021 + bic \irqnr, \irqstat, #0x1c00 + cmp \irqnr, #29 + cmpcc \irqnr, \irqnr + cmpne \irqnr, \tmp + cmpcs \irqnr, \irqnr + .endm + +/* We assume that irqstat (the raw value of the IRQ acknowledge + * register) is preserved from the macro above. + * If there is an IPI, we immediately signal end of interrupt on the + * controller, since this requires the original irqstat value which + * we won't easily be able to recreate later. + */ + + .macro test_for_ipi, irqnr, irqstat, base, tmp + bic \irqnr, \irqstat, #0x1c00 + cmp \irqnr, #16 + strcc \irqstat, [\base, #GIC_CPU_EOI] + cmpcs \irqnr, \irqnr + .endm + +/* As above, this assumes that irqstat and base are preserved.. */ + + .macro test_for_ltirq, irqnr, irqstat, base, tmp + bic \irqnr, \irqstat, #0x1c00 + mov \tmp, #0 + cmp \irqnr, #29 + moveq \tmp, #1 + streq \irqstat, [\base, #GIC_CPU_EOI] + cmp \tmp, #0 + .endm diff --git a/arch/arm/include/asm/hardware/entry-macro-iomd.S b/arch/arm/include/asm/hardware/entry-macro-iomd.S new file mode 100644 index 00000000..e0af4983 --- /dev/null +++ b/arch/arm/include/asm/hardware/entry-macro-iomd.S @@ -0,0 +1,139 @@ +/* + * arch/arm/include/asm/hardware/entry-macro-iomd.S + * + * Low-level IRQ helper macros for IOC/IOMD based platforms + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +/* IOC / IOMD based hardware */ +#include + + .macro disable_fiq + mov r12, #ioc_base_high + .if ioc_base_low + orr r12, r12, #ioc_base_low + .endif + strb r12, [r12, #0x38] @ Disable FIQ register + .endm + + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + ldrb \irqstat, [\base, #IOMD_IRQREQB] @ get high priority first + ldr \tmp, =irq_prio_h + teq \irqstat, #0 +#ifdef IOMD_BASE + ldreqb \irqstat, [\base, #IOMD_DMAREQ] @ get dma + addeq \tmp, \tmp, #256 @ irq_prio_h table size + teqeq \irqstat, #0 + bne 2406f +#endif + ldreqb \irqstat, [\base, #IOMD_IRQREQA] @ get low priority + addeq \tmp, \tmp, #256 @ irq_prio_d table size + teqeq \irqstat, #0 +#ifdef IOMD_IRQREQC + ldreqb \irqstat, [\base, #IOMD_IRQREQC] + addeq \tmp, \tmp, #256 @ irq_prio_l table size + teqeq \irqstat, #0 +#endif +#ifdef IOMD_IRQREQD + ldreqb \irqstat, [\base, #IOMD_IRQREQD] + addeq \tmp, \tmp, #256 @ irq_prio_lc table size + teqeq \irqstat, #0 +#endif +2406: ldrneb \irqnr, [\tmp, \irqstat] @ get IRQ number + .endm + +/* + * Interrupt table (incorporates priority). Please note that we + * rely on the order of these tables (see above code). + */ + .align 5 +irq_prio_h: .byte 0, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10 + .byte 12, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10 + .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10 + .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10 + .byte 14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10 + .byte 14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10 + .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10 + .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10 + .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10 + .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10 + .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10 + .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10 + .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10 + .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10 + .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10 + .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10 +#ifdef IOMD_BASE +irq_prio_d: .byte 0,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 + .byte 20,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 + .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 + .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 + .byte 22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 + .byte 22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 + .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 + .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 + .byte 23,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 + .byte 23,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 + .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 + .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 + .byte 22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 + .byte 22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 + .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 + .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16 +#endif +irq_prio_l: .byte 0, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3 + .byte 4, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3 + .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 + .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 + .byte 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3 + .byte 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3 + .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 + .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 + .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 + .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 + .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 + .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 + .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 + .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 + .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 + .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 +#ifdef IOMD_IRQREQC +irq_prio_lc: .byte 24,24,25,24,26,26,26,26,27,27,27,27,27,27,27,27 + .byte 28,24,25,24,26,26,26,26,27,27,27,27,27,27,27,27 + .byte 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29 + .byte 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29 + .byte 30,30,30,30,30,30,30,30,27,27,27,27,27,27,27,27 + .byte 30,30,30,30,30,30,30,30,27,27,27,27,27,27,27,27 + .byte 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29 + .byte 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29 + .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31 + .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31 + .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31 + .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31 + .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31 + .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31 + .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31 + .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31 +#endif +#ifdef IOMD_IRQREQD +irq_prio_ld: .byte 40,40,41,40,42,42,42,42,43,43,43,43,43,43,43,43 + .byte 44,40,41,40,42,42,42,42,43,43,43,43,43,43,43,43 + .byte 45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45 + .byte 45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45 + .byte 46,46,46,46,46,46,46,46,43,43,43,43,43,43,43,43 + .byte 46,46,46,46,46,46,46,46,43,43,43,43,43,43,43,43 + .byte 45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45 + .byte 45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45 + .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47 + .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47 + .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47 + .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47 + .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47 + .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47 + .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47 + .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47 +#endif + diff --git a/arch/arm/include/asm/hardware/ep7211.h b/arch/arm/include/asm/hardware/ep7211.h new file mode 100644 index 00000000..654d5f62 --- /dev/null +++ b/arch/arm/include/asm/hardware/ep7211.h @@ -0,0 +1,40 @@ +/* + * arch/arm/include/asm/hardware/ep7211.h + * + * This file contains the hardware definitions of the EP7211 internal + * registers. + * + * Copyright (C) 2001 Blue Mug, 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 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_HARDWARE_EP7211_H +#define __ASM_HARDWARE_EP7211_H + +#include + +/* + * define EP7211_BASE to be the base address of the region + * you want to access. + */ + +#define EP7211_PHYS_BASE (0x80000000) + +/* + * XXX miket@bluemug.com: need to introduce EP7211 registers (those not + * present in 7212) here. + */ + +#endif /* __ASM_HARDWARE_EP7211_H */ diff --git a/arch/arm/include/asm/hardware/ep7212.h b/arch/arm/include/asm/hardware/ep7212.h new file mode 100644 index 00000000..3b43bbea --- /dev/null +++ b/arch/arm/include/asm/hardware/ep7212.h @@ -0,0 +1,83 @@ +/* + * arch/arm/include/asm/hardware/ep7212.h + * + * This file contains the hardware definitions of the EP7212 internal + * registers. + * + * Copyright (C) 2000 Deep Blue Solutions Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __ASM_HARDWARE_EP7212_H +#define __ASM_HARDWARE_EP7212_H + +/* + * define EP7212_BASE to be the base address of the region + * you want to access. + */ + +#define EP7212_PHYS_BASE (0x80000000) + +#ifndef __ASSEMBLY__ +#define ep_readl(off) __raw_readl(EP7212_BASE + (off)) +#define ep_writel(val,off) __raw_writel(val, EP7212_BASE + (off)) +#endif + +/* + * These registers are specific to the EP7212 only + */ +#define DAIR 0x2000 +#define DAIR0 0x2040 +#define DAIDR1 0x2080 +#define DAIDR2 0x20c0 +#define DAISR 0x2100 +#define SYSCON3 0x2200 +#define INTSR3 0x2240 +#define INTMR3 0x2280 +#define LEDFLSH 0x22c0 + +#define DAIR_DAIEN (1 << 16) +#define DAIR_ECS (1 << 17) +#define DAIR_LCTM (1 << 19) +#define DAIR_LCRM (1 << 20) +#define DAIR_RCTM (1 << 21) +#define DAIR_RCRM (1 << 22) +#define DAIR_LBM (1 << 23) + +#define DAIDR2_FIFOEN (1 << 15) +#define DAIDR2_FIFOLEFT (0x0d << 16) +#define DAIDR2_FIFORIGHT (0x11 << 16) + +#define DAISR_RCTS (1 << 0) +#define DAISR_RCRS (1 << 1) +#define DAISR_LCTS (1 << 2) +#define DAISR_LCRS (1 << 3) +#define DAISR_RCTU (1 << 4) +#define DAISR_RCRO (1 << 5) +#define DAISR_LCTU (1 << 6) +#define DAISR_LCRO (1 << 7) +#define DAISR_RCNF (1 << 8) +#define DAISR_RCNE (1 << 9) +#define DAISR_LCNF (1 << 10) +#define DAISR_LCNE (1 << 11) +#define DAISR_FIFO (1 << 12) + +#define SYSCON3_ADCCON (1 << 0) +#define SYSCON3_DAISEL (1 << 3) +#define SYSCON3_ADCCKNSEN (1 << 4) +#define SYSCON3_FASTWAKE (1 << 8) +#define SYSCON3_DAIEN (1 << 9) + +#endif /* __ASM_HARDWARE_EP7212_H */ diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h new file mode 100644 index 00000000..c8647b30 --- /dev/null +++ b/arch/arm/include/asm/hardware/gic.h @@ -0,0 +1,77 @@ +/* + * arch/arm/include/asm/hardware/gic.h + * + * Copyright (C) 2002 ARM Limited, 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 version 2 as + * published by the Free Software Foundation. + */ +#ifndef __ASM_ARM_HARDWARE_GIC_H +#define __ASM_ARM_HARDWARE_GIC_H + +#include + +#define GIC_CPU_CTRL 0x00 +#define GIC_CPU_PRIMASK 0x04 +#define GIC_CPU_BINPOINT 0x08 +#define GIC_CPU_INTACK 0x0c +#define GIC_CPU_EOI 0x10 +#define GIC_CPU_RUNNINGPRI 0x14 +#define GIC_CPU_HIGHPRI 0x18 + +#define GIC_DIST_CTRL 0x000 +#define GIC_DIST_CTR 0x004 +#define GIC_DIST_ENABLE_SET 0x100 +#define GIC_DIST_ENABLE_CLEAR 0x180 +#define GIC_DIST_PENDING_SET 0x200 +#define GIC_DIST_PENDING_CLEAR 0x280 +#define GIC_DIST_ACTIVE_BIT 0x300 +#define GIC_DIST_PRI 0x400 +#define GIC_DIST_TARGET 0x800 +#define GIC_DIST_CONFIG 0xc00 +#define GIC_DIST_SOFTINT 0xf00 + +#ifndef __ASSEMBLY__ +extern void __iomem *gic_cpu_base_addr; +extern struct irq_chip gic_arch_extn; + +struct gic_dist_state { + u32 icddcr; /* 0x000 */ + /* 0x004 RO */ + /* 0x008 RO */ + /* 0x00c ~ 0x07c Reserved */ + u32 icdisrn[8]; /* 0x080 ~ 0x09c */ + u32 icdisern[8]; /* 0x100 ~ 0x11c Reserved */ + /* 0x120 ~ 0x17c */ + u32 icdicern[8]; /* 0x180 ~ 0x19c */ + u32 icdisprn[32]; /* 0x200 ~ 0x27c */ + u32 icdicprn[8]; /* 0x280 ~ 0x29c */ + u32 icdabrn[8]; /* 0x300 ~ 0x31c */ + /* 0x320 ~ 0x3fc Reserved */ + u32 icdiprn[64]; /* 0x400 ~ 0x4fc */ + /* 0x500 ~ 0x7fc Reserved */ + u32 icdiptrn[64]; /* 0x800 ~ 0x8fc */ + /* 0x900 ~ 0xbfc Reserved */ + u32 icdicfrn[16]; /* 0xc00 ~ 0xc3c */ +}; + +struct gic_cpu_state { + u32 iccicr; /* 0x000 */ + u32 iccpmr; /* 0x004 */ + u32 iccbpr; /* 0x008 */ +}; + +void gic_init(unsigned int, unsigned int, void __iomem *, void __iomem *); +void gic_secondary_init(unsigned int); +void gic_cascade_irq(unsigned int gic_nr, unsigned int irq); +void gic_raise_softirq(const struct cpumask *mask, unsigned int irq); +void gic_enable_ppi(unsigned int); +void gic_disable_ppi(unsigned int); +void save_gic_cpu_state(unsigned int gic_nr, struct gic_cpu_state *gcs); +void restore_gic_cpu_state(unsigned int gic_nr, struct gic_cpu_state *gcs); +void save_gic_dist_state(unsigned int gic_nr, struct gic_dist_state *gds); +void restore_gic_dist_state(unsigned int gic_nr, struct gic_dist_state *gds); +#endif + +#endif diff --git a/arch/arm/include/asm/hardware/icst.h b/arch/arm/include/asm/hardware/icst.h new file mode 100644 index 00000000..794220b0 --- /dev/null +++ b/arch/arm/include/asm/hardware/icst.h @@ -0,0 +1,59 @@ +/* + * arch/arm/include/asm/hardware/icst.h + * + * Copyright (C) 2003 Deep Blue Solutions, Ltd, 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 version 2 as + * published by the Free Software Foundation. + * + * Support functions for calculating clocks/divisors for the ICST + * clock generators. See http://www.idt.com/ for more information + * on these devices. + */ +#ifndef ASMARM_HARDWARE_ICST_H +#define ASMARM_HARDWARE_ICST_H + +struct icst_params { + unsigned long ref; + unsigned long vco_max; /* inclusive */ + unsigned long vco_min; /* exclusive */ + unsigned short vd_min; /* inclusive */ + unsigned short vd_max; /* inclusive */ + unsigned char rd_min; /* inclusive */ + unsigned char rd_max; /* inclusive */ + const unsigned char *s2div; /* chip specific s2div array */ + const unsigned char *idx2s; /* chip specific idx2s array */ +}; + +struct icst_vco { + unsigned short v; + unsigned char r; + unsigned char s; +}; + +unsigned long icst_hz(const struct icst_params *p, struct icst_vco vco); +struct icst_vco icst_hz_to_vco(const struct icst_params *p, unsigned long freq); + +/* + * ICST307 VCO frequency must be between 6MHz and 200MHz (3.3 or 5V). + * This frequency is pre-output divider. + */ +#define ICST307_VCO_MIN 6000000 +#define ICST307_VCO_MAX 200000000 + +extern const unsigned char icst307_s2div[]; +extern const unsigned char icst307_idx2s[]; + +/* + * ICST525 VCO frequency must be between 10MHz and 200MHz (3V) or 320MHz (5V). + * This frequency is pre-output divider. + */ +#define ICST525_VCO_MIN 10000000 +#define ICST525_VCO_MAX_3V 200000000 +#define ICST525_VCO_MAX_5V 320000000 + +extern const unsigned char icst525_s2div[]; +extern const unsigned char icst525_idx2s[]; + +#endif diff --git a/arch/arm/include/asm/hardware/ioc.h b/arch/arm/include/asm/hardware/ioc.h new file mode 100644 index 00000000..1f6b8013 --- /dev/null +++ b/arch/arm/include/asm/hardware/ioc.h @@ -0,0 +1,72 @@ +/* + * arch/arm/include/asm/hardware/ioc.h + * + * Copyright (C) Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Use these macros to read/write the IOC. All it does is perform the actual + * read/write. + */ +#ifndef __ASMARM_HARDWARE_IOC_H +#define __ASMARM_HARDWARE_IOC_H + +#ifndef __ASSEMBLY__ + +/* + * We use __raw_base variants here so that we give the compiler the + * chance to keep IOC_BASE in a register. + */ +#define ioc_readb(off) __raw_readb(IOC_BASE + (off)) +#define ioc_writeb(val,off) __raw_writeb(val, IOC_BASE + (off)) + +#endif + +#define IOC_CONTROL (0x00) +#define IOC_KARTTX (0x04) +#define IOC_KARTRX (0x04) + +#define IOC_IRQSTATA (0x10) +#define IOC_IRQREQA (0x14) +#define IOC_IRQCLRA (0x14) +#define IOC_IRQMASKA (0x18) + +#define IOC_IRQSTATB (0x20) +#define IOC_IRQREQB (0x24) +#define IOC_IRQMASKB (0x28) + +#define IOC_FIQSTAT (0x30) +#define IOC_FIQREQ (0x34) +#define IOC_FIQMASK (0x38) + +#define IOC_T0CNTL (0x40) +#define IOC_T0LTCHL (0x40) +#define IOC_T0CNTH (0x44) +#define IOC_T0LTCHH (0x44) +#define IOC_T0GO (0x48) +#define IOC_T0LATCH (0x4c) + +#define IOC_T1CNTL (0x50) +#define IOC_T1LTCHL (0x50) +#define IOC_T1CNTH (0x54) +#define IOC_T1LTCHH (0x54) +#define IOC_T1GO (0x58) +#define IOC_T1LATCH (0x5c) + +#define IOC_T2CNTL (0x60) +#define IOC_T2LTCHL (0x60) +#define IOC_T2CNTH (0x64) +#define IOC_T2LTCHH (0x64) +#define IOC_T2GO (0x68) +#define IOC_T2LATCH (0x6c) + +#define IOC_T3CNTL (0x70) +#define IOC_T3LTCHL (0x70) +#define IOC_T3CNTH (0x74) +#define IOC_T3LTCHH (0x74) +#define IOC_T3GO (0x78) +#define IOC_T3LATCH (0x7c) + +#endif diff --git a/arch/arm/include/asm/hardware/iomd.h b/arch/arm/include/asm/hardware/iomd.h new file mode 100644 index 00000000..f9ee69e4 --- /dev/null +++ b/arch/arm/include/asm/hardware/iomd.h @@ -0,0 +1,185 @@ +/* + * arch/arm/include/asm/hardware/iomd.h + * + * Copyright (C) 1999 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This file contains information out the IOMD ASIC used in the + * Acorn RiscPC and subsequently integrated into the CLPS7500 chips. + */ +#ifndef __ASMARM_HARDWARE_IOMD_H +#define __ASMARM_HARDWARE_IOMD_H + + +#ifndef __ASSEMBLY__ + +/* + * We use __raw_base variants here so that we give the compiler the + * chance to keep IOC_BASE in a register. + */ +#define iomd_readb(off) __raw_readb(IOMD_BASE + (off)) +#define iomd_readl(off) __raw_readl(IOMD_BASE + (off)) +#define iomd_writeb(val,off) __raw_writeb(val, IOMD_BASE + (off)) +#define iomd_writel(val,off) __raw_writel(val, IOMD_BASE + (off)) + +#endif + +#define IOMD_CONTROL (0x000) +#define IOMD_KARTTX (0x004) +#define IOMD_KARTRX (0x004) +#define IOMD_KCTRL (0x008) + +#define IOMD_IRQSTATA (0x010) +#define IOMD_IRQREQA (0x014) +#define IOMD_IRQCLRA (0x014) +#define IOMD_IRQMASKA (0x018) + +#define IOMD_IRQSTATB (0x020) +#define IOMD_IRQREQB (0x024) +#define IOMD_IRQMASKB (0x028) + +#define IOMD_FIQSTAT (0x030) +#define IOMD_FIQREQ (0x034) +#define IOMD_FIQMASK (0x038) + +#define IOMD_T0CNTL (0x040) +#define IOMD_T0LTCHL (0x040) +#define IOMD_T0CNTH (0x044) +#define IOMD_T0LTCHH (0x044) +#define IOMD_T0GO (0x048) +#define IOMD_T0LATCH (0x04c) + +#define IOMD_T1CNTL (0x050) +#define IOMD_T1LTCHL (0x050) +#define IOMD_T1CNTH (0x054) +#define IOMD_T1LTCHH (0x054) +#define IOMD_T1GO (0x058) +#define IOMD_T1LATCH (0x05c) + +#define IOMD_ROMCR0 (0x080) +#define IOMD_ROMCR1 (0x084) +#ifdef CONFIG_ARCH_RPC +#define IOMD_DRAMCR (0x088) +#endif +#define IOMD_REFCR (0x08C) + +#define IOMD_FSIZE (0x090) +#define IOMD_ID0 (0x094) +#define IOMD_ID1 (0x098) +#define IOMD_VERSION (0x09C) + +#ifdef CONFIG_ARCH_RPC +#define IOMD_MOUSEX (0x0A0) +#define IOMD_MOUSEY (0x0A4) +#endif + +#ifdef CONFIG_ARCH_RPC +#define IOMD_DMATCR (0x0C0) +#endif +#define IOMD_IOTCR (0x0C4) +#define IOMD_ECTCR (0x0C8) +#ifdef CONFIG_ARCH_RPC +#define IOMD_DMAEXT (0x0CC) +#endif + +#ifdef CONFIG_ARCH_RPC +#define DMA_EXT_IO0 1 +#define DMA_EXT_IO1 2 +#define DMA_EXT_IO2 4 +#define DMA_EXT_IO3 8 + +#define IOMD_IO0CURA (0x100) +#define IOMD_IO0ENDA (0x104) +#define IOMD_IO0CURB (0x108) +#define IOMD_IO0ENDB (0x10C) +#define IOMD_IO0CR (0x110) +#define IOMD_IO0ST (0x114) + +#define IOMD_IO1CURA (0x120) +#define IOMD_IO1ENDA (0x124) +#define IOMD_IO1CURB (0x128) +#define IOMD_IO1ENDB (0x12C) +#define IOMD_IO1CR (0x130) +#define IOMD_IO1ST (0x134) + +#define IOMD_IO2CURA (0x140) +#define IOMD_IO2ENDA (0x144) +#define IOMD_IO2CURB (0x148) +#define IOMD_IO2ENDB (0x14C) +#define IOMD_IO2CR (0x150) +#define IOMD_IO2ST (0x154) + +#define IOMD_IO3CURA (0x160) +#define IOMD_IO3ENDA (0x164) +#define IOMD_IO3CURB (0x168) +#define IOMD_IO3ENDB (0x16C) +#define IOMD_IO3CR (0x170) +#define IOMD_IO3ST (0x174) +#endif + +#define IOMD_SD0CURA (0x180) +#define IOMD_SD0ENDA (0x184) +#define IOMD_SD0CURB (0x188) +#define IOMD_SD0ENDB (0x18C) +#define IOMD_SD0CR (0x190) +#define IOMD_SD0ST (0x194) + +#ifdef CONFIG_ARCH_RPC +#define IOMD_SD1CURA (0x1A0) +#define IOMD_SD1ENDA (0x1A4) +#define IOMD_SD1CURB (0x1A8) +#define IOMD_SD1ENDB (0x1AC) +#define IOMD_SD1CR (0x1B0) +#define IOMD_SD1ST (0x1B4) +#endif + +#define IOMD_CURSCUR (0x1C0) +#define IOMD_CURSINIT (0x1C4) + +#define IOMD_VIDCUR (0x1D0) +#define IOMD_VIDEND (0x1D4) +#define IOMD_VIDSTART (0x1D8) +#define IOMD_VIDINIT (0x1DC) +#define IOMD_VIDCR (0x1E0) + +#define IOMD_DMASTAT (0x1F0) +#define IOMD_DMAREQ (0x1F4) +#define IOMD_DMAMASK (0x1F8) + +#define DMA_END_S (1 << 31) +#define DMA_END_L (1 << 30) + +#define DMA_CR_C 0x80 +#define DMA_CR_D 0x40 +#define DMA_CR_E 0x20 + +#define DMA_ST_OFL 4 +#define DMA_ST_INT 2 +#define DMA_ST_AB 1 + +/* + * DMA (MEMC) compatibility + */ +#define HALF_SAM vram_half_sam +#define VDMA_ALIGNMENT (HALF_SAM * 2) +#define VDMA_XFERSIZE (HALF_SAM) +#define VDMA_INIT IOMD_VIDINIT +#define VDMA_START IOMD_VIDSTART +#define VDMA_END IOMD_VIDEND + +#ifndef __ASSEMBLY__ +extern unsigned int vram_half_sam; +#define video_set_dma(start,end,offset) \ +do { \ + outl (SCREEN_START + start, VDMA_START); \ + outl (SCREEN_START + end - VDMA_XFERSIZE, VDMA_END); \ + if (offset >= end - VDMA_XFERSIZE) \ + offset |= 0x40000000; \ + outl (SCREEN_START + offset, VDMA_INIT); \ +} while (0) +#endif + +#endif diff --git a/arch/arm/include/asm/hardware/iop3xx-adma.h b/arch/arm/include/asm/hardware/iop3xx-adma.h new file mode 100644 index 00000000..9b28f124 --- /dev/null +++ b/arch/arm/include/asm/hardware/iop3xx-adma.h @@ -0,0 +1,962 @@ +/* + * Copyright © 2006, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions 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., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ +#ifndef _ADMA_H +#define _ADMA_H +#include +#include +#include +#include + +/* Memory copy units */ +#define DMA_CCR(chan) (chan->mmr_base + 0x0) +#define DMA_CSR(chan) (chan->mmr_base + 0x4) +#define DMA_DAR(chan) (chan->mmr_base + 0xc) +#define DMA_NDAR(chan) (chan->mmr_base + 0x10) +#define DMA_PADR(chan) (chan->mmr_base + 0x14) +#define DMA_PUADR(chan) (chan->mmr_base + 0x18) +#define DMA_LADR(chan) (chan->mmr_base + 0x1c) +#define DMA_BCR(chan) (chan->mmr_base + 0x20) +#define DMA_DCR(chan) (chan->mmr_base + 0x24) + +/* Application accelerator unit */ +#define AAU_ACR(chan) (chan->mmr_base + 0x0) +#define AAU_ASR(chan) (chan->mmr_base + 0x4) +#define AAU_ADAR(chan) (chan->mmr_base + 0x8) +#define AAU_ANDAR(chan) (chan->mmr_base + 0xc) +#define AAU_SAR(src, chan) (chan->mmr_base + (0x10 + ((src) << 2))) +#define AAU_DAR(chan) (chan->mmr_base + 0x20) +#define AAU_ABCR(chan) (chan->mmr_base + 0x24) +#define AAU_ADCR(chan) (chan->mmr_base + 0x28) +#define AAU_SAR_EDCR(src_edc) (chan->mmr_base + (0x02c + ((src_edc-4) << 2))) +#define AAU_EDCR0_IDX 8 +#define AAU_EDCR1_IDX 17 +#define AAU_EDCR2_IDX 26 + +#define DMA0_ID 0 +#define DMA1_ID 1 +#define AAU_ID 2 + +struct iop3xx_aau_desc_ctrl { + unsigned int int_en:1; + unsigned int blk1_cmd_ctrl:3; + unsigned int blk2_cmd_ctrl:3; + unsigned int blk3_cmd_ctrl:3; + unsigned int blk4_cmd_ctrl:3; + unsigned int blk5_cmd_ctrl:3; + unsigned int blk6_cmd_ctrl:3; + unsigned int blk7_cmd_ctrl:3; + unsigned int blk8_cmd_ctrl:3; + unsigned int blk_ctrl:2; + unsigned int dual_xor_en:1; + unsigned int tx_complete:1; + unsigned int zero_result_err:1; + unsigned int zero_result_en:1; + unsigned int dest_write_en:1; +}; + +struct iop3xx_aau_e_desc_ctrl { + unsigned int reserved:1; + unsigned int blk1_cmd_ctrl:3; + unsigned int blk2_cmd_ctrl:3; + unsigned int blk3_cmd_ctrl:3; + unsigned int blk4_cmd_ctrl:3; + unsigned int blk5_cmd_ctrl:3; + unsigned int blk6_cmd_ctrl:3; + unsigned int blk7_cmd_ctrl:3; + unsigned int blk8_cmd_ctrl:3; + unsigned int reserved2:7; +}; + +struct iop3xx_dma_desc_ctrl { + unsigned int pci_transaction:4; + unsigned int int_en:1; + unsigned int dac_cycle_en:1; + unsigned int mem_to_mem_en:1; + unsigned int crc_data_tx_en:1; + unsigned int crc_gen_en:1; + unsigned int crc_seed_dis:1; + unsigned int reserved:21; + unsigned int crc_tx_complete:1; +}; + +struct iop3xx_desc_dma { + u32 next_desc; + union { + u32 pci_src_addr; + u32 pci_dest_addr; + u32 src_addr; + }; + union { + u32 upper_pci_src_addr; + u32 upper_pci_dest_addr; + }; + union { + u32 local_pci_src_addr; + u32 local_pci_dest_addr; + u32 dest_addr; + }; + u32 byte_count; + union { + u32 desc_ctrl; + struct iop3xx_dma_desc_ctrl desc_ctrl_field; + }; + u32 crc_addr; +}; + +struct iop3xx_desc_aau { + u32 next_desc; + u32 src[4]; + u32 dest_addr; + u32 byte_count; + union { + u32 desc_ctrl; + struct iop3xx_aau_desc_ctrl desc_ctrl_field; + }; + union { + u32 src_addr; + u32 e_desc_ctrl; + struct iop3xx_aau_e_desc_ctrl e_desc_ctrl_field; + } src_edc[31]; +}; + +struct iop3xx_aau_gfmr { + unsigned int gfmr1:8; + unsigned int gfmr2:8; + unsigned int gfmr3:8; + unsigned int gfmr4:8; +}; + +struct iop3xx_desc_pq_xor { + u32 next_desc; + u32 src[3]; + union { + u32 data_mult1; + struct iop3xx_aau_gfmr data_mult1_field; + }; + u32 dest_addr; + u32 byte_count; + union { + u32 desc_ctrl; + struct iop3xx_aau_desc_ctrl desc_ctrl_field; + }; + union { + u32 src_addr; + u32 e_desc_ctrl; + struct iop3xx_aau_e_desc_ctrl e_desc_ctrl_field; + u32 data_multiplier; + struct iop3xx_aau_gfmr data_mult_field; + u32 reserved; + } src_edc_gfmr[19]; +}; + +struct iop3xx_desc_dual_xor { + u32 next_desc; + u32 src0_addr; + u32 src1_addr; + u32 h_src_addr; + u32 d_src_addr; + u32 h_dest_addr; + u32 byte_count; + union { + u32 desc_ctrl; + struct iop3xx_aau_desc_ctrl desc_ctrl_field; + }; + u32 d_dest_addr; +}; + +union iop3xx_desc { + struct iop3xx_desc_aau *aau; + struct iop3xx_desc_dma *dma; + struct iop3xx_desc_pq_xor *pq_xor; + struct iop3xx_desc_dual_xor *dual_xor; + void *ptr; +}; + +/* No support for p+q operations */ +static inline int +iop_chan_pq_slot_count(size_t len, int src_cnt, int *slots_per_op) +{ + BUG(); + return 0; +} + +static inline void +iop_desc_init_pq(struct iop_adma_desc_slot *desc, int src_cnt, + unsigned long flags) +{ + BUG(); +} + +static inline void +iop_desc_set_pq_addr(struct iop_adma_desc_slot *desc, dma_addr_t *addr) +{ + BUG(); +} + +static inline void +iop_desc_set_pq_src_addr(struct iop_adma_desc_slot *desc, int src_idx, + dma_addr_t addr, unsigned char coef) +{ + BUG(); +} + +static inline int +iop_chan_pq_zero_sum_slot_count(size_t len, int src_cnt, int *slots_per_op) +{ + BUG(); + return 0; +} + +static inline void +iop_desc_init_pq_zero_sum(struct iop_adma_desc_slot *desc, int src_cnt, + unsigned long flags) +{ + BUG(); +} + +static inline void +iop_desc_set_pq_zero_sum_byte_count(struct iop_adma_desc_slot *desc, u32 len) +{ + BUG(); +} + +#define iop_desc_set_pq_zero_sum_src_addr iop_desc_set_pq_src_addr + +static inline void +iop_desc_set_pq_zero_sum_addr(struct iop_adma_desc_slot *desc, int pq_idx, + dma_addr_t *src) +{ + BUG(); +} + +static inline int iop_adma_get_max_xor(void) +{ + return 32; +} + +static inline int iop_adma_get_max_pq(void) +{ + BUG(); + return 0; +} + +static inline u32 iop_chan_get_current_descriptor(struct iop_adma_chan *chan) +{ + int id = chan->device->id; + + switch (id) { + case DMA0_ID: + case DMA1_ID: + return __raw_readl(DMA_DAR(chan)); + case AAU_ID: + return __raw_readl(AAU_ADAR(chan)); + default: + BUG(); + } + return 0; +} + +static inline void iop_chan_set_next_descriptor(struct iop_adma_chan *chan, + u32 next_desc_addr) +{ + int id = chan->device->id; + + switch (id) { + case DMA0_ID: + case DMA1_ID: + __raw_writel(next_desc_addr, DMA_NDAR(chan)); + break; + case AAU_ID: + __raw_writel(next_desc_addr, AAU_ANDAR(chan)); + break; + } + +} + +#define IOP_ADMA_STATUS_BUSY (1 << 10) +#define IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT (1024) +#define IOP_ADMA_XOR_MAX_BYTE_COUNT (16 * 1024 * 1024) +#define IOP_ADMA_MAX_BYTE_COUNT (16 * 1024 * 1024) + +static inline int iop_chan_is_busy(struct iop_adma_chan *chan) +{ + u32 status = __raw_readl(DMA_CSR(chan)); + return (status & IOP_ADMA_STATUS_BUSY) ? 1 : 0; +} + +static inline int iop_desc_is_aligned(struct iop_adma_desc_slot *desc, + int num_slots) +{ + /* num_slots will only ever be 1, 2, 4, or 8 */ + return (desc->idx & (num_slots - 1)) ? 0 : 1; +} + +/* to do: support large (i.e. > hw max) buffer sizes */ +static inline int iop_chan_memcpy_slot_count(size_t len, int *slots_per_op) +{ + *slots_per_op = 1; + return 1; +} + +/* to do: support large (i.e. > hw max) buffer sizes */ +static inline int iop_chan_memset_slot_count(size_t len, int *slots_per_op) +{ + *slots_per_op = 1; + return 1; +} + +static inline int iop3xx_aau_xor_slot_count(size_t len, int src_cnt, + int *slots_per_op) +{ + static const char slot_count_table[] = { + 1, 1, 1, 1, /* 01 - 04 */ + 2, 2, 2, 2, /* 05 - 08 */ + 4, 4, 4, 4, /* 09 - 12 */ + 4, 4, 4, 4, /* 13 - 16 */ + 8, 8, 8, 8, /* 17 - 20 */ + 8, 8, 8, 8, /* 21 - 24 */ + 8, 8, 8, 8, /* 25 - 28 */ + 8, 8, 8, 8, /* 29 - 32 */ + }; + *slots_per_op = slot_count_table[src_cnt - 1]; + return *slots_per_op; +} + +static inline int +iop_chan_interrupt_slot_count(int *slots_per_op, struct iop_adma_chan *chan) +{ + switch (chan->device->id) { + case DMA0_ID: + case DMA1_ID: + return iop_chan_memcpy_slot_count(0, slots_per_op); + case AAU_ID: + return iop3xx_aau_xor_slot_count(0, 2, slots_per_op); + default: + BUG(); + } + return 0; +} + +static inline int iop_chan_xor_slot_count(size_t len, int src_cnt, + int *slots_per_op) +{ + int slot_cnt = iop3xx_aau_xor_slot_count(len, src_cnt, slots_per_op); + + if (len <= IOP_ADMA_XOR_MAX_BYTE_COUNT) + return slot_cnt; + + len -= IOP_ADMA_XOR_MAX_BYTE_COUNT; + while (len > IOP_ADMA_XOR_MAX_BYTE_COUNT) { + len -= IOP_ADMA_XOR_MAX_BYTE_COUNT; + slot_cnt += *slots_per_op; + } + + slot_cnt += *slots_per_op; + + return slot_cnt; +} + +/* zero sum on iop3xx is limited to 1k at a time so it requires multiple + * descriptors + */ +static inline int iop_chan_zero_sum_slot_count(size_t len, int src_cnt, + int *slots_per_op) +{ + int slot_cnt = iop3xx_aau_xor_slot_count(len, src_cnt, slots_per_op); + + if (len <= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT) + return slot_cnt; + + len -= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT; + while (len > IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT) { + len -= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT; + slot_cnt += *slots_per_op; + } + + slot_cnt += *slots_per_op; + + return slot_cnt; +} + +static inline int iop_desc_is_pq(struct iop_adma_desc_slot *desc) +{ + return 0; +} + +static inline u32 iop_desc_get_dest_addr(struct iop_adma_desc_slot *desc, + struct iop_adma_chan *chan) +{ + union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, }; + + switch (chan->device->id) { + case DMA0_ID: + case DMA1_ID: + return hw_desc.dma->dest_addr; + case AAU_ID: + return hw_desc.aau->dest_addr; + default: + BUG(); + } + return 0; +} + + +static inline u32 iop_desc_get_qdest_addr(struct iop_adma_desc_slot *desc, + struct iop_adma_chan *chan) +{ + BUG(); + return 0; +} + +static inline u32 iop_desc_get_byte_count(struct iop_adma_desc_slot *desc, + struct iop_adma_chan *chan) +{ + union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, }; + + switch (chan->device->id) { + case DMA0_ID: + case DMA1_ID: + return hw_desc.dma->byte_count; + case AAU_ID: + return hw_desc.aau->byte_count; + default: + BUG(); + } + return 0; +} + +/* translate the src_idx to a descriptor word index */ +static inline int __desc_idx(int src_idx) +{ + static const int desc_idx_table[] = { 0, 0, 0, 0, + 0, 1, 2, 3, + 5, 6, 7, 8, + 9, 10, 11, 12, + 14, 15, 16, 17, + 18, 19, 20, 21, + 23, 24, 25, 26, + 27, 28, 29, 30, + }; + + return desc_idx_table[src_idx]; +} + +static inline u32 iop_desc_get_src_addr(struct iop_adma_desc_slot *desc, + struct iop_adma_chan *chan, + int src_idx) +{ + union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, }; + + switch (chan->device->id) { + case DMA0_ID: + case DMA1_ID: + return hw_desc.dma->src_addr; + case AAU_ID: + break; + default: + BUG(); + } + + if (src_idx < 4) + return hw_desc.aau->src[src_idx]; + else + return hw_desc.aau->src_edc[__desc_idx(src_idx)].src_addr; +} + +static inline void iop3xx_aau_desc_set_src_addr(struct iop3xx_desc_aau *hw_desc, + int src_idx, dma_addr_t addr) +{ + if (src_idx < 4) + hw_desc->src[src_idx] = addr; + else + hw_desc->src_edc[__desc_idx(src_idx)].src_addr = addr; +} + +static inline void +iop_desc_init_memcpy(struct iop_adma_desc_slot *desc, unsigned long flags) +{ + struct iop3xx_desc_dma *hw_desc = desc->hw_desc; + union { + u32 value; + struct iop3xx_dma_desc_ctrl field; + } u_desc_ctrl; + + u_desc_ctrl.value = 0; + u_desc_ctrl.field.mem_to_mem_en = 1; + u_desc_ctrl.field.pci_transaction = 0xe; /* memory read block */ + u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT; + hw_desc->desc_ctrl = u_desc_ctrl.value; + hw_desc->upper_pci_src_addr = 0; + hw_desc->crc_addr = 0; +} + +static inline void +iop_desc_init_memset(struct iop_adma_desc_slot *desc, unsigned long flags) +{ + struct iop3xx_desc_aau *hw_desc = desc->hw_desc; + union { + u32 value; + struct iop3xx_aau_desc_ctrl field; + } u_desc_ctrl; + + u_desc_ctrl.value = 0; + u_desc_ctrl.field.blk1_cmd_ctrl = 0x2; /* memory block fill */ + u_desc_ctrl.field.dest_write_en = 1; + u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT; + hw_desc->desc_ctrl = u_desc_ctrl.value; +} + +static inline u32 +iop3xx_desc_init_xor(struct iop3xx_desc_aau *hw_desc, int src_cnt, + unsigned long flags) +{ + int i, shift; + u32 edcr; + union { + u32 value; + struct iop3xx_aau_desc_ctrl field; + } u_desc_ctrl; + + u_desc_ctrl.value = 0; + switch (src_cnt) { + case 25 ... 32: + u_desc_ctrl.field.blk_ctrl = 0x3; /* use EDCR[2:0] */ + edcr = 0; + shift = 1; + for (i = 24; i < src_cnt; i++) { + edcr |= (1 << shift); + shift += 3; + } + hw_desc->src_edc[AAU_EDCR2_IDX].e_desc_ctrl = edcr; + src_cnt = 24; + /* fall through */ + case 17 ... 24: + if (!u_desc_ctrl.field.blk_ctrl) { + hw_desc->src_edc[AAU_EDCR2_IDX].e_desc_ctrl = 0; + u_desc_ctrl.field.blk_ctrl = 0x3; /* use EDCR[2:0] */ + } + edcr = 0; + shift = 1; + for (i = 16; i < src_cnt; i++) { + edcr |= (1 << shift); + shift += 3; + } + hw_desc->src_edc[AAU_EDCR1_IDX].e_desc_ctrl = edcr; + src_cnt = 16; + /* fall through */ + case 9 ... 16: + if (!u_desc_ctrl.field.blk_ctrl) + u_desc_ctrl.field.blk_ctrl = 0x2; /* use EDCR0 */ + edcr = 0; + shift = 1; + for (i = 8; i < src_cnt; i++) { + edcr |= (1 << shift); + shift += 3; + } + hw_desc->src_edc[AAU_EDCR0_IDX].e_desc_ctrl = edcr; + src_cnt = 8; + /* fall through */ + case 2 ... 8: + shift = 1; + for (i = 0; i < src_cnt; i++) { + u_desc_ctrl.value |= (1 << shift); + shift += 3; + } + + if (!u_desc_ctrl.field.blk_ctrl && src_cnt > 4) + u_desc_ctrl.field.blk_ctrl = 0x1; /* use mini-desc */ + } + + u_desc_ctrl.field.dest_write_en = 1; + u_desc_ctrl.field.blk1_cmd_ctrl = 0x7; /* direct fill */ + u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT; + hw_desc->desc_ctrl = u_desc_ctrl.value; + + return u_desc_ctrl.value; +} + +static inline void +iop_desc_init_xor(struct iop_adma_desc_slot *desc, int src_cnt, + unsigned long flags) +{ + iop3xx_desc_init_xor(desc->hw_desc, src_cnt, flags); +} + +/* return the number of operations */ +static inline int +iop_desc_init_zero_sum(struct iop_adma_desc_slot *desc, int src_cnt, + unsigned long flags) +{ + int slot_cnt = desc->slot_cnt, slots_per_op = desc->slots_per_op; + struct iop3xx_desc_aau *hw_desc, *prev_hw_desc, *iter; + union { + u32 value; + struct iop3xx_aau_desc_ctrl field; + } u_desc_ctrl; + int i, j; + + hw_desc = desc->hw_desc; + + for (i = 0, j = 0; (slot_cnt -= slots_per_op) >= 0; + i += slots_per_op, j++) { + iter = iop_hw_desc_slot_idx(hw_desc, i); + u_desc_ctrl.value = iop3xx_desc_init_xor(iter, src_cnt, flags); + u_desc_ctrl.field.dest_write_en = 0; + u_desc_ctrl.field.zero_result_en = 1; + u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT; + iter->desc_ctrl = u_desc_ctrl.value; + + /* for the subsequent descriptors preserve the store queue + * and chain them together + */ + if (i) { + prev_hw_desc = + iop_hw_desc_slot_idx(hw_desc, i - slots_per_op); + prev_hw_desc->next_desc = + (u32) (desc->async_tx.phys + (i << 5)); + } + } + + return j; +} + +static inline void +iop_desc_init_null_xor(struct iop_adma_desc_slot *desc, int src_cnt, + unsigned long flags) +{ + struct iop3xx_desc_aau *hw_desc = desc->hw_desc; + union { + u32 value; + struct iop3xx_aau_desc_ctrl field; + } u_desc_ctrl; + + u_desc_ctrl.value = 0; + switch (src_cnt) { + case 25 ... 32: + u_desc_ctrl.field.blk_ctrl = 0x3; /* use EDCR[2:0] */ + hw_desc->src_edc[AAU_EDCR2_IDX].e_desc_ctrl = 0; + /* fall through */ + case 17 ... 24: + if (!u_desc_ctrl.field.blk_ctrl) { + hw_desc->src_edc[AAU_EDCR2_IDX].e_desc_ctrl = 0; + u_desc_ctrl.field.blk_ctrl = 0x3; /* use EDCR[2:0] */ + } + hw_desc->src_edc[AAU_EDCR1_IDX].e_desc_ctrl = 0; + /* fall through */ + case 9 ... 16: + if (!u_desc_ctrl.field.blk_ctrl) + u_desc_ctrl.field.blk_ctrl = 0x2; /* use EDCR0 */ + hw_desc->src_edc[AAU_EDCR0_IDX].e_desc_ctrl = 0; + /* fall through */ + case 1 ... 8: + if (!u_desc_ctrl.field.blk_ctrl && src_cnt > 4) + u_desc_ctrl.field.blk_ctrl = 0x1; /* use mini-desc */ + } + + u_desc_ctrl.field.dest_write_en = 0; + u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT; + hw_desc->desc_ctrl = u_desc_ctrl.value; +} + +static inline void iop_desc_set_byte_count(struct iop_adma_desc_slot *desc, + struct iop_adma_chan *chan, + u32 byte_count) +{ + union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, }; + + switch (chan->device->id) { + case DMA0_ID: + case DMA1_ID: + hw_desc.dma->byte_count = byte_count; + break; + case AAU_ID: + hw_desc.aau->byte_count = byte_count; + break; + default: + BUG(); + } +} + +static inline void +iop_desc_init_interrupt(struct iop_adma_desc_slot *desc, + struct iop_adma_chan *chan) +{ + union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, }; + + switch (chan->device->id) { + case DMA0_ID: + case DMA1_ID: + iop_desc_init_memcpy(desc, 1); + hw_desc.dma->byte_count = 0; + hw_desc.dma->dest_addr = 0; + hw_desc.dma->src_addr = 0; + break; + case AAU_ID: + iop_desc_init_null_xor(desc, 2, 1); + hw_desc.aau->byte_count = 0; + hw_desc.aau->dest_addr = 0; + hw_desc.aau->src[0] = 0; + hw_desc.aau->src[1] = 0; + break; + default: + BUG(); + } +} + +static inline void +iop_desc_set_zero_sum_byte_count(struct iop_adma_desc_slot *desc, u32 len) +{ + int slots_per_op = desc->slots_per_op; + struct iop3xx_desc_aau *hw_desc = desc->hw_desc, *iter; + int i = 0; + + if (len <= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT) { + hw_desc->byte_count = len; + } else { + do { + iter = iop_hw_desc_slot_idx(hw_desc, i); + iter->byte_count = IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT; + len -= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT; + i += slots_per_op; + } while (len > IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT); + + iter = iop_hw_desc_slot_idx(hw_desc, i); + iter->byte_count = len; + } +} + +static inline void iop_desc_set_dest_addr(struct iop_adma_desc_slot *desc, + struct iop_adma_chan *chan, + dma_addr_t addr) +{ + union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, }; + + switch (chan->device->id) { + case DMA0_ID: + case DMA1_ID: + hw_desc.dma->dest_addr = addr; + break; + case AAU_ID: + hw_desc.aau->dest_addr = addr; + break; + default: + BUG(); + } +} + +static inline void iop_desc_set_memcpy_src_addr(struct iop_adma_desc_slot *desc, + dma_addr_t addr) +{ + struct iop3xx_desc_dma *hw_desc = desc->hw_desc; + hw_desc->src_addr = addr; +} + +static inline void +iop_desc_set_zero_sum_src_addr(struct iop_adma_desc_slot *desc, int src_idx, + dma_addr_t addr) +{ + + struct iop3xx_desc_aau *hw_desc = desc->hw_desc, *iter; + int slot_cnt = desc->slot_cnt, slots_per_op = desc->slots_per_op; + int i; + + for (i = 0; (slot_cnt -= slots_per_op) >= 0; + i += slots_per_op, addr += IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT) { + iter = iop_hw_desc_slot_idx(hw_desc, i); + iop3xx_aau_desc_set_src_addr(iter, src_idx, addr); + } +} + +static inline void iop_desc_set_xor_src_addr(struct iop_adma_desc_slot *desc, + int src_idx, dma_addr_t addr) +{ + + struct iop3xx_desc_aau *hw_desc = desc->hw_desc, *iter; + int slot_cnt = desc->slot_cnt, slots_per_op = desc->slots_per_op; + int i; + + for (i = 0; (slot_cnt -= slots_per_op) >= 0; + i += slots_per_op, addr += IOP_ADMA_XOR_MAX_BYTE_COUNT) { + iter = iop_hw_desc_slot_idx(hw_desc, i); + iop3xx_aau_desc_set_src_addr(iter, src_idx, addr); + } +} + +static inline void iop_desc_set_next_desc(struct iop_adma_desc_slot *desc, + u32 next_desc_addr) +{ + /* hw_desc->next_desc is the same location for all channels */ + union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, }; + + iop_paranoia(hw_desc.dma->next_desc); + hw_desc.dma->next_desc = next_desc_addr; +} + +static inline u32 iop_desc_get_next_desc(struct iop_adma_desc_slot *desc) +{ + /* hw_desc->next_desc is the same location for all channels */ + union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, }; + return hw_desc.dma->next_desc; +} + +static inline void iop_desc_clear_next_desc(struct iop_adma_desc_slot *desc) +{ + /* hw_desc->next_desc is the same location for all channels */ + union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, }; + hw_desc.dma->next_desc = 0; +} + +static inline void iop_desc_set_block_fill_val(struct iop_adma_desc_slot *desc, + u32 val) +{ + struct iop3xx_desc_aau *hw_desc = desc->hw_desc; + hw_desc->src[0] = val; +} + +static inline enum sum_check_flags +iop_desc_get_zero_result(struct iop_adma_desc_slot *desc) +{ + struct iop3xx_desc_aau *hw_desc = desc->hw_desc; + struct iop3xx_aau_desc_ctrl desc_ctrl = hw_desc->desc_ctrl_field; + + iop_paranoia(!(desc_ctrl.tx_complete && desc_ctrl.zero_result_en)); + return desc_ctrl.zero_result_err << SUM_CHECK_P; +} + +static inline void iop_chan_append(struct iop_adma_chan *chan) +{ + u32 dma_chan_ctrl; + + dma_chan_ctrl = __raw_readl(DMA_CCR(chan)); + dma_chan_ctrl |= 0x2; + __raw_writel(dma_chan_ctrl, DMA_CCR(chan)); +} + +static inline u32 iop_chan_get_status(struct iop_adma_chan *chan) +{ + return __raw_readl(DMA_CSR(chan)); +} + +static inline void iop_chan_disable(struct iop_adma_chan *chan) +{ + u32 dma_chan_ctrl = __raw_readl(DMA_CCR(chan)); + dma_chan_ctrl &= ~1; + __raw_writel(dma_chan_ctrl, DMA_CCR(chan)); +} + +static inline void iop_chan_enable(struct iop_adma_chan *chan) +{ + u32 dma_chan_ctrl = __raw_readl(DMA_CCR(chan)); + + dma_chan_ctrl |= 1; + __raw_writel(dma_chan_ctrl, DMA_CCR(chan)); +} + +static inline void iop_adma_device_clear_eot_status(struct iop_adma_chan *chan) +{ + u32 status = __raw_readl(DMA_CSR(chan)); + status &= (1 << 9); + __raw_writel(status, DMA_CSR(chan)); +} + +static inline void iop_adma_device_clear_eoc_status(struct iop_adma_chan *chan) +{ + u32 status = __raw_readl(DMA_CSR(chan)); + status &= (1 << 8); + __raw_writel(status, DMA_CSR(chan)); +} + +static inline void iop_adma_device_clear_err_status(struct iop_adma_chan *chan) +{ + u32 status = __raw_readl(DMA_CSR(chan)); + + switch (chan->device->id) { + case DMA0_ID: + case DMA1_ID: + status &= (1 << 5) | (1 << 3) | (1 << 2) | (1 << 1); + break; + case AAU_ID: + status &= (1 << 5); + break; + default: + BUG(); + } + + __raw_writel(status, DMA_CSR(chan)); +} + +static inline int +iop_is_err_int_parity(unsigned long status, struct iop_adma_chan *chan) +{ + return 0; +} + +static inline int +iop_is_err_mcu_abort(unsigned long status, struct iop_adma_chan *chan) +{ + return 0; +} + +static inline int +iop_is_err_int_tabort(unsigned long status, struct iop_adma_chan *chan) +{ + return 0; +} + +static inline int +iop_is_err_int_mabort(unsigned long status, struct iop_adma_chan *chan) +{ + return test_bit(5, &status); +} + +static inline int +iop_is_err_pci_tabort(unsigned long status, struct iop_adma_chan *chan) +{ + switch (chan->device->id) { + case DMA0_ID: + case DMA1_ID: + return test_bit(2, &status); + default: + return 0; + } +} + +static inline int +iop_is_err_pci_mabort(unsigned long status, struct iop_adma_chan *chan) +{ + switch (chan->device->id) { + case DMA0_ID: + case DMA1_ID: + return test_bit(3, &status); + default: + return 0; + } +} + +static inline int +iop_is_err_split_tx(unsigned long status, struct iop_adma_chan *chan) +{ + switch (chan->device->id) { + case DMA0_ID: + case DMA1_ID: + return test_bit(1, &status); + default: + return 0; + } +} +#endif /* _ADMA_H */ diff --git a/arch/arm/include/asm/hardware/iop3xx-gpio.h b/arch/arm/include/asm/hardware/iop3xx-gpio.h new file mode 100644 index 00000000..b69d972b --- /dev/null +++ b/arch/arm/include/asm/hardware/iop3xx-gpio.h @@ -0,0 +1,73 @@ +/* + * arch/arm/include/asm/hardware/iop3xx-gpio.h + * + * IOP3xx GPIO wrappers + * + * Copyright (c) 2008 Arnaud Patard + * Based on IXP4XX gpio.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 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_ARM_HARDWARE_IOP3XX_GPIO_H +#define __ASM_ARM_HARDWARE_IOP3XX_GPIO_H + +#include +#include + +#define IOP3XX_N_GPIOS 8 + +static inline int gpio_get_value(unsigned gpio) +{ + if (gpio > IOP3XX_N_GPIOS) + return __gpio_get_value(gpio); + + return gpio_line_get(gpio); +} + +static inline void gpio_set_value(unsigned gpio, int value) +{ + if (gpio > IOP3XX_N_GPIOS) { + __gpio_set_value(gpio, value); + return; + } + gpio_line_set(gpio, value); +} + +static inline int gpio_cansleep(unsigned gpio) +{ + if (gpio < IOP3XX_N_GPIOS) + return 0; + else + return __gpio_cansleep(gpio); +} + +/* + * The GPIOs are not generating any interrupt + * Note : manuals are not clear about this + */ +static inline int gpio_to_irq(int gpio) +{ + return -EINVAL; +} + +static inline int irq_to_gpio(int gpio) +{ + return -EINVAL; +} + +#endif + diff --git a/arch/arm/include/asm/hardware/iop3xx.h b/arch/arm/include/asm/hardware/iop3xx.h new file mode 100644 index 00000000..5daea296 --- /dev/null +++ b/arch/arm/include/asm/hardware/iop3xx.h @@ -0,0 +1,329 @@ +/* + * arch/arm/include/asm/hardware/iop3xx.h + * + * Intel IOP32X and IOP33X register definitions + * + * Author: Rory Bolt + * Copyright (C) 2002 Rory Bolt + * Copyright (C) 2004 Intel Corp. + * + * 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. + */ + +#ifndef __IOP3XX_H +#define __IOP3XX_H + +/* + * IOP3XX GPIO handling + */ +#define GPIO_IN 0 +#define GPIO_OUT 1 +#define GPIO_LOW 0 +#define GPIO_HIGH 1 +#define IOP3XX_GPIO_LINE(x) (x) + +#ifndef __ASSEMBLY__ +extern void gpio_line_config(int line, int direction); +extern int gpio_line_get(int line); +extern void gpio_line_set(int line, int value); +extern int init_atu; +extern int iop3xx_get_init_atu(void); +#endif + + +/* + * IOP3XX processor registers + */ +#define IOP3XX_PERIPHERAL_PHYS_BASE 0xffffe000 +#define IOP3XX_PERIPHERAL_VIRT_BASE 0xfeffe000 +#define IOP3XX_PERIPHERAL_SIZE 0x00002000 +#define IOP3XX_PERIPHERAL_UPPER_PA (IOP3XX_PERIPHERAL_PHYS_BASE +\ + IOP3XX_PERIPHERAL_SIZE - 1) +#define IOP3XX_PERIPHERAL_UPPER_VA (IOP3XX_PERIPHERAL_VIRT_BASE +\ + IOP3XX_PERIPHERAL_SIZE - 1) +#define IOP3XX_PMMR_PHYS_TO_VIRT(addr) (u32) ((u32) (addr) -\ + (IOP3XX_PERIPHERAL_PHYS_BASE\ + - IOP3XX_PERIPHERAL_VIRT_BASE)) +#define IOP3XX_REG_ADDR(reg) (IOP3XX_PERIPHERAL_VIRT_BASE + (reg)) + +/* Address Translation Unit */ +#define IOP3XX_ATUVID (volatile u16 *)IOP3XX_REG_ADDR(0x0100) +#define IOP3XX_ATUDID (volatile u16 *)IOP3XX_REG_ADDR(0x0102) +#define IOP3XX_ATUCMD (volatile u16 *)IOP3XX_REG_ADDR(0x0104) +#define IOP3XX_ATUSR (volatile u16 *)IOP3XX_REG_ADDR(0x0106) +#define IOP3XX_ATURID (volatile u8 *)IOP3XX_REG_ADDR(0x0108) +#define IOP3XX_ATUCCR (volatile u32 *)IOP3XX_REG_ADDR(0x0109) +#define IOP3XX_ATUCLSR (volatile u8 *)IOP3XX_REG_ADDR(0x010c) +#define IOP3XX_ATULT (volatile u8 *)IOP3XX_REG_ADDR(0x010d) +#define IOP3XX_ATUHTR (volatile u8 *)IOP3XX_REG_ADDR(0x010e) +#define IOP3XX_ATUBIST (volatile u8 *)IOP3XX_REG_ADDR(0x010f) +#define IOP3XX_IABAR0 (volatile u32 *)IOP3XX_REG_ADDR(0x0110) +#define IOP3XX_IAUBAR0 (volatile u32 *)IOP3XX_REG_ADDR(0x0114) +#define IOP3XX_IABAR1 (volatile u32 *)IOP3XX_REG_ADDR(0x0118) +#define IOP3XX_IAUBAR1 (volatile u32 *)IOP3XX_REG_ADDR(0x011c) +#define IOP3XX_IABAR2 (volatile u32 *)IOP3XX_REG_ADDR(0x0120) +#define IOP3XX_IAUBAR2 (volatile u32 *)IOP3XX_REG_ADDR(0x0124) +#define IOP3XX_ASVIR (volatile u16 *)IOP3XX_REG_ADDR(0x012c) +#define IOP3XX_ASIR (volatile u16 *)IOP3XX_REG_ADDR(0x012e) +#define IOP3XX_ERBAR (volatile u32 *)IOP3XX_REG_ADDR(0x0130) +#define IOP3XX_ATUILR (volatile u8 *)IOP3XX_REG_ADDR(0x013c) +#define IOP3XX_ATUIPR (volatile u8 *)IOP3XX_REG_ADDR(0x013d) +#define IOP3XX_ATUMGNT (volatile u8 *)IOP3XX_REG_ADDR(0x013e) +#define IOP3XX_ATUMLAT (volatile u8 *)IOP3XX_REG_ADDR(0x013f) +#define IOP3XX_IALR0 (volatile u32 *)IOP3XX_REG_ADDR(0x0140) +#define IOP3XX_IATVR0 (volatile u32 *)IOP3XX_REG_ADDR(0x0144) +#define IOP3XX_ERLR (volatile u32 *)IOP3XX_REG_ADDR(0x0148) +#define IOP3XX_ERTVR (volatile u32 *)IOP3XX_REG_ADDR(0x014c) +#define IOP3XX_IALR1 (volatile u32 *)IOP3XX_REG_ADDR(0x0150) +#define IOP3XX_IALR2 (volatile u32 *)IOP3XX_REG_ADDR(0x0154) +#define IOP3XX_IATVR2 (volatile u32 *)IOP3XX_REG_ADDR(0x0158) +#define IOP3XX_OIOWTVR (volatile u32 *)IOP3XX_REG_ADDR(0x015c) +#define IOP3XX_OMWTVR0 (volatile u32 *)IOP3XX_REG_ADDR(0x0160) +#define IOP3XX_OUMWTVR0 (volatile u32 *)IOP3XX_REG_ADDR(0x0164) +#define IOP3XX_OMWTVR1 (volatile u32 *)IOP3XX_REG_ADDR(0x0168) +#define IOP3XX_OUMWTVR1 (volatile u32 *)IOP3XX_REG_ADDR(0x016c) +#define IOP3XX_OUDWTVR (volatile u32 *)IOP3XX_REG_ADDR(0x0178) +#define IOP3XX_ATUCR (volatile u32 *)IOP3XX_REG_ADDR(0x0180) +#define IOP3XX_PCSR (volatile u32 *)IOP3XX_REG_ADDR(0x0184) +#define IOP3XX_ATUISR (volatile u32 *)IOP3XX_REG_ADDR(0x0188) +#define IOP3XX_ATUIMR (volatile u32 *)IOP3XX_REG_ADDR(0x018c) +#define IOP3XX_IABAR3 (volatile u32 *)IOP3XX_REG_ADDR(0x0190) +#define IOP3XX_IAUBAR3 (volatile u32 *)IOP3XX_REG_ADDR(0x0194) +#define IOP3XX_IALR3 (volatile u32 *)IOP3XX_REG_ADDR(0x0198) +#define IOP3XX_IATVR3 (volatile u32 *)IOP3XX_REG_ADDR(0x019c) +#define IOP3XX_OCCAR (volatile u32 *)IOP3XX_REG_ADDR(0x01a4) +#define IOP3XX_OCCDR (volatile u32 *)IOP3XX_REG_ADDR(0x01ac) +#define IOP3XX_PDSCR (volatile u32 *)IOP3XX_REG_ADDR(0x01bc) +#define IOP3XX_PMCAPID (volatile u8 *)IOP3XX_REG_ADDR(0x01c0) +#define IOP3XX_PMNEXT (volatile u8 *)IOP3XX_REG_ADDR(0x01c1) +#define IOP3XX_APMCR (volatile u16 *)IOP3XX_REG_ADDR(0x01c2) +#define IOP3XX_APMCSR (volatile u16 *)IOP3XX_REG_ADDR(0x01c4) +#define IOP3XX_PCIXCAPID (volatile u8 *)IOP3XX_REG_ADDR(0x01e0) +#define IOP3XX_PCIXNEXT (volatile u8 *)IOP3XX_REG_ADDR(0x01e1) +#define IOP3XX_PCIXCMD (volatile u16 *)IOP3XX_REG_ADDR(0x01e2) +#define IOP3XX_PCIXSR (volatile u32 *)IOP3XX_REG_ADDR(0x01e4) +#define IOP3XX_PCIIRSR (volatile u32 *)IOP3XX_REG_ADDR(0x01ec) +#define IOP3XX_PCSR_OUT_Q_BUSY (1 << 15) +#define IOP3XX_PCSR_IN_Q_BUSY (1 << 14) +#define IOP3XX_ATUCR_OUT_EN (1 << 1) + +#define IOP3XX_INIT_ATU_DEFAULT 0 +#define IOP3XX_INIT_ATU_DISABLE -1 +#define IOP3XX_INIT_ATU_ENABLE 1 + +/* Messaging Unit */ +#define IOP3XX_IMR0 (volatile u32 *)IOP3XX_REG_ADDR(0x0310) +#define IOP3XX_IMR1 (volatile u32 *)IOP3XX_REG_ADDR(0x0314) +#define IOP3XX_OMR0 (volatile u32 *)IOP3XX_REG_ADDR(0x0318) +#define IOP3XX_OMR1 (volatile u32 *)IOP3XX_REG_ADDR(0x031c) +#define IOP3XX_IDR (volatile u32 *)IOP3XX_REG_ADDR(0x0320) +#define IOP3XX_IISR (volatile u32 *)IOP3XX_REG_ADDR(0x0324) +#define IOP3XX_IIMR (volatile u32 *)IOP3XX_REG_ADDR(0x0328) +#define IOP3XX_ODR (volatile u32 *)IOP3XX_REG_ADDR(0x032c) +#define IOP3XX_OISR (volatile u32 *)IOP3XX_REG_ADDR(0x0330) +#define IOP3XX_OIMR (volatile u32 *)IOP3XX_REG_ADDR(0x0334) +#define IOP3XX_MUCR (volatile u32 *)IOP3XX_REG_ADDR(0x0350) +#define IOP3XX_QBAR (volatile u32 *)IOP3XX_REG_ADDR(0x0354) +#define IOP3XX_IFHPR (volatile u32 *)IOP3XX_REG_ADDR(0x0360) +#define IOP3XX_IFTPR (volatile u32 *)IOP3XX_REG_ADDR(0x0364) +#define IOP3XX_IPHPR (volatile u32 *)IOP3XX_REG_ADDR(0x0368) +#define IOP3XX_IPTPR (volatile u32 *)IOP3XX_REG_ADDR(0x036c) +#define IOP3XX_OFHPR (volatile u32 *)IOP3XX_REG_ADDR(0x0370) +#define IOP3XX_OFTPR (volatile u32 *)IOP3XX_REG_ADDR(0x0374) +#define IOP3XX_OPHPR (volatile u32 *)IOP3XX_REG_ADDR(0x0378) +#define IOP3XX_OPTPR (volatile u32 *)IOP3XX_REG_ADDR(0x037c) +#define IOP3XX_IAR (volatile u32 *)IOP3XX_REG_ADDR(0x0380) + +/* DMA Controller */ +#define IOP3XX_DMA_PHYS_BASE(chan) (IOP3XX_PERIPHERAL_PHYS_BASE + \ + (0x400 + (chan << 6))) +#define IOP3XX_DMA_UPPER_PA(chan) (IOP3XX_DMA_PHYS_BASE(chan) + 0x27) + +/* Peripheral bus interface */ +#define IOP3XX_PBCR (volatile u32 *)IOP3XX_REG_ADDR(0x0680) +#define IOP3XX_PBISR (volatile u32 *)IOP3XX_REG_ADDR(0x0684) +#define IOP3XX_PBBAR0 (volatile u32 *)IOP3XX_REG_ADDR(0x0688) +#define IOP3XX_PBLR0 (volatile u32 *)IOP3XX_REG_ADDR(0x068c) +#define IOP3XX_PBBAR1 (volatile u32 *)IOP3XX_REG_ADDR(0x0690) +#define IOP3XX_PBLR1 (volatile u32 *)IOP3XX_REG_ADDR(0x0694) +#define IOP3XX_PBBAR2 (volatile u32 *)IOP3XX_REG_ADDR(0x0698) +#define IOP3XX_PBLR2 (volatile u32 *)IOP3XX_REG_ADDR(0x069c) +#define IOP3XX_PBBAR3 (volatile u32 *)IOP3XX_REG_ADDR(0x06a0) +#define IOP3XX_PBLR3 (volatile u32 *)IOP3XX_REG_ADDR(0x06a4) +#define IOP3XX_PBBAR4 (volatile u32 *)IOP3XX_REG_ADDR(0x06a8) +#define IOP3XX_PBLR4 (volatile u32 *)IOP3XX_REG_ADDR(0x06ac) +#define IOP3XX_PBBAR5 (volatile u32 *)IOP3XX_REG_ADDR(0x06b0) +#define IOP3XX_PBLR5 (volatile u32 *)IOP3XX_REG_ADDR(0x06b4) +#define IOP3XX_PMBR0 (volatile u32 *)IOP3XX_REG_ADDR(0x06c0) +#define IOP3XX_PMBR1 (volatile u32 *)IOP3XX_REG_ADDR(0x06e0) +#define IOP3XX_PMBR2 (volatile u32 *)IOP3XX_REG_ADDR(0x06e4) + +/* Peripheral performance monitoring unit */ +#define IOP3XX_GTMR (volatile u32 *)IOP3XX_REG_ADDR(0x0700) +#define IOP3XX_ESR (volatile u32 *)IOP3XX_REG_ADDR(0x0704) +#define IOP3XX_EMISR (volatile u32 *)IOP3XX_REG_ADDR(0x0708) +#define IOP3XX_GTSR (volatile u32 *)IOP3XX_REG_ADDR(0x0710) +/* PERCR0 DOESN'T EXIST - index from 1! */ +#define IOP3XX_PERCR0 (volatile u32 *)IOP3XX_REG_ADDR(0x0710) + +/* General Purpose I/O */ +#define IOP3XX_GPOE (volatile u32 *)IOP3XX_GPIO_REG(0x0000) +#define IOP3XX_GPID (volatile u32 *)IOP3XX_GPIO_REG(0x0004) +#define IOP3XX_GPOD (volatile u32 *)IOP3XX_GPIO_REG(0x0008) + +/* Timers */ +#define IOP3XX_TU_TMR0 (volatile u32 *)IOP3XX_TIMER_REG(0x0000) +#define IOP3XX_TU_TMR1 (volatile u32 *)IOP3XX_TIMER_REG(0x0004) +#define IOP3XX_TU_TCR0 (volatile u32 *)IOP3XX_TIMER_REG(0x0008) +#define IOP3XX_TU_TCR1 (volatile u32 *)IOP3XX_TIMER_REG(0x000c) +#define IOP3XX_TU_TRR0 (volatile u32 *)IOP3XX_TIMER_REG(0x0010) +#define IOP3XX_TU_TRR1 (volatile u32 *)IOP3XX_TIMER_REG(0x0014) +#define IOP3XX_TU_TISR (volatile u32 *)IOP3XX_TIMER_REG(0x0018) +#define IOP3XX_TU_WDTCR (volatile u32 *)IOP3XX_TIMER_REG(0x001c) +#define IOP_TMR_EN 0x02 +#define IOP_TMR_RELOAD 0x04 +#define IOP_TMR_PRIVILEGED 0x08 +#define IOP_TMR_RATIO_1_1 0x00 + +/* Watchdog timer definitions */ +#define IOP_WDTCR_EN_ARM 0x1e1e1e1e +#define IOP_WDTCR_EN 0xe1e1e1e1 +/* iop3xx does not support stopping the watchdog, so we just re-arm */ +#define IOP_WDTCR_DIS_ARM (IOP_WDTCR_EN_ARM) +#define IOP_WDTCR_DIS (IOP_WDTCR_EN) + +/* Application accelerator unit */ +#define IOP3XX_AAU_PHYS_BASE (IOP3XX_PERIPHERAL_PHYS_BASE + 0x800) +#define IOP3XX_AAU_UPPER_PA (IOP3XX_AAU_PHYS_BASE + 0xa7) + +/* I2C bus interface unit */ +#define IOP3XX_ICR0 (volatile u32 *)IOP3XX_REG_ADDR(0x1680) +#define IOP3XX_ISR0 (volatile u32 *)IOP3XX_REG_ADDR(0x1684) +#define IOP3XX_ISAR0 (volatile u32 *)IOP3XX_REG_ADDR(0x1688) +#define IOP3XX_IDBR0 (volatile u32 *)IOP3XX_REG_ADDR(0x168c) +#define IOP3XX_IBMR0 (volatile u32 *)IOP3XX_REG_ADDR(0x1694) +#define IOP3XX_ICR1 (volatile u32 *)IOP3XX_REG_ADDR(0x16a0) +#define IOP3XX_ISR1 (volatile u32 *)IOP3XX_REG_ADDR(0x16a4) +#define IOP3XX_ISAR1 (volatile u32 *)IOP3XX_REG_ADDR(0x16a8) +#define IOP3XX_IDBR1 (volatile u32 *)IOP3XX_REG_ADDR(0x16ac) +#define IOP3XX_IBMR1 (volatile u32 *)IOP3XX_REG_ADDR(0x16b4) + + +/* + * IOP3XX I/O and Mem space regions for PCI autoconfiguration + */ +#define IOP3XX_PCI_LOWER_MEM_PA 0x80000000 +#define IOP3XX_PCI_MEM_WINDOW_SIZE 0x08000000 + +#define IOP3XX_PCI_IO_WINDOW_SIZE 0x00010000 +#define IOP3XX_PCI_LOWER_IO_PA 0x90000000 +#define IOP3XX_PCI_LOWER_IO_VA 0xfe000000 +#define IOP3XX_PCI_LOWER_IO_BA 0x90000000 +#define IOP3XX_PCI_UPPER_IO_PA (IOP3XX_PCI_LOWER_IO_PA +\ + IOP3XX_PCI_IO_WINDOW_SIZE - 1) +#define IOP3XX_PCI_UPPER_IO_VA (IOP3XX_PCI_LOWER_IO_VA +\ + IOP3XX_PCI_IO_WINDOW_SIZE - 1) +#define IOP3XX_PCI_IO_PHYS_TO_VIRT(addr) (((u32) (addr) -\ + IOP3XX_PCI_LOWER_IO_PA) +\ + IOP3XX_PCI_LOWER_IO_VA) + + +#ifndef __ASSEMBLY__ +void iop3xx_map_io(void); +void iop_init_cp6_handler(void); +void iop_init_time(unsigned long tickrate); + +static inline u32 read_tmr0(void) +{ + u32 val; + asm volatile("mrc p6, 0, %0, c0, c1, 0" : "=r" (val)); + return val; +} + +static inline void write_tmr0(u32 val) +{ + asm volatile("mcr p6, 0, %0, c0, c1, 0" : : "r" (val)); +} + +static inline void write_tmr1(u32 val) +{ + asm volatile("mcr p6, 0, %0, c1, c1, 0" : : "r" (val)); +} + +static inline u32 read_tcr0(void) +{ + u32 val; + asm volatile("mrc p6, 0, %0, c2, c1, 0" : "=r" (val)); + return val; +} + +static inline void write_tcr0(u32 val) +{ + asm volatile("mcr p6, 0, %0, c2, c1, 0" : : "r" (val)); +} + +static inline u32 read_tcr1(void) +{ + u32 val; + asm volatile("mrc p6, 0, %0, c3, c1, 0" : "=r" (val)); + return val; +} + +static inline void write_tcr1(u32 val) +{ + asm volatile("mcr p6, 0, %0, c3, c1, 0" : : "r" (val)); +} + +static inline void write_trr0(u32 val) +{ + asm volatile("mcr p6, 0, %0, c4, c1, 0" : : "r" (val)); +} + +static inline void write_trr1(u32 val) +{ + asm volatile("mcr p6, 0, %0, c5, c1, 0" : : "r" (val)); +} + +static inline void write_tisr(u32 val) +{ + asm volatile("mcr p6, 0, %0, c6, c1, 0" : : "r" (val)); +} + +static inline u32 read_wdtcr(void) +{ + u32 val; + asm volatile("mrc p6, 0, %0, c7, c1, 0":"=r" (val)); + return val; +} +static inline void write_wdtcr(u32 val) +{ + asm volatile("mcr p6, 0, %0, c7, c1, 0"::"r" (val)); +} + +extern unsigned long get_iop_tick_rate(void); + +/* only iop13xx has these registers, we define these to present a + * common register interface for the iop_wdt driver. + */ +#define IOP_RCSR_WDT (0) +static inline u32 read_rcsr(void) +{ + return 0; +} +static inline void write_wdtsr(u32 val) +{ + do { } while (0); +} + +extern struct platform_device iop3xx_dma_0_channel; +extern struct platform_device iop3xx_dma_1_channel; +extern struct platform_device iop3xx_aau_channel; +extern struct platform_device iop3xx_i2c0_device; +extern struct platform_device iop3xx_i2c1_device; + +#endif + + +#endif diff --git a/arch/arm/include/asm/hardware/iop_adma.h b/arch/arm/include/asm/hardware/iop_adma.h new file mode 100644 index 00000000..59b8c389 --- /dev/null +++ b/arch/arm/include/asm/hardware/iop_adma.h @@ -0,0 +1,125 @@ +/* + * Copyright © 2006, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions 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., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ +#ifndef IOP_ADMA_H +#define IOP_ADMA_H +#include +#include +#include + +#define IOP_ADMA_SLOT_SIZE 32 +#define IOP_ADMA_THRESHOLD 4 +#ifdef DEBUG +#define IOP_PARANOIA 1 +#else +#define IOP_PARANOIA 0 +#endif +#define iop_paranoia(x) BUG_ON(IOP_PARANOIA && (x)) + +/** + * struct iop_adma_device - internal representation of an ADMA device + * @pdev: Platform device + * @id: HW ADMA Device selector + * @dma_desc_pool: base of DMA descriptor region (DMA address) + * @dma_desc_pool_virt: base of DMA descriptor region (CPU address) + * @common: embedded struct dma_device + */ +struct iop_adma_device { + struct platform_device *pdev; + int id; + dma_addr_t dma_desc_pool; + void *dma_desc_pool_virt; + struct dma_device common; +}; + +/** + * struct iop_adma_chan - internal representation of an ADMA device + * @pending: allows batching of hardware operations + * @completed_cookie: identifier for the most recently completed operation + * @lock: serializes enqueue/dequeue operations to the slot pool + * @mmr_base: memory mapped register base + * @chain: device chain view of the descriptors + * @device: parent device + * @common: common dmaengine channel object members + * @last_used: place holder for allocation to continue from where it left off + * @all_slots: complete domain of slots usable by the channel + * @slots_allocated: records the actual size of the descriptor slot pool + * @irq_tasklet: bottom half where iop_adma_slot_cleanup runs + */ +struct iop_adma_chan { + int pending; + dma_cookie_t completed_cookie; + spinlock_t lock; /* protects the descriptor slot pool */ + void __iomem *mmr_base; + struct list_head chain; + struct iop_adma_device *device; + struct dma_chan common; + struct iop_adma_desc_slot *last_used; + struct list_head all_slots; + int slots_allocated; + struct tasklet_struct irq_tasklet; +}; + +/** + * struct iop_adma_desc_slot - IOP-ADMA software descriptor + * @slot_node: node on the iop_adma_chan.all_slots list + * @chain_node: node on the op_adma_chan.chain list + * @hw_desc: virtual address of the hardware descriptor chain + * @phys: hardware address of the hardware descriptor chain + * @group_head: first operation in a transaction + * @slot_cnt: total slots used in an transaction (group of operations) + * @slots_per_op: number of slots per operation + * @idx: pool index + * @unmap_src_cnt: number of xor sources + * @unmap_len: transaction bytecount + * @tx_list: list of descriptors that are associated with one operation + * @async_tx: support for the async_tx api + * @group_list: list of slots that make up a multi-descriptor transaction + * for example transfer lengths larger than the supported hw max + * @xor_check_result: result of zero sum + * @crc32_result: result crc calculation + */ +struct iop_adma_desc_slot { + struct list_head slot_node; + struct list_head chain_node; + void *hw_desc; + struct iop_adma_desc_slot *group_head; + u16 slot_cnt; + u16 slots_per_op; + u16 idx; + u16 unmap_src_cnt; + size_t unmap_len; + struct list_head tx_list; + struct dma_async_tx_descriptor async_tx; + union { + u32 *xor_check_result; + u32 *crc32_result; + u32 *pq_check_result; + }; +}; + +struct iop_adma_platform_data { + int hw_id; + dma_cap_mask_t cap_mask; + size_t pool_size; +}; + +#define to_iop_sw_desc(addr_hw_desc) \ + container_of(addr_hw_desc, struct iop_adma_desc_slot, hw_desc) +#define iop_hw_desc_slot_idx(hw_desc, idx) \ + ( (void *) (((unsigned long) hw_desc) + ((idx) << 5)) ) +#endif diff --git a/arch/arm/include/asm/hardware/it8152.h b/arch/arm/include/asm/hardware/it8152.h new file mode 100644 index 00000000..b2f95c72 --- /dev/null +++ b/arch/arm/include/asm/hardware/it8152.h @@ -0,0 +1,112 @@ +/* + * linux/include/arm/hardware/it8152.h + * + * Copyright Compulab Ltd., 2006,2007 + * Mike Rapoport + * + * ITE 8152 companion chip register definitions + */ + +#ifndef __ASM_HARDWARE_IT8152_H +#define __ASM_HARDWARE_IT8152_H +extern unsigned long it8152_base_address; + +#define IT8152_IO_BASE (it8152_base_address + 0x03e00000) +#define IT8152_CFGREG_BASE (it8152_base_address + 0x03f00000) + +#define __REG_IT8152(x) (it8152_base_address + (x)) + +#define IT8152_PCI_CFG_ADDR __REG_IT8152(0x3f00800) +#define IT8152_PCI_CFG_DATA __REG_IT8152(0x3f00804) + +#define IT8152_INTC_LDCNIRR __REG_IT8152(0x3f00300) +#define IT8152_INTC_LDPNIRR __REG_IT8152(0x3f00304) +#define IT8152_INTC_LDCNIMR __REG_IT8152(0x3f00308) +#define IT8152_INTC_LDPNIMR __REG_IT8152(0x3f0030C) +#define IT8152_INTC_LDNITR __REG_IT8152(0x3f00310) +#define IT8152_INTC_LDNIAR __REG_IT8152(0x3f00314) +#define IT8152_INTC_LPCNIRR __REG_IT8152(0x3f00320) +#define IT8152_INTC_LPPNIRR __REG_IT8152(0x3f00324) +#define IT8152_INTC_LPCNIMR __REG_IT8152(0x3f00328) +#define IT8152_INTC_LPPNIMR __REG_IT8152(0x3f0032C) +#define IT8152_INTC_LPNITR __REG_IT8152(0x3f00330) +#define IT8152_INTC_LPNIAR __REG_IT8152(0x3f00334) +#define IT8152_INTC_PDCNIRR __REG_IT8152(0x3f00340) +#define IT8152_INTC_PDPNIRR __REG_IT8152(0x3f00344) +#define IT8152_INTC_PDCNIMR __REG_IT8152(0x3f00348) +#define IT8152_INTC_PDPNIMR __REG_IT8152(0x3f0034C) +#define IT8152_INTC_PDNITR __REG_IT8152(0x3f00350) +#define IT8152_INTC_PDNIAR __REG_IT8152(0x3f00354) +#define IT8152_INTC_INTC_TYPER __REG_IT8152(0x3f003FC) + +#define IT8152_GPIO_GPDR __REG_IT8152(0x3f00500) + +/* + Interrupt controller per register summary: + --------------------------------------- + LCDNIRR: + IT8152_LD_IRQ(8) PCICLK stop + IT8152_LD_IRQ(7) MCLK ready + IT8152_LD_IRQ(6) s/w + IT8152_LD_IRQ(5) UART + IT8152_LD_IRQ(4) GPIO + IT8152_LD_IRQ(3) TIMER 4 + IT8152_LD_IRQ(2) TIMER 3 + IT8152_LD_IRQ(1) TIMER 2 + IT8152_LD_IRQ(0) TIMER 1 + + LPCNIRR: + IT8152_LP_IRQ(x) serial IRQ x + + PCIDNIRR: + IT8152_PD_IRQ(14) PCISERR + IT8152_PD_IRQ(13) CPU/PCI bridge target abort (h2pTADR) + IT8152_PD_IRQ(12) CPU/PCI bridge master abort (h2pMADR) + IT8152_PD_IRQ(11) PCI INTD + IT8152_PD_IRQ(10) PCI INTC + IT8152_PD_IRQ(9) PCI INTB + IT8152_PD_IRQ(8) PCI INTA + IT8152_PD_IRQ(7) serial INTD + IT8152_PD_IRQ(6) serial INTC + IT8152_PD_IRQ(5) serial INTB + IT8152_PD_IRQ(4) serial INTA + IT8152_PD_IRQ(3) serial IRQ IOCHK (IOCHKR) + IT8152_PD_IRQ(2) chaining DMA (CDMAR) + IT8152_PD_IRQ(1) USB (USBR) + IT8152_PD_IRQ(0) Audio controller (ACR) + */ +#define IT8152_IRQ(x) (IRQ_BOARD_START + (x)) +#define IT8152_LAST_IRQ (IRQ_BOARD_START + 40) + +/* IRQ-sources in 3 groups - local devices, LPC (serial), and external PCI */ +#define IT8152_LD_IRQ_COUNT 9 +#define IT8152_LP_IRQ_COUNT 16 +#define IT8152_PD_IRQ_COUNT 15 + +/* Priorities: */ +#define IT8152_PD_IRQ(i) IT8152_IRQ(i) +#define IT8152_LP_IRQ(i) (IT8152_IRQ(i) + IT8152_PD_IRQ_COUNT) +#define IT8152_LD_IRQ(i) (IT8152_IRQ(i) + IT8152_PD_IRQ_COUNT + IT8152_LP_IRQ_COUNT) + +/* frequently used interrupts */ +#define IT8152_PCISERR IT8152_PD_IRQ(14) +#define IT8152_H2PTADR IT8152_PD_IRQ(13) +#define IT8152_H2PMAR IT8152_PD_IRQ(12) +#define IT8152_PCI_INTD IT8152_PD_IRQ(11) +#define IT8152_PCI_INTC IT8152_PD_IRQ(10) +#define IT8152_PCI_INTB IT8152_PD_IRQ(9) +#define IT8152_PCI_INTA IT8152_PD_IRQ(8) +#define IT8152_CDMA_INT IT8152_PD_IRQ(2) +#define IT8152_USB_INT IT8152_PD_IRQ(1) +#define IT8152_AUDIO_INT IT8152_PD_IRQ(0) + +struct pci_dev; +struct pci_sys_data; + +extern void it8152_irq_demux(unsigned int irq, struct irq_desc *desc); +extern void it8152_init_irq(void); +extern int it8152_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin); +extern int it8152_pci_setup(int nr, struct pci_sys_data *sys); +extern struct pci_bus *it8152_pci_scan_bus(int nr, struct pci_sys_data *sys); + +#endif /* __ASM_HARDWARE_IT8152_H */ diff --git a/arch/arm/include/asm/hardware/linkup-l1110.h b/arch/arm/include/asm/hardware/linkup-l1110.h new file mode 100644 index 00000000..7ec91168 --- /dev/null +++ b/arch/arm/include/asm/hardware/linkup-l1110.h @@ -0,0 +1,48 @@ +/* +* +* Definitions for H3600 Handheld Computer +* +* Copyright 2001 Compaq Computer Corporation. +* +* Use consistent with the GNU GPL is permitted, +* provided that this copyright notice is +* preserved in its entirety in all copies and derived works. +* +* COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED, +* AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS +* FITNESS FOR ANY PARTICULAR PURPOSE. +* +* Author: Jamey Hicks. +* +*/ + +/* LinkUp Systems PCCard/CompactFlash Interface for SA-1100 */ + +/* PC Card Status Register */ +#define LINKUP_PRS_S1 (1 << 0) /* voltage control bits S1-S4 */ +#define LINKUP_PRS_S2 (1 << 1) +#define LINKUP_PRS_S3 (1 << 2) +#define LINKUP_PRS_S4 (1 << 3) +#define LINKUP_PRS_BVD1 (1 << 4) +#define LINKUP_PRS_BVD2 (1 << 5) +#define LINKUP_PRS_VS1 (1 << 6) +#define LINKUP_PRS_VS2 (1 << 7) +#define LINKUP_PRS_RDY (1 << 8) +#define LINKUP_PRS_CD1 (1 << 9) +#define LINKUP_PRS_CD2 (1 << 10) + +/* PC Card Command Register */ +#define LINKUP_PRC_S1 (1 << 0) +#define LINKUP_PRC_S2 (1 << 1) +#define LINKUP_PRC_S3 (1 << 2) +#define LINKUP_PRC_S4 (1 << 3) +#define LINKUP_PRC_RESET (1 << 4) +#define LINKUP_PRC_APOE (1 << 5) /* Auto Power Off Enable: clears S1-S4 when either nCD goes high */ +#define LINKUP_PRC_CFE (1 << 6) /* CompactFlash mode Enable: addresses A[10:0] only, A[25:11] high */ +#define LINKUP_PRC_SOE (1 << 7) /* signal output driver enable */ +#define LINKUP_PRC_SSP (1 << 8) /* sock select polarity: 0 for socket 0, 1 for socket 1 */ +#define LINKUP_PRC_MBZ (1 << 15) /* must be zero */ + +struct linkup_l1110 { + volatile short prc; +}; diff --git a/arch/arm/include/asm/hardware/locomo.h b/arch/arm/include/asm/hardware/locomo.h new file mode 100644 index 00000000..74e51d6b --- /dev/null +++ b/arch/arm/include/asm/hardware/locomo.h @@ -0,0 +1,221 @@ +/* + * arch/arm/include/asm/hardware/locomo.h + * + * This file contains the definitions for the LoCoMo G/A Chip + * + * (C) Copyright 2004 John Lenz + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * Based on sa1111.h + */ +#ifndef _ASM_ARCH_LOCOMO +#define _ASM_ARCH_LOCOMO + +#define locomo_writel(val,addr) ({ *(volatile u16 *)(addr) = (val); }) +#define locomo_readl(addr) (*(volatile u16 *)(addr)) + +/* LOCOMO version */ +#define LOCOMO_VER 0x00 + +/* Pin status */ +#define LOCOMO_ST 0x04 + +/* Pin status */ +#define LOCOMO_C32K 0x08 + +/* Interrupt controller */ +#define LOCOMO_ICR 0x0C + +/* MCS decoder for boot selecting */ +#define LOCOMO_MCSX0 0x10 +#define LOCOMO_MCSX1 0x14 +#define LOCOMO_MCSX2 0x18 +#define LOCOMO_MCSX3 0x1c + +/* Touch panel controller */ +#define LOCOMO_ASD 0x20 /* AD start delay */ +#define LOCOMO_HSD 0x28 /* HSYS delay */ +#define LOCOMO_HSC 0x2c /* HSYS period */ +#define LOCOMO_TADC 0x30 /* tablet ADC clock */ + + +/* Long time timer */ +#define LOCOMO_LTC 0xd8 /* LTC interrupt setting */ +#define LOCOMO_LTINT 0xdc /* LTC interrupt */ + +/* DAC control signal for LCD (COMADJ ) */ +#define LOCOMO_DAC 0xe0 +/* DAC control */ +#define LOCOMO_DAC_SCLOEB 0x08 /* SCL pin output data */ +#define LOCOMO_DAC_TEST 0x04 /* Test bit */ +#define LOCOMO_DAC_SDA 0x02 /* SDA pin level (read-only) */ +#define LOCOMO_DAC_SDAOEB 0x01 /* SDA pin output data */ + +/* SPI interface */ +#define LOCOMO_SPI 0x60 +#define LOCOMO_SPIMD 0x00 /* SPI mode setting */ +#define LOCOMO_SPICT 0x04 /* SPI mode control */ +#define LOCOMO_SPIST 0x08 /* SPI status */ +#define LOCOMO_SPI_TEND (1 << 3) /* Transfer end bit */ +#define LOCOMO_SPI_REND (1 << 2) /* Receive end bit */ +#define LOCOMO_SPI_RFW (1 << 1) /* write buffer bit */ +#define LOCOMO_SPI_RFR (1) /* read buffer bit */ + +#define LOCOMO_SPIIS 0x10 /* SPI interrupt status */ +#define LOCOMO_SPIWE 0x14 /* SPI interrupt status write enable */ +#define LOCOMO_SPIIE 0x18 /* SPI interrupt enable */ +#define LOCOMO_SPIIR 0x1c /* SPI interrupt request */ +#define LOCOMO_SPITD 0x20 /* SPI transfer data write */ +#define LOCOMO_SPIRD 0x24 /* SPI receive data read */ +#define LOCOMO_SPITS 0x28 /* SPI transfer data shift */ +#define LOCOMO_SPIRS 0x2C /* SPI receive data shift */ + +/* GPIO */ +#define LOCOMO_GPD 0x90 /* GPIO direction */ +#define LOCOMO_GPE 0x94 /* GPIO input enable */ +#define LOCOMO_GPL 0x98 /* GPIO level */ +#define LOCOMO_GPO 0x9c /* GPIO out data setting */ +#define LOCOMO_GRIE 0xa0 /* GPIO rise detection */ +#define LOCOMO_GFIE 0xa4 /* GPIO fall detection */ +#define LOCOMO_GIS 0xa8 /* GPIO edge detection status */ +#define LOCOMO_GWE 0xac /* GPIO status write enable */ +#define LOCOMO_GIE 0xb0 /* GPIO interrupt enable */ +#define LOCOMO_GIR 0xb4 /* GPIO interrupt request */ +#define LOCOMO_GPIO(Nb) (0x01 << (Nb)) +#define LOCOMO_GPIO_RTS LOCOMO_GPIO(0) +#define LOCOMO_GPIO_CTS LOCOMO_GPIO(1) +#define LOCOMO_GPIO_DSR LOCOMO_GPIO(2) +#define LOCOMO_GPIO_DTR LOCOMO_GPIO(3) +#define LOCOMO_GPIO_LCD_VSHA_ON LOCOMO_GPIO(4) +#define LOCOMO_GPIO_LCD_VSHD_ON LOCOMO_GPIO(5) +#define LOCOMO_GPIO_LCD_VEE_ON LOCOMO_GPIO(6) +#define LOCOMO_GPIO_LCD_MOD LOCOMO_GPIO(7) +#define LOCOMO_GPIO_DAC_ON LOCOMO_GPIO(8) +#define LOCOMO_GPIO_FL_VR LOCOMO_GPIO(9) +#define LOCOMO_GPIO_DAC_SDATA LOCOMO_GPIO(10) +#define LOCOMO_GPIO_DAC_SCK LOCOMO_GPIO(11) +#define LOCOMO_GPIO_DAC_SLOAD LOCOMO_GPIO(12) +#define LOCOMO_GPIO_CARD_DETECT LOCOMO_GPIO(13) +#define LOCOMO_GPIO_WRITE_PROT LOCOMO_GPIO(14) +#define LOCOMO_GPIO_CARD_POWER LOCOMO_GPIO(15) + +/* Start the definitions of the devices. Each device has an initial + * base address and a series of offsets from that base address. */ + +/* Keyboard controller */ +#define LOCOMO_KEYBOARD 0x40 +#define LOCOMO_KIB 0x00 /* KIB level */ +#define LOCOMO_KSC 0x04 /* KSTRB control */ +#define LOCOMO_KCMD 0x08 /* KSTRB command */ +#define LOCOMO_KIC 0x0c /* Key interrupt */ + +/* Front light adjustment controller */ +#define LOCOMO_FRONTLIGHT 0xc8 +#define LOCOMO_ALS 0x00 /* Adjust light cycle */ +#define LOCOMO_ALD 0x04 /* Adjust light duty */ + +#define LOCOMO_ALC_EN 0x8000 + +/* Backlight controller: TFT signal */ +#define LOCOMO_BACKLIGHT 0x38 +#define LOCOMO_TC 0x00 /* TFT control signal */ +#define LOCOMO_CPSD 0x04 /* CPS delay */ + +/* Audio controller */ +#define LOCOMO_AUDIO 0x54 +#define LOCOMO_ACC 0x00 /* Audio clock */ +#define LOCOMO_PAIF 0xD0 /* PCM audio interface */ +/* Audio clock */ +#define LOCOMO_ACC_XON 0x80 +#define LOCOMO_ACC_XEN 0x40 +#define LOCOMO_ACC_XSEL0 0x00 +#define LOCOMO_ACC_XSEL1 0x20 +#define LOCOMO_ACC_MCLKEN 0x10 +#define LOCOMO_ACC_64FSEN 0x08 +#define LOCOMO_ACC_CLKSEL000 0x00 /* mclk 2 */ +#define LOCOMO_ACC_CLKSEL001 0x01 /* mclk 3 */ +#define LOCOMO_ACC_CLKSEL010 0x02 /* mclk 4 */ +#define LOCOMO_ACC_CLKSEL011 0x03 /* mclk 6 */ +#define LOCOMO_ACC_CLKSEL100 0x04 /* mclk 8 */ +#define LOCOMO_ACC_CLKSEL101 0x05 /* mclk 12 */ +/* PCM audio interface */ +#define LOCOMO_PAIF_SCINV 0x20 +#define LOCOMO_PAIF_SCEN 0x10 +#define LOCOMO_PAIF_LRCRST 0x08 +#define LOCOMO_PAIF_LRCEVE 0x04 +#define LOCOMO_PAIF_LRCINV 0x02 +#define LOCOMO_PAIF_LRCEN 0x01 + +/* LED controller */ +#define LOCOMO_LED 0xe8 +#define LOCOMO_LPT0 0x00 +#define LOCOMO_LPT1 0x04 +/* LED control */ +#define LOCOMO_LPT_TOFH 0x80 +#define LOCOMO_LPT_TOFL 0x08 +#define LOCOMO_LPT_TOH(TOH) ((TOH & 0x7) << 4) +#define LOCOMO_LPT_TOL(TOL) ((TOL & 0x7)) + +extern struct bus_type locomo_bus_type; + +#define LOCOMO_DEVID_KEYBOARD 0 +#define LOCOMO_DEVID_FRONTLIGHT 1 +#define LOCOMO_DEVID_BACKLIGHT 2 +#define LOCOMO_DEVID_AUDIO 3 +#define LOCOMO_DEVID_LED 4 +#define LOCOMO_DEVID_UART 5 +#define LOCOMO_DEVID_SPI 6 + +struct locomo_dev { + struct device dev; + unsigned int devid; + unsigned int irq[1]; + + void *mapbase; + unsigned long length; + + u64 dma_mask; +}; + +#define LOCOMO_DEV(_d) container_of((_d), struct locomo_dev, dev) + +#define locomo_get_drvdata(d) dev_get_drvdata(&(d)->dev) +#define locomo_set_drvdata(d,p) dev_set_drvdata(&(d)->dev, p) + +struct locomo_driver { + struct device_driver drv; + unsigned int devid; + int (*probe)(struct locomo_dev *); + int (*remove)(struct locomo_dev *); + int (*suspend)(struct locomo_dev *, pm_message_t); + int (*resume)(struct locomo_dev *); +}; + +#define LOCOMO_DRV(_d) container_of((_d), struct locomo_driver, drv) + +#define LOCOMO_DRIVER_NAME(_ldev) ((_ldev)->dev.driver->name) + +void locomo_lcd_power(struct locomo_dev *, int, unsigned int); + +int locomo_driver_register(struct locomo_driver *); +void locomo_driver_unregister(struct locomo_driver *); + +/* GPIO control functions */ +void locomo_gpio_set_dir(struct device *dev, unsigned int bits, unsigned int dir); +int locomo_gpio_read_level(struct device *dev, unsigned int bits); +int locomo_gpio_read_output(struct device *dev, unsigned int bits); +void locomo_gpio_write(struct device *dev, unsigned int bits, unsigned int set); + +/* M62332 control function */ +void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int channel); + +/* Frontlight control */ +void locomo_frontlight_set(struct locomo_dev *dev, int duty, int vr, int bpwf); + +struct locomo_platform_data { + int irq_base; /* IRQ base for cascaded on-chip IRQs */ +}; + +#endif diff --git a/arch/arm/include/asm/hardware/memc.h b/arch/arm/include/asm/hardware/memc.h new file mode 100644 index 00000000..42ba7c16 --- /dev/null +++ b/arch/arm/include/asm/hardware/memc.h @@ -0,0 +1,26 @@ +/* + * arch/arm/include/asm/hardware/memc.h + * + * Copyright (C) Russell King. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#define VDMA_ALIGNMENT PAGE_SIZE +#define VDMA_XFERSIZE 16 +#define VDMA_INIT 0 +#define VDMA_START 1 +#define VDMA_END 2 + +#ifndef __ASSEMBLY__ +extern void memc_write(unsigned int reg, unsigned long val); + +#define video_set_dma(start,end,offset) \ +do { \ + memc_write (VDMA_START, (start >> 2)); \ + memc_write (VDMA_END, (end - VDMA_XFERSIZE) >> 2); \ + memc_write (VDMA_INIT, (offset >> 2)); \ +} while (0) + +#endif diff --git a/arch/arm/include/asm/hardware/pci_v3.h b/arch/arm/include/asm/hardware/pci_v3.h new file mode 100644 index 00000000..2811c7e2 --- /dev/null +++ b/arch/arm/include/asm/hardware/pci_v3.h @@ -0,0 +1,186 @@ +/* + * arch/arm/include/asm/hardware/pci_v3.h + * + * Internal header file PCI V3 chip + * + * Copyright (C) ARM Limited + * Copyright (C) 2000-2001 Deep Blue Solutions Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef ASM_ARM_HARDWARE_PCI_V3_H +#define ASM_ARM_HARDWARE_PCI_V3_H + +/* ------------------------------------------------------------------------------- + * V3 Local Bus to PCI Bridge definitions + * ------------------------------------------------------------------------------- + * Registers (these are taken from page 129 of the EPC User's Manual Rev 1.04 + * All V3 register names are prefaced by V3_ to avoid clashing with any other + * PCI definitions. Their names match the user's manual. + * + * I'm assuming that I20 is disabled. + * + */ +#define V3_PCI_VENDOR 0x00000000 +#define V3_PCI_DEVICE 0x00000002 +#define V3_PCI_CMD 0x00000004 +#define V3_PCI_STAT 0x00000006 +#define V3_PCI_CC_REV 0x00000008 +#define V3_PCI_HDR_CFG 0x0000000C +#define V3_PCI_IO_BASE 0x00000010 +#define V3_PCI_BASE0 0x00000014 +#define V3_PCI_BASE1 0x00000018 +#define V3_PCI_SUB_VENDOR 0x0000002C +#define V3_PCI_SUB_ID 0x0000002E +#define V3_PCI_ROM 0x00000030 +#define V3_PCI_BPARAM 0x0000003C +#define V3_PCI_MAP0 0x00000040 +#define V3_PCI_MAP1 0x00000044 +#define V3_PCI_INT_STAT 0x00000048 +#define V3_PCI_INT_CFG 0x0000004C +#define V3_LB_BASE0 0x00000054 +#define V3_LB_BASE1 0x00000058 +#define V3_LB_MAP0 0x0000005E +#define V3_LB_MAP1 0x00000062 +#define V3_LB_BASE2 0x00000064 +#define V3_LB_MAP2 0x00000066 +#define V3_LB_SIZE 0x00000068 +#define V3_LB_IO_BASE 0x0000006E +#define V3_FIFO_CFG 0x00000070 +#define V3_FIFO_PRIORITY 0x00000072 +#define V3_FIFO_STAT 0x00000074 +#define V3_LB_ISTAT 0x00000076 +#define V3_LB_IMASK 0x00000077 +#define V3_SYSTEM 0x00000078 +#define V3_LB_CFG 0x0000007A +#define V3_PCI_CFG 0x0000007C +#define V3_DMA_PCI_ADR0 0x00000080 +#define V3_DMA_PCI_ADR1 0x00000090 +#define V3_DMA_LOCAL_ADR0 0x00000084 +#define V3_DMA_LOCAL_ADR1 0x00000094 +#define V3_DMA_LENGTH0 0x00000088 +#define V3_DMA_LENGTH1 0x00000098 +#define V3_DMA_CSR0 0x0000008B +#define V3_DMA_CSR1 0x0000009B +#define V3_DMA_CTLB_ADR0 0x0000008C +#define V3_DMA_CTLB_ADR1 0x0000009C +#define V3_DMA_DELAY 0x000000E0 +#define V3_MAIL_DATA 0x000000C0 +#define V3_PCI_MAIL_IEWR 0x000000D0 +#define V3_PCI_MAIL_IERD 0x000000D2 +#define V3_LB_MAIL_IEWR 0x000000D4 +#define V3_LB_MAIL_IERD 0x000000D6 +#define V3_MAIL_WR_STAT 0x000000D8 +#define V3_MAIL_RD_STAT 0x000000DA +#define V3_QBA_MAP 0x000000DC + +/* PCI COMMAND REGISTER bits + */ +#define V3_COMMAND_M_FBB_EN (1 << 9) +#define V3_COMMAND_M_SERR_EN (1 << 8) +#define V3_COMMAND_M_PAR_EN (1 << 6) +#define V3_COMMAND_M_MASTER_EN (1 << 2) +#define V3_COMMAND_M_MEM_EN (1 << 1) +#define V3_COMMAND_M_IO_EN (1 << 0) + +/* SYSTEM REGISTER bits + */ +#define V3_SYSTEM_M_RST_OUT (1 << 15) +#define V3_SYSTEM_M_LOCK (1 << 14) + +/* PCI_CFG bits + */ +#define V3_PCI_CFG_M_I2O_EN (1 << 15) +#define V3_PCI_CFG_M_IO_REG_DIS (1 << 14) +#define V3_PCI_CFG_M_IO_DIS (1 << 13) +#define V3_PCI_CFG_M_EN3V (1 << 12) +#define V3_PCI_CFG_M_RETRY_EN (1 << 10) +#define V3_PCI_CFG_M_AD_LOW1 (1 << 9) +#define V3_PCI_CFG_M_AD_LOW0 (1 << 8) + +/* PCI_BASE register bits (PCI -> Local Bus) + */ +#define V3_PCI_BASE_M_ADR_BASE 0xFFF00000 +#define V3_PCI_BASE_M_ADR_BASEL 0x000FFF00 +#define V3_PCI_BASE_M_PREFETCH (1 << 3) +#define V3_PCI_BASE_M_TYPE (3 << 1) +#define V3_PCI_BASE_M_IO (1 << 0) + +/* PCI MAP register bits (PCI -> Local bus) + */ +#define V3_PCI_MAP_M_MAP_ADR 0xFFF00000 +#define V3_PCI_MAP_M_RD_POST_INH (1 << 15) +#define V3_PCI_MAP_M_ROM_SIZE (3 << 10) +#define V3_PCI_MAP_M_SWAP (3 << 8) +#define V3_PCI_MAP_M_ADR_SIZE 0x000000F0 +#define V3_PCI_MAP_M_REG_EN (1 << 1) +#define V3_PCI_MAP_M_ENABLE (1 << 0) + +/* + * LB_BASE0,1 register bits (Local bus -> PCI) + */ +#define V3_LB_BASE_ADR_BASE 0xfff00000 +#define V3_LB_BASE_SWAP (3 << 8) +#define V3_LB_BASE_ADR_SIZE (15 << 4) +#define V3_LB_BASE_PREFETCH (1 << 3) +#define V3_LB_BASE_ENABLE (1 << 0) + +#define V3_LB_BASE_ADR_SIZE_1MB (0 << 4) +#define V3_LB_BASE_ADR_SIZE_2MB (1 << 4) +#define V3_LB_BASE_ADR_SIZE_4MB (2 << 4) +#define V3_LB_BASE_ADR_SIZE_8MB (3 << 4) +#define V3_LB_BASE_ADR_SIZE_16MB (4 << 4) +#define V3_LB_BASE_ADR_SIZE_32MB (5 << 4) +#define V3_LB_BASE_ADR_SIZE_64MB (6 << 4) +#define V3_LB_BASE_ADR_SIZE_128MB (7 << 4) +#define V3_LB_BASE_ADR_SIZE_256MB (8 << 4) +#define V3_LB_BASE_ADR_SIZE_512MB (9 << 4) +#define V3_LB_BASE_ADR_SIZE_1GB (10 << 4) +#define V3_LB_BASE_ADR_SIZE_2GB (11 << 4) + +#define v3_addr_to_lb_base(a) ((a) & V3_LB_BASE_ADR_BASE) + +/* + * LB_MAP0,1 register bits (Local bus -> PCI) + */ +#define V3_LB_MAP_MAP_ADR 0xfff0 +#define V3_LB_MAP_TYPE (7 << 1) +#define V3_LB_MAP_AD_LOW_EN (1 << 0) + +#define V3_LB_MAP_TYPE_IACK (0 << 1) +#define V3_LB_MAP_TYPE_IO (1 << 1) +#define V3_LB_MAP_TYPE_MEM (3 << 1) +#define V3_LB_MAP_TYPE_CONFIG (5 << 1) +#define V3_LB_MAP_TYPE_MEM_MULTIPLE (6 << 1) + +#define v3_addr_to_lb_map(a) (((a) >> 16) & V3_LB_MAP_MAP_ADR) + +/* + * LB_BASE2 register bits (Local bus -> PCI IO) + */ +#define V3_LB_BASE2_ADR_BASE 0xff00 +#define V3_LB_BASE2_SWAP (3 << 6) +#define V3_LB_BASE2_ENABLE (1 << 0) + +#define v3_addr_to_lb_base2(a) (((a) >> 16) & V3_LB_BASE2_ADR_BASE) + +/* + * LB_MAP2 register bits (Local bus -> PCI IO) + */ +#define V3_LB_MAP2_MAP_ADR 0xff00 + +#define v3_addr_to_lb_map2(a) (((a) >> 16) & V3_LB_MAP2_MAP_ADR) + +#endif diff --git a/arch/arm/include/asm/hardware/pl080.h b/arch/arm/include/asm/hardware/pl080.h new file mode 100644 index 00000000..e4a04e4e --- /dev/null +++ b/arch/arm/include/asm/hardware/pl080.h @@ -0,0 +1,140 @@ +/* arch/arm/include/asm/hardware/pl080.h + * + * Copyright 2008 Openmoko, Inc. + * Copyright 2008 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * + * ARM PrimeCell PL080 DMA controller + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +/* Note, there are some Samsung updates to this controller block which + * make it not entierly compatible with the PL080 specification from + * ARM. When in doubt, check the Samsung documentation first. + * + * The Samsung defines are PL080S, and add an extra control register, + * the ability to move more than 2^11 counts of data and some extra + * OneNAND features. +*/ + +#define PL080_INT_STATUS (0x00) +#define PL080_TC_STATUS (0x04) +#define PL080_TC_CLEAR (0x08) +#define PL080_ERR_STATUS (0x0C) +#define PL080_ERR_CLEAR (0x10) +#define PL080_RAW_TC_STATUS (0x14) +#define PL080_RAW_ERR_STATUS (0x18) +#define PL080_EN_CHAN (0x1c) +#define PL080_SOFT_BREQ (0x20) +#define PL080_SOFT_SREQ (0x24) +#define PL080_SOFT_LBREQ (0x28) +#define PL080_SOFT_LSREQ (0x2C) + +#define PL080_CONFIG (0x30) +#define PL080_CONFIG_M2_BE (1 << 2) +#define PL080_CONFIG_M1_BE (1 << 1) +#define PL080_CONFIG_ENABLE (1 << 0) + +#define PL080_SYNC (0x34) + +/* Per channel configuration registers */ + +#define PL080_Cx_STRIDE (0x20) +#define PL080_Cx_BASE(x) ((0x100 + (x * 0x20))) +#define PL080_Cx_SRC_ADDR(x) ((0x100 + (x * 0x20))) +#define PL080_Cx_DST_ADDR(x) ((0x104 + (x * 0x20))) +#define PL080_Cx_LLI(x) ((0x108 + (x * 0x20))) +#define PL080_Cx_CONTROL(x) ((0x10C + (x * 0x20))) +#define PL080_Cx_CONFIG(x) ((0x110 + (x * 0x20))) +#define PL080S_Cx_CONTROL2(x) ((0x110 + (x * 0x20))) +#define PL080S_Cx_CONFIG(x) ((0x114 + (x * 0x20))) + +#define PL080_CH_SRC_ADDR (0x00) +#define PL080_CH_DST_ADDR (0x04) +#define PL080_CH_LLI (0x08) +#define PL080_CH_CONTROL (0x0C) +#define PL080_CH_CONFIG (0x10) +#define PL080S_CH_CONTROL2 (0x10) +#define PL080S_CH_CONFIG (0x14) + +#define PL080_LLI_ADDR_MASK (0x3fffffff << 2) +#define PL080_LLI_ADDR_SHIFT (2) +#define PL080_LLI_LM_AHB2 (1 << 0) + +#define PL080_CONTROL_TC_IRQ_EN (1 << 31) +#define PL080_CONTROL_PROT_MASK (0x7 << 28) +#define PL080_CONTROL_PROT_SHIFT (28) +#define PL080_CONTROL_PROT_CACHE (1 << 30) +#define PL080_CONTROL_PROT_BUFF (1 << 29) +#define PL080_CONTROL_PROT_SYS (1 << 28) +#define PL080_CONTROL_DST_INCR (1 << 27) +#define PL080_CONTROL_SRC_INCR (1 << 26) +#define PL080_CONTROL_DST_AHB2 (1 << 25) +#define PL080_CONTROL_SRC_AHB2 (1 << 24) +#define PL080_CONTROL_DWIDTH_MASK (0x7 << 21) +#define PL080_CONTROL_DWIDTH_SHIFT (21) +#define PL080_CONTROL_SWIDTH_MASK (0x7 << 18) +#define PL080_CONTROL_SWIDTH_SHIFT (18) +#define PL080_CONTROL_DB_SIZE_MASK (0x7 << 15) +#define PL080_CONTROL_DB_SIZE_SHIFT (15) +#define PL080_CONTROL_SB_SIZE_MASK (0x7 << 12) +#define PL080_CONTROL_SB_SIZE_SHIFT (12) +#define PL080_CONTROL_TRANSFER_SIZE_MASK (0xfff << 0) +#define PL080_CONTROL_TRANSFER_SIZE_SHIFT (0) + +#define PL080_BSIZE_1 (0x0) +#define PL080_BSIZE_4 (0x1) +#define PL080_BSIZE_8 (0x2) +#define PL080_BSIZE_16 (0x3) +#define PL080_BSIZE_32 (0x4) +#define PL080_BSIZE_64 (0x5) +#define PL080_BSIZE_128 (0x6) +#define PL080_BSIZE_256 (0x7) + +#define PL080_WIDTH_8BIT (0x0) +#define PL080_WIDTH_16BIT (0x1) +#define PL080_WIDTH_32BIT (0x2) + +#define PL080_CONFIG_HALT (1 << 18) +#define PL080_CONFIG_ACTIVE (1 << 17) /* RO */ +#define PL080_CONFIG_LOCK (1 << 16) +#define PL080_CONFIG_TC_IRQ_MASK (1 << 15) +#define PL080_CONFIG_ERR_IRQ_MASK (1 << 14) +#define PL080_CONFIG_FLOW_CONTROL_MASK (0x7 << 11) +#define PL080_CONFIG_FLOW_CONTROL_SHIFT (11) +#define PL080_CONFIG_DST_SEL_MASK (0xf << 6) +#define PL080_CONFIG_DST_SEL_SHIFT (6) +#define PL080_CONFIG_SRC_SEL_MASK (0xf << 1) +#define PL080_CONFIG_SRC_SEL_SHIFT (1) +#define PL080_CONFIG_ENABLE (1 << 0) + +#define PL080_FLOW_MEM2MEM (0x0) +#define PL080_FLOW_MEM2PER (0x1) +#define PL080_FLOW_PER2MEM (0x2) +#define PL080_FLOW_SRC2DST (0x3) +#define PL080_FLOW_SRC2DST_DST (0x4) +#define PL080_FLOW_MEM2PER_PER (0x5) +#define PL080_FLOW_PER2MEM_PER (0x6) +#define PL080_FLOW_SRC2DST_SRC (0x7) + +/* DMA linked list chain structure */ + +struct pl080_lli { + u32 src_addr; + u32 dst_addr; + u32 next_lli; + u32 control0; +}; + +struct pl080s_lli { + u32 src_addr; + u32 dst_addr; + u32 next_lli; + u32 control0; + u32 control1; +}; + diff --git a/arch/arm/include/asm/hardware/pl330.h b/arch/arm/include/asm/hardware/pl330.h new file mode 100644 index 00000000..575fa818 --- /dev/null +++ b/arch/arm/include/asm/hardware/pl330.h @@ -0,0 +1,217 @@ +/* linux/include/asm/hardware/pl330.h + * + * Copyright (C) 2010 Samsung Electronics Co. Ltd. + * Jaswinder Singh + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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. + */ + +#ifndef __PL330_CORE_H +#define __PL330_CORE_H + +#define PL330_MAX_CHAN 8 +#define PL330_MAX_IRQS 32 +#define PL330_MAX_PERI 32 + +enum pl330_srccachectrl { + SCCTRL0 = 0, /* Noncacheable and nonbufferable */ + SCCTRL1, /* Bufferable only */ + SCCTRL2, /* Cacheable, but do not allocate */ + SCCTRL3, /* Cacheable and bufferable, but do not allocate */ + SINVALID1, + SINVALID2, + SCCTRL6, /* Cacheable write-through, allocate on reads only */ + SCCTRL7, /* Cacheable write-back, allocate on reads only */ +}; + +enum pl330_dstcachectrl { + DCCTRL0 = 0, /* Noncacheable and nonbufferable */ + DCCTRL1, /* Bufferable only */ + DCCTRL2, /* Cacheable, but do not allocate */ + DCCTRL3, /* Cacheable and bufferable, but do not allocate */ + DINVALID1 = 8, + DINVALID2, + DCCTRL6, /* Cacheable write-through, allocate on writes only */ + DCCTRL7, /* Cacheable write-back, allocate on writes only */ +}; + +/* Populated by the PL330 core driver for DMA API driver's info */ +struct pl330_config { + u32 periph_id; + u32 pcell_id; +#define DMAC_MODE_NS (1 << 0) + unsigned int mode; + unsigned int data_bus_width:10; /* In number of bits */ + unsigned int data_buf_dep:10; + unsigned int num_chan:4; + unsigned int num_peri:6; + u32 peri_ns; + unsigned int num_events:6; + u32 irq_ns; +}; + +/* Handle to the DMAC provided to the PL330 core */ +struct pl330_info { + /* Owning device */ + struct device *dev; + /* Size of MicroCode buffers for each channel. */ + unsigned mcbufsz; + /* ioremap'ed address of PL330 registers. */ + void __iomem *base; + /* Client can freely use it. */ + void *client_data; + /* PL330 core data, Client must not touch it. */ + void *pl330_data; + /* Populated by the PL330 core driver during pl330_add */ + struct pl330_config pcfg; + /* + * If the DMAC has some reset mechanism, then the + * client may want to provide pointer to the method. + */ + void (*dmac_reset)(struct pl330_info *pi); +}; + +enum pl330_byteswap { + SWAP_NO = 0, + SWAP_2, + SWAP_4, + SWAP_8, + SWAP_16, +}; + +/** + * Request Configuration. + * The PL330 core does not modify this and uses the last + * working configuration if the request doesn't provide any. + * + * The Client may want to provide this info only for the + * first request and a request with new settings. + */ +struct pl330_reqcfg { + /* Address Incrementing */ + unsigned dst_inc:1; + unsigned src_inc:1; + + /* + * For now, the SRC & DST protection levels + * and burst size/length are assumed same. + */ + bool nonsecure; + bool privileged; + bool insnaccess; + unsigned brst_len:5; + unsigned brst_size:3; /* in power of 2 */ + + enum pl330_dstcachectrl dcctl; + enum pl330_srccachectrl scctl; + enum pl330_byteswap swap; +}; + +/* + * One cycle of DMAC operation. + * There may be more than one xfer in a request. + */ +struct pl330_xfer { + u32 src_addr; + u32 dst_addr; + /* Size to xfer */ + u32 bytes; + /* + * Pointer to next xfer in the list. + * The last xfer in the req must point to NULL. + */ + struct pl330_xfer *next; +}; + +/* The xfer callbacks are made with one of these arguments. */ +enum pl330_op_err { + /* The all xfers in the request were success. */ + PL330_ERR_NONE, + /* If req aborted due to global error. */ + PL330_ERR_ABORT, + /* If req failed due to problem with Channel. */ + PL330_ERR_FAIL, +}; + +enum pl330_reqtype { + MEMTOMEM, + MEMTODEV, + DEVTOMEM, + DEVTODEV, +}; + +/* A request defining Scatter-Gather List ending with NULL xfer. */ +struct pl330_req { + enum pl330_reqtype rqtype; + /* Index of peripheral for the xfer. */ + unsigned peri:5; + /* Unique token for this xfer, set by the client. */ + void *token; + /* Callback to be called after xfer. */ + void (*xfer_cb)(void *token, enum pl330_op_err err); + /* If NULL, req will be done at last set parameters. */ + struct pl330_reqcfg *cfg; + /* Pointer to first xfer in the request. */ + struct pl330_xfer *x; +}; + +/* + * To know the status of the channel and DMAC, the client + * provides a pointer to this structure. The PL330 core + * fills it with current information. + */ +struct pl330_chanstatus { + /* + * If the DMAC engine halted due to some error, + * the client should remove-add DMAC. + */ + bool dmac_halted; + /* + * If channel is halted due to some error, + * the client should ABORT/FLUSH and START the channel. + */ + bool faulting; + /* Location of last load */ + u32 src_addr; + /* Location of last store */ + u32 dst_addr; + /* + * Pointer to the currently active req, NULL if channel is + * inactive, even though the requests may be present. + */ + struct pl330_req *top_req; + /* Pointer to req waiting second in the queue if any. */ + struct pl330_req *wait_req; +}; + +enum pl330_chan_op { + /* Start the channel */ + PL330_OP_START, + /* Abort the active xfer */ + PL330_OP_ABORT, + /* Stop xfer and flush queue */ + PL330_OP_FLUSH, +}; + +extern int pl330_add(struct pl330_info *); +extern void pl330_del(struct pl330_info *pi); +extern int pl330_update(const struct pl330_info *pi); +extern void pl330_release_channel(void *ch_id); +extern void *pl330_request_channel(const struct pl330_info *pi); +extern int pl330_chan_status(void *ch_id, struct pl330_chanstatus *pstatus); +extern int pl330_chan_ctrl(void *ch_id, enum pl330_chan_op op); +extern int pl330_submit_req(void *ch_id, struct pl330_req *r); + +#endif /* __PL330_CORE_H */ diff --git a/arch/arm/include/asm/hardware/sa1111.h b/arch/arm/include/asm/hardware/sa1111.h new file mode 100644 index 00000000..92ed254c --- /dev/null +++ b/arch/arm/include/asm/hardware/sa1111.h @@ -0,0 +1,585 @@ +/* + * arch/arm/include/asm/hardware/sa1111.h + * + * Copyright (C) 2000 John G Dorsey + * + * This file contains definitions for the SA-1111 Companion Chip. + * (Structure and naming borrowed from SA-1101.h, by Peter Danielsson.) + * + * Macro that calculates real address for registers in the SA-1111 + */ + +#ifndef _ASM_ARCH_SA1111 +#define _ASM_ARCH_SA1111 + +#include + +/* + * The SA1111 is always located at virtual 0xf4000000, and is always + * "native" endian. + */ + +#define SA1111_VBASE 0xf4000000 + +/* Don't use these! */ +#define SA1111_p2v( x ) ((x) - SA1111_BASE + SA1111_VBASE) +#define SA1111_v2p( x ) ((x) - SA1111_VBASE + SA1111_BASE) + +#ifndef __ASSEMBLY__ +#define _SA1111(x) ((x) + sa1111->resource.start) +#endif + +#define sa1111_writel(val,addr) __raw_writel(val, addr) +#define sa1111_readl(addr) __raw_readl(addr) + +/* + * 26 bits of the SA-1110 address bus are available to the SA-1111. + * Use these when feeding target addresses to the DMA engines. + */ + +#define SA1111_ADDR_WIDTH (26) +#define SA1111_ADDR_MASK ((1<dev) +#define sa1111_set_drvdata(d,p) dev_set_drvdata(&(d)->dev, p) + +struct sa1111_driver { + struct device_driver drv; + unsigned int devid; + int (*probe)(struct sa1111_dev *); + int (*remove)(struct sa1111_dev *); + int (*suspend)(struct sa1111_dev *, pm_message_t); + int (*resume)(struct sa1111_dev *); +}; + +#define SA1111_DRV(_d) container_of((_d), struct sa1111_driver, drv) + +#define SA1111_DRIVER_NAME(_sadev) ((_sadev)->dev.driver->name) + +/* + * These frob the SKPCR register. + */ +void sa1111_enable_device(struct sa1111_dev *); +void sa1111_disable_device(struct sa1111_dev *); + +unsigned int sa1111_pll_clock(struct sa1111_dev *); + +#define SA1111_AUDIO_ACLINK 0 +#define SA1111_AUDIO_I2S 1 + +void sa1111_select_audio_mode(struct sa1111_dev *sadev, int mode); +int sa1111_set_audio_rate(struct sa1111_dev *sadev, int rate); +int sa1111_get_audio_rate(struct sa1111_dev *sadev); + +int sa1111_check_dma_bug(dma_addr_t addr); + +int sa1111_driver_register(struct sa1111_driver *); +void sa1111_driver_unregister(struct sa1111_driver *); + +void sa1111_set_io_dir(struct sa1111_dev *sadev, unsigned int bits, unsigned int dir, unsigned int sleep_dir); +void sa1111_set_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v); +void sa1111_set_sleep_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v); + +struct sa1111_platform_data { + int irq_base; /* base for cascaded on-chip IRQs */ +}; + +#endif /* _ASM_ARCH_SA1111 */ diff --git a/arch/arm/include/asm/hardware/scoop.h b/arch/arm/include/asm/hardware/scoop.h new file mode 100644 index 00000000..ebb3ceaa --- /dev/null +++ b/arch/arm/include/asm/hardware/scoop.h @@ -0,0 +1,72 @@ +/* + * Definitions for the SCOOP interface found on various Sharp PDAs + * + * Copyright (c) 2004 Richard Purdie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#define SCOOP_MCR 0x00 +#define SCOOP_CDR 0x04 +#define SCOOP_CSR 0x08 +#define SCOOP_CPR 0x0C +#define SCOOP_CCR 0x10 +#define SCOOP_IRR 0x14 +#define SCOOP_IRM 0x14 +#define SCOOP_IMR 0x18 +#define SCOOP_ISR 0x1C +#define SCOOP_GPCR 0x20 +#define SCOOP_GPWR 0x24 +#define SCOOP_GPRR 0x28 + +#define SCOOP_CPR_OUT (1 << 7) +#define SCOOP_CPR_SD_3V (1 << 2) +#define SCOOP_CPR_CF_XV (1 << 1) +#define SCOOP_CPR_CF_3V (1 << 0) + +#define SCOOP_GPCR_PA22 (1 << 12) +#define SCOOP_GPCR_PA21 (1 << 11) +#define SCOOP_GPCR_PA20 (1 << 10) +#define SCOOP_GPCR_PA19 (1 << 9) +#define SCOOP_GPCR_PA18 (1 << 8) +#define SCOOP_GPCR_PA17 (1 << 7) +#define SCOOP_GPCR_PA16 (1 << 6) +#define SCOOP_GPCR_PA15 (1 << 5) +#define SCOOP_GPCR_PA14 (1 << 4) +#define SCOOP_GPCR_PA13 (1 << 3) +#define SCOOP_GPCR_PA12 (1 << 2) +#define SCOOP_GPCR_PA11 (1 << 1) + +struct scoop_config { + unsigned short io_out; + unsigned short io_dir; + unsigned short suspend_clr; + unsigned short suspend_set; + int gpio_base; +}; + +/* Structure for linking scoop devices to PCMCIA sockets */ +struct scoop_pcmcia_dev { + struct device *dev; /* Pointer to this socket's scoop device */ + int irq; /* irq for socket */ + int cd_irq; + const char *cd_irq_str; + unsigned char keep_vs; + unsigned char keep_rd; +}; + +struct scoop_pcmcia_config { + struct scoop_pcmcia_dev *devs; + int num_devs; + void (*pcmcia_init)(void); + void (*power_ctrl)(struct device *scoop, unsigned short cpr, int nr); +}; + +extern struct scoop_pcmcia_config *platform_scoop_config; + +void reset_scoop(struct device *dev); +unsigned short read_scoop_reg(struct device *dev, unsigned short reg); +void write_scoop_reg(struct device *dev, unsigned short reg, unsigned short data); diff --git a/arch/arm/include/asm/hardware/sp810.h b/arch/arm/include/asm/hardware/sp810.h new file mode 100644 index 00000000..e0d1c0cf --- /dev/null +++ b/arch/arm/include/asm/hardware/sp810.h @@ -0,0 +1,68 @@ +/* + * arch/arm/include/asm/hardware/sp810.h + * + * ARM PrimeXsys System Controller SP810 header file + * + * Copyright (C) 2009 ST Microelectronics + * Viresh Kumar + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#ifndef __ASM_ARM_SP810_H +#define __ASM_ARM_SP810_H + +#include + +/* sysctl registers offset */ +#define SCCTRL 0x000 +#define SCSYSSTAT 0x004 +#define SCIMCTRL 0x008 +#define SCIMSTAT 0x00C +#define SCXTALCTRL 0x010 +#define SCPLLCTRL 0x014 +#define SCPLLFCTRL 0x018 +#define SCPERCTRL0 0x01C +#define SCPERCTRL1 0x020 +#define SCPEREN 0x024 +#define SCPERDIS 0x028 +#define SCPERCLKEN 0x02C +#define SCPERSTAT 0x030 +#define SCSYSID0 0xEE0 +#define SCSYSID1 0xEE4 +#define SCSYSID2 0xEE8 +#define SCSYSID3 0xEEC +#define SCITCR 0xF00 +#define SCITIR0 0xF04 +#define SCITIR1 0xF08 +#define SCITOR 0xF0C +#define SCCNTCTRL 0xF10 +#define SCCNTDATA 0xF14 +#define SCCNTSTEP 0xF18 +#define SCPERIPHID0 0xFE0 +#define SCPERIPHID1 0xFE4 +#define SCPERIPHID2 0xFE8 +#define SCPERIPHID3 0xFEC +#define SCPCELLID0 0xFF0 +#define SCPCELLID1 0xFF4 +#define SCPCELLID2 0xFF8 +#define SCPCELLID3 0xFFC + +#define SCCTRL_TIMEREN0SEL_REFCLK (0 << 15) +#define SCCTRL_TIMEREN0SEL_TIMCLK (1 << 15) + +#define SCCTRL_TIMEREN1SEL_REFCLK (0 << 17) +#define SCCTRL_TIMEREN1SEL_TIMCLK (1 << 17) + +static inline void sysctl_soft_reset(void __iomem *base) +{ + /* switch to slow mode */ + writel(0x2, base + SCCTRL); + + /* writing any value to SCSYSSTAT reg will reset system */ + writel(0, base + SCSYSSTAT); +} + +#endif /* __ASM_ARM_SP810_H */ diff --git a/arch/arm/include/asm/hardware/ssp.h b/arch/arm/include/asm/hardware/ssp.h new file mode 100644 index 00000000..3b42e181 --- /dev/null +++ b/arch/arm/include/asm/hardware/ssp.h @@ -0,0 +1,28 @@ +/* + * ssp.h + * + * Copyright (C) 2003 Russell King, 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 version 2 as + * published by the Free Software Foundation. + */ +#ifndef SSP_H +#define SSP_H + +struct ssp_state { + unsigned int cr0; + unsigned int cr1; +}; + +int ssp_write_word(u16 data); +int ssp_read_word(u16 *data); +int ssp_flush(void); +void ssp_enable(void); +void ssp_disable(void); +void ssp_save_state(struct ssp_state *ssp); +void ssp_restore_state(struct ssp_state *ssp); +int ssp_init(void); +void ssp_exit(void); + +#endif diff --git a/arch/arm/include/asm/hardware/timer-sp.h b/arch/arm/include/asm/hardware/timer-sp.h new file mode 100644 index 00000000..4384d81e --- /dev/null +++ b/arch/arm/include/asm/hardware/timer-sp.h @@ -0,0 +1,2 @@ +void sp804_clocksource_init(void __iomem *, const char *); +void sp804_clockevents_init(void __iomem *, unsigned int, const char *); diff --git a/arch/arm/include/asm/hardware/uengine.h b/arch/arm/include/asm/hardware/uengine.h new file mode 100644 index 00000000..b442d65c --- /dev/null +++ b/arch/arm/include/asm/hardware/uengine.h @@ -0,0 +1,62 @@ +/* + * Generic library functions for the microengines found on the Intel + * IXP2000 series of network processors. + * + * Copyright (C) 2004, 2005 Lennert Buytenhek + * Dedicated to Marija Kulikova. + * + * 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. + */ + +#ifndef __IXP2000_UENGINE_H +#define __IXP2000_UENGINE_H + +extern u32 ixp2000_uengine_mask; + +struct ixp2000_uengine_code +{ + u32 cpu_model_bitmask; + u8 cpu_min_revision; + u8 cpu_max_revision; + + u32 uengine_parameters; + + struct ixp2000_reg_value { + int reg; + u32 value; + } *initial_reg_values; + + int num_insns; + u8 *insns; +}; + +u32 ixp2000_uengine_csr_read(int uengine, int offset); +void ixp2000_uengine_csr_write(int uengine, int offset, u32 value); +void ixp2000_uengine_reset(u32 uengine_mask); +void ixp2000_uengine_set_mode(int uengine, u32 mode); +void ixp2000_uengine_load_microcode(int uengine, u8 *ucode, int insns); +void ixp2000_uengine_init_context(int uengine, int context, int pc); +void ixp2000_uengine_start_contexts(int uengine, u8 ctx_mask); +void ixp2000_uengine_stop_contexts(int uengine, u8 ctx_mask); +int ixp2000_uengine_load(int uengine, struct ixp2000_uengine_code *c); + +#define IXP2000_UENGINE_8_CONTEXTS 0x00000000 +#define IXP2000_UENGINE_4_CONTEXTS 0x80000000 +#define IXP2000_UENGINE_PRN_UPDATE_EVERY 0x40000000 +#define IXP2000_UENGINE_PRN_UPDATE_ON_ACCESS 0x00000000 +#define IXP2000_UENGINE_NN_FROM_SELF 0x00100000 +#define IXP2000_UENGINE_NN_FROM_PREVIOUS 0x00000000 +#define IXP2000_UENGINE_ASSERT_EMPTY_AT_3 0x000c0000 +#define IXP2000_UENGINE_ASSERT_EMPTY_AT_2 0x00080000 +#define IXP2000_UENGINE_ASSERT_EMPTY_AT_1 0x00040000 +#define IXP2000_UENGINE_ASSERT_EMPTY_AT_0 0x00000000 +#define IXP2000_UENGINE_LM_ADDR1_GLOBAL 0x00020000 +#define IXP2000_UENGINE_LM_ADDR1_PER_CONTEXT 0x00000000 +#define IXP2000_UENGINE_LM_ADDR0_GLOBAL 0x00010000 +#define IXP2000_UENGINE_LM_ADDR0_PER_CONTEXT 0x00000000 + + +#endif diff --git a/arch/arm/include/asm/hardware/vic.h b/arch/arm/include/asm/hardware/vic.h new file mode 100644 index 00000000..5d72550a --- /dev/null +++ b/arch/arm/include/asm/hardware/vic.h @@ -0,0 +1,47 @@ +/* + * arch/arm/include/asm/hardware/vic.h + * + * Copyright (c) ARM Limited 2003. 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 __ASM_ARM_HARDWARE_VIC_H +#define __ASM_ARM_HARDWARE_VIC_H + +#define VIC_IRQ_STATUS 0x00 +#define VIC_FIQ_STATUS 0x04 +#define VIC_RAW_STATUS 0x08 +#define VIC_INT_SELECT 0x0c /* 1 = FIQ, 0 = IRQ */ +#define VIC_INT_ENABLE 0x10 /* 1 = enable, 0 = disable */ +#define VIC_INT_ENABLE_CLEAR 0x14 +#define VIC_INT_SOFT 0x18 +#define VIC_INT_SOFT_CLEAR 0x1c +#define VIC_PROTECT 0x20 +#define VIC_PL190_VECT_ADDR 0x30 /* PL190 only */ +#define VIC_PL190_DEF_VECT_ADDR 0x34 /* PL190 only */ + +#define VIC_VECT_ADDR0 0x100 /* 0 to 15 (0..31 PL192) */ +#define VIC_VECT_CNTL0 0x200 /* 0 to 15 (0..31 PL192) */ +#define VIC_ITCR 0x300 /* VIC test control register */ + +#define VIC_VECT_CNTL_ENABLE (1 << 5) + +#define VIC_PL192_VECT_ADDR 0xF00 + +#ifndef __ASSEMBLY__ +void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources); +#endif + +#endif diff --git a/arch/arm/include/asm/highmem.h b/arch/arm/include/asm/highmem.h new file mode 100644 index 00000000..a4edd19d --- /dev/null +++ b/arch/arm/include/asm/highmem.h @@ -0,0 +1,66 @@ +#ifndef _ASM_HIGHMEM_H +#define _ASM_HIGHMEM_H + +#include + +#define PKMAP_BASE (PAGE_OFFSET - PMD_SIZE) +#define LAST_PKMAP PTRS_PER_PTE +#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)) + +#define kmap_prot PAGE_KERNEL + +#define flush_cache_kmaps() \ + do { \ + if (cache_is_vivt()) \ + flush_cache_all(); \ + } while (0) + +extern pte_t *pkmap_page_table; + +extern void *kmap_high(struct page *page); +extern void kunmap_high(struct page *page); + +/* + * The reason for kmap_high_get() is to ensure that the currently kmap'd + * page usage count does not decrease to zero while we're using its + * existing virtual mapping in an atomic context. With a VIVT cache this + * is essential to do, but with a VIPT cache this is only an optimization + * so not to pay the price of establishing a second mapping if an existing + * one can be used. However, on platforms without hardware TLB maintenance + * broadcast, we simply cannot use ARCH_NEEDS_KMAP_HIGH_GET at all since + * the locking involved must also disable IRQs which is incompatible with + * the IPI mechanism used by global TLB operations. + */ +#define ARCH_NEEDS_KMAP_HIGH_GET +#if defined(CONFIG_SMP) && defined(CONFIG_CPU_TLB_V6) +#undef ARCH_NEEDS_KMAP_HIGH_GET +#if defined(CONFIG_HIGHMEM) && defined(CONFIG_CPU_CACHE_VIVT) +#error "The sum of features in your kernel config cannot be supported together" +#endif +#endif + +#ifdef ARCH_NEEDS_KMAP_HIGH_GET +extern void *kmap_high_get(struct page *page); +#else +static inline void *kmap_high_get(struct page *page) +{ + return NULL; +} +#endif + +/* + * The following functions are already defined by + * when CONFIG_HIGHMEM is not set. + */ +#ifdef CONFIG_HIGHMEM +extern void *kmap(struct page *page); +extern void kunmap(struct page *page); +extern void *__kmap_atomic(struct page *page); +extern void __kunmap_atomic(void *kvaddr); +extern void *kmap_atomic_pfn(unsigned long pfn); +extern struct page *kmap_atomic_to_page(const void *ptr); +#endif + +#endif diff --git a/arch/arm/include/asm/hw_breakpoint.h b/arch/arm/include/asm/hw_breakpoint.h new file mode 100644 index 00000000..f389b270 --- /dev/null +++ b/arch/arm/include/asm/hw_breakpoint.h @@ -0,0 +1,133 @@ +#ifndef _ARM_HW_BREAKPOINT_H +#define _ARM_HW_BREAKPOINT_H + +#ifdef __KERNEL__ + +struct task_struct; + +#ifdef CONFIG_HAVE_HW_BREAKPOINT + +struct arch_hw_breakpoint_ctrl { + u32 __reserved : 9, + mismatch : 1, + : 9, + len : 8, + type : 2, + privilege : 2, + enabled : 1; +}; + +struct arch_hw_breakpoint { + u32 address; + u32 trigger; + struct arch_hw_breakpoint_ctrl step_ctrl; + struct arch_hw_breakpoint_ctrl ctrl; +}; + +static inline u32 encode_ctrl_reg(struct arch_hw_breakpoint_ctrl ctrl) +{ + return (ctrl.mismatch << 22) | (ctrl.len << 5) | (ctrl.type << 3) | + (ctrl.privilege << 1) | ctrl.enabled; +} + +static inline void decode_ctrl_reg(u32 reg, + struct arch_hw_breakpoint_ctrl *ctrl) +{ + ctrl->enabled = reg & 0x1; + reg >>= 1; + ctrl->privilege = reg & 0x3; + reg >>= 2; + ctrl->type = reg & 0x3; + reg >>= 2; + ctrl->len = reg & 0xff; + reg >>= 17; + ctrl->mismatch = reg & 0x1; +} + +/* Debug architecture numbers. */ +#define ARM_DEBUG_ARCH_RESERVED 0 /* In case of ptrace ABI updates. */ +#define ARM_DEBUG_ARCH_V6 1 +#define ARM_DEBUG_ARCH_V6_1 2 +#define ARM_DEBUG_ARCH_V7_ECP14 3 +#define ARM_DEBUG_ARCH_V7_MM 4 + +/* Breakpoint */ +#define ARM_BREAKPOINT_EXECUTE 0 + +/* Watchpoints */ +#define ARM_BREAKPOINT_LOAD 1 +#define ARM_BREAKPOINT_STORE 2 + +/* Privilege Levels */ +#define ARM_BREAKPOINT_PRIV 1 +#define ARM_BREAKPOINT_USER 2 + +/* Lengths */ +#define ARM_BREAKPOINT_LEN_1 0x1 +#define ARM_BREAKPOINT_LEN_2 0x3 +#define ARM_BREAKPOINT_LEN_4 0xf +#define ARM_BREAKPOINT_LEN_8 0xff + +/* Limits */ +#define ARM_MAX_BRP 16 +#define ARM_MAX_WRP 16 +#define ARM_MAX_HBP_SLOTS (ARM_MAX_BRP + ARM_MAX_WRP) + +/* DSCR method of entry bits. */ +#define ARM_DSCR_MOE(x) ((x >> 2) & 0xf) +#define ARM_ENTRY_BREAKPOINT 0x1 +#define ARM_ENTRY_ASYNC_WATCHPOINT 0x2 +#define ARM_ENTRY_SYNC_WATCHPOINT 0xa + +/* DSCR monitor/halting bits. */ +#define ARM_DSCR_HDBGEN (1 << 14) +#define ARM_DSCR_MDBGEN (1 << 15) + +/* opcode2 numbers for the co-processor instructions. */ +#define ARM_OP2_BVR 4 +#define ARM_OP2_BCR 5 +#define ARM_OP2_WVR 6 +#define ARM_OP2_WCR 7 + +/* Base register numbers for the debug registers. */ +#define ARM_BASE_BVR 64 +#define ARM_BASE_BCR 80 +#define ARM_BASE_WVR 96 +#define ARM_BASE_WCR 112 + +/* Accessor macros for the debug registers. */ +#define ARM_DBG_READ(M, OP2, VAL) do {\ + asm volatile("mrc p14, 0, %0, c0," #M ", " #OP2 : "=r" (VAL));\ +} while (0) + +#define ARM_DBG_WRITE(M, OP2, VAL) do {\ + asm volatile("mcr p14, 0, %0, c0," #M ", " #OP2 : : "r" (VAL));\ +} while (0) + +struct notifier_block; +struct perf_event; +struct pmu; + +extern struct pmu perf_ops_bp; +extern int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl, + int *gen_len, int *gen_type); +extern int arch_check_bp_in_kernelspace(struct perf_event *bp); +extern int arch_validate_hwbkpt_settings(struct perf_event *bp); +extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused, + unsigned long val, void *data); + +extern u8 arch_get_debug_arch(void); +extern u8 arch_get_max_wp_len(void); +extern void clear_ptrace_hw_breakpoint(struct task_struct *tsk); + +int arch_install_hw_breakpoint(struct perf_event *bp); +void arch_uninstall_hw_breakpoint(struct perf_event *bp); +void hw_breakpoint_pmu_read(struct perf_event *bp); +int hw_breakpoint_slots(int type); + +#else +static inline void clear_ptrace_hw_breakpoint(struct task_struct *tsk) {} + +#endif /* CONFIG_HAVE_HW_BREAKPOINT */ +#endif /* __KERNEL__ */ +#endif /* _ARM_HW_BREAKPOINT_H */ diff --git a/arch/arm/include/asm/hw_irq.h b/arch/arm/include/asm/hw_irq.h new file mode 100644 index 00000000..a71b417b --- /dev/null +++ b/arch/arm/include/asm/hw_irq.h @@ -0,0 +1,21 @@ +/* + * Nothing to see here yet + */ +#ifndef _ARCH_ARM_HW_IRQ_H +#define _ARCH_ARM_HW_IRQ_H + +static inline void ack_bad_irq(int irq) +{ + extern unsigned long irq_err_count; + irq_err_count++; +} + +void set_irq_flags(unsigned int irq, unsigned int flags); + +#define IRQF_VALID (1 << 0) +#define IRQF_PROBE (1 << 1) +#define IRQF_NOAUTOEN (1 << 2) + +#define ARCH_IRQ_INIT_FLAGS (IRQ_NOREQUEST | IRQ_NOPROBE) + +#endif diff --git a/arch/arm/include/asm/hwcap.h b/arch/arm/include/asm/hwcap.h new file mode 100644 index 00000000..c1062c31 --- /dev/null +++ b/arch/arm/include/asm/hwcap.h @@ -0,0 +1,33 @@ +#ifndef __ASMARM_HWCAP_H +#define __ASMARM_HWCAP_H + +/* + * HWCAP flags - for elf_hwcap (in kernel) and AT_HWCAP + */ +#define HWCAP_SWP 1 +#define HWCAP_HALF 2 +#define HWCAP_THUMB 4 +#define HWCAP_26BIT 8 /* Play it safe */ +#define HWCAP_FAST_MULT 16 +#define HWCAP_FPA 32 +#define HWCAP_VFP 64 +#define HWCAP_EDSP 128 +#define HWCAP_JAVA 256 +#define HWCAP_IWMMXT 512 +#define HWCAP_CRUNCH 1024 +#define HWCAP_THUMBEE 2048 +#define HWCAP_NEON 4096 +#define HWCAP_VFPv3 8192 +#define HWCAP_VFPv3D16 16384 +#define HWCAP_TLS 32768 + +#if defined(__KERNEL__) && !defined(__ASSEMBLY__) +/* + * This yields a mask that user programs can use to figure out what + * instruction set this cpu supports. + */ +#define ELF_HWCAP (elf_hwcap) +extern unsigned int elf_hwcap; +#endif + +#endif diff --git a/arch/arm/include/asm/i8253.h b/arch/arm/include/asm/i8253.h new file mode 100644 index 00000000..70656b69 --- /dev/null +++ b/arch/arm/include/asm/i8253.h @@ -0,0 +1,15 @@ +#ifndef __ASMARM_I8253_H +#define __ASMARM_I8253_H + +/* i8253A PIT registers */ +#define PIT_MODE 0x43 +#define PIT_CH0 0x40 + +#define PIT_LATCH ((PIT_TICK_RATE + HZ / 2) / HZ) + +extern raw_spinlock_t i8253_lock; + +#define outb_pit outb_p +#define inb_pit inb_p + +#endif diff --git a/arch/arm/include/asm/ide.h b/arch/arm/include/asm/ide.h new file mode 100644 index 00000000..b507ce8e --- /dev/null +++ b/arch/arm/include/asm/ide.h @@ -0,0 +1,23 @@ +/* + * arch/arm/include/asm/ide.h + * + * Copyright (C) 1994-1996 Linus Torvalds & authors + */ + +/* + * This file contains the ARM architecture specific IDE code. + */ + +#ifndef __ASMARM_IDE_H +#define __ASMARM_IDE_H + +#ifdef __KERNEL__ + +#define __ide_mm_insw(port,addr,len) readsw(port,addr,len) +#define __ide_mm_insl(port,addr,len) readsl(port,addr,len) +#define __ide_mm_outsw(port,addr,len) writesw(port,addr,len) +#define __ide_mm_outsl(port,addr,len) writesl(port,addr,len) + +#endif /* __KERNEL__ */ + +#endif /* __ASMARM_IDE_H */ diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h new file mode 100644 index 00000000..d66605de --- /dev/null +++ b/arch/arm/include/asm/io.h @@ -0,0 +1,317 @@ +/* + * arch/arm/include/asm/io.h + * + * Copyright (C) 1996-2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Modifications: + * 16-Sep-1996 RMK Inlined the inx/outx functions & optimised for both + * constant addresses and variable addresses. + * 04-Dec-1997 RMK Moved a lot of this stuff to the new architecture + * specific IO header files. + * 27-Mar-1999 PJB Second parameter of memcpy_toio is const.. + * 04-Apr-1999 PJB Added check_signature. + * 12-Dec-1999 RMK More cleanups + * 18-Jun-2000 RMK Removed virt_to_* and friends definitions + * 05-Oct-2004 BJD Moved memory string functions to use void __iomem + */ +#ifndef __ASM_ARM_IO_H +#define __ASM_ARM_IO_H + +#ifdef __KERNEL__ + +#include +#include +#include +#include + +/* + * ISA I/O bus memory addresses are 1:1 with the physical address. + */ +#define isa_virt_to_bus virt_to_phys +#define isa_page_to_bus page_to_phys +#define isa_bus_to_virt phys_to_virt + +/* + * Generic IO read/write. These perform native-endian accesses. Note + * that some architectures will want to re-define __raw_{read,write}w. + */ +extern void __raw_writesb(void __iomem *addr, const void *data, int bytelen); +extern void __raw_writesw(void __iomem *addr, const void *data, int wordlen); +extern void __raw_writesl(void __iomem *addr, const void *data, int longlen); + +extern void __raw_readsb(const void __iomem *addr, void *data, int bytelen); +extern void __raw_readsw(const void __iomem *addr, void *data, int wordlen); +extern void __raw_readsl(const void __iomem *addr, void *data, int longlen); + +#define __raw_writeb(v,a) (__chk_io_ptr(a), *(volatile unsigned char __force *)(a) = (v)) +#define __raw_writew(v,a) (__chk_io_ptr(a), *(volatile unsigned short __force *)(a) = (v)) +#define __raw_writel(v,a) (__chk_io_ptr(a), *(volatile unsigned int __force *)(a) = (v)) + +#define __raw_readb(a) (__chk_io_ptr(a), *(volatile unsigned char __force *)(a)) +#define __raw_readw(a) (__chk_io_ptr(a), *(volatile unsigned short __force *)(a)) +#define __raw_readl(a) (__chk_io_ptr(a), *(volatile unsigned int __force *)(a)) + +/* + * Architecture ioremap implementation. + */ +#define MT_DEVICE 0 +#define MT_DEVICE_NONSHARED 1 +#define MT_DEVICE_CACHED 2 +#define MT_DEVICE_WC 3 +/* + * types 4 onwards can be found in asm/mach/map.h and are undefined + * for ioremap + */ + +/* + * __arm_ioremap takes CPU physical address. + * __arm_ioremap_pfn takes a Page Frame Number and an offset into that page + * The _caller variety takes a __builtin_return_address(0) value for + * /proc/vmalloc to use - and should only be used in non-inline functions. + */ +extern void __iomem *__arm_ioremap_pfn_caller(unsigned long, unsigned long, + size_t, unsigned int, void *); +extern void __iomem *__arm_ioremap_caller(unsigned long, size_t, unsigned int, + void *); + +extern void __iomem *__arm_ioremap_pfn(unsigned long, unsigned long, size_t, unsigned int); +extern void __iomem *__arm_ioremap(unsigned long, size_t, unsigned int); +extern void __iounmap(volatile void __iomem *addr); + +/* + * Bad read/write accesses... + */ +extern void __readwrite_bug(const char *fn); + +/* + * A typesafe __io() helper + */ +static inline void __iomem *__typesafe_io(unsigned long addr) +{ + return (void __iomem *)addr; +} + +/* IO barriers */ +#ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE +#define __iormb() rmb() +#define __iowmb() wmb() +#else +#define __iormb() do { } while (0) +#define __iowmb() do { } while (0) +#endif + +/* + * Now, pick up the machine-defined IO definitions + */ +#include + +/* + * IO port access primitives + * ------------------------- + * + * The ARM doesn't have special IO access instructions; all IO is memory + * mapped. Note that these are defined to perform little endian accesses + * only. Their primary purpose is to access PCI and ISA peripherals. + * + * Note that for a big endian machine, this implies that the following + * big endian mode connectivity is in place, as described by numerous + * ARM documents: + * + * PCI: D0-D7 D8-D15 D16-D23 D24-D31 + * ARM: D24-D31 D16-D23 D8-D15 D0-D7 + * + * The machine specific io.h include defines __io to translate an "IO" + * address to a memory address. + * + * Note that we prevent GCC re-ordering or caching values in expressions + * by introducing sequence points into the in*() definitions. Note that + * __raw_* do not guarantee this behaviour. + * + * The {in,out}[bwl] macros are for emulating x86-style PCI/ISA IO space. + */ +#ifdef __io +#define outb(v,p) ({ __iowmb(); __raw_writeb(v,__io(p)); }) +#define outw(v,p) ({ __iowmb(); __raw_writew((__force __u16) \ + cpu_to_le16(v),__io(p)); }) +#define outl(v,p) ({ __iowmb(); __raw_writel((__force __u32) \ + cpu_to_le32(v),__io(p)); }) + +#define inb(p) ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; }) +#define inw(p) ({ __u16 __v = le16_to_cpu((__force __le16) \ + __raw_readw(__io(p))); __iormb(); __v; }) +#define inl(p) ({ __u32 __v = le32_to_cpu((__force __le32) \ + __raw_readl(__io(p))); __iormb(); __v; }) + +#define outsb(p,d,l) __raw_writesb(__io(p),d,l) +#define outsw(p,d,l) __raw_writesw(__io(p),d,l) +#define outsl(p,d,l) __raw_writesl(__io(p),d,l) + +#define insb(p,d,l) __raw_readsb(__io(p),d,l) +#define insw(p,d,l) __raw_readsw(__io(p),d,l) +#define insl(p,d,l) __raw_readsl(__io(p),d,l) +#endif + +#define outb_p(val,port) outb((val),(port)) +#define outw_p(val,port) outw((val),(port)) +#define outl_p(val,port) outl((val),(port)) +#define inb_p(port) inb((port)) +#define inw_p(port) inw((port)) +#define inl_p(port) inl((port)) + +#define outsb_p(port,from,len) outsb(port,from,len) +#define outsw_p(port,from,len) outsw(port,from,len) +#define outsl_p(port,from,len) outsl(port,from,len) +#define insb_p(port,to,len) insb(port,to,len) +#define insw_p(port,to,len) insw(port,to,len) +#define insl_p(port,to,len) insl(port,to,len) + +/* + * String version of IO memory access ops: + */ +extern void _memcpy_fromio(void *, const volatile void __iomem *, size_t); +extern void _memcpy_toio(volatile void __iomem *, const void *, size_t); +extern void _memset_io(volatile void __iomem *, int, size_t); + +#define mmiowb() + +/* + * Memory access primitives + * ------------------------ + * + * These perform PCI memory accesses via an ioremap region. They don't + * take an address as such, but a cookie. + * + * Again, this are defined to perform little endian accesses. See the + * IO port primitives for more information. + */ +#ifdef __mem_pci +#define readb_relaxed(c) ({ u8 __v = __raw_readb(__mem_pci(c)); __v; }) +#define readw_relaxed(c) ({ u16 __v = le16_to_cpu((__force __le16) \ + __raw_readw(__mem_pci(c))); __v; }) +#define readl_relaxed(c) ({ u32 __v = le32_to_cpu((__force __le32) \ + __raw_readl(__mem_pci(c))); __v; }) + +#define writeb_relaxed(v,c) ((void)__raw_writeb(v,__mem_pci(c))) +#define writew_relaxed(v,c) ((void)__raw_writew((__force u16) \ + cpu_to_le16(v),__mem_pci(c))) +#define writel_relaxed(v,c) ((void)__raw_writel((__force u32) \ + cpu_to_le32(v),__mem_pci(c))) + +#define readb(c) ({ u8 __v = readb_relaxed(c); __iormb(); __v; }) +#define readw(c) ({ u16 __v = readw_relaxed(c); __iormb(); __v; }) +#define readl(c) ({ u32 __v = readl_relaxed(c); __iormb(); __v; }) + +#define writeb(v,c) ({ __iowmb(); writeb_relaxed(v,c); }) +#define writew(v,c) ({ __iowmb(); writew_relaxed(v,c); }) +#define writel(v,c) ({ __iowmb(); writel_relaxed(v,c); }) + +#define readsb(p,d,l) __raw_readsb(__mem_pci(p),d,l) +#define readsw(p,d,l) __raw_readsw(__mem_pci(p),d,l) +#define readsl(p,d,l) __raw_readsl(__mem_pci(p),d,l) + +#define writesb(p,d,l) __raw_writesb(__mem_pci(p),d,l) +#define writesw(p,d,l) __raw_writesw(__mem_pci(p),d,l) +#define writesl(p,d,l) __raw_writesl(__mem_pci(p),d,l) + +#define memset_io(c,v,l) _memset_io(__mem_pci(c),(v),(l)) +#define memcpy_fromio(a,c,l) _memcpy_fromio((a),__mem_pci(c),(l)) +#define memcpy_toio(c,a,l) _memcpy_toio(__mem_pci(c),(a),(l)) + +#elif !defined(readb) + +#define readb(c) (__readwrite_bug("readb"),0) +#define readw(c) (__readwrite_bug("readw"),0) +#define readl(c) (__readwrite_bug("readl"),0) +#define writeb(v,c) __readwrite_bug("writeb") +#define writew(v,c) __readwrite_bug("writew") +#define writel(v,c) __readwrite_bug("writel") + +#define check_signature(io,sig,len) (0) + +#endif /* __mem_pci */ + +/* + * ioremap and friends. + * + * ioremap takes a PCI memory address, as specified in + * Documentation/IO-mapping.txt. + * + */ +#ifndef __arch_ioremap +#define __arch_ioremap __arm_ioremap +#define __arch_iounmap __iounmap +#endif + +#define ioremap(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE) +#define ioremap_nocache(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE) +#define ioremap_cached(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE_CACHED) +#define ioremap_wc(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE_WC) +#define iounmap __arch_iounmap + +/* + * io{read,write}{8,16,32} macros + */ +#ifndef ioread8 +#define ioread8(p) ({ unsigned int __v = __raw_readb(p); __iormb(); __v; }) +#define ioread16(p) ({ unsigned int __v = le16_to_cpu((__force __le16)__raw_readw(p)); __iormb(); __v; }) +#define ioread32(p) ({ unsigned int __v = le32_to_cpu((__force __le32)__raw_readl(p)); __iormb(); __v; }) + +#define iowrite8(v,p) ({ __iowmb(); (void)__raw_writeb(v, p); }) +#define iowrite16(v,p) ({ __iowmb(); (void)__raw_writew((__force __u16)cpu_to_le16(v), p); }) +#define iowrite32(v,p) ({ __iowmb(); (void)__raw_writel((__force __u32)cpu_to_le32(v), p); }) + +#define ioread8_rep(p,d,c) __raw_readsb(p,d,c) +#define ioread16_rep(p,d,c) __raw_readsw(p,d,c) +#define ioread32_rep(p,d,c) __raw_readsl(p,d,c) + +#define iowrite8_rep(p,s,c) __raw_writesb(p,s,c) +#define iowrite16_rep(p,s,c) __raw_writesw(p,s,c) +#define iowrite32_rep(p,s,c) __raw_writesl(p,s,c) + +extern void __iomem *ioport_map(unsigned long port, unsigned int nr); +extern void ioport_unmap(void __iomem *addr); +#endif + +struct pci_dev; + +extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen); +extern void pci_iounmap(struct pci_dev *dev, void __iomem *addr); + +/* + * can the hardware map this into one segment or not, given no other + * constraints. + */ +#define BIOVEC_MERGEABLE(vec1, vec2) \ + ((bvec_to_phys((vec1)) + (vec1)->bv_len) == bvec_to_phys((vec2))) + +#ifdef CONFIG_MMU +#define ARCH_HAS_VALID_PHYS_ADDR_RANGE +extern int valid_phys_addr_range(unsigned long addr, size_t size); +extern int valid_mmap_phys_addr_range(unsigned long pfn, size_t size); +extern int devmem_is_allowed(unsigned long pfn); +#endif + +/* + * Convert a physical pointer to a virtual kernel pointer for /dev/mem + * access + */ +#define xlate_dev_mem_ptr(p) __va(p) + +/* + * Convert a virtual cached pointer to an uncached pointer + */ +#define xlate_dev_kmem_ptr(p) p + +/* + * Register ISA memory and port locations for glibc iopl/inb/outb + * emulation. + */ +extern void register_isa_ports(unsigned int mmio, unsigned int io, + unsigned int io_shift); + +#endif /* __KERNEL__ */ +#endif /* __ASM_ARM_IO_H */ diff --git a/arch/arm/include/asm/ioctl.h b/arch/arm/include/asm/ioctl.h new file mode 100644 index 00000000..b279fe06 --- /dev/null +++ b/arch/arm/include/asm/ioctl.h @@ -0,0 +1 @@ +#include diff --git a/arch/arm/include/asm/ioctls.h b/arch/arm/include/asm/ioctls.h new file mode 100644 index 00000000..9c962981 --- /dev/null +++ b/arch/arm/include/asm/ioctls.h @@ -0,0 +1,8 @@ +#ifndef __ASM_ARM_IOCTLS_H +#define __ASM_ARM_IOCTLS_H + +#define FIOQSIZE 0x545E + +#include + +#endif diff --git a/arch/arm/include/asm/ipcbuf.h b/arch/arm/include/asm/ipcbuf.h new file mode 100644 index 00000000..97683975 --- /dev/null +++ b/arch/arm/include/asm/ipcbuf.h @@ -0,0 +1,29 @@ +#ifndef __ASMARM_IPCBUF_H +#define __ASMARM_IPCBUF_H + +/* + * The ipc64_perm structure for arm architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 32-bit mode_t and seq + * - 2 miscellaneous 32-bit values + */ + +struct ipc64_perm +{ + __kernel_key_t key; + __kernel_uid32_t uid; + __kernel_gid32_t gid; + __kernel_uid32_t cuid; + __kernel_gid32_t cgid; + __kernel_mode_t mode; + unsigned short __pad1; + unsigned short seq; + unsigned short __pad2; + unsigned long __unused1; + unsigned long __unused2; +}; + +#endif /* __ASMARM_IPCBUF_H */ diff --git a/arch/arm/include/asm/irq.h b/arch/arm/include/asm/irq.h new file mode 100644 index 00000000..a5656333 --- /dev/null +++ b/arch/arm/include/asm/irq.h @@ -0,0 +1,35 @@ +#ifndef __ASM_ARM_IRQ_H +#define __ASM_ARM_IRQ_H + +#include + +#ifndef irq_canonicalize +#define irq_canonicalize(i) (i) +#endif + +#define NR_IRQS_LEGACY 16 + +/* + * Use this value to indicate lack of interrupt + * capability + */ +#ifndef NO_IRQ +#define NO_IRQ ((unsigned int)(-1)) +#endif + +#ifndef __ASSEMBLY__ +struct irqaction; +struct pt_regs; +extern void migrate_irqs(void); + +extern void asm_do_IRQ(unsigned int, struct pt_regs *); +void handle_IRQ(unsigned int, struct pt_regs *); +void init_IRQ(void); + +void arch_trigger_all_cpu_backtrace(void); +#define arch_trigger_all_cpu_backtrace arch_trigger_all_cpu_backtrace + +#endif + +#endif + diff --git a/arch/arm/include/asm/irq_regs.h b/arch/arm/include/asm/irq_regs.h new file mode 100644 index 00000000..3dd9c0b7 --- /dev/null +++ b/arch/arm/include/asm/irq_regs.h @@ -0,0 +1 @@ +#include diff --git a/arch/arm/include/asm/irqflags.h b/arch/arm/include/asm/irqflags.h new file mode 100644 index 00000000..1e6cca55 --- /dev/null +++ b/arch/arm/include/asm/irqflags.h @@ -0,0 +1,155 @@ +#ifndef __ASM_ARM_IRQFLAGS_H +#define __ASM_ARM_IRQFLAGS_H + +#ifdef __KERNEL__ + +#include + +/* + * CPU interrupt mask handling. + */ +#if __LINUX_ARM_ARCH__ >= 6 + +static inline unsigned long arch_local_irq_save(void) +{ + unsigned long flags; + + asm volatile( + " mrs %0, cpsr @ arch_local_irq_save\n" + " cpsid i" + : "=r" (flags) : : "memory", "cc"); + return flags; +} + +static inline void arch_local_irq_enable(void) +{ + asm volatile( + " cpsie i @ arch_local_irq_enable" + : + : + : "memory", "cc"); +} + +static inline void arch_local_irq_disable(void) +{ + asm volatile( + " cpsid i @ arch_local_irq_disable" + : + : + : "memory", "cc"); +} + +#define local_fiq_enable() __asm__("cpsie f @ __stf" : : : "memory", "cc") +#define local_fiq_disable() __asm__("cpsid f @ __clf" : : : "memory", "cc") +#else + +/* + * Save the current interrupt enable state & disable IRQs + */ +static inline unsigned long arch_local_irq_save(void) +{ + unsigned long flags, temp; + + asm volatile( + " mrs %0, cpsr @ arch_local_irq_save\n" + " orr %1, %0, #128\n" + " msr cpsr_c, %1" + : "=r" (flags), "=r" (temp) + : + : "memory", "cc"); + return flags; +} + +/* + * Enable IRQs + */ +static inline void arch_local_irq_enable(void) +{ + unsigned long temp; + asm volatile( + " mrs %0, cpsr @ arch_local_irq_enable\n" + " bic %0, %0, #128\n" + " msr cpsr_c, %0" + : "=r" (temp) + : + : "memory", "cc"); +} + +/* + * Disable IRQs + */ +static inline void arch_local_irq_disable(void) +{ + unsigned long temp; + asm volatile( + " mrs %0, cpsr @ arch_local_irq_disable\n" + " orr %0, %0, #128\n" + " msr cpsr_c, %0" + : "=r" (temp) + : + : "memory", "cc"); +} + +/* + * Enable FIQs + */ +#define local_fiq_enable() \ + ({ \ + unsigned long temp; \ + __asm__ __volatile__( \ + "mrs %0, cpsr @ stf\n" \ +" bic %0, %0, #64\n" \ +" msr cpsr_c, %0" \ + : "=r" (temp) \ + : \ + : "memory", "cc"); \ + }) + +/* + * Disable FIQs + */ +#define local_fiq_disable() \ + ({ \ + unsigned long temp; \ + __asm__ __volatile__( \ + "mrs %0, cpsr @ clf\n" \ +" orr %0, %0, #64\n" \ +" msr cpsr_c, %0" \ + : "=r" (temp) \ + : \ + : "memory", "cc"); \ + }) + +#endif + +/* + * Save the current interrupt enable state. + */ +static inline unsigned long arch_local_save_flags(void) +{ + unsigned long flags; + asm volatile( + " mrs %0, cpsr @ local_save_flags" + : "=r" (flags) : : "memory", "cc"); + return flags; +} + +/* + * restore saved IRQ & FIQ state + */ +static inline void arch_local_irq_restore(unsigned long flags) +{ + asm volatile( + " msr cpsr_c, %0 @ local_irq_restore" + : + : "r" (flags) + : "memory", "cc"); +} + +static inline int arch_irqs_disabled_flags(unsigned long flags) +{ + return flags & PSR_I_BIT; +} + +#endif +#endif diff --git a/arch/arm/include/asm/kdebug.h b/arch/arm/include/asm/kdebug.h new file mode 100644 index 00000000..6ece1b03 --- /dev/null +++ b/arch/arm/include/asm/kdebug.h @@ -0,0 +1 @@ +#include diff --git a/arch/arm/include/asm/kexec.h b/arch/arm/include/asm/kexec.h new file mode 100644 index 00000000..c2b9b4bd --- /dev/null +++ b/arch/arm/include/asm/kexec.h @@ -0,0 +1,60 @@ +#ifndef _ARM_KEXEC_H +#define _ARM_KEXEC_H + +#ifdef CONFIG_KEXEC + +/* Maximum physical address we can use pages from */ +#define KEXEC_SOURCE_MEMORY_LIMIT (-1UL) +/* Maximum address we can reach in physical address mode */ +#define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL) +/* Maximum address we can use for the control code buffer */ +#define KEXEC_CONTROL_MEMORY_LIMIT (-1UL) + +#define KEXEC_CONTROL_PAGE_SIZE 4096 + +#define KEXEC_ARCH KEXEC_ARCH_ARM + +#define KEXEC_ARM_ATAGS_OFFSET 0x1000 +#define KEXEC_ARM_ZIMAGE_OFFSET 0x8000 + +#ifndef __ASSEMBLY__ + +/** + * crash_setup_regs() - save registers for the panic kernel + * @newregs: registers are saved here + * @oldregs: registers to be saved (may be %NULL) + * + * Function copies machine registers from @oldregs to @newregs. If @oldregs is + * %NULL then current registers are stored there. + */ +static inline void crash_setup_regs(struct pt_regs *newregs, + struct pt_regs *oldregs) +{ + if (oldregs) { + memcpy(newregs, oldregs, sizeof(*newregs)); + } else { + __asm__ __volatile__ ( + "stmia %[regs_base], {r0-r12}\n\t" + "mov %[_ARM_sp], sp\n\t" + "str lr, %[_ARM_lr]\n\t" + "adr %[_ARM_pc], 1f\n\t" + "mrs %[_ARM_cpsr], cpsr\n\t" + "1:" + : [_ARM_pc] "=r" (newregs->ARM_pc), + [_ARM_cpsr] "=r" (newregs->ARM_cpsr), + [_ARM_sp] "=r" (newregs->ARM_sp), + [_ARM_lr] "=o" (newregs->ARM_lr) + : [regs_base] "r" (&newregs->ARM_r0) + : "memory" + ); + } +} + +/* Function pointer to optional machine-specific reinitialization */ +extern void (*kexec_reinit)(void); + +#endif /* __ASSEMBLY__ */ + +#endif /* CONFIG_KEXEC */ + +#endif /* _ARM_KEXEC_H */ diff --git a/arch/arm/include/asm/kgdb.h b/arch/arm/include/asm/kgdb.h new file mode 100644 index 00000000..48066ce9 --- /dev/null +++ b/arch/arm/include/asm/kgdb.h @@ -0,0 +1,105 @@ +/* + * ARM KGDB support + * + * Author: Deepak Saxena + * + * Copyright (C) 2002 MontaVista Software Inc. + * + */ + +#ifndef __ARM_KGDB_H__ +#define __ARM_KGDB_H__ + +#include + +/* + * GDB assumes that we're a user process being debugged, so + * it will send us an SWI command to write into memory as the + * debug trap. When an SWI occurs, the next instruction addr is + * placed into R14_svc before jumping to the vector trap. + * This doesn't work for kernel debugging as we are already in SVC + * we would loose the kernel's LR, which is a bad thing. This + * is bad thing. + * + * By doing this as an undefined instruction trap, we force a mode + * switch from SVC to UND mode, allowing us to save full kernel state. + * + * We also define a KGDB_COMPILED_BREAK which can be used to compile + * in breakpoints. This is important for things like sysrq-G and for + * the initial breakpoint from trap_init(). + * + * Note to ARM HW designers: Add real trap support like SH && PPC to + * make our lives much much simpler. :) + */ +#define BREAK_INSTR_SIZE 4 +#define GDB_BREAKINST 0xef9f0001 +#define KGDB_BREAKINST 0xe7ffdefe +#define KGDB_COMPILED_BREAK 0xe7ffdeff +#define CACHE_FLUSH_IS_SAFE 1 + +#ifndef __ASSEMBLY__ + +static inline void arch_kgdb_breakpoint(void) +{ + asm(".word 0xe7ffdeff"); +} + +extern void kgdb_handle_bus_error(void); +extern int kgdb_fault_expected; + +#endif /* !__ASSEMBLY__ */ + +/* + * From Kevin Hilman: + * + * gdb is expecting the following registers layout. + * + * r0-r15: 1 long word each + * f0-f7: unused, 3 long words each !! + * fps: unused, 1 long word + * cpsr: 1 long word + * + * Even though f0-f7 and fps are not used, they need to be + * present in the registers sent for correct processing in + * the host-side gdb. + * + * In particular, it is crucial that CPSR is in the right place, + * otherwise gdb will not be able to correctly interpret stepping over + * conditional branches. + */ +#define _GP_REGS 16 +#define _FP_REGS 8 +#define _EXTRA_REGS 2 +#define GDB_MAX_REGS (_GP_REGS + (_FP_REGS * 3) + _EXTRA_REGS) +#define DBG_MAX_REG_NUM (_GP_REGS + _FP_REGS + _EXTRA_REGS) + +#define KGDB_MAX_NO_CPUS 1 +#define BUFMAX 400 +#define NUMREGBYTES (DBG_MAX_REG_NUM << 2) +#define NUMCRITREGBYTES (32 << 2) + +#define _R0 0 +#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 _FP 11 +#define _IP 12 +#define _SPT 13 +#define _LR 14 +#define _PC 15 +#define _CPSR (GDB_MAX_REGS - 1) + +/* + * So that we can denote the end of a frame for tracing, + * in the simple case: + */ +#define CFI_END_FRAME(func) __CFI_END_FRAME(_PC, _SPT, func) + +#endif /* __ASM_KGDB_H__ */ diff --git a/arch/arm/include/asm/kmap_types.h b/arch/arm/include/asm/kmap_types.h new file mode 100644 index 00000000..e51b1e81 --- /dev/null +++ b/arch/arm/include/asm/kmap_types.h @@ -0,0 +1,33 @@ +#ifndef __ARM_KMAP_TYPES_H +#define __ARM_KMAP_TYPES_H + +/* + * This is the "bare minimum". AIO seems to require this. + */ +enum km_type { + KM_BOUNCE_READ, + KM_SKB_SUNRPC_DATA, + KM_SKB_DATA_SOFTIRQ, + KM_USER0, + KM_USER1, + KM_BIO_SRC_IRQ, + KM_BIO_DST_IRQ, + KM_PTE0, + KM_PTE1, + KM_IRQ0, + KM_IRQ1, + KM_SOFTIRQ0, + KM_SOFTIRQ1, + KM_L1_CACHE, + KM_L2_CACHE, + KM_KDB, + KM_TYPE_NR +}; + +#ifdef CONFIG_DEBUG_HIGHMEM +#define KM_NMI (-1) +#define KM_NMI_PTE (-1) +#define KM_IRQ_PTE (-1) +#endif + +#endif diff --git a/arch/arm/include/asm/kprobes.h b/arch/arm/include/asm/kprobes.h new file mode 100644 index 00000000..e46bdd00 --- /dev/null +++ b/arch/arm/include/asm/kprobes.h @@ -0,0 +1,81 @@ +/* + * arch/arm/include/asm/kprobes.h + * + * Copyright (C) 2006, 2007 Motorola Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This 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. + */ + +#ifndef _ARM_KPROBES_H +#define _ARM_KPROBES_H + +#include +#include +#include + +#define __ARCH_WANT_KPROBES_INSN_SLOT +#define MAX_INSN_SIZE 2 +#define MAX_STACK_SIZE 64 /* 32 would probably be OK */ + +/* + * This undefined instruction must be unique and + * reserved solely for kprobes' use. + */ +#define KPROBE_BREAKPOINT_INSTRUCTION 0xe7f001f8 + +#define regs_return_value(regs) ((regs)->ARM_r0) +#define flush_insn_slot(p) do { } while (0) +#define kretprobe_blacklist_size 0 + +typedef u32 kprobe_opcode_t; + +struct kprobe; +typedef void (kprobe_insn_handler_t)(struct kprobe *, struct pt_regs *); + +typedef unsigned long (kprobe_check_cc)(unsigned long); + +/* Architecture specific copy of original instruction. */ +struct arch_specific_insn { + kprobe_opcode_t *insn; + kprobe_insn_handler_t *insn_handler; + kprobe_check_cc *insn_check_cc; +}; + +struct prev_kprobe { + struct kprobe *kp; + unsigned int status; +}; + +/* per-cpu kprobe control block */ +struct kprobe_ctlblk { + unsigned int kprobe_status; + struct prev_kprobe prev_kprobe; + struct pt_regs jprobe_saved_regs; + char jprobes_stack[MAX_STACK_SIZE]; +}; + +void arch_remove_kprobe(struct kprobe *); +void kretprobe_trampoline(void); + +int kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr); +int kprobe_exceptions_notify(struct notifier_block *self, + unsigned long val, void *data); + +enum kprobe_insn { + INSN_REJECTED, + INSN_GOOD, + INSN_GOOD_NO_SLOT +}; + +enum kprobe_insn arm_kprobe_decode_insn(kprobe_opcode_t, + struct arch_specific_insn *); +void __init arm_kprobe_decode_init(void); + +#endif /* _ARM_KPROBES_H */ diff --git a/arch/arm/include/asm/leds.h b/arch/arm/include/asm/leds.h new file mode 100644 index 00000000..c545739f --- /dev/null +++ b/arch/arm/include/asm/leds.h @@ -0,0 +1,50 @@ +/* + * arch/arm/include/asm/leds.h + * + * Copyright (C) 1998 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Event-driven interface for LEDs on machines + * Added led_start and led_stop- Alex Holden, 28th Dec 1998. + */ +#ifndef ASM_ARM_LEDS_H +#define ASM_ARM_LEDS_H + + +typedef enum { + led_idle_start, + led_idle_end, + led_timer, + led_start, + led_stop, + led_claim, /* override idle & timer leds */ + led_release, /* restore idle & timer leds */ + led_start_timer_mode, + led_stop_timer_mode, + led_green_on, + led_green_off, + led_amber_on, + led_amber_off, + led_red_on, + led_red_off, + led_blue_on, + led_blue_off, + /* + * I want this between led_timer and led_start, but + * someone has decided to export this to user space + */ + led_halted +} led_event_t; + +/* Use this routine to handle LEDs */ + +#ifdef CONFIG_LEDS +extern void (*leds_event)(led_event_t); +#else +#define leds_event(e) +#endif + +#endif diff --git a/arch/arm/include/asm/limits.h b/arch/arm/include/asm/limits.h new file mode 100644 index 00000000..08d8c660 --- /dev/null +++ b/arch/arm/include/asm/limits.h @@ -0,0 +1,11 @@ +#ifndef __ASM_PIPE_H +#define __ASM_PIPE_H + +#ifndef PAGE_SIZE +#include +#endif + +#define PIPE_BUF PAGE_SIZE + +#endif + diff --git a/arch/arm/include/asm/linkage.h b/arch/arm/include/asm/linkage.h new file mode 100644 index 00000000..5a25632b --- /dev/null +++ b/arch/arm/include/asm/linkage.h @@ -0,0 +1,11 @@ +#ifndef __ASM_LINKAGE_H +#define __ASM_LINKAGE_H + +#define __ALIGN .align 0 +#define __ALIGN_STR ".align 0" + +#define ENDPROC(name) \ + .type name, %function; \ + END(name) + +#endif diff --git a/arch/arm/include/asm/local.h b/arch/arm/include/asm/local.h new file mode 100644 index 00000000..c11c530f --- /dev/null +++ b/arch/arm/include/asm/local.h @@ -0,0 +1 @@ +#include diff --git a/arch/arm/include/asm/local64.h b/arch/arm/include/asm/local64.h new file mode 100644 index 00000000..36c93b5c --- /dev/null +++ b/arch/arm/include/asm/local64.h @@ -0,0 +1 @@ +#include diff --git a/arch/arm/include/asm/localtimer.h b/arch/arm/include/asm/localtimer.h new file mode 100644 index 00000000..080d74f8 --- /dev/null +++ b/arch/arm/include/asm/localtimer.h @@ -0,0 +1,57 @@ +/* + * arch/arm/include/asm/localtimer.h + * + * Copyright (C) 2004-2005 ARM Ltd. + * + * 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. + */ +#ifndef __ASM_ARM_LOCALTIMER_H +#define __ASM_ARM_LOCALTIMER_H + +struct clock_event_device; + +/* + * Setup a per-cpu timer, whether it be a local timer or dummy broadcast + */ +void percpu_timer_setup(void); + +/* + * Called from assembly, this is the local timer IRQ handler + */ +asmlinkage void do_local_timer(struct pt_regs *); + + +#ifdef CONFIG_LOCAL_TIMERS + +#ifdef CONFIG_HAVE_ARM_TWD + +#include "smp_twd.h" + +#define local_timer_ack() twd_timer_ack() + +#else + +/* + * Platform provides this to acknowledge a local timer IRQ. + * Returns true if the local timer IRQ is to be processed. + */ +int local_timer_ack(void); + +#endif + +/* + * Setup a local timer interrupt for a CPU. + */ +int local_timer_setup(struct clock_event_device *); + +#else + +static inline int local_timer_setup(struct clock_event_device *evt) +{ + return -ENXIO; +} +#endif + +#endif diff --git a/arch/arm/include/asm/locks.h b/arch/arm/include/asm/locks.h new file mode 100644 index 00000000..ef4c8977 --- /dev/null +++ b/arch/arm/include/asm/locks.h @@ -0,0 +1,274 @@ +/* + * arch/arm/include/asm/locks.h + * + * Copyright (C) 2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Interrupt safe locking assembler. + */ +#ifndef __ASM_PROC_LOCKS_H +#define __ASM_PROC_LOCKS_H + +#if __LINUX_ARM_ARCH__ >= 6 + +#define __down_op(ptr,fail) \ + ({ \ + __asm__ __volatile__( \ + "@ down_op\n" \ +"1: ldrex lr, [%0]\n" \ +" sub lr, lr, %1\n" \ +" strex ip, lr, [%0]\n" \ +" teq ip, #0\n" \ +" bne 1b\n" \ +" teq lr, #0\n" \ +" movmi ip, %0\n" \ +" blmi " #fail \ + : \ + : "r" (ptr), "I" (1) \ + : "ip", "lr", "cc"); \ + smp_mb(); \ + }) + +#define __down_op_ret(ptr,fail) \ + ({ \ + unsigned int ret; \ + __asm__ __volatile__( \ + "@ down_op_ret\n" \ +"1: ldrex lr, [%1]\n" \ +" sub lr, lr, %2\n" \ +" strex ip, lr, [%1]\n" \ +" teq ip, #0\n" \ +" bne 1b\n" \ +" teq lr, #0\n" \ +" movmi ip, %1\n" \ +" movpl ip, #0\n" \ +" blmi " #fail "\n" \ +" mov %0, ip" \ + : "=&r" (ret) \ + : "r" (ptr), "I" (1) \ + : "ip", "lr", "cc"); \ + smp_mb(); \ + ret; \ + }) + +#define __up_op(ptr,wake) \ + ({ \ + smp_mb(); \ + __asm__ __volatile__( \ + "@ up_op\n" \ +"1: ldrex lr, [%0]\n" \ +" add lr, lr, %1\n" \ +" strex ip, lr, [%0]\n" \ +" teq ip, #0\n" \ +" bne 1b\n" \ +" cmp lr, #0\n" \ +" movle ip, %0\n" \ +" blle " #wake \ + : \ + : "r" (ptr), "I" (1) \ + : "ip", "lr", "cc"); \ + }) + +/* + * The value 0x01000000 supports up to 128 processors and + * lots of processes. BIAS must be chosen such that sub'ing + * BIAS once per CPU will result in the long remaining + * negative. + */ +#define RW_LOCK_BIAS 0x01000000 +#define RW_LOCK_BIAS_STR "0x01000000" + +#define __down_op_write(ptr,fail) \ + ({ \ + __asm__ __volatile__( \ + "@ down_op_write\n" \ +"1: ldrex lr, [%0]\n" \ +" sub lr, lr, %1\n" \ +" strex ip, lr, [%0]\n" \ +" teq ip, #0\n" \ +" bne 1b\n" \ +" teq lr, #0\n" \ +" movne ip, %0\n" \ +" blne " #fail \ + : \ + : "r" (ptr), "I" (RW_LOCK_BIAS) \ + : "ip", "lr", "cc"); \ + smp_mb(); \ + }) + +#define __up_op_write(ptr,wake) \ + ({ \ + smp_mb(); \ + __asm__ __volatile__( \ + "@ up_op_write\n" \ +"1: ldrex lr, [%0]\n" \ +" adds lr, lr, %1\n" \ +" strex ip, lr, [%0]\n" \ +" teq ip, #0\n" \ +" bne 1b\n" \ +" movcs ip, %0\n" \ +" blcs " #wake \ + : \ + : "r" (ptr), "I" (RW_LOCK_BIAS) \ + : "ip", "lr", "cc"); \ + }) + +#define __down_op_read(ptr,fail) \ + __down_op(ptr, fail) + +#define __up_op_read(ptr,wake) \ + ({ \ + smp_mb(); \ + __asm__ __volatile__( \ + "@ up_op_read\n" \ +"1: ldrex lr, [%0]\n" \ +" add lr, lr, %1\n" \ +" strex ip, lr, [%0]\n" \ +" teq ip, #0\n" \ +" bne 1b\n" \ +" teq lr, #0\n" \ +" moveq ip, %0\n" \ +" bleq " #wake \ + : \ + : "r" (ptr), "I" (1) \ + : "ip", "lr", "cc"); \ + }) + +#else + +#define __down_op(ptr,fail) \ + ({ \ + __asm__ __volatile__( \ + "@ down_op\n" \ +" mrs ip, cpsr\n" \ +" orr lr, ip, #128\n" \ +" msr cpsr_c, lr\n" \ +" ldr lr, [%0]\n" \ +" subs lr, lr, %1\n" \ +" str lr, [%0]\n" \ +" msr cpsr_c, ip\n" \ +" movmi ip, %0\n" \ +" blmi " #fail \ + : \ + : "r" (ptr), "I" (1) \ + : "ip", "lr", "cc"); \ + smp_mb(); \ + }) + +#define __down_op_ret(ptr,fail) \ + ({ \ + unsigned int ret; \ + __asm__ __volatile__( \ + "@ down_op_ret\n" \ +" mrs ip, cpsr\n" \ +" orr lr, ip, #128\n" \ +" msr cpsr_c, lr\n" \ +" ldr lr, [%1]\n" \ +" subs lr, lr, %2\n" \ +" str lr, [%1]\n" \ +" msr cpsr_c, ip\n" \ +" movmi ip, %1\n" \ +" movpl ip, #0\n" \ +" blmi " #fail "\n" \ +" mov %0, ip" \ + : "=&r" (ret) \ + : "r" (ptr), "I" (1) \ + : "ip", "lr", "cc"); \ + smp_mb(); \ + ret; \ + }) + +#define __up_op(ptr,wake) \ + ({ \ + smp_mb(); \ + __asm__ __volatile__( \ + "@ up_op\n" \ +" mrs ip, cpsr\n" \ +" orr lr, ip, #128\n" \ +" msr cpsr_c, lr\n" \ +" ldr lr, [%0]\n" \ +" adds lr, lr, %1\n" \ +" str lr, [%0]\n" \ +" msr cpsr_c, ip\n" \ +" movle ip, %0\n" \ +" blle " #wake \ + : \ + : "r" (ptr), "I" (1) \ + : "ip", "lr", "cc"); \ + }) + +/* + * The value 0x01000000 supports up to 128 processors and + * lots of processes. BIAS must be chosen such that sub'ing + * BIAS once per CPU will result in the long remaining + * negative. + */ +#define RW_LOCK_BIAS 0x01000000 +#define RW_LOCK_BIAS_STR "0x01000000" + +#define __down_op_write(ptr,fail) \ + ({ \ + __asm__ __volatile__( \ + "@ down_op_write\n" \ +" mrs ip, cpsr\n" \ +" orr lr, ip, #128\n" \ +" msr cpsr_c, lr\n" \ +" ldr lr, [%0]\n" \ +" subs lr, lr, %1\n" \ +" str lr, [%0]\n" \ +" msr cpsr_c, ip\n" \ +" movne ip, %0\n" \ +" blne " #fail \ + : \ + : "r" (ptr), "I" (RW_LOCK_BIAS) \ + : "ip", "lr", "cc"); \ + smp_mb(); \ + }) + +#define __up_op_write(ptr,wake) \ + ({ \ + __asm__ __volatile__( \ + "@ up_op_write\n" \ +" mrs ip, cpsr\n" \ +" orr lr, ip, #128\n" \ +" msr cpsr_c, lr\n" \ +" ldr lr, [%0]\n" \ +" adds lr, lr, %1\n" \ +" str lr, [%0]\n" \ +" msr cpsr_c, ip\n" \ +" movcs ip, %0\n" \ +" blcs " #wake \ + : \ + : "r" (ptr), "I" (RW_LOCK_BIAS) \ + : "ip", "lr", "cc"); \ + smp_mb(); \ + }) + +#define __down_op_read(ptr,fail) \ + __down_op(ptr, fail) + +#define __up_op_read(ptr,wake) \ + ({ \ + smp_mb(); \ + __asm__ __volatile__( \ + "@ up_op_read\n" \ +" mrs ip, cpsr\n" \ +" orr lr, ip, #128\n" \ +" msr cpsr_c, lr\n" \ +" ldr lr, [%0]\n" \ +" adds lr, lr, %1\n" \ +" str lr, [%0]\n" \ +" msr cpsr_c, ip\n" \ +" moveq ip, %0\n" \ +" bleq " #wake \ + : \ + : "r" (ptr), "I" (1) \ + : "ip", "lr", "cc"); \ + }) + +#endif + +#endif diff --git a/arch/arm/include/asm/mach-types.h b/arch/arm/include/asm/mach-types.h new file mode 100644 index 00000000..948178cc --- /dev/null +++ b/arch/arm/include/asm/mach-types.h @@ -0,0 +1 @@ +#include diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h new file mode 100644 index 00000000..946f4d77 --- /dev/null +++ b/arch/arm/include/asm/mach/arch.h @@ -0,0 +1,73 @@ +/* + * arch/arm/include/asm/mach/arch.h + * + * Copyright (C) 2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ASSEMBLY__ + +struct tag; +struct meminfo; +struct sys_timer; + +struct machine_desc { + unsigned int nr; /* architecture number */ + const char *name; /* architecture name */ + unsigned long boot_params; /* tagged list */ + const char **dt_compat; /* array of device tree + * 'compatible' strings */ + + unsigned int nr_irqs; /* number of IRQs */ + + unsigned int video_start; /* start of video RAM */ + unsigned int video_end; /* end of video RAM */ + + unsigned int reserve_lp0 :1; /* never has lp0 */ + unsigned int reserve_lp1 :1; /* never has lp1 */ + unsigned int reserve_lp2 :1; /* never has lp2 */ + unsigned int soft_reboot :1; /* soft reboot */ + void (*fixup)(struct machine_desc *, + struct tag *, char **, + struct meminfo *); + void (*reserve)(void);/* reserve mem blocks */ + void (*map_io)(void);/* IO mapping function */ + void (*init_early)(void); + void (*init_irq)(void); + struct sys_timer *timer; /* system tick timer */ + void (*init_machine)(void); +#ifdef CONFIG_MULTI_IRQ_HANDLER + void (*handle_irq)(struct pt_regs *); +#endif +}; + +/* + * Current machine - only accessible during boot. + */ +extern struct machine_desc *machine_desc; + +/* + * Machine type table - also only accessible during boot + */ +extern struct machine_desc __arch_info_begin[], __arch_info_end[]; +#define for_each_machine_desc(p) \ + for (p = __arch_info_begin; p < __arch_info_end; p++) + +/* + * Set of macros to define architecture features. This is built into + * a table by the linker. + */ +#define MACHINE_START(_type,_name) \ +static const struct machine_desc __mach_desc_##_type \ + __used \ + __attribute__((__section__(".arch.info.init"))) = { \ + .nr = MACH_TYPE_##_type, \ + .name = _name, + +#define MACHINE_END \ +}; + +#endif diff --git a/arch/arm/include/asm/mach/dma.h b/arch/arm/include/asm/mach/dma.h new file mode 100644 index 00000000..9e614a18 --- /dev/null +++ b/arch/arm/include/asm/mach/dma.h @@ -0,0 +1,54 @@ +/* + * arch/arm/include/asm/mach/dma.h + * + * Copyright (C) 1998-2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This header file describes the interface between the generic DMA handler + * (dma.c) and the architecture-specific DMA backends (dma-*.c) + */ + +struct dma_struct; +typedef struct dma_struct dma_t; + +struct dma_ops { + int (*request)(unsigned int, dma_t *); /* optional */ + void (*free)(unsigned int, dma_t *); /* optional */ + void (*enable)(unsigned int, dma_t *); /* mandatory */ + void (*disable)(unsigned int, dma_t *); /* mandatory */ + int (*residue)(unsigned int, dma_t *); /* optional */ + int (*setspeed)(unsigned int, dma_t *, int); /* optional */ + const char *type; +}; + +struct dma_struct { + void *addr; /* single DMA address */ + unsigned long count; /* single DMA size */ + struct scatterlist buf; /* single DMA */ + int sgcount; /* number of DMA SG */ + struct scatterlist *sg; /* DMA Scatter-Gather List */ + + unsigned int active:1; /* Transfer active */ + unsigned int invalid:1; /* Address/Count changed */ + + unsigned int dma_mode; /* DMA mode */ + int speed; /* DMA speed */ + + unsigned int lock; /* Device is allocated */ + const char *device_id; /* Device name */ + + const struct dma_ops *d_ops; +}; + +/* + * isa_dma_add - add an ISA-style DMA channel + */ +extern int isa_dma_add(unsigned int, dma_t *dma); + +/* + * Add the ISA DMA controller. Always takes channels 0-7. + */ +extern void isa_init_dma(void); diff --git a/arch/arm/include/asm/mach/flash.h b/arch/arm/include/asm/mach/flash.h new file mode 100644 index 00000000..4ca69fe2 --- /dev/null +++ b/arch/arm/include/asm/mach/flash.h @@ -0,0 +1,39 @@ +/* + * arch/arm/include/asm/mach/flash.h + * + * Copyright (C) 2003 Russell King, 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 version 2 as + * published by the Free Software Foundation. + */ +#ifndef ASMARM_MACH_FLASH_H +#define ASMARM_MACH_FLASH_H + +struct mtd_partition; +struct mtd_info; + +/* + * map_name: the map probe function name + * name: flash device name (eg, as used with mtdparts=) + * width: width of mapped device + * init: method called at driver/device initialisation + * exit: method called at driver/device removal + * set_vpp: method called to enable or disable VPP + * mmcontrol: method called to enable or disable Sync. Burst Read in OneNAND + * parts: optional array of mtd_partitions for static partitioning + * nr_parts: number of mtd_partitions for static partitoning + */ +struct flash_platform_data { + const char *map_name; + const char *name; + unsigned int width; + int (*init)(void); + void (*exit)(void); + void (*set_vpp)(int on); + void (*mmcontrol)(struct mtd_info *mtd, int sync_read); + struct mtd_partition *parts; + unsigned int nr_parts; +}; + +#endif diff --git a/arch/arm/include/asm/mach/irda.h b/arch/arm/include/asm/mach/irda.h new file mode 100644 index 00000000..38f77b5e --- /dev/null +++ b/arch/arm/include/asm/mach/irda.h @@ -0,0 +1,20 @@ +/* + * arch/arm/include/asm/mach/irda.h + * + * Copyright (C) 2004 Russell King. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __ASM_ARM_MACH_IRDA_H +#define __ASM_ARM_MACH_IRDA_H + +struct irda_platform_data { + int (*startup)(struct device *); + void (*shutdown)(struct device *); + int (*set_power)(struct device *, unsigned int state); + void (*set_speed)(struct device *, unsigned int speed); +}; + +#endif diff --git a/arch/arm/include/asm/mach/irq.h b/arch/arm/include/asm/mach/irq.h new file mode 100644 index 00000000..febe495d --- /dev/null +++ b/arch/arm/include/asm/mach/irq.h @@ -0,0 +1,68 @@ +/* + * arch/arm/include/asm/mach/irq.h + * + * Copyright (C) 1995-2000 Russell King. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __ASM_ARM_MACH_IRQ_H +#define __ASM_ARM_MACH_IRQ_H + +#include + +struct seq_file; + +/* + * This is internal. Do not use it. + */ +extern void init_FIQ(void); +extern int show_fiq_list(struct seq_file *, int); + +#ifdef CONFIG_MULTI_IRQ_HANDLER +extern void (*handle_arch_irq)(struct pt_regs *); +#endif + +/* + * This is for easy migration, but should be changed in the source + */ +#define do_bad_IRQ(irq,desc) \ +do { \ + raw_spin_lock(&desc->lock); \ + handle_bad_irq(irq, desc); \ + raw_spin_unlock(&desc->lock); \ +} while(0) + +#ifndef __ASSEMBLY__ +/* + * Entry/exit functions for chained handlers where the primary IRQ chip + * may implement either fasteoi or level-trigger flow control. + */ +static inline void chained_irq_enter(struct irq_chip *chip, + struct irq_desc *desc) +{ + /* FastEOI controllers require no action on entry. */ + if (chip->irq_eoi) + return; + + if (chip->irq_mask_ack) { + chip->irq_mask_ack(&desc->irq_data); + } else { + chip->irq_mask(&desc->irq_data); + if (chip->irq_ack) + chip->irq_ack(&desc->irq_data); + } +} + +static inline void chained_irq_exit(struct irq_chip *chip, + struct irq_desc *desc) +{ + if (chip->irq_eoi) + chip->irq_eoi(&desc->irq_data); + else + chip->irq_unmask(&desc->irq_data); +} +#endif + +#endif diff --git a/arch/arm/include/asm/mach/map.h b/arch/arm/include/asm/mach/map.h new file mode 100644 index 00000000..d2fedb5a --- /dev/null +++ b/arch/arm/include/asm/mach/map.h @@ -0,0 +1,45 @@ +/* + * arch/arm/include/asm/map.h + * + * Copyright (C) 1999-2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Page table mapping constructs and function prototypes + */ +#include + +struct map_desc { + unsigned long virtual; + unsigned long pfn; + unsigned long length; + unsigned int type; +}; + +/* types 0-3 are defined in asm/io.h */ +#define MT_UNCACHED 4 +#define MT_CACHECLEAN 5 +#define MT_MINICLEAN 6 +#define MT_LOW_VECTORS 7 +#define MT_HIGH_VECTORS 8 +#define MT_MEMORY 9 +#define MT_ROM 10 +#define MT_MEMORY_NONCACHED 11 +#define MT_MEMORY_DTCM 12 +#define MT_MEMORY_ITCM 13 + +#ifdef CONFIG_MMU +extern void iotable_init(struct map_desc *, int); + +struct mem_type; +extern const struct mem_type *get_mem_type(unsigned int type); +/* + * external interface to remap single page with appropriate type + */ +extern int ioremap_page(unsigned long virt, unsigned long phys, + const struct mem_type *mtype); +#else +#define iotable_init(map,num) do { } while (0) +#endif diff --git a/arch/arm/include/asm/mach/mmc.h b/arch/arm/include/asm/mach/mmc.h new file mode 100644 index 00000000..bca864ac --- /dev/null +++ b/arch/arm/include/asm/mach/mmc.h @@ -0,0 +1,28 @@ +/* + * arch/arm/include/asm/mach/mmc.h + */ +#ifndef ASMARM_MACH_MMC_H +#define ASMARM_MACH_MMC_H + +#include +#include +#include + +struct embedded_sdio_data { + struct sdio_cis cis; + struct sdio_cccr cccr; + struct sdio_embedded_func *funcs; + int num_funcs; +}; + +struct mmc_platform_data { + unsigned int ocr_mask; /* available voltages */ + int built_in; /* built-in device flag */ + int card_present; /* card detect state */ + u32 (*translate_vdd)(struct device *, unsigned int); + unsigned int (*status)(struct device *); + struct embedded_sdio_data *embedded_sdio; + int (*register_status_notify)(void (*callback)(int card_present, void *dev_id), void *dev_id); +}; + +#endif diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h new file mode 100644 index 00000000..16330bd0 --- /dev/null +++ b/arch/arm/include/asm/mach/pci.h @@ -0,0 +1,84 @@ +/* + * arch/arm/include/asm/mach/pci.h + * + * Copyright (C) 2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ASM_MACH_PCI_H +#define __ASM_MACH_PCI_H + +struct pci_sys_data; +struct pci_bus; + +struct hw_pci { +#ifdef CONFIG_PCI_DOMAINS + int domain; +#endif + struct list_head buses; + int nr_controllers; + int (*setup)(int nr, struct pci_sys_data *); + struct pci_bus *(*scan)(int nr, struct pci_sys_data *); + void (*preinit)(void); + void (*postinit)(void); + u8 (*swizzle)(struct pci_dev *dev, u8 *pin); + int (*map_irq)(struct pci_dev *dev, u8 slot, u8 pin); +}; + +/* + * Per-controller structure + */ +struct pci_sys_data { +#ifdef CONFIG_PCI_DOMAINS + int domain; +#endif + struct list_head node; + int busnr; /* primary bus number */ + u64 mem_offset; /* bus->cpu memory mapping offset */ + unsigned long io_offset; /* bus->cpu IO mapping offset */ + struct pci_bus *bus; /* PCI bus */ + struct resource *resource[3]; /* Primary PCI bus resources */ + /* Bridge swizzling */ + u8 (*swizzle)(struct pci_dev *, u8 *); + /* IRQ mapping */ + int (*map_irq)(struct pci_dev *, u8, u8); + struct hw_pci *hw; + void *private_data; /* platform controller private data */ +}; + +/* + * This is the standard PCI-PCI bridge swizzling algorithm. + */ +#define pci_std_swizzle pci_common_swizzle + +/* + * Call this with your hw_pci struct to initialise the PCI system. + */ +void pci_common_init(struct hw_pci *); + +/* + * PCI controllers + */ +extern int iop3xx_pci_setup(int nr, struct pci_sys_data *); +extern struct pci_bus *iop3xx_pci_scan_bus(int nr, struct pci_sys_data *); +extern void iop3xx_pci_preinit(void); +extern void iop3xx_pci_preinit_cond(void); + +extern int dc21285_setup(int nr, struct pci_sys_data *); +extern struct pci_bus *dc21285_scan_bus(int nr, struct pci_sys_data *); +extern void dc21285_preinit(void); +extern void dc21285_postinit(void); + +extern int via82c505_setup(int nr, struct pci_sys_data *); +extern struct pci_bus *via82c505_scan_bus(int nr, struct pci_sys_data *); +extern void via82c505_init(void *sysdata); + +extern int pci_v3_setup(int nr, struct pci_sys_data *); +extern struct pci_bus *pci_v3_scan_bus(int nr, struct pci_sys_data *); +extern void pci_v3_preinit(void); +extern void pci_v3_postinit(void); + +#endif /* __ASM_MACH_PCI_H */ diff --git a/arch/arm/include/asm/mach/serial_at91.h b/arch/arm/include/asm/mach/serial_at91.h new file mode 100644 index 00000000..ea6d0639 --- /dev/null +++ b/arch/arm/include/asm/mach/serial_at91.h @@ -0,0 +1,33 @@ +/* + * arch/arm/include/asm/mach/serial_at91.h + * + * Based on serial_sa1100.h by Nicolas Pitre + * + * Copyright (C) 2002 ATMEL Rousset + * + * Low level machine dependent UART functions. + */ + +struct uart_port; + +/* + * This is a temporary structure for registering these + * functions; it is intended to be discarded after boot. + */ +struct atmel_port_fns { + void (*set_mctrl)(struct uart_port *, u_int); + u_int (*get_mctrl)(struct uart_port *); + void (*enable_ms)(struct uart_port *); + void (*pm)(struct uart_port *, u_int, u_int); + int (*set_wake)(struct uart_port *, u_int); + int (*open)(struct uart_port *); + void (*close)(struct uart_port *); +}; + +#if defined(CONFIG_SERIAL_ATMEL) +void atmel_register_uart_fns(struct atmel_port_fns *fns); +#else +#define atmel_register_uart_fns(fns) do { } while (0) +#endif + + diff --git a/arch/arm/include/asm/mach/serial_sa1100.h b/arch/arm/include/asm/mach/serial_sa1100.h new file mode 100644 index 00000000..d09064bf --- /dev/null +++ b/arch/arm/include/asm/mach/serial_sa1100.h @@ -0,0 +1,31 @@ +/* + * arch/arm/include/asm/mach/serial_sa1100.h + * + * Author: Nicolas Pitre + * + * Moved and changed lots, Russell King + * + * Low level machine dependent UART functions. + */ + +struct uart_port; +struct uart_info; + +/* + * This is a temporary structure for registering these + * functions; it is intended to be discarded after boot. + */ +struct sa1100_port_fns { + void (*set_mctrl)(struct uart_port *, u_int); + u_int (*get_mctrl)(struct uart_port *); + void (*pm)(struct uart_port *, u_int, u_int); + int (*set_wake)(struct uart_port *, u_int); +}; + +#ifdef CONFIG_SERIAL_SA1100 +void sa1100_register_uart_fns(struct sa1100_port_fns *fns); +void sa1100_register_uart(int idx, int port); +#else +#define sa1100_register_uart_fns(fns) do { } while (0) +#define sa1100_register_uart(idx,port) do { } while (0) +#endif diff --git a/arch/arm/include/asm/mach/sharpsl_param.h b/arch/arm/include/asm/mach/sharpsl_param.h new file mode 100644 index 00000000..7a24ecf0 --- /dev/null +++ b/arch/arm/include/asm/mach/sharpsl_param.h @@ -0,0 +1,37 @@ +/* + * Hardware parameter area specific to Sharp SL series devices + * + * Copyright (c) 2005 Richard Purdie + * + * Based on Sharp's 2.4 kernel patches + * + * 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. + * + */ + +struct sharpsl_param_info { + unsigned int comadj_keyword; + unsigned int comadj; + + unsigned int uuid_keyword; + unsigned char uuid[16]; + + unsigned int touch_keyword; + unsigned int touch_xp; + unsigned int touch_yp; + unsigned int touch_xd; + unsigned int touch_yd; + + unsigned int adadj_keyword; + unsigned int adadj; + + unsigned int phad_keyword; + unsigned int phadadj; +} __attribute__((packed)); + + +extern struct sharpsl_param_info sharpsl_param; +extern void sharpsl_save_param(void); + diff --git a/arch/arm/include/asm/mach/time.h b/arch/arm/include/asm/mach/time.h new file mode 100644 index 00000000..d5adaae5 --- /dev/null +++ b/arch/arm/include/asm/mach/time.h @@ -0,0 +1,47 @@ +/* + * arch/arm/include/asm/mach/time.h + * + * Copyright (C) 2004 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 version 2 as + * published by the Free Software Foundation. + */ +#ifndef __ASM_ARM_MACH_TIME_H +#define __ASM_ARM_MACH_TIME_H + +#include + +/* + * This is our kernel timer structure. + * + * - init + * Initialise the kernels jiffy timer source, claim interrupt + * using setup_irq. This is called early on during initialisation + * while interrupts are still disabled on the local CPU. + * - suspend + * Suspend the kernel jiffy timer source, if necessary. This + * is called with interrupts disabled, after all normal devices + * have been suspended. If no action is required, set this to + * NULL. + * - resume + * Resume the kernel jiffy timer source, if necessary. This + * is called with interrupts disabled before any normal devices + * are resumed. If no action is required, set this to NULL. + * - offset + * Return the timer offset in microseconds since the last timer + * interrupt. Note: this must take account of any unprocessed + * timer interrupt which may be pending. + */ +struct sys_timer { + void (*init)(void); + void (*suspend)(void); + void (*resume)(void); +#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET + unsigned long (*offset)(void); +#endif +}; + +extern void timer_tick(void); + +#endif diff --git a/arch/arm/include/asm/mach/udc_pxa2xx.h b/arch/arm/include/asm/mach/udc_pxa2xx.h new file mode 100644 index 00000000..ea297ac7 --- /dev/null +++ b/arch/arm/include/asm/mach/udc_pxa2xx.h @@ -0,0 +1,26 @@ +/* + * arch/arm/include/asm/mach/udc_pxa2xx.h + * + * This supports machine-specific differences in how the PXA2xx + * USB Device Controller (UDC) is wired. + * + * It is set in linux/arch/arm/mach-pxa/.c or in + * linux/arch/mach-ixp4xx/.c and used in + * the probe routine of linux/drivers/usb/gadget/pxa2xx_udc.c + */ + +struct pxa2xx_udc_mach_info { + int (*udc_is_connected)(void); /* do we see host? */ + void (*udc_command)(int cmd); +#define PXA2XX_UDC_CMD_CONNECT 0 /* let host see us */ +#define PXA2XX_UDC_CMD_DISCONNECT 1 /* so host won't see us */ + + /* Boards following the design guidelines in the developer's manual, + * with on-chip GPIOs not Lubbock's weird hardware, can have a sane + * VBUS IRQ and omit the methods above. Store the GPIO number + * here. Note that sometimes the signals go through inverters... + */ + bool gpio_pullup_inverted; + int gpio_pullup; /* high == pullup activated */ +}; + diff --git a/arch/arm/include/asm/mc146818rtc.h b/arch/arm/include/asm/mc146818rtc.h new file mode 100644 index 00000000..6b884d2b --- /dev/null +++ b/arch/arm/include/asm/mc146818rtc.h @@ -0,0 +1,28 @@ +/* + * Machine dependent access functions for RTC registers. + */ +#ifndef _ASM_MC146818RTC_H +#define _ASM_MC146818RTC_H + +#include +#include + +#ifndef RTC_PORT +#define RTC_PORT(x) (0x70 + (x)) +#define RTC_ALWAYS_BCD 1 /* RTC operates in binary mode */ +#endif + +/* + * 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) ({ \ +outb_p((addr),RTC_PORT(0)); \ +inb_p(RTC_PORT(1)); \ +}) +#define CMOS_WRITE(val, addr) ({ \ +outb_p((addr),RTC_PORT(0)); \ +outb_p((val),RTC_PORT(1)); \ +}) + +#endif /* _ASM_MC146818RTC_H */ diff --git a/arch/arm/include/asm/memblock.h b/arch/arm/include/asm/memblock.h new file mode 100644 index 00000000..b8da2e41 --- /dev/null +++ b/arch/arm/include/asm/memblock.h @@ -0,0 +1,9 @@ +#ifndef _ASM_ARM_MEMBLOCK_H +#define _ASM_ARM_MEMBLOCK_H + +struct meminfo; +struct machine_desc; + +extern void arm_memblock_init(struct meminfo *, struct machine_desc *); + +#endif diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h new file mode 100644 index 00000000..af44a8fb --- /dev/null +++ b/arch/arm/include/asm/memory.h @@ -0,0 +1,306 @@ +/* + * arch/arm/include/asm/memory.h + * + * Copyright (C) 2000-2002 Russell King + * modification for nommu, Hyok S. Choi, 2004 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Note: this file should not be included by non-asm/.h files + */ +#ifndef __ASM_ARM_MEMORY_H +#define __ASM_ARM_MEMORY_H + +#include +#include +#include +#include +#include + +/* + * Allow for constants defined here to be used from assembly code + * by prepending the UL suffix only with actual C code compilation. + */ +#define UL(x) _AC(x, UL) + +#ifdef CONFIG_MMU + +/* + * PAGE_OFFSET - the virtual address of the start of the kernel image + * TASK_SIZE - the maximum size of a user space task. + * TASK_UNMAPPED_BASE - the lower boundary of the mmap VM area + */ +#define PAGE_OFFSET UL(CONFIG_PAGE_OFFSET) +#define TASK_SIZE (UL(CONFIG_PAGE_OFFSET) - UL(0x01000000)) +#define TASK_UNMAPPED_BASE (UL(CONFIG_PAGE_OFFSET) / 3) + +/* + * The maximum size of a 26-bit user space task. + */ +#define TASK_SIZE_26 UL(0x04000000) + +/* + * The module space lives between the addresses given by TASK_SIZE + * and PAGE_OFFSET - it must be within 32MB of the kernel text. + */ +#ifndef CONFIG_THUMB2_KERNEL +#define MODULES_VADDR (PAGE_OFFSET - 16*1024*1024) +#else +/* smaller range for Thumb-2 symbols relocation (2^24)*/ +#define MODULES_VADDR (PAGE_OFFSET - 8*1024*1024) +#endif + +#if TASK_SIZE > MODULES_VADDR +#error Top of user space clashes with start of module space +#endif + +/* + * The highmem pkmap virtual space shares the end of the module area. + */ +#ifdef CONFIG_HIGHMEM +#define MODULES_END (PAGE_OFFSET - PMD_SIZE) +#else +#define MODULES_END (PAGE_OFFSET) +#endif + +/* + * The XIP kernel gets mapped at the bottom of the module vm area. + * Since we use sections to map it, this macro replaces the physical address + * with its virtual address while keeping offset from the base section. + */ +#define XIP_VIRT_ADDR(physaddr) (MODULES_VADDR + ((physaddr) & 0x000fffff)) + +/* + * Allow 16MB-aligned ioremap pages + */ +#define IOREMAP_MAX_ORDER 24 + +/* + * Size of DMA-consistent memory region. Must be multiple of 2M, + * between 2MB and 14MB inclusive. + */ +#ifndef CONSISTENT_DMA_SIZE +#define CONSISTENT_DMA_SIZE SZ_2M +#endif + +#define CONSISTENT_END (0xffe00000UL) +#define CONSISTENT_BASE (CONSISTENT_END - CONSISTENT_DMA_SIZE) + +#else /* CONFIG_MMU */ + +/* + * The limitation of user task size can grow up to the end of free ram region. + * It is difficult to define and perhaps will never meet the original meaning + * of this define that was meant to. + * Fortunately, there is no reference for this in noMMU mode, for now. + */ +#ifndef TASK_SIZE +#define TASK_SIZE (CONFIG_DRAM_SIZE) +#endif + +#ifndef TASK_UNMAPPED_BASE +#define TASK_UNMAPPED_BASE UL(0x00000000) +#endif + +#ifndef PHYS_OFFSET +#define PHYS_OFFSET UL(CONFIG_DRAM_BASE) +#endif + +#ifndef END_MEM +#define END_MEM (UL(CONFIG_DRAM_BASE) + CONFIG_DRAM_SIZE) +#endif + +#ifndef PAGE_OFFSET +#define PAGE_OFFSET (PHYS_OFFSET) +#endif + +/* + * The module can be at any place in ram in nommu mode. + */ +#define MODULES_END (END_MEM) +#define MODULES_VADDR (PHYS_OFFSET) + +#endif /* !CONFIG_MMU */ + +/* + * We fix the TCM memories max 32 KiB ITCM resp DTCM at these + * locations + */ +#ifdef CONFIG_HAVE_TCM +#define ITCM_OFFSET UL(0xfffe0000) +#define DTCM_OFFSET UL(0xfffe8000) +#endif + +/* + * Convert a physical address to a Page Frame Number and back + */ +#define __phys_to_pfn(paddr) ((unsigned long)((paddr) >> PAGE_SHIFT)) +#define __pfn_to_phys(pfn) ((phys_addr_t)(pfn) << PAGE_SHIFT) + +/* + * Convert a page to/from a physical address + */ +#define page_to_phys(page) (__pfn_to_phys(page_to_pfn(page))) +#define phys_to_page(phys) (pfn_to_page(__phys_to_pfn(phys))) + +#ifndef __ASSEMBLY__ + +/* + * Physical vs virtual RAM address space conversion. These are + * private definitions which should NOT be used outside memory.h + * files. Use virt_to_phys/phys_to_virt/__pa/__va instead. + */ +#ifndef __virt_to_phys +#ifdef CONFIG_ARM_PATCH_PHYS_VIRT + +/* + * Constants used to force the right instruction encodings and shifts + * so that all we need to do is modify the 8-bit constant field. + */ +#define __PV_BITS_31_24 0x81000000 +#define __PV_BITS_23_16 0x00810000 + +extern unsigned long __pv_phys_offset; +#define PHYS_OFFSET __pv_phys_offset + +#define __pv_stub(from,to,instr,type) \ + __asm__("@ __pv_stub\n" \ + "1: " instr " %0, %1, %2\n" \ + " .pushsection .pv_table,\"a\"\n" \ + " .long 1b\n" \ + " .popsection\n" \ + : "=r" (to) \ + : "r" (from), "I" (type)) + +static inline unsigned long __virt_to_phys(unsigned long x) +{ + unsigned long t; + __pv_stub(x, t, "add", __PV_BITS_31_24); +#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT + __pv_stub(t, t, "add", __PV_BITS_23_16); +#endif + return t; +} + +static inline unsigned long __phys_to_virt(unsigned long x) +{ + unsigned long t; + __pv_stub(x, t, "sub", __PV_BITS_31_24); +#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT + __pv_stub(t, t, "sub", __PV_BITS_23_16); +#endif + return t; +} +#else +#define __virt_to_phys(x) ((x) - PAGE_OFFSET + PHYS_OFFSET) +#define __phys_to_virt(x) ((x) - PHYS_OFFSET + PAGE_OFFSET) +#endif +#endif + +#ifndef PHYS_OFFSET +#define PHYS_OFFSET PLAT_PHYS_OFFSET +#endif + +/* + * The DMA mask corresponding to the maximum bus address allocatable + * using GFP_DMA. The default here places no restriction on DMA + * allocations. This must be the smallest DMA mask in the system, + * so a successful GFP_DMA allocation will always satisfy this. + */ +#ifndef ARM_DMA_ZONE_SIZE +#define ISA_DMA_THRESHOLD (0xffffffffULL) +#else +#define ISA_DMA_THRESHOLD (PHYS_OFFSET + ARM_DMA_ZONE_SIZE - 1) +#endif + +/* + * PFNs are used to describe any physical page; this means + * PFN 0 == physical address 0. + * + * This is the PFN of the first RAM page in the kernel + * direct-mapped view. We assume this is the first page + * of RAM in the mem_map as well. + */ +#define PHYS_PFN_OFFSET (PHYS_OFFSET >> PAGE_SHIFT) + +/* + * These are *only* valid on the kernel direct mapped RAM memory. + * Note: Drivers should NOT use these. They are the wrong + * translation for translating DMA addresses. Use the driver + * DMA support - see dma-mapping.h. + */ +static inline phys_addr_t virt_to_phys(const volatile void *x) +{ + return __virt_to_phys((unsigned long)(x)); +} + +static inline void *phys_to_virt(phys_addr_t x) +{ + return (void *)(__phys_to_virt((unsigned long)(x))); +} + +/* + * Drivers should NOT use these either. + */ +#define __pa(x) __virt_to_phys((unsigned long)(x)) +#define __va(x) ((void *)__phys_to_virt((unsigned long)(x))) +#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) + +/* + * Virtual <-> DMA view memory address translations + * Again, these are *only* valid on the kernel direct mapped RAM + * memory. Use of these is *deprecated* (and that doesn't mean + * use the __ prefixed forms instead.) See dma-mapping.h. + */ +#ifndef __virt_to_bus +#define __virt_to_bus __virt_to_phys +#define __bus_to_virt __phys_to_virt +#define __pfn_to_bus(x) __pfn_to_phys(x) +#define __bus_to_pfn(x) __phys_to_pfn(x) +#endif + +static inline __deprecated unsigned long virt_to_bus(void *x) +{ + return __virt_to_bus((unsigned long)x); +} + +static inline __deprecated void *bus_to_virt(unsigned long x) +{ + return (void *)__bus_to_virt(x); +} + +/* + * Conversion between a struct page and a physical address. + * + * Note: when converting an unknown physical address to a + * struct page, the resulting pointer must be validated + * using VALID_PAGE(). It must return an invalid struct page + * for any physical address not corresponding to a system + * RAM address. + * + * page_to_pfn(page) convert a struct page * to a PFN number + * pfn_to_page(pfn) convert a _valid_ PFN number to struct page * + * + * virt_to_page(k) convert a _valid_ virtual address to struct page * + * virt_addr_valid(k) indicates whether a virtual address is valid + */ +#define ARCH_PFN_OFFSET PHYS_PFN_OFFSET + +#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) +#define virt_addr_valid(kaddr) ((unsigned long)(kaddr) >= PAGE_OFFSET && (unsigned long)(kaddr) < (unsigned long)high_memory) + +/* + * Optional coherency support. Currently used only by selected + * Intel XSC3-based systems. + */ +#ifndef arch_is_coherent +#define arch_is_coherent() 0 +#endif + +#endif + +#include + +#endif diff --git a/arch/arm/include/asm/mman.h b/arch/arm/include/asm/mman.h new file mode 100644 index 00000000..41f99c57 --- /dev/null +++ b/arch/arm/include/asm/mman.h @@ -0,0 +1,4 @@ +#include + +#define arch_mmap_check(addr, len, flags) \ + (((flags) & MAP_FIXED && (addr) < FIRST_USER_ADDRESS) ? -EINVAL : 0) diff --git a/arch/arm/include/asm/mmu.h b/arch/arm/include/asm/mmu.h new file mode 100644 index 00000000..b4ffe9d5 --- /dev/null +++ b/arch/arm/include/asm/mmu.h @@ -0,0 +1,37 @@ +#ifndef __ARM_MMU_H +#define __ARM_MMU_H + +#ifdef CONFIG_MMU + +typedef struct { +#ifdef CONFIG_CPU_HAS_ASID + unsigned int id; + spinlock_t id_lock; +#endif + unsigned int kvm_seq; +} mm_context_t; + +#ifdef CONFIG_CPU_HAS_ASID +#define ASID(mm) ((mm)->context.id & 255) + +/* init_mm.context.id_lock should be initialized. */ +#define INIT_MM_CONTEXT(name) \ + .context.id_lock = __SPIN_LOCK_UNLOCKED(name.context.id_lock), +#else +#define ASID(mm) (0) +#endif + +#else + +/* + * From nommu.h: + * Copyright (C) 2002, David McCullough + * modified for 2.6 by Hyok S. Choi + */ +typedef struct { + unsigned long end_brk; +} mm_context_t; + +#endif + +#endif diff --git a/arch/arm/include/asm/mmu_context.h b/arch/arm/include/asm/mmu_context.h new file mode 100644 index 00000000..71605d9f --- /dev/null +++ b/arch/arm/include/asm/mmu_context.h @@ -0,0 +1,164 @@ +/* + * arch/arm/include/asm/mmu_context.h + * + * Copyright (C) 1996 Russell King. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Changelog: + * 27-06-1996 RMK Created + */ +#ifndef __ASM_ARM_MMU_CONTEXT_H +#define __ASM_ARM_MMU_CONTEXT_H + +#include +#include +#include +#include +#include + +void __check_kvm_seq(struct mm_struct *mm); + +#ifdef CONFIG_CPU_HAS_ASID + +/* + * On ARMv6, we have the following structure in the Context ID: + * + * 31 7 0 + * +-------------------------+-----------+ + * | process ID | ASID | + * +-------------------------+-----------+ + * | context ID | + * +-------------------------------------+ + * + * The ASID is used to tag entries in the CPU caches and TLBs. + * The context ID is used by debuggers and trace logic, and + * should be unique within all running processes. + */ +#define ASID_BITS 8 +#define ASID_MASK ((~0) << ASID_BITS) +#define ASID_FIRST_VERSION (1 << ASID_BITS) + +extern unsigned int cpu_last_asid; +#ifdef CONFIG_SMP +DECLARE_PER_CPU(struct mm_struct *, current_mm); +#endif + +void __init_new_context(struct task_struct *tsk, struct mm_struct *mm); +void __new_context(struct mm_struct *mm); + +static inline void check_context(struct mm_struct *mm) +{ + /* + * This code is executed with interrupts enabled. Therefore, + * mm->context.id cannot be updated to the latest ASID version + * on a different CPU (and condition below not triggered) + * without first getting an IPI to reset the context. The + * alternative is to take a read_lock on mm->context.id_lock + * (after changing its type to rwlock_t). + */ + if (unlikely((mm->context.id ^ cpu_last_asid) >> ASID_BITS)) + __new_context(mm); + + if (unlikely(mm->context.kvm_seq != init_mm.context.kvm_seq)) + __check_kvm_seq(mm); +} + +#define init_new_context(tsk,mm) (__init_new_context(tsk,mm),0) + +#else + +static inline void check_context(struct mm_struct *mm) +{ +#ifdef CONFIG_MMU + if (unlikely(mm->context.kvm_seq != init_mm.context.kvm_seq)) + __check_kvm_seq(mm); +#endif +} + +#define init_new_context(tsk,mm) 0 + +#endif + +#define destroy_context(mm) do { } while(0) + +/* + * This is called when "tsk" is about to enter lazy TLB mode. + * + * mm: describes the currently active mm context + * tsk: task which is entering lazy tlb + * cpu: cpu number which is entering lazy tlb + * + * tsk->mm will be NULL + */ +static inline void +enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) +{ +} + +/* + * This is the actual mm switch as far as the scheduler + * is concerned. No registers are touched. We avoid + * calling the CPU specific function when the mm hasn't + * actually changed. + */ +static inline void +switch_mm(struct mm_struct *prev, struct mm_struct *next, + struct task_struct *tsk) +{ +#ifdef CONFIG_MMU + unsigned int cpu = smp_processor_id(); + +#ifdef CONFIG_SMP + /* check for possible thread migration */ + if (!cpumask_empty(mm_cpumask(next)) && + !cpumask_test_cpu(cpu, mm_cpumask(next))) + __flush_icache_all(); +#endif + if (!cpumask_test_and_set_cpu(cpu, mm_cpumask(next)) || prev != next) { +#ifdef CONFIG_SMP + struct mm_struct **crt_mm = &per_cpu(current_mm, cpu); + *crt_mm = next; +#endif + check_context(next); + cpu_switch_mm(next->pgd, next); + if (cache_is_vivt()) + cpumask_clear_cpu(cpu, mm_cpumask(prev)); + } +#endif +} + +#define deactivate_mm(tsk,mm) do { } while (0) +#define activate_mm(prev,next) switch_mm(prev, next, NULL) + +/* + * We are inserting a "fake" vma for the user-accessible vector page so + * gdb and friends can get to it through ptrace and /proc//mem. + * But we also want to remove it before the generic code gets to see it + * during process exit or the unmapping of it would cause total havoc. + * (the macro is used as remove_vma() is static to mm/mmap.c) + */ +#define arch_exit_mmap(mm) \ +do { \ + struct vm_area_struct *high_vma = find_vma(mm, 0xffff0000); \ + if (high_vma) { \ + BUG_ON(high_vma->vm_next); /* it should be last */ \ + if (high_vma->vm_prev) \ + high_vma->vm_prev->vm_next = NULL; \ + else \ + mm->mmap = NULL; \ + rb_erase(&high_vma->vm_rb, &mm->mm_rb); \ + mm->mmap_cache = NULL; \ + mm->map_count--; \ + remove_vma(high_vma); \ + } \ +} while (0) + +static inline void arch_dup_mmap(struct mm_struct *oldmm, + struct mm_struct *mm) +{ +} + +#endif diff --git a/arch/arm/include/asm/module.h b/arch/arm/include/asm/module.h new file mode 100644 index 00000000..543b4491 --- /dev/null +++ b/arch/arm/include/asm/module.h @@ -0,0 +1,55 @@ +#ifndef _ASM_ARM_MODULE_H +#define _ASM_ARM_MODULE_H + +#define Elf_Shdr Elf32_Shdr +#define Elf_Sym Elf32_Sym +#define Elf_Ehdr Elf32_Ehdr + +struct unwind_table; + +#ifdef CONFIG_ARM_UNWIND +enum { + ARM_SEC_INIT, + ARM_SEC_DEVINIT, + ARM_SEC_CORE, + ARM_SEC_EXIT, + ARM_SEC_DEVEXIT, + ARM_SEC_MAX, +}; +#endif + +struct mod_arch_specific { +#ifdef CONFIG_ARM_UNWIND + struct unwind_table *unwind[ARM_SEC_MAX]; +#endif +}; + +/* + * Add the ARM architecture version to the version magic string + */ +#define MODULE_ARCH_VERMAGIC_ARMVSN "ARMv" __stringify(__LINUX_ARM_ARCH__) " " + +/* Add __virt_to_phys patching state as well */ +#ifdef CONFIG_ARM_PATCH_PHYS_VIRT +#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT +#define MODULE_ARCH_VERMAGIC_P2V "p2v16 " +#else +#define MODULE_ARCH_VERMAGIC_P2V "p2v8 " +#endif +#else +#define MODULE_ARCH_VERMAGIC_P2V "" +#endif + +/* Add instruction set architecture tag to distinguish ARM/Thumb kernels */ +#ifdef CONFIG_THUMB2_KERNEL +#define MODULE_ARCH_VERMAGIC_ARMTHUMB "thumb2 " +#else +#define MODULE_ARCH_VERMAGIC_ARMTHUMB "" +#endif + +#define MODULE_ARCH_VERMAGIC \ + MODULE_ARCH_VERMAGIC_ARMVSN \ + MODULE_ARCH_VERMAGIC_ARMTHUMB \ + MODULE_ARCH_VERMAGIC_P2V + +#endif /* _ASM_ARM_MODULE_H */ diff --git a/arch/arm/include/asm/msgbuf.h b/arch/arm/include/asm/msgbuf.h new file mode 100644 index 00000000..33b35b94 --- /dev/null +++ b/arch/arm/include/asm/msgbuf.h @@ -0,0 +1,31 @@ +#ifndef _ASMARM_MSGBUF_H +#define _ASMARM_MSGBUF_H + +/* + * The msqid64_ds structure for arm architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 64-bit time_t to solve y2038 problem + * - 2 miscellaneous 32-bit values + */ + +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 __unused4; + unsigned long __unused5; +}; + +#endif /* _ASMARM_MSGBUF_H */ diff --git a/arch/arm/include/asm/mtd-xip.h b/arch/arm/include/asm/mtd-xip.h new file mode 100644 index 00000000..d79d66d2 --- /dev/null +++ b/arch/arm/include/asm/mtd-xip.h @@ -0,0 +1,23 @@ +/* + * MTD primitives for XIP support. Architecture specific functions + * + * Do not include this file directly. It's included from linux/mtd/xip.h + * + * Author: Nicolas Pitre + * Created: Nov 2, 2004 + * Copyright: (C) 2004 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 version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ARM_MTD_XIP_H__ +#define __ARM_MTD_XIP_H__ + +#include + +/* fill instruction prefetch */ +#define xip_iprefetch() do { asm volatile (".rep 8; nop; .endr"); } while (0) + +#endif /* __ARM_MTD_XIP_H__ */ diff --git a/arch/arm/include/asm/mutex.h b/arch/arm/include/asm/mutex.h new file mode 100644 index 00000000..93226cf2 --- /dev/null +++ b/arch/arm/include/asm/mutex.h @@ -0,0 +1,127 @@ +/* + * arch/arm/include/asm/mutex.h + * + * ARM optimized mutex locking primitives + * + * Please look into asm-generic/mutex-xchg.h for a formal definition. + */ +#ifndef _ASM_MUTEX_H +#define _ASM_MUTEX_H + +#if __LINUX_ARM_ARCH__ < 6 +/* On pre-ARMv6 hardware the swp based implementation is the most efficient. */ +# include +#else + +/* + * Attempting to lock a mutex on ARMv6+ can be done with a bastardized + * atomic decrement (it is not a reliable atomic decrement but it satisfies + * the defined semantics for our purpose, while being smaller and faster + * than a real atomic decrement or atomic swap. The idea is to attempt + * decrementing the lock value only once. If once decremented it isn't zero, + * or if its store-back fails due to a dispute on the exclusive store, we + * simply bail out immediately through the slow path where the lock will be + * reattempted until it succeeds. + */ +static inline void +__mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *)) +{ + int __ex_flag, __res; + + __asm__ ( + + "ldrex %0, [%2] \n\t" + "sub %0, %0, #1 \n\t" + "strex %1, %0, [%2] " + + : "=&r" (__res), "=&r" (__ex_flag) + : "r" (&(count)->counter) + : "cc","memory" ); + + __res |= __ex_flag; + if (unlikely(__res != 0)) + fail_fn(count); +} + +static inline int +__mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *)) +{ + int __ex_flag, __res; + + __asm__ ( + + "ldrex %0, [%2] \n\t" + "sub %0, %0, #1 \n\t" + "strex %1, %0, [%2] " + + : "=&r" (__res), "=&r" (__ex_flag) + : "r" (&(count)->counter) + : "cc","memory" ); + + __res |= __ex_flag; + if (unlikely(__res != 0)) + __res = fail_fn(count); + return __res; +} + +/* + * Same trick is used for the unlock fast path. However the original value, + * rather than the result, is used to test for success in order to have + * better generated assembly. + */ +static inline void +__mutex_fastpath_unlock(atomic_t *count, void (*fail_fn)(atomic_t *)) +{ + int __ex_flag, __res, __orig; + + __asm__ ( + + "ldrex %0, [%3] \n\t" + "add %1, %0, #1 \n\t" + "strex %2, %1, [%3] " + + : "=&r" (__orig), "=&r" (__res), "=&r" (__ex_flag) + : "r" (&(count)->counter) + : "cc","memory" ); + + __orig |= __ex_flag; + if (unlikely(__orig != 0)) + fail_fn(count); +} + +/* + * If the unlock was done on a contended lock, or if the unlock simply fails + * then the mutex remains locked. + */ +#define __mutex_slowpath_needs_to_unlock() 1 + +/* + * For __mutex_fastpath_trylock we use another construct which could be + * described as a "single value cmpxchg". + * + * This provides the needed trylock semantics like cmpxchg would, but it is + * lighter and less generic than a true cmpxchg implementation. + */ +static inline int +__mutex_fastpath_trylock(atomic_t *count, int (*fail_fn)(atomic_t *)) +{ + int __ex_flag, __res, __orig; + + __asm__ ( + + "1: ldrex %0, [%3] \n\t" + "subs %1, %0, #1 \n\t" + "strexeq %2, %1, [%3] \n\t" + "movlt %0, #0 \n\t" + "cmpeq %2, #0 \n\t" + "bgt 1b " + + : "=&r" (__orig), "=&r" (__res), "=&r" (__ex_flag) + : "r" (&count->counter) + : "cc", "memory" ); + + return __orig; +} + +#endif +#endif diff --git a/arch/arm/include/asm/nwflash.h b/arch/arm/include/asm/nwflash.h new file mode 100644 index 00000000..04e5a557 --- /dev/null +++ b/arch/arm/include/asm/nwflash.h @@ -0,0 +1,9 @@ +#ifndef _FLASH_H +#define _FLASH_H + +#define FLASH_MINOR 160 /* MAJOR is 10 - miscdevice */ +#define CMD_WRITE_DISABLE 0 +#define CMD_WRITE_ENABLE 0x28 +#define CMD_WRITE_BASE64K_ENABLE 0x47 + +#endif /* _FLASH_H */ diff --git a/arch/arm/include/asm/outercache.h b/arch/arm/include/asm/outercache.h new file mode 100644 index 00000000..d8387437 --- /dev/null +++ b/arch/arm/include/asm/outercache.h @@ -0,0 +1,102 @@ +/* + * arch/arm/include/asm/outercache.h + * + * Copyright (C) 2010 ARM Ltd. + * Written by Catalin Marinas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This 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_OUTERCACHE_H +#define __ASM_OUTERCACHE_H + +#include + +struct outer_cache_fns { + void (*inv_range)(unsigned long, unsigned long); + void (*clean_range)(unsigned long, unsigned long); + void (*flush_range)(unsigned long, unsigned long); + void (*flush_all)(void); + void (*inv_all)(void); + void (*disable)(void); +#ifdef CONFIG_OUTER_CACHE_SYNC + void (*sync)(void); +#endif + void (*set_debug)(unsigned long); +}; + +#ifdef CONFIG_OUTER_CACHE + +extern struct outer_cache_fns outer_cache; + +static inline void outer_inv_range(phys_addr_t start, phys_addr_t end) +{ + if (outer_cache.inv_range) + outer_cache.inv_range(start, end); +} +static inline void outer_clean_range(phys_addr_t start, phys_addr_t end) +{ + if (outer_cache.clean_range) + outer_cache.clean_range(start, end); +} +static inline void outer_flush_range(phys_addr_t start, phys_addr_t end) +{ + if (outer_cache.flush_range) + outer_cache.flush_range(start, end); +} + +static inline void outer_flush_all(void) +{ + if (outer_cache.flush_all) + outer_cache.flush_all(); +} + +static inline void outer_inv_all(void) +{ + if (outer_cache.inv_all) + outer_cache.inv_all(); +} + +static inline void outer_disable(void) +{ + if (outer_cache.disable) + outer_cache.disable(); +} + +#else + +static inline void outer_inv_range(phys_addr_t start, phys_addr_t end) +{ } +static inline void outer_clean_range(phys_addr_t start, phys_addr_t end) +{ } +static inline void outer_flush_range(phys_addr_t start, phys_addr_t end) +{ } +static inline void outer_flush_all(void) { } +static inline void outer_inv_all(void) { } +static inline void outer_disable(void) { } + +#endif + +#ifdef CONFIG_OUTER_CACHE_SYNC +static inline void outer_sync(void) +{ + if (outer_cache.sync) + outer_cache.sync(); +} +#else +static inline void outer_sync(void) +{ } +#endif + +#endif /* __ASM_OUTERCACHE_H */ diff --git a/arch/arm/include/asm/page-nommu.h b/arch/arm/include/asm/page-nommu.h new file mode 100644 index 00000000..d1b162a1 --- /dev/null +++ b/arch/arm/include/asm/page-nommu.h @@ -0,0 +1,46 @@ +/* + * arch/arm/include/asm/page-nommu.h + * + * Copyright (C) 2004 Hyok S. Choi + * + * 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. + */ + +#ifndef _ASMARM_PAGE_NOMMU_H +#define _ASMARM_PAGE_NOMMU_H + +#if !defined(CONFIG_SMALL_TASKS) && PAGE_SHIFT < 13 +#define KTHREAD_SIZE (8192) +#else +#define KTHREAD_SIZE PAGE_SIZE +#endif + +#define get_user_page(vaddr) __get_free_page(GFP_KERNEL) +#define free_user_page(page, addr) free_page(addr) + +#define clear_page(page) memset((page), 0, PAGE_SIZE) +#define copy_page(to,from) memcpy((to), (from), PAGE_SIZE) + +#define clear_user_page(page, vaddr, pg) clear_page(page) +#define copy_user_page(to, from, vaddr, pg) copy_page(to, from) + +/* + * These are used to make use of C type-checking.. + */ +typedef unsigned long pte_t; +typedef unsigned long pmd_t; +typedef unsigned long pgd_t[2]; +typedef unsigned long pgprot_t; + +#define pte_val(x) (x) +#define pmd_val(x) (x) +#define pgd_val(x) ((x)[0]) +#define pgprot_val(x) (x) + +#define __pte(x) (x) +#define __pmd(x) (x) +#define __pgprot(x) (x) + +#endif diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h new file mode 100644 index 00000000..ac75d084 --- /dev/null +++ b/arch/arm/include/asm/page.h @@ -0,0 +1,214 @@ +/* + * arch/arm/include/asm/page.h + * + * Copyright (C) 1995-2003 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef _ASMARM_PAGE_H +#define _ASMARM_PAGE_H + +/* PAGE_SHIFT determines the page size */ +#define PAGE_SHIFT 12 +#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) +#define PAGE_MASK (~(PAGE_SIZE-1)) + +#ifndef __ASSEMBLY__ + +#ifndef CONFIG_MMU + +#include "page-nommu.h" + +#else + +#include + +/* + * User Space Model + * ================ + * + * This section selects the correct set of functions for dealing with + * page-based copying and clearing for user space for the particular + * processor(s) we're building for. + * + * We have the following to choose from: + * v3 - ARMv3 + * v4wt - ARMv4 with writethrough cache, without minicache + * v4wb - ARMv4 with writeback cache, without minicache + * v4_mc - ARMv4 with minicache + * xscale - Xscale + * xsc3 - XScalev3 + */ +#undef _USER +#undef MULTI_USER + +#ifdef CONFIG_CPU_COPY_V3 +# ifdef _USER +# define MULTI_USER 1 +# else +# define _USER v3 +# endif +#endif + +#ifdef CONFIG_CPU_COPY_V4WT +# ifdef _USER +# define MULTI_USER 1 +# else +# define _USER v4wt +# endif +#endif + +#ifdef CONFIG_CPU_COPY_V4WB +# ifdef _USER +# define MULTI_USER 1 +# else +# define _USER v4wb +# endif +#endif + +#ifdef CONFIG_CPU_COPY_FEROCEON +# ifdef _USER +# define MULTI_USER 1 +# else +# define _USER feroceon +# endif +#endif + +#ifdef CONFIG_CPU_COPY_FA +# ifdef _USER +# define MULTI_USER 1 +# else +# define _USER fa +# endif +#endif + +#ifdef CONFIG_CPU_SA1100 +# ifdef _USER +# define MULTI_USER 1 +# else +# define _USER v4_mc +# endif +#endif + +#ifdef CONFIG_CPU_XSCALE +# ifdef _USER +# define MULTI_USER 1 +# else +# define _USER xscale_mc +# endif +#endif + +#ifdef CONFIG_CPU_XSC3 +# ifdef _USER +# define MULTI_USER 1 +# else +# define _USER xsc3_mc +# endif +#endif + +#ifdef CONFIG_CPU_COPY_V6 +# define MULTI_USER 1 +#endif + +#if !defined(_USER) && !defined(MULTI_USER) +#error Unknown user operations model +#endif + +struct page; +struct vm_area_struct; + +struct cpu_user_fns { + void (*cpu_clear_user_highpage)(struct page *page, unsigned long vaddr); + void (*cpu_copy_user_highpage)(struct page *to, struct page *from, + unsigned long vaddr, struct vm_area_struct *vma); +}; + +#ifdef MULTI_USER +extern struct cpu_user_fns cpu_user; + +#define __cpu_clear_user_highpage cpu_user.cpu_clear_user_highpage +#define __cpu_copy_user_highpage cpu_user.cpu_copy_user_highpage + +#else + +#define __cpu_clear_user_highpage __glue(_USER,_clear_user_highpage) +#define __cpu_copy_user_highpage __glue(_USER,_copy_user_highpage) + +extern void __cpu_clear_user_highpage(struct page *page, unsigned long vaddr); +extern void __cpu_copy_user_highpage(struct page *to, struct page *from, + unsigned long vaddr, struct vm_area_struct *vma); +#endif + +#define clear_user_highpage(page,vaddr) \ + __cpu_clear_user_highpage(page, vaddr) + +#define __HAVE_ARCH_COPY_USER_HIGHPAGE +#define copy_user_highpage(to,from,vaddr,vma) \ + __cpu_copy_user_highpage(to, from, vaddr, vma) + +#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE) +extern void copy_page(void *to, const void *from); + +typedef unsigned long pteval_t; + +#undef STRICT_MM_TYPECHECKS + +#ifdef STRICT_MM_TYPECHECKS +/* + * These are used to make use of C type-checking.. + */ +typedef struct { pteval_t pte; } pte_t; +typedef struct { unsigned long pmd; } pmd_t; +typedef struct { unsigned long pgd[2]; } pgd_t; +typedef struct { unsigned long pgprot; } pgprot_t; + +#define pte_val(x) ((x).pte) +#define pmd_val(x) ((x).pmd) +#define pgd_val(x) ((x).pgd[0]) +#define pgprot_val(x) ((x).pgprot) + +#define __pte(x) ((pte_t) { (x) } ) +#define __pmd(x) ((pmd_t) { (x) } ) +#define __pgprot(x) ((pgprot_t) { (x) } ) + +#else +/* + * .. while these make it easier on the compiler + */ +typedef pteval_t pte_t; +typedef unsigned long pmd_t; +typedef unsigned long pgd_t[2]; +typedef unsigned long pgprot_t; + +#define pte_val(x) (x) +#define pmd_val(x) (x) +#define pgd_val(x) ((x)[0]) +#define pgprot_val(x) (x) + +#define __pte(x) (x) +#define __pmd(x) (x) +#define __pgprot(x) (x) + +#endif /* STRICT_MM_TYPECHECKS */ + +#endif /* CONFIG_MMU */ + +typedef struct page *pgtable_t; + +#ifdef CONFIG_HAVE_ARCH_PFN_VALID +extern int pfn_valid(unsigned long); +#endif + +#include + +#endif /* !__ASSEMBLY__ */ + +#define VM_DATA_DEFAULT_FLAGS \ + (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \ + VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) + +#include + +#endif diff --git a/arch/arm/include/asm/param.h b/arch/arm/include/asm/param.h new file mode 100644 index 00000000..8b24bf94 --- /dev/null +++ b/arch/arm/include/asm/param.h @@ -0,0 +1,31 @@ +/* + * arch/arm/include/asm/param.h + * + * Copyright (C) 1995-1999 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __ASM_PARAM_H +#define __ASM_PARAM_H + +#ifdef __KERNEL__ +# define HZ CONFIG_HZ /* Internal kernel timer frequency */ +# define USER_HZ 100 /* User interfaces are in "ticks" */ +# define CLOCKS_PER_SEC (USER_HZ) /* like times() */ +#else +# define HZ 100 +#endif + +#define EXEC_PAGESIZE 4096 + +#ifndef NOGROUP +#define NOGROUP (-1) +#endif + +/* max length of hostname */ +#define MAXHOSTNAMELEN 64 + +#endif + diff --git a/arch/arm/include/asm/parport.h b/arch/arm/include/asm/parport.h new file mode 100644 index 00000000..26e94b09 --- /dev/null +++ b/arch/arm/include/asm/parport.h @@ -0,0 +1,18 @@ +/* + * arch/arm/include/asm/parport.h: ARM-specific parport initialisation + * + * Copyright (C) 1999, 2000 Tim Waugh + * + * This file should only be included by drivers/parport/parport_pc.c. + */ + +#ifndef __ASMARM_PARPORT_H +#define __ASMARM_PARPORT_H + +static int __devinit parport_pc_find_isa_ports (int autoirq, int autodma); +static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma) +{ + return parport_pc_find_isa_ports (autoirq, autodma); +} + +#endif /* !(_ASMARM_PARPORT_H) */ diff --git a/arch/arm/include/asm/pci.h b/arch/arm/include/asm/pci.h new file mode 100644 index 00000000..92e2a833 --- /dev/null +++ b/arch/arm/include/asm/pci.h @@ -0,0 +1,80 @@ +#ifndef ASMARM_PCI_H +#define ASMARM_PCI_H + +#ifdef __KERNEL__ +#include + +#include /* for pci_sys_data */ +#include /* for PCIBIOS_MIN_* */ + +#ifdef CONFIG_PCI_DOMAINS +static inline int pci_domain_nr(struct pci_bus *bus) +{ + struct pci_sys_data *root = bus->sysdata; + + return root->domain; +} + +static inline int pci_proc_domain(struct pci_bus *bus) +{ + return pci_domain_nr(bus); +} +#endif /* CONFIG_PCI_DOMAINS */ + +#ifdef CONFIG_PCI_HOST_ITE8152 +/* ITE bridge requires setting latency timer to avoid early bus access + termination by PIC bus mater devices +*/ +extern void pcibios_set_master(struct pci_dev *dev); +#else +static inline void pcibios_set_master(struct pci_dev *dev) +{ + /* No special bus mastering setup handling */ +} +#endif + +static inline void pcibios_penalize_isa_irq(int irq, int active) +{ + /* We don't do dynamic PCI IRQ allocation */ +} + +/* + * 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) + +#ifdef CONFIG_PCI +static inline void pci_dma_burst_advice(struct pci_dev *pdev, + enum pci_dma_burst_strategy *strat, + unsigned long *strategy_parameter) +{ + *strat = PCI_DMA_BURST_INFINITY; + *strategy_parameter = ~0UL; +} +#endif + +#define HAVE_PCI_MMAP +extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, + enum pci_mmap_state mmap_state, int write_combine); + +extern void +pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, + struct resource *res); + +extern void +pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, + struct pci_bus_region *region); + +/* + * Dummy implementation; always return 0. + */ +static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) +{ + return 0; +} + +#endif /* __KERNEL__ */ + +#endif diff --git a/arch/arm/include/asm/percpu.h b/arch/arm/include/asm/percpu.h new file mode 100644 index 00000000..b4e32d8e --- /dev/null +++ b/arch/arm/include/asm/percpu.h @@ -0,0 +1,6 @@ +#ifndef __ARM_PERCPU +#define __ARM_PERCPU + +#include + +#endif diff --git a/arch/arm/include/asm/perf_event.h b/arch/arm/include/asm/perf_event.h new file mode 100644 index 00000000..c4aa4e8c --- /dev/null +++ b/arch/arm/include/asm/perf_event.h @@ -0,0 +1,36 @@ +/* + * linux/arch/arm/include/asm/perf_event.h + * + * Copyright (C) 2009 picoChip Designs Ltd, Jamie Iles + * + * 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. + * + */ + +#ifndef __ARM_PERF_EVENT_H__ +#define __ARM_PERF_EVENT_H__ + +/* ARM performance counters start from 1 (in the cp15 accesses) so use the + * same indexes here for consistency. */ +#define PERF_EVENT_INDEX_OFFSET 1 + +/* ARM perf PMU IDs for use by internal perf clients. */ +enum arm_perf_pmu_ids { + ARM_PERF_PMU_ID_XSCALE1 = 0, + ARM_PERF_PMU_ID_XSCALE2, + ARM_PERF_PMU_ID_V6, + ARM_PERF_PMU_ID_V6MP, + ARM_PERF_PMU_ID_CA8, + ARM_PERF_PMU_ID_CA9, + ARM_NUM_PMU_IDS, +}; + +extern enum arm_perf_pmu_ids +armpmu_get_pmu_id(void); + +extern int +armpmu_get_max_events(void); + +#endif /* __ARM_PERF_EVENT_H__ */ diff --git a/arch/arm/include/asm/pgalloc.h b/arch/arm/include/asm/pgalloc.h new file mode 100644 index 00000000..22de005f --- /dev/null +++ b/arch/arm/include/asm/pgalloc.h @@ -0,0 +1,140 @@ +/* + * arch/arm/include/asm/pgalloc.h + * + * Copyright (C) 2000-2001 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef _ASMARM_PGALLOC_H +#define _ASMARM_PGALLOC_H + +#include + +#include +#include +#include +#include +#include + +#define check_pgt_cache() do { } while (0) + +#ifdef CONFIG_MMU + +#define _PAGE_USER_TABLE (PMD_TYPE_TABLE | PMD_BIT4 | PMD_DOMAIN(DOMAIN_USER)) +#define _PAGE_KERNEL_TABLE (PMD_TYPE_TABLE | PMD_BIT4 | PMD_DOMAIN(DOMAIN_KERNEL)) + +/* + * Since we have only two-level page tables, these are trivial + */ +#define pmd_alloc_one(mm,addr) ({ BUG(); ((pmd_t *)2); }) +#define pmd_free(mm, pmd) do { } while (0) +#define pgd_populate(mm,pmd,pte) BUG() + +extern pgd_t *pgd_alloc(struct mm_struct *mm); +extern void pgd_free(struct mm_struct *mm, pgd_t *pgd); + +#define PGALLOC_GFP (GFP_KERNEL | __GFP_NOTRACK | __GFP_REPEAT | __GFP_ZERO) + +static inline void clean_pte_table(pte_t *pte) +{ + clean_dcache_area(pte + PTE_HWTABLE_PTRS, PTE_HWTABLE_SIZE); +} + +/* + * Allocate one PTE table. + * + * This actually allocates two hardware PTE tables, but we wrap this up + * into one table thus: + * + * +------------+ + * | Linux pt 0 | + * +------------+ + * | Linux pt 1 | + * +------------+ + * | h/w pt 0 | + * +------------+ + * | h/w pt 1 | + * +------------+ + */ +static inline pte_t * +pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr) +{ + pte_t *pte; + + pte = (pte_t *)__get_free_page(PGALLOC_GFP); + if (pte) + clean_pte_table(pte); + + return pte; +} + +static inline pgtable_t +pte_alloc_one(struct mm_struct *mm, unsigned long addr) +{ + struct page *pte; + +#ifdef CONFIG_HIGHPTE + pte = alloc_pages(PGALLOC_GFP | __GFP_HIGHMEM, 0); +#else + pte = alloc_pages(PGALLOC_GFP, 0); +#endif + if (pte) { + if (!PageHighMem(pte)) + clean_pte_table(page_address(pte)); + pgtable_page_ctor(pte); + } + + return pte; +} + +/* + * Free one PTE table. + */ +static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) +{ + if (pte) + free_page((unsigned long)pte); +} + +static inline void pte_free(struct mm_struct *mm, pgtable_t pte) +{ + pgtable_page_dtor(pte); + __free_page(pte); +} + +static inline void __pmd_populate(pmd_t *pmdp, phys_addr_t pte, + unsigned long prot) +{ + unsigned long pmdval = (pte + PTE_HWTABLE_OFF) | prot; + pmdp[0] = __pmd(pmdval); + pmdp[1] = __pmd(pmdval + 256 * sizeof(pte_t)); + flush_pmd_entry(pmdp); +} + +/* + * Populate the pmdp entry with a pointer to the pte. This pmd is part + * of the mm address space. + * + * Ensure that we always set both PMD entries. + */ +static inline void +pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep) +{ + /* + * The pmd must be loaded with the physical address of the PTE table + */ + __pmd_populate(pmdp, __pa(ptep), _PAGE_KERNEL_TABLE); +} + +static inline void +pmd_populate(struct mm_struct *mm, pmd_t *pmdp, pgtable_t ptep) +{ + __pmd_populate(pmdp, page_to_phys(ptep), _PAGE_USER_TABLE); +} +#define pmd_pgtable(pmd) pmd_page(pmd) + +#endif /* CONFIG_MMU */ + +#endif diff --git a/arch/arm/include/asm/pgtable-hwdef.h b/arch/arm/include/asm/pgtable-hwdef.h new file mode 100644 index 00000000..fd1521d5 --- /dev/null +++ b/arch/arm/include/asm/pgtable-hwdef.h @@ -0,0 +1,90 @@ +/* + * arch/arm/include/asm/pgtable-hwdef.h + * + * Copyright (C) 1995-2002 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef _ASMARM_PGTABLE_HWDEF_H +#define _ASMARM_PGTABLE_HWDEF_H + +/* + * Hardware page table definitions. + * + * + Level 1 descriptor (PMD) + * - common + */ +#define PMD_TYPE_MASK (3 << 0) +#define PMD_TYPE_FAULT (0 << 0) +#define PMD_TYPE_TABLE (1 << 0) +#define PMD_TYPE_SECT (2 << 0) +#define PMD_BIT4 (1 << 4) +#define PMD_DOMAIN(x) ((x) << 5) +#define PMD_PROTECTION (1 << 9) /* v5 */ +/* + * - section + */ +#define PMD_SECT_BUFFERABLE (1 << 2) +#define PMD_SECT_CACHEABLE (1 << 3) +#define PMD_SECT_XN (1 << 4) /* v6 */ +#define PMD_SECT_AP_WRITE (1 << 10) +#define PMD_SECT_AP_READ (1 << 11) +#define PMD_SECT_TEX(x) ((x) << 12) /* v5 */ +#define PMD_SECT_APX (1 << 15) /* v6 */ +#define PMD_SECT_S (1 << 16) /* v6 */ +#define PMD_SECT_nG (1 << 17) /* v6 */ +#define PMD_SECT_SUPER (1 << 18) /* v6 */ + +#define PMD_SECT_UNCACHED (0) +#define PMD_SECT_BUFFERED (PMD_SECT_BUFFERABLE) +#define PMD_SECT_WT (PMD_SECT_CACHEABLE) +#define PMD_SECT_WB (PMD_SECT_CACHEABLE | PMD_SECT_BUFFERABLE) +#define PMD_SECT_MINICACHE (PMD_SECT_TEX(1) | PMD_SECT_CACHEABLE) +#define PMD_SECT_WBWA (PMD_SECT_TEX(1) | PMD_SECT_CACHEABLE | PMD_SECT_BUFFERABLE) +#define PMD_SECT_NONSHARED_DEV (PMD_SECT_TEX(2)) + +/* + * - coarse table (not used) + */ + +/* + * + Level 2 descriptor (PTE) + * - common + */ +#define PTE_TYPE_MASK (3 << 0) +#define PTE_TYPE_FAULT (0 << 0) +#define PTE_TYPE_LARGE (1 << 0) +#define PTE_TYPE_SMALL (2 << 0) +#define PTE_TYPE_EXT (3 << 0) /* v5 */ +#define PTE_BUFFERABLE (1 << 2) +#define PTE_CACHEABLE (1 << 3) + +/* + * - extended small page/tiny page + */ +#define PTE_EXT_XN (1 << 0) /* v6 */ +#define PTE_EXT_AP_MASK (3 << 4) +#define PTE_EXT_AP0 (1 << 4) +#define PTE_EXT_AP1 (2 << 4) +#define PTE_EXT_AP_UNO_SRO (0 << 4) +#define PTE_EXT_AP_UNO_SRW (PTE_EXT_AP0) +#define PTE_EXT_AP_URO_SRW (PTE_EXT_AP1) +#define PTE_EXT_AP_URW_SRW (PTE_EXT_AP1|PTE_EXT_AP0) +#define PTE_EXT_TEX(x) ((x) << 6) /* v5 */ +#define PTE_EXT_APX (1 << 9) /* v6 */ +#define PTE_EXT_COHERENT (1 << 9) /* XScale3 */ +#define PTE_EXT_SHARED (1 << 10) /* v6 */ +#define PTE_EXT_NG (1 << 11) /* v6 */ + +/* + * - small page + */ +#define PTE_SMALL_AP_MASK (0xff << 4) +#define PTE_SMALL_AP_UNO_SRO (0x00 << 4) +#define PTE_SMALL_AP_UNO_SRW (0x55 << 4) +#define PTE_SMALL_AP_URO_SRW (0xaa << 4) +#define PTE_SMALL_AP_URW_SRW (0xff << 4) + +#endif diff --git a/arch/arm/include/asm/pgtable-nommu.h b/arch/arm/include/asm/pgtable-nommu.h new file mode 100644 index 00000000..ffc0e857 --- /dev/null +++ b/arch/arm/include/asm/pgtable-nommu.h @@ -0,0 +1,119 @@ +/* + * arch/arm/include/asm/pgtable-nommu.h + * + * Copyright (C) 1995-2002 Russell King + * Copyright (C) 2004 Hyok S. Choi + * + * 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. + */ +#ifndef _ASMARM_PGTABLE_NOMMU_H +#define _ASMARM_PGTABLE_NOMMU_H + +#ifndef __ASSEMBLY__ + +#include +#include +#include + +/* + * Trivial page table functions. + */ +#define pgd_present(pgd) (1) +#define pgd_none(pgd) (0) +#define pgd_bad(pgd) (0) +#define pgd_clear(pgdp) +#define kern_addr_valid(addr) (1) +#define pmd_offset(a, b) ((void *)0) +/* FIXME */ +/* + * PMD_SHIFT determines the size of the area a second-level page table can map + * PGDIR_SHIFT determines what a third-level page table entry can map + */ +#define PGDIR_SHIFT 21 + +#define PGDIR_SIZE (1UL << PGDIR_SHIFT) +#define PGDIR_MASK (~(PGDIR_SIZE-1)) +/* FIXME */ + +#define PAGE_NONE __pgprot(0) +#define PAGE_SHARED __pgprot(0) +#define PAGE_COPY __pgprot(0) +#define PAGE_READONLY __pgprot(0) +#define PAGE_KERNEL __pgprot(0) + +#define swapper_pg_dir ((pgd_t *) 0) + +#define __swp_type(x) (0) +#define __swp_offset(x) (0) +#define __swp_entry(typ,off) ((swp_entry_t) { ((typ) | ((off) << 7)) }) +#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) +#define __swp_entry_to_pte(x) ((pte_t) { (x).val }) + + +typedef pte_t *pte_addr_t; + +static inline int pte_file(pte_t pte) { return 0; } + +/* + * ZERO_PAGE is a global shared page that is always zero: used + * for zero-mapped memory areas etc.. + */ +#define ZERO_PAGE(vaddr) (virt_to_page(0)) + +/* + * Mark the prot value as uncacheable and unbufferable. + */ +#define pgprot_noncached(prot) __pgprot(0) +#define pgprot_writecombine(prot) __pgprot(0) +#define pgprot_dmacoherent(prot) __pgprot(0) + + +/* + * These would be in other places but having them here reduces the diffs. + */ +extern unsigned int kobjsize(const void *objp); + +/* + * No page table caches to initialise. + */ +#define pgtable_cache_init() do { } while (0) +#define io_remap_page_range remap_page_range +#define io_remap_pfn_range remap_pfn_range + + +/* + * All 32bit addresses are effectively valid for vmalloc... + * Sort of meaningless for non-VM targets. + */ +#define VMALLOC_START 0UL +#define VMALLOC_END 0xffffffffUL + +#define FIRST_USER_ADDRESS (0) + +#include + +#else + +/* + * dummy tlb and user structures. + */ +#define v3_tlb_fns (0) +#define v4_tlb_fns (0) +#define v4wb_tlb_fns (0) +#define v4wbi_tlb_fns (0) +#define v6wbi_tlb_fns (0) +#define v7wbi_tlb_fns (0) + +#define v3_user_fns (0) +#define v4_user_fns (0) +#define v4_mc_user_fns (0) +#define v4wb_user_fns (0) +#define v4wt_user_fns (0) +#define v6_user_fns (0) +#define xscale_mc_user_fns (0) + +#endif /*__ASSEMBLY__*/ + +#endif /* _ASMARM_PGTABLE_H */ diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h new file mode 100644 index 00000000..6682ab93 --- /dev/null +++ b/arch/arm/include/asm/pgtable.h @@ -0,0 +1,487 @@ +/* + * arch/arm/include/asm/pgtable.h + * + * Copyright (C) 1995-2002 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef _ASMARM_PGTABLE_H +#define _ASMARM_PGTABLE_H + +#include +#include +#include + +#ifndef CONFIG_MMU + +#include "pgtable-nommu.h" + +#else + +#include +#include +#include + +/* + * Just any arbitrary offset to the start of the vmalloc VM area: the + * current 8MB value just means that there will be a 8MB "hole" after the + * physical memory until the kernel virtual memory starts. That means that + * any out-of-bounds memory accesses will hopefully be caught. + * The vmalloc() routines leaves a hole of 4kB between each vmalloced + * area for the same reason. ;) + * + * Note that platforms may override VMALLOC_START, but they must provide + * VMALLOC_END. VMALLOC_END defines the (exclusive) limit of this space, + * which may not overlap IO space. + */ +#ifndef VMALLOC_START +#define VMALLOC_OFFSET (8*1024*1024) +#define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) +#endif + +/* + * Hardware-wise, we have a two level page table structure, where the first + * level has 4096 entries, and the second level has 256 entries. Each entry + * is one 32-bit word. Most of the bits in the second level entry are used + * by hardware, and there aren't any "accessed" and "dirty" bits. + * + * Linux on the other hand has a three level page table structure, which can + * be wrapped to fit a two level page table structure easily - using the PGD + * and PTE only. However, Linux also expects one "PTE" table per page, and + * at least a "dirty" bit. + * + * Therefore, we tweak the implementation slightly - we tell Linux that we + * have 2048 entries in the first level, each of which is 8 bytes (iow, two + * hardware pointers to the second level.) The second level contains two + * hardware PTE tables arranged contiguously, preceded by Linux versions + * which contain the state information Linux needs. We, therefore, end up + * with 512 entries in the "PTE" level. + * + * This leads to the page tables having the following layout: + * + * pgd pte + * | | + * +--------+ + * | | +------------+ +0 + * +- - - - + | Linux pt 0 | + * | | +------------+ +1024 + * +--------+ +0 | Linux pt 1 | + * | |-----> +------------+ +2048 + * +- - - - + +4 | h/w pt 0 | + * | |-----> +------------+ +3072 + * +--------+ +8 | h/w pt 1 | + * | | +------------+ +4096 + * + * See L_PTE_xxx below for definitions of bits in the "Linux pt", and + * PTE_xxx for definitions of bits appearing in the "h/w pt". + * + * PMD_xxx definitions refer to bits in the first level page table. + * + * The "dirty" bit is emulated by only granting hardware write permission + * iff the page is marked "writable" and "dirty" in the Linux PTE. This + * means that a write to a clean page will cause a permission fault, and + * the Linux MM layer will mark the page dirty via handle_pte_fault(). + * For the hardware to notice the permission change, the TLB entry must + * be flushed, and ptep_set_access_flags() does that for us. + * + * The "accessed" or "young" bit is emulated by a similar method; we only + * allow accesses to the page if the "young" bit is set. Accesses to the + * page will cause a fault, and handle_pte_fault() will set the young bit + * for us as long as the page is marked present in the corresponding Linux + * PTE entry. Again, ptep_set_access_flags() will ensure that the TLB is + * up to date. + * + * However, when the "young" bit is cleared, we deny access to the page + * by clearing the hardware PTE. Currently Linux does not flush the TLB + * for us in this case, which means the TLB will retain the transation + * until either the TLB entry is evicted under pressure, or a context + * switch which changes the user space mapping occurs. + */ +#define PTRS_PER_PTE 512 +#define PTRS_PER_PMD 1 +#define PTRS_PER_PGD 2048 + +#define PTE_HWTABLE_PTRS (PTRS_PER_PTE) +#define PTE_HWTABLE_OFF (PTE_HWTABLE_PTRS * sizeof(pte_t)) +#define PTE_HWTABLE_SIZE (PTRS_PER_PTE * sizeof(u32)) + +/* + * PMD_SHIFT determines the size of the area a second-level page table can map + * PGDIR_SHIFT determines what a third-level page table entry can map + */ +#define PMD_SHIFT 21 +#define PGDIR_SHIFT 21 + +#define LIBRARY_TEXT_START 0x0c000000 + +#ifndef __ASSEMBLY__ +extern void __pte_error(const char *file, int line, pte_t); +extern void __pmd_error(const char *file, int line, pmd_t); +extern void __pgd_error(const char *file, int line, pgd_t); + +#define pte_ERROR(pte) __pte_error(__FILE__, __LINE__, pte) +#define pmd_ERROR(pmd) __pmd_error(__FILE__, __LINE__, pmd) +#define pgd_ERROR(pgd) __pgd_error(__FILE__, __LINE__, pgd) +#endif /* !__ASSEMBLY__ */ + +#define PMD_SIZE (1UL << PMD_SHIFT) +#define PMD_MASK (~(PMD_SIZE-1)) +#define PGDIR_SIZE (1UL << PGDIR_SHIFT) +#define PGDIR_MASK (~(PGDIR_SIZE-1)) + +/* + * This is the lowest virtual address we can permit any user space + * mapping to be mapped at. This is particularly important for + * non-high vector CPUs. + */ +#define FIRST_USER_ADDRESS PAGE_SIZE + +#define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE) + +/* + * section address mask and size definitions. + */ +#define SECTION_SHIFT 20 +#define SECTION_SIZE (1UL << SECTION_SHIFT) +#define SECTION_MASK (~(SECTION_SIZE-1)) + +/* + * ARMv6 supersection address mask and size definitions. + */ +#define SUPERSECTION_SHIFT 24 +#define SUPERSECTION_SIZE (1UL << SUPERSECTION_SHIFT) +#define SUPERSECTION_MASK (~(SUPERSECTION_SIZE-1)) + +/* + * "Linux" PTE definitions. + * + * We keep two sets of PTEs - the hardware and the linux version. + * This allows greater flexibility in the way we map the Linux bits + * onto the hardware tables, and allows us to have YOUNG and DIRTY + * bits. + * + * The PTE table pointer refers to the hardware entries; the "Linux" + * entries are stored 1024 bytes below. + */ +#define L_PTE_PRESENT (_AT(pteval_t, 1) << 0) +#define L_PTE_YOUNG (_AT(pteval_t, 1) << 1) +#define L_PTE_FILE (_AT(pteval_t, 1) << 2) /* only when !PRESENT */ +#define L_PTE_DIRTY (_AT(pteval_t, 1) << 6) +#define L_PTE_RDONLY (_AT(pteval_t, 1) << 7) +#define L_PTE_USER (_AT(pteval_t, 1) << 8) +#define L_PTE_XN (_AT(pteval_t, 1) << 9) +#define L_PTE_SHARED (_AT(pteval_t, 1) << 10) /* shared(v6), coherent(xsc3) */ + +/* + * These are the memory types, defined to be compatible with + * pre-ARMv6 CPUs cacheable and bufferable bits: XXCB + */ +#define L_PTE_MT_UNCACHED (_AT(pteval_t, 0x00) << 2) /* 0000 */ +#define L_PTE_MT_BUFFERABLE (_AT(pteval_t, 0x01) << 2) /* 0001 */ +#define L_PTE_MT_WRITETHROUGH (_AT(pteval_t, 0x02) << 2) /* 0010 */ +#define L_PTE_MT_WRITEBACK (_AT(pteval_t, 0x03) << 2) /* 0011 */ +#define L_PTE_MT_MINICACHE (_AT(pteval_t, 0x06) << 2) /* 0110 (sa1100, xscale) */ +#define L_PTE_MT_WRITEALLOC (_AT(pteval_t, 0x07) << 2) /* 0111 */ +#define L_PTE_MT_DEV_SHARED (_AT(pteval_t, 0x04) << 2) /* 0100 */ +#define L_PTE_MT_DEV_NONSHARED (_AT(pteval_t, 0x0c) << 2) /* 1100 */ +#define L_PTE_MT_DEV_WC (_AT(pteval_t, 0x09) << 2) /* 1001 */ +#define L_PTE_MT_DEV_CACHED (_AT(pteval_t, 0x0b) << 2) /* 1011 */ +#define L_PTE_MT_MASK (_AT(pteval_t, 0x0f) << 2) + +#ifndef __ASSEMBLY__ + +/* + * The pgprot_* and protection_map entries will be fixed up in runtime + * to include the cachable and bufferable bits based on memory policy, + * as well as any architecture dependent bits like global/ASID and SMP + * shared mapping bits. + */ +#define _L_PTE_DEFAULT L_PTE_PRESENT | L_PTE_YOUNG + +extern pgprot_t pgprot_user; +extern pgprot_t pgprot_kernel; + +#define _MOD_PROT(p, b) __pgprot(pgprot_val(p) | (b)) + +#define PAGE_NONE _MOD_PROT(pgprot_user, L_PTE_XN | L_PTE_RDONLY) +#define PAGE_SHARED _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_XN) +#define PAGE_SHARED_EXEC _MOD_PROT(pgprot_user, L_PTE_USER) +#define PAGE_COPY _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_RDONLY | L_PTE_XN) +#define PAGE_COPY_EXEC _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_RDONLY) +#define PAGE_READONLY _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_RDONLY | L_PTE_XN) +#define PAGE_READONLY_EXEC _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_RDONLY) +#define PAGE_KERNEL _MOD_PROT(pgprot_kernel, L_PTE_XN) +#define PAGE_KERNEL_EXEC pgprot_kernel + +#define __PAGE_NONE __pgprot(_L_PTE_DEFAULT | L_PTE_RDONLY | L_PTE_XN) +#define __PAGE_SHARED __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_XN) +#define __PAGE_SHARED_EXEC __pgprot(_L_PTE_DEFAULT | L_PTE_USER) +#define __PAGE_COPY __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_RDONLY | L_PTE_XN) +#define __PAGE_COPY_EXEC __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_RDONLY) +#define __PAGE_READONLY __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_RDONLY | L_PTE_XN) +#define __PAGE_READONLY_EXEC __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_RDONLY) + +#define __pgprot_modify(prot,mask,bits) \ + __pgprot((pgprot_val(prot) & ~(mask)) | (bits)) + +#define pgprot_noncached(prot) \ + __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED) + +#define pgprot_writecombine(prot) \ + __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE) + +#define pgprot_writethrough(prot) \ + __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_WRITETHROUGH) + +#ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE +#define pgprot_dmacoherent(prot) \ + __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE | L_PTE_XN) +#define __HAVE_PHYS_MEM_ACCESS_PROT +struct file; +extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, + unsigned long size, pgprot_t vma_prot); +#else +#define pgprot_dmacoherent(prot) \ + __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED | L_PTE_XN) +#endif + +#endif /* __ASSEMBLY__ */ + +/* + * The table below defines the page protection levels that we insert into our + * Linux page table version. These get translated into the best that the + * architecture can perform. Note that on most ARM hardware: + * 1) We cannot do execute protection + * 2) If we could do execute protection, then read is implied + * 3) write implies read permissions + */ +#define __P000 __PAGE_NONE +#define __P001 __PAGE_READONLY +#define __P010 __PAGE_COPY +#define __P011 __PAGE_COPY +#define __P100 __PAGE_READONLY_EXEC +#define __P101 __PAGE_READONLY_EXEC +#define __P110 __PAGE_COPY_EXEC +#define __P111 __PAGE_COPY_EXEC + +#define __S000 __PAGE_NONE +#define __S001 __PAGE_READONLY +#define __S010 __PAGE_SHARED +#define __S011 __PAGE_SHARED +#define __S100 __PAGE_READONLY_EXEC +#define __S101 __PAGE_READONLY_EXEC +#define __S110 __PAGE_SHARED_EXEC +#define __S111 __PAGE_SHARED_EXEC + +#ifndef __ASSEMBLY__ +/* + * ZERO_PAGE is a global shared page that is always zero: used + * for zero-mapped memory areas etc.. + */ +extern struct page *empty_zero_page; +#define ZERO_PAGE(vaddr) (empty_zero_page) + + +extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; + +/* to find an entry in a page-table-directory */ +#define pgd_index(addr) ((addr) >> PGDIR_SHIFT) + +#define pgd_offset(mm, addr) ((mm)->pgd + pgd_index(addr)) + +/* to find an entry in a kernel page-table-directory */ +#define pgd_offset_k(addr) pgd_offset(&init_mm, addr) + +/* + * The "pgd_xxx()" functions here are trivial for a folded two-level + * setup: the pgd is never bad, and a pmd always exists (as it's folded + * into the pgd entry) + */ +#define pgd_none(pgd) (0) +#define pgd_bad(pgd) (0) +#define pgd_present(pgd) (1) +#define pgd_clear(pgdp) do { } while (0) +#define set_pgd(pgd,pgdp) do { } while (0) +#define set_pud(pud,pudp) do { } while (0) + + +/* Find an entry in the second-level page table.. */ +#define pmd_offset(dir, addr) ((pmd_t *)(dir)) + +#define pmd_none(pmd) (!pmd_val(pmd)) +#define pmd_present(pmd) (pmd_val(pmd)) +#define pmd_bad(pmd) (pmd_val(pmd) & 2) + +#define copy_pmd(pmdpd,pmdps) \ + do { \ + pmdpd[0] = pmdps[0]; \ + pmdpd[1] = pmdps[1]; \ + flush_pmd_entry(pmdpd); \ + } while (0) + +#define pmd_clear(pmdp) \ + do { \ + pmdp[0] = __pmd(0); \ + pmdp[1] = __pmd(0); \ + clean_pmd_entry(pmdp); \ + } while (0) + +static inline pte_t *pmd_page_vaddr(pmd_t pmd) +{ + return __va(pmd_val(pmd) & PAGE_MASK); +} + +#define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd))) + +/* we don't need complex calculations here as the pmd is folded into the pgd */ +#define pmd_addr_end(addr,end) (end) + + +#ifndef CONFIG_HIGHPTE +#define __pte_map(pmd) pmd_page_vaddr(*(pmd)) +#define __pte_unmap(pte) do { } while (0) +#else +#define __pte_map(pmd) (pte_t *)kmap_atomic(pmd_page(*(pmd))) +#define __pte_unmap(pte) kunmap_atomic(pte) +#endif + +#define pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) + +#define pte_offset_kernel(pmd,addr) (pmd_page_vaddr(*(pmd)) + pte_index(addr)) + +#define pte_offset_map(pmd,addr) (__pte_map(pmd) + pte_index(addr)) +#define pte_unmap(pte) __pte_unmap(pte) + +#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT) +#define pfn_pte(pfn,prot) __pte(__pfn_to_phys(pfn) | pgprot_val(prot)) + +#define pte_page(pte) pfn_to_page(pte_pfn(pte)) +#define mk_pte(page,prot) pfn_pte(page_to_pfn(page), prot) + +#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext) +#define pte_clear(mm,addr,ptep) set_pte_ext(ptep, __pte(0), 0) + +#if __LINUX_ARM_ARCH__ < 6 +static inline void __sync_icache_dcache(pte_t pteval) +{ +} +#else +extern void __sync_icache_dcache(pte_t pteval); +#endif + +static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, pte_t pteval) +{ + if (addr >= TASK_SIZE) + set_pte_ext(ptep, pteval, 0); + else { + __sync_icache_dcache(pteval); + set_pte_ext(ptep, pteval, PTE_EXT_NG); + } +} + +#define pte_none(pte) (!pte_val(pte)) +#define pte_present(pte) (pte_val(pte) & L_PTE_PRESENT) +#define pte_write(pte) (!(pte_val(pte) & L_PTE_RDONLY)) +#define pte_dirty(pte) (pte_val(pte) & L_PTE_DIRTY) +#define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG) +#define pte_exec(pte) (!(pte_val(pte) & L_PTE_XN)) +#define pte_special(pte) (0) + +#define pte_present_user(pte) \ + ((pte_val(pte) & (L_PTE_PRESENT | L_PTE_USER)) == \ + (L_PTE_PRESENT | L_PTE_USER)) + +#define PTE_BIT_FUNC(fn,op) \ +static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; } + +PTE_BIT_FUNC(wrprotect, |= L_PTE_RDONLY); +PTE_BIT_FUNC(mkwrite, &= ~L_PTE_RDONLY); +PTE_BIT_FUNC(mkclean, &= ~L_PTE_DIRTY); +PTE_BIT_FUNC(mkdirty, |= L_PTE_DIRTY); +PTE_BIT_FUNC(mkold, &= ~L_PTE_YOUNG); +PTE_BIT_FUNC(mkyoung, |= L_PTE_YOUNG); + +static inline pte_t pte_mkspecial(pte_t pte) { return pte; } + +static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) +{ + const pteval_t mask = L_PTE_XN | L_PTE_RDONLY | L_PTE_USER; + pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask); + return pte; +} + +/* + * Encode and decode a swap entry. Swap entries are stored in the Linux + * page tables as follows: + * + * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * <--------------- offset --------------------> <- type --> 0 0 0 + * + * This gives us up to 63 swap files and 32GB per swap file. Note that + * the offset field is always non-zero. + */ +#define __SWP_TYPE_SHIFT 3 +#define __SWP_TYPE_BITS 6 +#define __SWP_TYPE_MASK ((1 << __SWP_TYPE_BITS) - 1) +#define __SWP_OFFSET_SHIFT (__SWP_TYPE_BITS + __SWP_TYPE_SHIFT) + +#define __swp_type(x) (((x).val >> __SWP_TYPE_SHIFT) & __SWP_TYPE_MASK) +#define __swp_offset(x) ((x).val >> __SWP_OFFSET_SHIFT) +#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << __SWP_TYPE_SHIFT) | ((offset) << __SWP_OFFSET_SHIFT) }) + +#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) +#define __swp_entry_to_pte(swp) ((pte_t) { (swp).val }) + +/* + * It is an error for the kernel to have more swap files than we can + * encode in the PTEs. This ensures that we know when MAX_SWAPFILES + * is increased beyond what we presently support. + */ +#define MAX_SWAPFILES_CHECK() BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > __SWP_TYPE_BITS) + +/* + * Encode and decode a file entry. File entries are stored in the Linux + * page tables as follows: + * + * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * <----------------------- offset ------------------------> 1 0 0 + */ +#define pte_file(pte) (pte_val(pte) & L_PTE_FILE) +#define pte_to_pgoff(x) (pte_val(x) >> 3) +#define pgoff_to_pte(x) __pte(((x) << 3) | L_PTE_FILE) + +#define PTE_FILE_MAX_BITS 29 + +/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */ +/* FIXME: this is not correct */ +#define kern_addr_valid(addr) (1) + +#include + +/* + * We provide our own arch_get_unmapped_area to cope with VIPT caches. + */ +#define HAVE_ARCH_UNMAPPED_AREA + +/* + * remap a physical page `pfn' of size `size' with page protection `prot' + * into virtual address `from' + */ +#define io_remap_pfn_range(vma,from,pfn,size,prot) \ + remap_pfn_range(vma, from, pfn, size, prot) + +#define pgtable_cache_init() do { } while (0) + +void identity_mapping_add(pgd_t *, unsigned long, unsigned long); +void identity_mapping_del(pgd_t *, unsigned long, unsigned long); + +#endif /* !__ASSEMBLY__ */ + +#endif /* CONFIG_MMU */ + +#endif /* _ASMARM_PGTABLE_H */ diff --git a/arch/arm/include/asm/pmu.h b/arch/arm/include/asm/pmu.h new file mode 100644 index 00000000..7544ce6b --- /dev/null +++ b/arch/arm/include/asm/pmu.h @@ -0,0 +1,91 @@ +/* + * linux/arch/arm/include/asm/pmu.h + * + * Copyright (C) 2009 picoChip Designs Ltd, Jamie Iles + * + * 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. + * + */ + +#ifndef __ARM_PMU_H__ +#define __ARM_PMU_H__ + +#include + +enum arm_pmu_type { + ARM_PMU_DEVICE_CPU = 0, + ARM_NUM_PMU_DEVICES, +}; + +/* + * struct arm_pmu_platdata - ARM PMU platform data + * + * @handle_irq: an optional handler which will be called from the interrupt and + * passed the address of the low level handler, and can be used to implement + * any platform specific handling before or after calling it. + */ +struct arm_pmu_platdata { + irqreturn_t (*handle_irq)(int irq, void *dev, + irq_handler_t pmu_handler); +}; + +#ifdef CONFIG_CPU_HAS_PMU + +/** + * reserve_pmu() - reserve the hardware performance counters + * + * Reserve the hardware performance counters in the system for exclusive use. + * The platform_device for the system is returned on success, ERR_PTR() + * encoded error on failure. + */ +extern struct platform_device * +reserve_pmu(enum arm_pmu_type device); + +/** + * release_pmu() - Relinquish control of the performance counters + * + * Release the performance counters and allow someone else to use them. + * Callers must have disabled the counters and released IRQs before calling + * this. The platform_device returned from reserve_pmu() must be passed as + * a cookie. + */ +extern int +release_pmu(struct platform_device *pdev); + +/** + * init_pmu() - Initialise the PMU. + * + * Initialise the system ready for PMU enabling. This should typically set the + * IRQ affinity and nothing else. The users (oprofile/perf events etc) will do + * the actual hardware initialisation. + */ +extern int +init_pmu(enum arm_pmu_type device); + +#else /* CONFIG_CPU_HAS_PMU */ + +#include + +static inline struct platform_device * +reserve_pmu(enum arm_pmu_type device) +{ + return ERR_PTR(-ENODEV); +} + +static inline int +release_pmu(struct platform_device *pdev) +{ + return -ENODEV; +} + +static inline int +init_pmu(enum arm_pmu_type device) +{ + return -ENODEV; +} + +#endif /* CONFIG_CPU_HAS_PMU */ + +#endif /* __ARM_PMU_H__ */ diff --git a/arch/arm/include/asm/poll.h b/arch/arm/include/asm/poll.h new file mode 100644 index 00000000..c98509d3 --- /dev/null +++ b/arch/arm/include/asm/poll.h @@ -0,0 +1 @@ +#include diff --git a/arch/arm/include/asm/posix_types.h b/arch/arm/include/asm/posix_types.h new file mode 100644 index 00000000..2446d23b --- /dev/null +++ b/arch/arm/include/asm/posix_types.h @@ -0,0 +1,77 @@ +/* + * arch/arm/include/asm/posix_types.h + * + * Copyright (C) 1996-1998 Russell King. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Changelog: + * 27-06-1996 RMK Created + */ +#ifndef __ARCH_ARM_POSIX_TYPES_H +#define __ARCH_ARM_POSIX_TYPES_H + +/* + * This file is generally used by user-level software, so you need to + * be a little careful about namespace pollution etc. Also, we cannot + * assume GCC is being used. + */ + +typedef unsigned long __kernel_ino_t; +typedef unsigned short __kernel_mode_t; +typedef unsigned short __kernel_nlink_t; +typedef long __kernel_off_t; +typedef int __kernel_pid_t; +typedef unsigned short __kernel_ipc_pid_t; +typedef unsigned short __kernel_uid_t; +typedef unsigned short __kernel_gid_t; +typedef unsigned int __kernel_size_t; +typedef int __kernel_ssize_t; +typedef int __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 int __kernel_daddr_t; +typedef char * __kernel_caddr_t; +typedef unsigned short __kernel_uid16_t; +typedef unsigned short __kernel_gid16_t; +typedef unsigned int __kernel_uid32_t; +typedef unsigned int __kernel_gid32_t; + +typedef unsigned short __kernel_old_uid_t; +typedef unsigned short __kernel_old_gid_t; +typedef unsigned short __kernel_old_dev_t; + +#ifdef __GNUC__ +typedef long long __kernel_loff_t; +#endif + +typedef struct { + int val[2]; +} __kernel_fsid_t; + +#if defined(__KERNEL__) + +#undef __FD_SET +#define __FD_SET(fd, fdsetp) \ + (((fd_set *)(fdsetp))->fds_bits[(fd) >> 5] |= (1<<((fd) & 31))) + +#undef __FD_CLR +#define __FD_CLR(fd, fdsetp) \ + (((fd_set *)(fdsetp))->fds_bits[(fd) >> 5] &= ~(1<<((fd) & 31))) + +#undef __FD_ISSET +#define __FD_ISSET(fd, fdsetp) \ + ((((fd_set *)(fdsetp))->fds_bits[(fd) >> 5] & (1<<((fd) & 31))) != 0) + +#undef __FD_ZERO +#define __FD_ZERO(fdsetp) \ + (memset (fdsetp, 0, sizeof (*(fd_set *)(fdsetp)))) + +#endif + +#endif diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h new file mode 100644 index 00000000..8ec535e1 --- /dev/null +++ b/arch/arm/include/asm/proc-fns.h @@ -0,0 +1,115 @@ +/* + * arch/arm/include/asm/proc-fns.h + * + * Copyright (C) 1997-1999 Russell King + * Copyright (C) 2000 Deep Blue Solutions Ltd + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __ASM_PROCFNS_H +#define __ASM_PROCFNS_H + +#ifdef __KERNEL__ + +#include +#include + +#ifndef __ASSEMBLY__ + +struct mm_struct; + +/* + * Don't change this structure - ASM code relies on it. + */ +extern struct processor { + /* MISC + * get data abort address/flags + */ + void (*_data_abort)(unsigned long pc); + /* + * Retrieve prefetch fault address + */ + unsigned long (*_prefetch_abort)(unsigned long lr); + /* + * Set up any processor specifics + */ + void (*_proc_init)(void); + /* + * Disable any processor specifics + */ + void (*_proc_fin)(void); + /* + * Special stuff for a reset + */ + void (*reset)(unsigned long addr) __attribute__((noreturn)); + /* + * Idle the processor + */ + int (*_do_idle)(void); + /* + * Processor architecture specific + */ + /* + * clean a virtual address range from the + * D-cache without flushing the cache. + */ + void (*dcache_clean_area)(void *addr, int size); + + /* + * Set the page table + */ + void (*switch_mm)(unsigned long pgd_phys, struct mm_struct *mm); + /* + * Set a possibly extended PTE. Non-extended PTEs should + * ignore 'ext'. + */ + void (*set_pte_ext)(pte_t *ptep, pte_t pte, unsigned int ext); + + /* Suspend/resume */ + unsigned int suspend_size; + void (*do_suspend)(void *); + void (*do_resume)(void *); +} processor; + +#ifndef MULTI_CPU +extern void cpu_proc_init(void); +extern void cpu_proc_fin(void); +extern int cpu_do_idle(void); +extern void cpu_dcache_clean_area(void *, int); +extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm); +extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext); +extern void cpu_reset(unsigned long addr) __attribute__((noreturn)); +#else +#define cpu_proc_init() processor._proc_init() +#define cpu_proc_fin() processor._proc_fin() +#define cpu_reset(addr) processor.reset(addr) +#define cpu_do_idle() processor._do_idle() +#define cpu_dcache_clean_area(addr,sz) processor.dcache_clean_area(addr,sz) +#define cpu_set_pte_ext(ptep,pte,ext) processor.set_pte_ext(ptep,pte,ext) +#define cpu_do_switch_mm(pgd,mm) processor.switch_mm(pgd,mm) +#endif + +extern void cpu_resume(void); + +#include + +#ifdef CONFIG_MMU + +#define cpu_switch_mm(pgd,mm) cpu_do_switch_mm(virt_to_phys(pgd),mm) + +#define cpu_get_pgd() \ + ({ \ + unsigned long pg; \ + __asm__("mrc p15, 0, %0, c2, c0, 0" \ + : "=r" (pg) : : "cc"); \ + pg &= ~0x3fff; \ + (pgd_t *)phys_to_virt(pg); \ + }) + +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __KERNEL__ */ +#endif /* __ASM_PROCFNS_H */ diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h new file mode 100644 index 00000000..b2d9df56 --- /dev/null +++ b/arch/arm/include/asm/processor.h @@ -0,0 +1,128 @@ +/* + * arch/arm/include/asm/processor.h + * + * Copyright (C) 1995-1999 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ASM_ARM_PROCESSOR_H +#define __ASM_ARM_PROCESSOR_H + +/* + * Default implementation of macro that returns current + * instruction pointer ("program counter"). + */ +#define current_text_addr() ({ __label__ _l; _l: &&_l;}) + +#ifdef __KERNEL__ + +#include +#include +#include + +#ifdef __KERNEL__ +#define STACK_TOP ((current->personality & ADDR_LIMIT_32BIT) ? \ + TASK_SIZE : TASK_SIZE_26) +#define STACK_TOP_MAX TASK_SIZE +#endif + +struct debug_info { +#ifdef CONFIG_HAVE_HW_BREAKPOINT + struct perf_event *hbp[ARM_MAX_HBP_SLOTS]; +#endif +}; + +struct thread_struct { + /* fault info */ + unsigned long address; + unsigned long trap_no; + unsigned long error_code; + /* debugging */ + struct debug_info debug; +}; + +#define INIT_THREAD { } + +#ifdef CONFIG_MMU +#define nommu_start_thread(regs) do { } while (0) +#else +#define nommu_start_thread(regs) regs->ARM_r10 = current->mm->start_data +#endif + +#define start_thread(regs,pc,sp) \ +({ \ + unsigned long *stack = (unsigned long *)sp; \ + set_fs(USER_DS); \ + memset(regs->uregs, 0, sizeof(regs->uregs)); \ + if (current->personality & ADDR_LIMIT_32BIT) \ + regs->ARM_cpsr = USR_MODE; \ + else \ + regs->ARM_cpsr = USR26_MODE; \ + if (elf_hwcap & HWCAP_THUMB && pc & 1) \ + regs->ARM_cpsr |= PSR_T_BIT; \ + regs->ARM_cpsr |= PSR_ENDSTATE; \ + regs->ARM_pc = pc & ~1; /* pc */ \ + regs->ARM_sp = sp; /* sp */ \ + regs->ARM_r2 = stack[2]; /* r2 (envp) */ \ + regs->ARM_r1 = stack[1]; /* r1 (argv) */ \ + regs->ARM_r0 = stack[0]; /* r0 (argc) */ \ + nommu_start_thread(regs); \ +}) + +/* Forward declaration, a strange C thing */ +struct task_struct; + +/* Free all resources held by a thread. */ +extern void release_thread(struct task_struct *); + +/* Prepare to copy thread state - unlazy all lazy status */ +#define prepare_to_copy(tsk) do { } while (0) + +unsigned long get_wchan(struct task_struct *p); + +#if __LINUX_ARM_ARCH__ == 6 || defined(CONFIG_ARM_ERRATA_754327) +#define cpu_relax() smp_mb() +#else +#define cpu_relax() barrier() +#endif + +/* + * Create a new kernel thread + */ +extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); + +#define task_pt_regs(p) \ + ((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1) + +#define KSTK_EIP(tsk) task_pt_regs(tsk)->ARM_pc +#define KSTK_ESP(tsk) task_pt_regs(tsk)->ARM_sp + +/* + * Prefetching support - only ARMv5. + */ +#if __LINUX_ARM_ARCH__ >= 5 + +#define ARCH_HAS_PREFETCH +static inline void prefetch(const void *ptr) +{ + __asm__ __volatile__( + "pld\t%a0" + : + : "p" (ptr) + : "cc"); +} + +#define ARCH_HAS_PREFETCHW +#define prefetchw(ptr) prefetch(ptr) + +#define ARCH_HAS_SPINLOCK_PREFETCH +#define spin_lock_prefetch(x) do { } while (0) + +#endif + +#endif + +#endif /* __ASM_ARM_PROCESSOR_H */ diff --git a/arch/arm/include/asm/procinfo.h b/arch/arm/include/asm/procinfo.h new file mode 100644 index 00000000..ca52e584 --- /dev/null +++ b/arch/arm/include/asm/procinfo.h @@ -0,0 +1,49 @@ +/* + * arch/arm/include/asm/procinfo.h + * + * Copyright (C) 1996-1999 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __ASM_PROCINFO_H +#define __ASM_PROCINFO_H + +#ifdef __KERNEL__ + +struct cpu_tlb_fns; +struct cpu_user_fns; +struct cpu_cache_fns; +struct processor; + +/* + * Note! struct processor is always defined if we're + * using MULTI_CPU, otherwise this entry is unused, + * but still exists. + * + * NOTE! The following structure is defined by assembly + * language, NOT C code. For more information, check: + * arch/arm/mm/proc-*.S and arch/arm/kernel/head.S + */ +struct proc_info_list { + unsigned int cpu_val; + unsigned int cpu_mask; + unsigned long __cpu_mm_mmu_flags; /* used by head.S */ + unsigned long __cpu_io_mmu_flags; /* used by head.S */ + unsigned long __cpu_flush; /* used by head.S */ + const char *arch_name; + const char *elf_name; + unsigned int elf_hwcap; + const char *cpu_name; + struct processor *proc; + struct cpu_tlb_fns *tlb; + struct cpu_user_fns *user; + struct cpu_cache_fns *cache; +}; + +#else /* __KERNEL__ */ +#include +#warning "Please include asm/elf.h instead" +#endif /* __KERNEL__ */ +#endif diff --git a/arch/arm/include/asm/prom.h b/arch/arm/include/asm/prom.h new file mode 100644 index 00000000..11b8708f --- /dev/null +++ b/arch/arm/include/asm/prom.h @@ -0,0 +1,37 @@ +/* + * arch/arm/include/asm/prom.h + * + * Copyright (C) 2009 Canonical Ltd. + * + * 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. + * + */ +#ifndef __ASMARM_PROM_H +#define __ASMARM_PROM_H + +#ifdef CONFIG_OF + +#include +#include + +static inline void irq_dispose_mapping(unsigned int virq) +{ + return; +} + +extern struct machine_desc *setup_machine_fdt(unsigned int dt_phys); +extern void arm_dt_memblock_reserve(void); + +#else /* CONFIG_OF */ + +static inline struct machine_desc *setup_machine_fdt(unsigned int dt_phys) +{ + return NULL; +} + +static inline void arm_dt_memblock_reserve(void) { } + +#endif /* CONFIG_OF */ +#endif /* ASMARM_PROM_H */ diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h new file mode 100644 index 00000000..312d1087 --- /dev/null +++ b/arch/arm/include/asm/ptrace.h @@ -0,0 +1,243 @@ +/* + * arch/arm/include/asm/ptrace.h + * + * Copyright (C) 1996-2003 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __ASM_ARM_PTRACE_H +#define __ASM_ARM_PTRACE_H + +#include + +#define PTRACE_GETREGS 12 +#define PTRACE_SETREGS 13 +#define PTRACE_GETFPREGS 14 +#define PTRACE_SETFPREGS 15 +/* PTRACE_ATTACH is 16 */ +/* PTRACE_DETACH is 17 */ +#define PTRACE_GETWMMXREGS 18 +#define PTRACE_SETWMMXREGS 19 +/* 20 is unused */ +#define PTRACE_OLDSETOPTIONS 21 +#define PTRACE_GET_THREAD_AREA 22 +#define PTRACE_SET_SYSCALL 23 +/* PTRACE_SYSCALL is 24 */ +#define PTRACE_GETCRUNCHREGS 25 +#define PTRACE_SETCRUNCHREGS 26 +#define PTRACE_GETVFPREGS 27 +#define PTRACE_SETVFPREGS 28 +#define PTRACE_GETHBPREGS 29 +#define PTRACE_SETHBPREGS 30 + +/* + * PSR bits + */ +#define USR26_MODE 0x00000000 +#define FIQ26_MODE 0x00000001 +#define IRQ26_MODE 0x00000002 +#define SVC26_MODE 0x00000003 +#define USR_MODE 0x00000010 +#define FIQ_MODE 0x00000011 +#define IRQ_MODE 0x00000012 +#define SVC_MODE 0x00000013 +#define ABT_MODE 0x00000017 +#define UND_MODE 0x0000001b +#define SYSTEM_MODE 0x0000001f +#define MODE32_BIT 0x00000010 +#define MODE_MASK 0x0000001f +#define PSR_T_BIT 0x00000020 +#define PSR_F_BIT 0x00000040 +#define PSR_I_BIT 0x00000080 +#define PSR_A_BIT 0x00000100 +#define PSR_E_BIT 0x00000200 +#define PSR_J_BIT 0x01000000 +#define PSR_Q_BIT 0x08000000 +#define PSR_V_BIT 0x10000000 +#define PSR_C_BIT 0x20000000 +#define PSR_Z_BIT 0x40000000 +#define PSR_N_BIT 0x80000000 + +/* + * Groups of PSR bits + */ +#define PSR_f 0xff000000 /* Flags */ +#define PSR_s 0x00ff0000 /* Status */ +#define PSR_x 0x0000ff00 /* Extension */ +#define PSR_c 0x000000ff /* Control */ + +/* + * ARMv7 groups of APSR bits + */ +#define PSR_ISET_MASK 0x01000010 /* ISA state (J, T) mask */ +#define PSR_IT_MASK 0x0600fc00 /* If-Then execution state mask */ +#define PSR_ENDIAN_MASK 0x00000200 /* Endianness state mask */ + +/* + * Default endianness state + */ +#ifdef CONFIG_CPU_ENDIAN_BE8 +#define PSR_ENDSTATE PSR_E_BIT +#else +#define PSR_ENDSTATE 0 +#endif + +/* + * These are 'magic' values for PTRACE_PEEKUSR that return info about where a + * process is located in memory. + */ +#define PT_TEXT_ADDR 0x10000 +#define PT_DATA_ADDR 0x10004 +#define PT_TEXT_END_ADDR 0x10008 + +#ifndef __ASSEMBLY__ + +/* + * This struct defines the way the registers are stored on the + * stack during a system call. Note that sizeof(struct pt_regs) + * has to be a multiple of 8. + */ +#ifndef __KERNEL__ +struct pt_regs { + long uregs[18]; +}; +#else /* __KERNEL__ */ +struct pt_regs { + unsigned long uregs[18]; +}; +#endif /* __KERNEL__ */ + +#define ARM_cpsr uregs[16] +#define ARM_pc uregs[15] +#define ARM_lr uregs[14] +#define ARM_sp uregs[13] +#define ARM_ip uregs[12] +#define ARM_fp uregs[11] +#define ARM_r10 uregs[10] +#define ARM_r9 uregs[9] +#define ARM_r8 uregs[8] +#define ARM_r7 uregs[7] +#define ARM_r6 uregs[6] +#define ARM_r5 uregs[5] +#define ARM_r4 uregs[4] +#define ARM_r3 uregs[3] +#define ARM_r2 uregs[2] +#define ARM_r1 uregs[1] +#define ARM_r0 uregs[0] +#define ARM_ORIG_r0 uregs[17] + +/* + * The size of the user-visible VFP state as seen by PTRACE_GET/SETVFPREGS + * and core dumps. + */ +#define ARM_VFPREGS_SIZE ( 32 * 8 /*fpregs*/ + 4 /*fpscr*/ ) + +#ifdef __KERNEL__ + +#define user_mode(regs) \ + (((regs)->ARM_cpsr & 0xf) == 0) + +#ifdef CONFIG_ARM_THUMB +#define thumb_mode(regs) \ + (((regs)->ARM_cpsr & PSR_T_BIT)) +#else +#define thumb_mode(regs) (0) +#endif + +#define isa_mode(regs) \ + ((((regs)->ARM_cpsr & PSR_J_BIT) >> 23) | \ + (((regs)->ARM_cpsr & PSR_T_BIT) >> 5)) + +#define processor_mode(regs) \ + ((regs)->ARM_cpsr & MODE_MASK) + +#define interrupts_enabled(regs) \ + (!((regs)->ARM_cpsr & PSR_I_BIT)) + +#define fast_interrupts_enabled(regs) \ + (!((regs)->ARM_cpsr & PSR_F_BIT)) + +/* Are the current registers suitable for user mode? + * (used to maintain security in signal handlers) + */ +static inline int valid_user_regs(struct pt_regs *regs) +{ + unsigned long mode = regs->ARM_cpsr & MODE_MASK; + + /* + * Always clear the F (FIQ) and A (delayed abort) bits + */ + regs->ARM_cpsr &= ~(PSR_F_BIT | PSR_A_BIT); + + if ((regs->ARM_cpsr & PSR_I_BIT) == 0) { + if (mode == USR_MODE) + return 1; + if (elf_hwcap & HWCAP_26BIT && mode == USR26_MODE) + return 1; + } + + /* + * Force CPSR to something logical... + */ + regs->ARM_cpsr &= PSR_f | PSR_s | PSR_x | PSR_T_BIT | MODE32_BIT; + if (!(elf_hwcap & HWCAP_26BIT)) + regs->ARM_cpsr |= USR_MODE; + + return 0; +} + +#define instruction_pointer(regs) (regs)->ARM_pc + +#ifdef CONFIG_SMP +extern unsigned long profile_pc(struct pt_regs *regs); +#else +#define profile_pc(regs) instruction_pointer(regs) +#endif + +#define predicate(x) ((x) & 0xf0000000) +#define PREDICATE_ALWAYS 0xe0000000 + +/* + * kprobe-based event tracer support + */ +#include +#include +#define MAX_REG_OFFSET (offsetof(struct pt_regs, ARM_ORIG_r0)) + +extern int regs_query_register_offset(const char *name); +extern const char *regs_query_register_name(unsigned int offset); +extern bool regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr); +extern unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, + unsigned int n); + +/** + * regs_get_register() - get register value from its offset + * @regs: pt_regs from which register value is gotten + * @offset: offset number of the register. + * + * regs_get_register returns the value of a register whose offset from @regs. + * The @offset is the offset of the register in struct pt_regs. + * If @offset is bigger than MAX_REG_OFFSET, this returns 0. + */ +static inline unsigned long regs_get_register(struct pt_regs *regs, + unsigned int offset) +{ + if (unlikely(offset > MAX_REG_OFFSET)) + return 0; + return *(unsigned long *)((unsigned long)regs + offset); +} + +/* Valid only for Kernel mode traps. */ +static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) +{ + return regs->ARM_sp; +} + +#endif /* __KERNEL__ */ + +#endif /* __ASSEMBLY__ */ + +#endif + diff --git a/arch/arm/include/asm/resource.h b/arch/arm/include/asm/resource.h new file mode 100644 index 00000000..734b581b --- /dev/null +++ b/arch/arm/include/asm/resource.h @@ -0,0 +1,6 @@ +#ifndef _ARM_RESOURCE_H +#define _ARM_RESOURCE_H + +#include + +#endif diff --git a/arch/arm/include/asm/scatterlist.h b/arch/arm/include/asm/scatterlist.h new file mode 100644 index 00000000..2f87870d --- /dev/null +++ b/arch/arm/include/asm/scatterlist.h @@ -0,0 +1,8 @@ +#ifndef _ASMARM_SCATTERLIST_H +#define _ASMARM_SCATTERLIST_H + +#include +#include +#include + +#endif /* _ASMARM_SCATTERLIST_H */ diff --git a/arch/arm/include/asm/sched_clock.h b/arch/arm/include/asm/sched_clock.h new file mode 100644 index 00000000..c8e6ddf3 --- /dev/null +++ b/arch/arm/include/asm/sched_clock.h @@ -0,0 +1,120 @@ +/* + * sched_clock.h: support for extending counters to full 64-bit ns counter + * + * 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. + */ +#ifndef ASM_SCHED_CLOCK +#define ASM_SCHED_CLOCK + +#include +#include + +struct clock_data { + u64 epoch_ns; + u32 epoch_cyc; + u32 epoch_cyc_copy; + u32 mult; + u32 shift; +}; + +#define DEFINE_CLOCK_DATA(name) struct clock_data name + +static inline u64 cyc_to_ns(u64 cyc, u32 mult, u32 shift) +{ + return (cyc * mult) >> shift; +} + +/* + * Atomically update the sched_clock epoch. Your update callback will + * be called from a timer before the counter wraps - read the current + * counter value, and call this function to safely move the epochs + * forward. Only use this from the update callback. + */ +static inline void update_sched_clock(struct clock_data *cd, u32 cyc, u32 mask) +{ + unsigned long flags; + u64 ns = cd->epoch_ns + + cyc_to_ns((cyc - cd->epoch_cyc) & mask, cd->mult, cd->shift); + + /* + * Write epoch_cyc and epoch_ns in a way that the update is + * detectable in cyc_to_fixed_sched_clock(). + */ + raw_local_irq_save(flags); + cd->epoch_cyc = cyc; + smp_wmb(); + cd->epoch_ns = ns; + smp_wmb(); + cd->epoch_cyc_copy = cyc; + raw_local_irq_restore(flags); +} + +/* + * If your clock rate is known at compile time, using this will allow + * you to optimize the mult/shift loads away. This is paired with + * init_fixed_sched_clock() to ensure that your mult/shift are correct. + */ +static inline unsigned long long cyc_to_fixed_sched_clock(struct clock_data *cd, + u32 cyc, u32 mask, u32 mult, u32 shift) +{ + u64 epoch_ns; + u32 epoch_cyc; + + /* + * Load the epoch_cyc and epoch_ns atomically. We do this by + * ensuring that we always write epoch_cyc, epoch_ns and + * epoch_cyc_copy in strict order, and read them in strict order. + * If epoch_cyc and epoch_cyc_copy are not equal, then we're in + * the middle of an update, and we should repeat the load. + */ + do { + epoch_cyc = cd->epoch_cyc; + smp_rmb(); + epoch_ns = cd->epoch_ns; + smp_rmb(); + } while (epoch_cyc != cd->epoch_cyc_copy); + + return epoch_ns + cyc_to_ns((cyc - epoch_cyc) & mask, mult, shift); +} + +/* + * Otherwise, you need to use this, which will obtain the mult/shift + * from the clock_data structure. Use init_sched_clock() with this. + */ +static inline unsigned long long cyc_to_sched_clock(struct clock_data *cd, + u32 cyc, u32 mask) +{ + return cyc_to_fixed_sched_clock(cd, cyc, mask, cd->mult, cd->shift); +} + +/* + * Initialize the clock data - calculate the appropriate multiplier + * and shift. Also setup a timer to ensure that the epoch is refreshed + * at the appropriate time interval, which will call your update + * handler. + */ +void init_sched_clock(struct clock_data *, void (*)(void), + unsigned int, unsigned long); + +/* + * Use this initialization function rather than init_sched_clock() if + * you're using cyc_to_fixed_sched_clock, which will warn if your + * constants are incorrect. + */ +static inline void init_fixed_sched_clock(struct clock_data *cd, + void (*update)(void), unsigned int bits, unsigned long rate, + u32 mult, u32 shift) +{ + init_sched_clock(cd, update, bits, rate); + if (cd->mult != mult || cd->shift != shift) { + pr_crit("sched_clock: wrong multiply/shift: %u>>%u vs calculated %u>>%u\n" + "sched_clock: fix multiply/shift to avoid scheduler hiccups\n", + mult, shift, cd->mult, cd->shift); + } +} + +extern void sched_clock_postinit(void); + +#endif diff --git a/arch/arm/include/asm/seccomp.h b/arch/arm/include/asm/seccomp.h new file mode 100644 index 00000000..52b156b3 --- /dev/null +++ b/arch/arm/include/asm/seccomp.h @@ -0,0 +1,11 @@ +#ifndef _ASM_ARM_SECCOMP_H +#define _ASM_ARM_SECCOMP_H + +#include + +#define __NR_seccomp_read __NR_read +#define __NR_seccomp_write __NR_write +#define __NR_seccomp_exit __NR_exit +#define __NR_seccomp_sigreturn __NR_rt_sigreturn + +#endif /* _ASM_ARM_SECCOMP_H */ diff --git a/arch/arm/include/asm/sections.h b/arch/arm/include/asm/sections.h new file mode 100644 index 00000000..2b8c5160 --- /dev/null +++ b/arch/arm/include/asm/sections.h @@ -0,0 +1 @@ +#include diff --git a/arch/arm/include/asm/segment.h b/arch/arm/include/asm/segment.h new file mode 100644 index 00000000..9e24c21f --- /dev/null +++ b/arch/arm/include/asm/segment.h @@ -0,0 +1,11 @@ +#ifndef __ASM_ARM_SEGMENT_H +#define __ASM_ARM_SEGMENT_H + +#define __KERNEL_CS 0x0 +#define __KERNEL_DS 0x0 + +#define __USER_CS 0x1 +#define __USER_DS 0x1 + +#endif /* __ASM_ARM_SEGMENT_H */ + diff --git a/arch/arm/include/asm/sembuf.h b/arch/arm/include/asm/sembuf.h new file mode 100644 index 00000000..1c028395 --- /dev/null +++ b/arch/arm/include/asm/sembuf.h @@ -0,0 +1,25 @@ +#ifndef _ASMARM_SEMBUF_H +#define _ASMARM_SEMBUF_H + +/* + * The semid64_ds structure for arm architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 64-bit time_t to solve y2038 problem + * - 2 miscellaneous 32-bit values + */ + +struct semid64_ds { + struct ipc64_perm sem_perm; /* permissions .. see ipc.h */ + __kernel_time_t sem_otime; /* last semop time */ + unsigned long __unused1; + __kernel_time_t sem_ctime; /* last change time */ + unsigned long __unused2; + unsigned long sem_nsems; /* no. of semaphores in array */ + unsigned long __unused3; + unsigned long __unused4; +}; + +#endif /* _ASMARM_SEMBUF_H */ diff --git a/arch/arm/include/asm/serial.h b/arch/arm/include/asm/serial.h new file mode 100644 index 00000000..ebb04909 --- /dev/null +++ b/arch/arm/include/asm/serial.h @@ -0,0 +1,19 @@ +/* + * arch/arm/include/asm/serial.h + * + * Copyright (C) 1996 Russell King. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Changelog: + * 15-10-1996 RMK Created + */ + +#ifndef __ASM_SERIAL_H +#define __ASM_SERIAL_H + +#define BASE_BAUD (1843200 / 16) + +#endif diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h new file mode 100644 index 00000000..ee2ad8ae --- /dev/null +++ b/arch/arm/include/asm/setup.h @@ -0,0 +1,226 @@ +/* + * linux/include/asm/setup.h + * + * Copyright (C) 1997-1999 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Structure passed to kernel to tell it about the + * hardware it's running on. See Documentation/arm/Setup + * for more info. + */ +#ifndef __ASMARM_SETUP_H +#define __ASMARM_SETUP_H + +#include + +#define COMMAND_LINE_SIZE 1024 + +/* The list ends with an ATAG_NONE node. */ +#define ATAG_NONE 0x00000000 + +struct tag_header { + __u32 size; + __u32 tag; +}; + +/* The list must start with an ATAG_CORE node */ +#define ATAG_CORE 0x54410001 + +struct tag_core { + __u32 flags; /* bit 0 = read-only */ + __u32 pagesize; + __u32 rootdev; +}; + +/* it is allowed to have multiple ATAG_MEM nodes */ +#define ATAG_MEM 0x54410002 + +struct tag_mem32 { + __u32 size; + __u32 start; /* physical start address */ +}; + +/* VGA text type displays */ +#define ATAG_VIDEOTEXT 0x54410003 + +struct tag_videotext { + __u8 x; + __u8 y; + __u16 video_page; + __u8 video_mode; + __u8 video_cols; + __u16 video_ega_bx; + __u8 video_lines; + __u8 video_isvga; + __u16 video_points; +}; + +/* describes how the ramdisk will be used in kernel */ +#define ATAG_RAMDISK 0x54410004 + +struct tag_ramdisk { + __u32 flags; /* bit 0 = load, bit 1 = prompt */ + __u32 size; /* decompressed ramdisk size in _kilo_ bytes */ + __u32 start; /* starting block of floppy-based RAM disk image */ +}; + +/* describes where the compressed ramdisk image lives (virtual address) */ +/* + * this one accidentally used virtual addresses - as such, + * it's deprecated. + */ +#define ATAG_INITRD 0x54410005 + +/* describes where the compressed ramdisk image lives (physical address) */ +#define ATAG_INITRD2 0x54420005 + +struct tag_initrd { + __u32 start; /* physical start address */ + __u32 size; /* size of compressed ramdisk image in bytes */ +}; + +/* board serial number. "64 bits should be enough for everybody" */ +#define ATAG_SERIAL 0x54410006 + +struct tag_serialnr { + __u32 low; + __u32 high; +}; + +/* board revision */ +#define ATAG_REVISION 0x54410007 + +struct tag_revision { + __u32 rev; +}; + +/* initial values for vesafb-type framebuffers. see struct screen_info + * in include/linux/tty.h + */ +#define ATAG_VIDEOLFB 0x54410008 + +struct tag_videolfb { + __u16 lfb_width; + __u16 lfb_height; + __u16 lfb_depth; + __u16 lfb_linelength; + __u32 lfb_base; + __u32 lfb_size; + __u8 red_size; + __u8 red_pos; + __u8 green_size; + __u8 green_pos; + __u8 blue_size; + __u8 blue_pos; + __u8 rsvd_size; + __u8 rsvd_pos; +}; + +/* command line: \0 terminated string */ +#define ATAG_CMDLINE 0x54410009 + +struct tag_cmdline { + char cmdline[1]; /* this is the minimum size */ +}; + +/* acorn RiscPC specific information */ +#define ATAG_ACORN 0x41000101 + +struct tag_acorn { + __u32 memc_control_reg; + __u32 vram_pages; + __u8 sounddefault; + __u8 adfsdrives; +}; + +/* footbridge memory clock, see arch/arm/mach-footbridge/arch.c */ +#define ATAG_MEMCLK 0x41000402 + +struct tag_memclk { + __u32 fmemclk; +}; + +struct tag { + struct tag_header hdr; + union { + struct tag_core core; + struct tag_mem32 mem; + struct tag_videotext videotext; + struct tag_ramdisk ramdisk; + struct tag_initrd initrd; + struct tag_serialnr serialnr; + struct tag_revision revision; + struct tag_videolfb videolfb; + struct tag_cmdline cmdline; + + /* + * Acorn specific + */ + struct tag_acorn acorn; + + /* + * DC21285 specific + */ + struct tag_memclk memclk; + } u; +}; + +struct tagtable { + __u32 tag; + int (*parse)(const struct tag *); +}; + +#define tag_member_present(tag,member) \ + ((unsigned long)(&((struct tag *)0L)->member + 1) \ + <= (tag)->hdr.size * 4) + +#define tag_next(t) ((struct tag *)((__u32 *)(t) + (t)->hdr.size)) +#define tag_size(type) ((sizeof(struct tag_header) + sizeof(struct type)) >> 2) + +#define for_each_tag(t,base) \ + for (t = base; t->hdr.size; t = tag_next(t)) + +#ifdef __KERNEL__ + +#define __tag __used __attribute__((__section__(".taglist.init"))) +#define __tagtable(tag, fn) \ +static struct tagtable __tagtable_##fn __tag = { tag, fn } + +/* + * Memory map description + */ +#define NR_BANKS 8 + +struct membank { + phys_addr_t start; + unsigned long size; + unsigned int highmem; +}; + +struct meminfo { + int nr_banks; + struct membank bank[NR_BANKS]; +}; + +extern struct meminfo meminfo; + +#define for_each_bank(iter,mi) \ + for (iter = 0; iter < (mi)->nr_banks; iter++) + +#define bank_pfn_start(bank) __phys_to_pfn((bank)->start) +#define bank_pfn_end(bank) __phys_to_pfn((bank)->start + (bank)->size) +#define bank_pfn_size(bank) ((bank)->size >> PAGE_SHIFT) +#define bank_phys_start(bank) (bank)->start +#define bank_phys_end(bank) ((bank)->start + (bank)->size) +#define bank_phys_size(bank) (bank)->size + +extern int arm_add_memory(phys_addr_t start, unsigned long size); +extern void early_print(const char *str, ...); +extern void dump_machine_table(void); + +#endif /* __KERNEL__ */ + +#endif diff --git a/arch/arm/include/asm/shmbuf.h b/arch/arm/include/asm/shmbuf.h new file mode 100644 index 00000000..2e5c67ba --- /dev/null +++ b/arch/arm/include/asm/shmbuf.h @@ -0,0 +1,42 @@ +#ifndef _ASMARM_SHMBUF_H +#define _ASMARM_SHMBUF_H + +/* + * The shmid64_ds structure for arm architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + * + * Pad space is left for: + * - 64-bit time_t to solve y2038 problem + * - 2 miscellaneous 32-bit values + */ + +struct shmid64_ds { + struct ipc64_perm shm_perm; /* operation perms */ + size_t shm_segsz; /* size of segment (bytes) */ + __kernel_time_t shm_atime; /* last attach time */ + unsigned long __unused1; + __kernel_time_t shm_dtime; /* last detach time */ + unsigned long __unused2; + __kernel_time_t shm_ctime; /* last change time */ + unsigned long __unused3; + __kernel_pid_t shm_cpid; /* pid of creator */ + __kernel_pid_t shm_lpid; /* pid of last operator */ + unsigned long shm_nattch; /* no. of current attaches */ + unsigned long __unused4; + unsigned long __unused5; +}; + +struct shminfo64 { + unsigned long shmmax; + unsigned long shmmin; + unsigned long shmmni; + unsigned long shmseg; + unsigned long shmall; + unsigned long __unused1; + unsigned long __unused2; + unsigned long __unused3; + unsigned long __unused4; +}; + +#endif /* _ASMARM_SHMBUF_H */ diff --git a/arch/arm/include/asm/shmparam.h b/arch/arm/include/asm/shmparam.h new file mode 100644 index 00000000..a5223b3a --- /dev/null +++ b/arch/arm/include/asm/shmparam.h @@ -0,0 +1,16 @@ +#ifndef _ASMARM_SHMPARAM_H +#define _ASMARM_SHMPARAM_H + +/* + * This should be the size of the virtually indexed cache/ways, + * or page size, whichever is greater since the cache aliases + * every size/ways bytes. + */ +#define SHMLBA (4 * PAGE_SIZE) /* attach addr a multiple of this */ + +/* + * Enforce SHMLBA in shmat + */ +#define __ARCH_FORCE_SHMLBA + +#endif /* _ASMARM_SHMPARAM_H */ diff --git a/arch/arm/include/asm/sigcontext.h b/arch/arm/include/asm/sigcontext.h new file mode 100644 index 00000000..fc0b80b6 --- /dev/null +++ b/arch/arm/include/asm/sigcontext.h @@ -0,0 +1,34 @@ +#ifndef _ASMARM_SIGCONTEXT_H +#define _ASMARM_SIGCONTEXT_H + +/* + * Signal context structure - contains all info to do with the state + * before the signal handler was invoked. Note: only add new entries + * to the end of the structure. + */ +struct sigcontext { + unsigned long trap_no; + unsigned long error_code; + unsigned long oldmask; + unsigned long arm_r0; + unsigned long arm_r1; + unsigned long arm_r2; + unsigned long arm_r3; + unsigned long arm_r4; + unsigned long arm_r5; + unsigned long arm_r6; + unsigned long arm_r7; + unsigned long arm_r8; + unsigned long arm_r9; + unsigned long arm_r10; + unsigned long arm_fp; + unsigned long arm_ip; + unsigned long arm_sp; + unsigned long arm_lr; + unsigned long arm_pc; + unsigned long arm_cpsr; + unsigned long fault_address; +}; + + +#endif diff --git a/arch/arm/include/asm/siginfo.h b/arch/arm/include/asm/siginfo.h new file mode 100644 index 00000000..5e21852e --- /dev/null +++ b/arch/arm/include/asm/siginfo.h @@ -0,0 +1,6 @@ +#ifndef _ASMARM_SIGINFO_H +#define _ASMARM_SIGINFO_H + +#include + +#endif diff --git a/arch/arm/include/asm/signal.h b/arch/arm/include/asm/signal.h new file mode 100644 index 00000000..43ba0fb1 --- /dev/null +++ b/arch/arm/include/asm/signal.h @@ -0,0 +1,164 @@ +#ifndef _ASMARM_SIGNAL_H +#define _ASMARM_SIGNAL_H + +#include + +/* Avoid too many header ordering problems. */ +struct siginfo; + +#ifdef __KERNEL__ +/* Most things should be clean enough to redefine this at will, if care + is taken to make libc match. */ + +#define _NSIG 64 +#define _NSIG_BPW 32 +#define _NSIG_WORDS (_NSIG / _NSIG_BPW) + +typedef unsigned long old_sigset_t; /* at least 32 bits */ + +typedef struct { + unsigned long sig[_NSIG_WORDS]; +} sigset_t; + +#else +/* Here we must cater to libcs that poke about in kernel headers. */ + +#define NSIG 32 +typedef unsigned long sigset_t; + +#endif /* __KERNEL__ */ + +#define SIGHUP 1 +#define SIGINT 2 +#define SIGQUIT 3 +#define SIGILL 4 +#define SIGTRAP 5 +#define SIGABRT 6 +#define SIGIOT 6 +#define SIGBUS 7 +#define SIGFPE 8 +#define SIGKILL 9 +#define SIGUSR1 10 +#define SIGSEGV 11 +#define SIGUSR2 12 +#define SIGPIPE 13 +#define SIGALRM 14 +#define SIGTERM 15 +#define SIGSTKFLT 16 +#define SIGCHLD 17 +#define SIGCONT 18 +#define SIGSTOP 19 +#define SIGTSTP 20 +#define SIGTTIN 21 +#define SIGTTOU 22 +#define SIGURG 23 +#define SIGXCPU 24 +#define SIGXFSZ 25 +#define SIGVTALRM 26 +#define SIGPROF 27 +#define SIGWINCH 28 +#define SIGIO 29 +#define SIGPOLL SIGIO +/* +#define SIGLOST 29 +*/ +#define SIGPWR 30 +#define SIGSYS 31 +#define SIGUNUSED 31 + +/* These should not be considered constants from userland. */ +#define SIGRTMIN 32 +#define SIGRTMAX _NSIG + +#define SIGSWI 32 + +/* + * SA_FLAGS values: + * + * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop. + * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies. + * SA_SIGINFO deliver the signal with SIGINFO structs + * SA_THIRTYTWO delivers the signal in 32-bit mode, even if the task + * is running in 26-bit. + * SA_ONSTACK allows alternate signal stacks (see sigaltstack(2)). + * SA_RESTART flag to get restarting signals (which were the default long ago) + * SA_NODEFER prevents the current signal from being masked in the handler. + * SA_RESETHAND clears the handler when the signal is delivered. + * + * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single + * Unix names RESETHAND and NODEFER respectively. + */ +#define SA_NOCLDSTOP 0x00000001 +#define SA_NOCLDWAIT 0x00000002 +#define SA_SIGINFO 0x00000004 +#define SA_THIRTYTWO 0x02000000 +#define SA_RESTORER 0x04000000 +#define SA_ONSTACK 0x08000000 +#define SA_RESTART 0x10000000 +#define SA_NODEFER 0x40000000 +#define SA_RESETHAND 0x80000000 + +#define SA_NOMASK SA_NODEFER +#define SA_ONESHOT SA_RESETHAND + + +/* + * sigaltstack controls + */ +#define SS_ONSTACK 1 +#define SS_DISABLE 2 + +#define MINSIGSTKSZ 2048 +#define SIGSTKSZ 8192 + +#include + +#ifdef __KERNEL__ +struct old_sigaction { + __sighandler_t sa_handler; + old_sigset_t sa_mask; + unsigned long sa_flags; + __sigrestore_t sa_restorer; +}; + +struct sigaction { + __sighandler_t sa_handler; + unsigned long sa_flags; + __sigrestore_t sa_restorer; + sigset_t sa_mask; /* mask last for extensibility */ +}; + +struct k_sigaction { + struct sigaction sa; +}; + +#else +/* Here we must cater to libcs that poke about in kernel headers. */ + +struct sigaction { + union { + __sighandler_t _sa_handler; + void (*_sa_sigaction)(int, struct siginfo *, void *); + } _u; + sigset_t sa_mask; + unsigned long sa_flags; + void (*sa_restorer)(void); +}; + +#define sa_handler _u._sa_handler +#define sa_sigaction _u._sa_sigaction + +#endif /* __KERNEL__ */ + +typedef struct sigaltstack { + void __user *ss_sp; + int ss_flags; + size_t ss_size; +} stack_t; + +#ifdef __KERNEL__ +#include +#define ptrace_signal_deliver(regs, cookie) do { } while (0) +#endif + +#endif diff --git a/arch/arm/include/asm/sizes.h b/arch/arm/include/asm/sizes.h new file mode 100644 index 00000000..154b89b8 --- /dev/null +++ b/arch/arm/include/asm/sizes.h @@ -0,0 +1,21 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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 + */ +/* Size definitions + * Copyright (C) ARM Limited 1998. All rights reserved. + */ +#include + +#define SZ_48M (SZ_32M + SZ_16M) diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h new file mode 100644 index 00000000..74f288f4 --- /dev/null +++ b/arch/arm/include/asm/smp.h @@ -0,0 +1,98 @@ +/* + * arch/arm/include/asm/smp.h + * + * Copyright (C) 2004-2005 ARM Ltd. + * + * 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. + */ +#ifndef __ASM_ARM_SMP_H +#define __ASM_ARM_SMP_H + +#include +#include +#include + +#ifndef CONFIG_SMP +# error " included in non-SMP build" +#endif + +#define raw_smp_processor_id() (current_thread_info()->cpu) + +struct seq_file; + +/* + * generate IPI list text + */ +extern void show_ipi_list(struct seq_file *, int); + +/* + * Called from assembly code, this handles an IPI. + */ +asmlinkage void do_IPI(int ipinr, struct pt_regs *regs); + +/* + * Setup the set of possible CPUs (via set_cpu_possible) + */ +extern void smp_init_cpus(void); + + +/* + * Provide a function to raise an IPI cross call on CPUs in callmap. + */ +extern void set_smp_cross_call(void (*)(const struct cpumask *, unsigned int)); + +/* + * Boot a secondary CPU, and assign it the specified idle task. + * This also gives us the initial stack to use for this CPU. + */ +extern int boot_secondary(unsigned int cpu, struct task_struct *); + +/* + * Called from platform specific assembly code, this is the + * secondary CPU entry point. + */ +asmlinkage void secondary_start_kernel(void); + +/* + * Perform platform specific initialisation of the specified CPU. + */ +extern void platform_secondary_init(unsigned int cpu); + +/* + * Initialize cpu_possible map, and enable coherency + */ +extern void platform_smp_prepare_cpus(unsigned int); + +/* + * Initial data for bringing up a secondary CPU. + */ +struct secondary_data { + unsigned long pgdir; + unsigned long swapper_pg_dir; + void *stack; +}; +extern struct secondary_data secondary_data; + +extern int __cpu_disable(void); +extern int platform_cpu_disable(unsigned int cpu); + +extern void __cpu_die(unsigned int cpu); +extern void cpu_die(void); + +extern void platform_cpu_die(unsigned int cpu); +extern int platform_cpu_kill(unsigned int cpu); +extern void platform_cpu_enable(unsigned int cpu); + +extern void arch_send_call_function_single_ipi(int cpu); +extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); + +/* + * show local interrupt info + */ +extern void show_local_irqs(struct seq_file *, int); + +extern void smp_send_all_cpu_backtrace(void); + +#endif /* ifndef __ASM_ARM_SMP_H */ diff --git a/arch/arm/include/asm/smp_plat.h b/arch/arm/include/asm/smp_plat.h new file mode 100644 index 00000000..f24c1b9e --- /dev/null +++ b/arch/arm/include/asm/smp_plat.h @@ -0,0 +1,46 @@ +/* + * ARM specific SMP header, this contains our implementation + * details. + */ +#ifndef __ASMARM_SMP_PLAT_H +#define __ASMARM_SMP_PLAT_H + +#include + +/* + * Return true if we are running on a SMP platform + */ +static inline bool is_smp(void) +{ +#ifndef CONFIG_SMP + return false; +#elif defined(CONFIG_SMP_ON_UP) + extern unsigned int smp_on_up; + return !!smp_on_up; +#else + return true; +#endif +} + +/* all SMP configurations have the extended CPUID registers */ +static inline int tlb_ops_need_broadcast(void) +{ + if (!is_smp()) + return 0; + + return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 2; +} + +#if !defined(CONFIG_SMP) || __LINUX_ARM_ARCH__ >= 7 +#define cache_ops_need_broadcast() 0 +#else +static inline int cache_ops_need_broadcast(void) +{ + if (!is_smp()) + return 0; + + return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 1; +} +#endif + +#endif diff --git a/arch/arm/include/asm/smp_scu.h b/arch/arm/include/asm/smp_scu.h new file mode 100644 index 00000000..4eb6d005 --- /dev/null +++ b/arch/arm/include/asm/smp_scu.h @@ -0,0 +1,14 @@ +#ifndef __ASMARM_ARCH_SCU_H +#define __ASMARM_ARCH_SCU_H + +#define SCU_PM_NORMAL 0 +#define SCU_PM_DORMANT 2 +#define SCU_PM_POWEROFF 3 + +#ifndef __ASSEMBLER__ +unsigned int scu_get_core_count(void __iomem *); +void scu_enable(void __iomem *); +int scu_power_mode(void __iomem *, unsigned int); +#endif + +#endif diff --git a/arch/arm/include/asm/smp_twd.h b/arch/arm/include/asm/smp_twd.h new file mode 100644 index 00000000..fed9981f --- /dev/null +++ b/arch/arm/include/asm/smp_twd.h @@ -0,0 +1,28 @@ +#ifndef __ASMARM_SMP_TWD_H +#define __ASMARM_SMP_TWD_H + +#define TWD_TIMER_LOAD 0x00 +#define TWD_TIMER_COUNTER 0x04 +#define TWD_TIMER_CONTROL 0x08 +#define TWD_TIMER_INTSTAT 0x0C + +#define TWD_WDOG_LOAD 0x20 +#define TWD_WDOG_COUNTER 0x24 +#define TWD_WDOG_CONTROL 0x28 +#define TWD_WDOG_INTSTAT 0x2C +#define TWD_WDOG_RESETSTAT 0x30 +#define TWD_WDOG_DISABLE 0x34 + +#define TWD_TIMER_CONTROL_ENABLE (1 << 0) +#define TWD_TIMER_CONTROL_ONESHOT (0 << 1) +#define TWD_TIMER_CONTROL_PERIODIC (1 << 1) +#define TWD_TIMER_CONTROL_IT_ENABLE (1 << 2) + +struct clock_event_device; + +extern void __iomem *twd_base; + +int twd_timer_ack(void); +void twd_timer_setup(struct clock_event_device *); + +#endif diff --git a/arch/arm/include/asm/socket.h b/arch/arm/include/asm/socket.h new file mode 100644 index 00000000..90ffd04b --- /dev/null +++ b/arch/arm/include/asm/socket.h @@ -0,0 +1,65 @@ +#ifndef _ASMARM_SOCKET_H +#define _ASMARM_SOCKET_H + +#include + +/* For setsockopt(2) */ +#define SOL_SOCKET 1 + +#define SO_DEBUG 1 +#define SO_REUSEADDR 2 +#define SO_TYPE 3 +#define SO_ERROR 4 +#define SO_DONTROUTE 5 +#define SO_BROADCAST 6 +#define SO_SNDBUF 7 +#define SO_RCVBUF 8 +#define SO_SNDBUFFORCE 32 +#define SO_RCVBUFFORCE 33 +#define SO_KEEPALIVE 9 +#define SO_OOBINLINE 10 +#define SO_NO_CHECK 11 +#define SO_PRIORITY 12 +#define SO_LINGER 13 +#define SO_BSDCOMPAT 14 +/* To add :#define SO_REUSEPORT 15 */ +#define SO_PASSCRED 16 +#define SO_PEERCRED 17 +#define SO_RCVLOWAT 18 +#define SO_SNDLOWAT 19 +#define SO_RCVTIMEO 20 +#define SO_SNDTIMEO 21 + +/* Security levels - as per NRL IPv6 - don't actually do anything */ +#define SO_SECURITY_AUTHENTICATION 22 +#define SO_SECURITY_ENCRYPTION_TRANSPORT 23 +#define SO_SECURITY_ENCRYPTION_NETWORK 24 + +#define SO_BINDTODEVICE 25 + +/* Socket filtering */ +#define SO_ATTACH_FILTER 26 +#define SO_DETACH_FILTER 27 + +#define SO_PEERNAME 28 +#define SO_TIMESTAMP 29 +#define SCM_TIMESTAMP SO_TIMESTAMP + +#define SO_ACCEPTCONN 30 + +#define SO_PEERSEC 31 +#define SO_PASSSEC 34 +#define SO_TIMESTAMPNS 35 +#define SCM_TIMESTAMPNS SO_TIMESTAMPNS + +#define SO_MARK 36 + +#define SO_TIMESTAMPING 37 +#define SCM_TIMESTAMPING SO_TIMESTAMPING + +#define SO_PROTOCOL 38 +#define SO_DOMAIN 39 + +#define SO_RXQ_OVFL 40 + +#endif /* _ASM_SOCKET_H */ diff --git a/arch/arm/include/asm/sockios.h b/arch/arm/include/asm/sockios.h new file mode 100644 index 00000000..a2588a25 --- /dev/null +++ b/arch/arm/include/asm/sockios.h @@ -0,0 +1,13 @@ +#ifndef __ARCH_ARM_SOCKIOS_H +#define __ARCH_ARM_SOCKIOS_H + +/* Socket-level I/O control calls. */ +#define FIOSETOWN 0x8901 +#define SIOCSPGRP 0x8902 +#define FIOGETOWN 0x8903 +#define SIOCGPGRP 0x8904 +#define SIOCATMARK 0x8905 +#define SIOCGSTAMP 0x8906 /* Get stamp (timeval) */ +#define SIOCGSTAMPNS 0x8907 /* Get stamp (timespec) */ + +#endif diff --git a/arch/arm/include/asm/sparsemem.h b/arch/arm/include/asm/sparsemem.h new file mode 100644 index 00000000..00098615 --- /dev/null +++ b/arch/arm/include/asm/sparsemem.h @@ -0,0 +1,24 @@ +#ifndef ASMARM_SPARSEMEM_H +#define ASMARM_SPARSEMEM_H + +#include + +/* + * Two definitions are required for sparsemem: + * + * MAX_PHYSMEM_BITS: The number of physical address bits required + * to address the last byte of memory. + * + * SECTION_SIZE_BITS: The number of physical address bits to cover + * the maximum amount of memory in a section. + * + * Eg, if you have 2 banks of up to 64MB at 0x80000000, 0x84000000, + * then MAX_PHYSMEM_BITS is 32, SECTION_SIZE_BITS is 26. + * + * Define these in your mach/memory.h. + */ +#if !defined(SECTION_SIZE_BITS) || !defined(MAX_PHYSMEM_BITS) +#error Sparsemem is not supported on this platform +#endif + +#endif diff --git a/arch/arm/include/asm/spinlock.h b/arch/arm/include/asm/spinlock.h new file mode 100644 index 00000000..65fa3c88 --- /dev/null +++ b/arch/arm/include/asm/spinlock.h @@ -0,0 +1,268 @@ +#ifndef __ASM_SPINLOCK_H +#define __ASM_SPINLOCK_H + +#if __LINUX_ARM_ARCH__ < 6 +#error SMP not supported on pre-ARMv6 CPUs +#endif + +#include + +/* + * sev and wfe are ARMv6K extensions. Uniprocessor ARMv6 may not have the K + * extensions, so when running on UP, we have to patch these instructions away. + */ +#define ALT_SMP(smp, up) \ + "9998: " smp "\n" \ + " .pushsection \".alt.smp.init\", \"a\"\n" \ + " .long 9998b\n" \ + " " up "\n" \ + " .popsection\n" + +#ifdef CONFIG_THUMB2_KERNEL +#define SEV ALT_SMP("sev.w", "nop.w") +/* + * For Thumb-2, special care is needed to ensure that the conditional WFE + * instruction really does assemble to exactly 4 bytes (as required by + * the SMP_ON_UP fixup code). By itself "wfene" might cause the + * assembler to insert a extra (16-bit) IT instruction, depending on the + * presence or absence of neighbouring conditional instructions. + * + * To avoid this unpredictableness, an approprite IT is inserted explicitly: + * the assembler won't change IT instructions which are explicitly present + * in the input. + */ +#define WFE(cond) ALT_SMP( \ + "it " cond "\n\t" \ + "wfe" cond ".n", \ + \ + "nop.w" \ +) +#else +#define SEV ALT_SMP("sev", "nop") +#define WFE(cond) ALT_SMP("wfe" cond, "nop") +#endif + +static inline void dsb_sev(void) +{ +#if __LINUX_ARM_ARCH__ >= 7 + __asm__ __volatile__ ( + "dsb\n" + SEV + ); +#else + __asm__ __volatile__ ( + "mcr p15, 0, %0, c7, c10, 4\n" + SEV + : : "r" (0) + ); +#endif +} + +/* + * ARMv6 Spin-locking. + * + * We exclusively read the old value. If it is zero, we may have + * won the lock, so we try exclusively storing it. A memory barrier + * is required after we get a lock, and before we release it, because + * V6 CPUs are assumed to have weakly ordered memory. + * + * Unlocked value: 0 + * Locked value: 1 + */ + +#define arch_spin_is_locked(x) ((x)->lock != 0) +#define arch_spin_unlock_wait(lock) \ + do { while (arch_spin_is_locked(lock)) cpu_relax(); } while (0) + +#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock) + +static inline void arch_spin_lock(arch_spinlock_t *lock) +{ + unsigned long tmp; + + __asm__ __volatile__( +"1: ldrex %0, [%1]\n" +" teq %0, #0\n" + WFE("ne") +" strexeq %0, %2, [%1]\n" +" teqeq %0, #0\n" +" bne 1b" + : "=&r" (tmp) + : "r" (&lock->lock), "r" (1) + : "cc"); + + smp_mb(); +} + +static inline int arch_spin_trylock(arch_spinlock_t *lock) +{ + unsigned long tmp; + + __asm__ __volatile__( +" ldrex %0, [%1]\n" +" teq %0, #0\n" +" strexeq %0, %2, [%1]" + : "=&r" (tmp) + : "r" (&lock->lock), "r" (1) + : "cc"); + + if (tmp == 0) { + smp_mb(); + return 1; + } else { + return 0; + } +} + +static inline void arch_spin_unlock(arch_spinlock_t *lock) +{ + smp_mb(); + + __asm__ __volatile__( +" str %1, [%0]\n" + : + : "r" (&lock->lock), "r" (0) + : "cc"); + + dsb_sev(); +} + +/* + * RWLOCKS + * + * + * Write locks are easy - we just set bit 31. When unlocking, we can + * just write zero since the lock is exclusively held. + */ + +static inline void arch_write_lock(arch_rwlock_t *rw) +{ + unsigned long tmp; + + __asm__ __volatile__( +"1: ldrex %0, [%1]\n" +" teq %0, #0\n" + WFE("ne") +" strexeq %0, %2, [%1]\n" +" teq %0, #0\n" +" bne 1b" + : "=&r" (tmp) + : "r" (&rw->lock), "r" (0x80000000) + : "cc"); + + smp_mb(); +} + +static inline int arch_write_trylock(arch_rwlock_t *rw) +{ + unsigned long tmp; + + __asm__ __volatile__( +"1: ldrex %0, [%1]\n" +" teq %0, #0\n" +" strexeq %0, %2, [%1]" + : "=&r" (tmp) + : "r" (&rw->lock), "r" (0x80000000) + : "cc"); + + if (tmp == 0) { + smp_mb(); + return 1; + } else { + return 0; + } +} + +static inline void arch_write_unlock(arch_rwlock_t *rw) +{ + smp_mb(); + + __asm__ __volatile__( + "str %1, [%0]\n" + : + : "r" (&rw->lock), "r" (0) + : "cc"); + + dsb_sev(); +} + +/* write_can_lock - would write_trylock() succeed? */ +#define arch_write_can_lock(x) ((x)->lock == 0) + +/* + * Read locks are a bit more hairy: + * - Exclusively load the lock value. + * - Increment it. + * - Store new lock value if positive, and we still own this location. + * If the value is negative, we've already failed. + * - If we failed to store the value, we want a negative result. + * - If we failed, try again. + * Unlocking is similarly hairy. We may have multiple read locks + * currently active. However, we know we won't have any write + * locks. + */ +static inline void arch_read_lock(arch_rwlock_t *rw) +{ + unsigned long tmp, tmp2; + + __asm__ __volatile__( +"1: ldrex %0, [%2]\n" +" adds %0, %0, #1\n" +" strexpl %1, %0, [%2]\n" + WFE("mi") +" rsbpls %0, %1, #0\n" +" bmi 1b" + : "=&r" (tmp), "=&r" (tmp2) + : "r" (&rw->lock) + : "cc"); + + smp_mb(); +} + +static inline void arch_read_unlock(arch_rwlock_t *rw) +{ + unsigned long tmp, tmp2; + + smp_mb(); + + __asm__ __volatile__( +"1: ldrex %0, [%2]\n" +" sub %0, %0, #1\n" +" strex %1, %0, [%2]\n" +" teq %1, #0\n" +" bne 1b" + : "=&r" (tmp), "=&r" (tmp2) + : "r" (&rw->lock) + : "cc"); + + if (tmp == 0) + dsb_sev(); +} + +static inline int arch_read_trylock(arch_rwlock_t *rw) +{ + unsigned long tmp, tmp2 = 1; + + __asm__ __volatile__( +"1: ldrex %0, [%2]\n" +" adds %0, %0, #1\n" +" strexpl %1, %0, [%2]\n" + : "=&r" (tmp), "+r" (tmp2) + : "r" (&rw->lock) + : "cc"); + + smp_mb(); + return tmp2 == 0; +} + +/* read_can_lock - would read_trylock() succeed? */ +#define arch_read_can_lock(x) ((x)->lock < 0x80000000) + +#define arch_read_lock_flags(lock, flags) arch_read_lock(lock) +#define arch_write_lock_flags(lock, flags) arch_write_lock(lock) + +#define arch_spin_relax(lock) cpu_relax() +#define arch_read_relax(lock) cpu_relax() +#define arch_write_relax(lock) cpu_relax() + +#endif /* __ASM_SPINLOCK_H */ diff --git a/arch/arm/include/asm/spinlock_types.h b/arch/arm/include/asm/spinlock_types.h new file mode 100644 index 00000000..d14d197a --- /dev/null +++ b/arch/arm/include/asm/spinlock_types.h @@ -0,0 +1,20 @@ +#ifndef __ASM_SPINLOCK_TYPES_H +#define __ASM_SPINLOCK_TYPES_H + +#ifndef __LINUX_SPINLOCK_TYPES_H +# error "please don't include this file directly" +#endif + +typedef struct { + volatile unsigned int lock; +} arch_spinlock_t; + +#define __ARCH_SPIN_LOCK_UNLOCKED { 0 } + +typedef struct { + volatile unsigned int lock; +} arch_rwlock_t; + +#define __ARCH_RW_LOCK_UNLOCKED { 0 } + +#endif diff --git a/arch/arm/include/asm/stackprotector.h b/arch/arm/include/asm/stackprotector.h new file mode 100644 index 00000000..de003327 --- /dev/null +++ b/arch/arm/include/asm/stackprotector.h @@ -0,0 +1,38 @@ +/* + * GCC stack protector support. + * + * Stack protector works by putting predefined pattern at the start of + * the stack frame and verifying that it hasn't been overwritten when + * returning from the function. The pattern is called stack canary + * and gcc expects it to be defined by a global variable called + * "__stack_chk_guard" on ARM. This unfortunately means that on SMP + * we cannot have a different canary value per task. + */ + +#ifndef _ASM_STACKPROTECTOR_H +#define _ASM_STACKPROTECTOR_H 1 + +#include +#include + +extern unsigned long __stack_chk_guard; + +/* + * Initialize the stackprotector canary value. + * + * NOTE: this must only be called from functions that never return, + * and it must always be inlined. + */ +static __always_inline void boot_init_stack_canary(void) +{ + unsigned long canary; + + /* Try to get a semi random initial value. */ + get_random_bytes(&canary, sizeof(canary)); + canary ^= LINUX_VERSION_CODE; + + current->stack_canary = canary; + __stack_chk_guard = current->stack_canary; +} + +#endif /* _ASM_STACKPROTECTOR_H */ diff --git a/arch/arm/include/asm/stacktrace.h b/arch/arm/include/asm/stacktrace.h new file mode 100644 index 00000000..4d0a1644 --- /dev/null +++ b/arch/arm/include/asm/stacktrace.h @@ -0,0 +1,15 @@ +#ifndef __ASM_STACKTRACE_H +#define __ASM_STACKTRACE_H + +struct stackframe { + unsigned long fp; + unsigned long sp; + unsigned long lr; + unsigned long pc; +}; + +extern int unwind_frame(struct stackframe *frame); +extern void walk_stackframe(struct stackframe *frame, + int (*fn)(struct stackframe *, void *), void *data); + +#endif /* __ASM_STACKTRACE_H */ diff --git a/arch/arm/include/asm/stat.h b/arch/arm/include/asm/stat.h new file mode 100644 index 00000000..42c0c139 --- /dev/null +++ b/arch/arm/include/asm/stat.h @@ -0,0 +1,87 @@ +#ifndef _ASMARM_STAT_H +#define _ASMARM_STAT_H + +struct __old_kernel_stat { + unsigned short st_dev; + unsigned short st_ino; + unsigned short st_mode; + unsigned short st_nlink; + unsigned short st_uid; + unsigned short st_gid; + unsigned short st_rdev; + unsigned long st_size; + unsigned long st_atime; + unsigned long st_mtime; + unsigned long st_ctime; +}; + +#define STAT_HAVE_NSEC + +struct stat { +#if defined(__ARMEB__) + unsigned short st_dev; + unsigned short __pad1; +#else + unsigned long st_dev; +#endif + unsigned long st_ino; + unsigned short st_mode; + unsigned short st_nlink; + unsigned short st_uid; + unsigned short st_gid; +#if defined(__ARMEB__) + unsigned short st_rdev; + unsigned short __pad2; +#else + unsigned long st_rdev; +#endif + unsigned long st_size; + unsigned long st_blksize; + unsigned long st_blocks; + unsigned long st_atime; + unsigned long st_atime_nsec; + unsigned long st_mtime; + unsigned long st_mtime_nsec; + unsigned long st_ctime; + unsigned long st_ctime_nsec; + unsigned long __unused4; + unsigned long __unused5; +}; + +/* This matches struct stat64 in glibc2.1, hence the absolutely + * insane amounts of padding around dev_t's. + * Note: The kernel zero's the padded region because glibc might read them + * in the hope that the kernel has stretched to using larger sizes. + */ +struct stat64 { + unsigned long long st_dev; + unsigned char __pad0[4]; + +#define STAT64_HAS_BROKEN_ST_INO 1 + unsigned long __st_ino; + unsigned int st_mode; + unsigned int st_nlink; + + unsigned long st_uid; + unsigned long st_gid; + + unsigned long long st_rdev; + unsigned char __pad3[4]; + + long long st_size; + unsigned long st_blksize; + unsigned long long st_blocks; /* Number 512-byte blocks allocated. */ + + unsigned long st_atime; + unsigned long st_atime_nsec; + + unsigned long st_mtime; + unsigned long st_mtime_nsec; + + unsigned long st_ctime; + unsigned long st_ctime_nsec; + + unsigned long long st_ino; +}; + +#endif diff --git a/arch/arm/include/asm/statfs.h b/arch/arm/include/asm/statfs.h new file mode 100644 index 00000000..079447c0 --- /dev/null +++ b/arch/arm/include/asm/statfs.h @@ -0,0 +1,12 @@ +#ifndef _ASMARM_STATFS_H +#define _ASMARM_STATFS_H + +/* + * With EABI there is 4 bytes of padding added to this structure. + * Let's pack it so the padding goes away to simplify dual ABI support. + * Note that user space does NOT have to pack this structure. + */ +#define ARCH_PACK_STATFS64 __attribute__((packed,aligned(4))) + +#include +#endif diff --git a/arch/arm/include/asm/string.h b/arch/arm/include/asm/string.h new file mode 100644 index 00000000..cf4f3aad --- /dev/null +++ b/arch/arm/include/asm/string.h @@ -0,0 +1,41 @@ +#ifndef __ASM_ARM_STRING_H +#define __ASM_ARM_STRING_H + +/* + * We don't do inline string functions, since the + * optimised inline asm versions are not small. + */ + +#define __HAVE_ARCH_STRRCHR +extern char * strrchr(const char * s, int c); + +#define __HAVE_ARCH_STRCHR +extern char * strchr(const char * s, int c); + +#define __HAVE_ARCH_MEMCPY +extern void * memcpy(void *, const void *, __kernel_size_t); + +#define __HAVE_ARCH_MEMMOVE +extern void * memmove(void *, const void *, __kernel_size_t); + +#define __HAVE_ARCH_MEMCHR +extern void * memchr(const void *, int, __kernel_size_t); + +#define __HAVE_ARCH_MEMSET +extern void * memset(void *, int, __kernel_size_t); + +extern void __memzero(void *ptr, __kernel_size_t n); + +#define memset(p,v,n) \ + ({ \ + void *__p = (p); size_t __n = n; \ + if ((__n) != 0) { \ + if (__builtin_constant_p((v)) && (v) == 0) \ + __memzero((__p),(__n)); \ + else \ + memset((__p),(v),(__n)); \ + } \ + (__p); \ + }) + +#endif diff --git a/arch/arm/include/asm/swab.h b/arch/arm/include/asm/swab.h new file mode 100644 index 00000000..9997ad20 --- /dev/null +++ b/arch/arm/include/asm/swab.h @@ -0,0 +1,69 @@ +/* + * arch/arm/include/asm/byteorder.h + * + * ARM Endian-ness. In little endian mode, the data bus is connected such + * that byte accesses appear as: + * 0 = d0...d7, 1 = d8...d15, 2 = d16...d23, 3 = d24...d31 + * and word accesses (data or instruction) appear as: + * d0...d31 + * + * When in big endian mode, byte accesses appear as: + * 0 = d24...d31, 1 = d16...d23, 2 = d8...d15, 3 = d0...d7 + * and word accesses (data or instruction) appear as: + * d0...d31 + */ +#ifndef __ASM_ARM_SWAB_H +#define __ASM_ARM_SWAB_H + +#include +#include + +#if !defined(__STRICT_ANSI__) || defined(__KERNEL__) +# define __SWAB_64_THRU_32__ +#endif + +#if defined(__KERNEL__) && __LINUX_ARM_ARCH__ >= 6 + +static inline __attribute_const__ __u16 __arch_swab16(__u16 x) +{ + __asm__ ("rev16 %0, %1" : "=r" (x) : "r" (x)); + return x; +} +#define __arch_swab16 __arch_swab16 + +static inline __attribute_const__ __u32 __arch_swab32(__u32 x) +{ + __asm__ ("rev %0, %1" : "=r" (x) : "r" (x)); + return x; +} +#define __arch_swab32 __arch_swab32 + +#else + +static inline __attribute_const__ __u32 __arch_swab32(__u32 x) +{ + __u32 t; + +#ifndef __thumb__ + if (!__builtin_constant_p(x)) { + /* + * The compiler needs a bit of a hint here to always do the + * right thing and not screw it up to different degrees + * depending on the gcc version. + */ + asm ("eor\t%0, %1, %1, ror #16" : "=r" (t) : "r" (x)); + } else +#endif + t = x ^ ((x << 16) | (x >> 16)); /* eor r1,r0,r0,ror #16 */ + + x = (x << 24) | (x >> 8); /* mov r0,r0,ror #8 */ + t &= ~0x00FF0000; /* bic r1,r1,#0x00FF0000 */ + x ^= (t >> 8); /* eor r0,r0,r1,lsr #8 */ + + return x; +} +#define __arch_swab32 __arch_swab32 + +#endif + +#endif diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h new file mode 100644 index 00000000..832888d0 --- /dev/null +++ b/arch/arm/include/asm/system.h @@ -0,0 +1,542 @@ +#ifndef __ASM_ARM_SYSTEM_H +#define __ASM_ARM_SYSTEM_H + +#ifdef __KERNEL__ + +#define CPU_ARCH_UNKNOWN 0 +#define CPU_ARCH_ARMv3 1 +#define CPU_ARCH_ARMv4 2 +#define CPU_ARCH_ARMv4T 3 +#define CPU_ARCH_ARMv5 4 +#define CPU_ARCH_ARMv5T 5 +#define CPU_ARCH_ARMv5TE 6 +#define CPU_ARCH_ARMv5TEJ 7 +#define CPU_ARCH_ARMv6 8 +#define CPU_ARCH_ARMv7 9 + +/* + * CR1 bits (CP#15 CR1) + */ +#define CR_M (1 << 0) /* MMU enable */ +#define CR_A (1 << 1) /* Alignment abort enable */ +#define CR_C (1 << 2) /* Dcache enable */ +#define CR_W (1 << 3) /* Write buffer enable */ +#define CR_P (1 << 4) /* 32-bit exception handler */ +#define CR_D (1 << 5) /* 32-bit data address range */ +#define CR_L (1 << 6) /* Implementation defined */ +#define CR_B (1 << 7) /* Big endian */ +#define CR_S (1 << 8) /* System MMU protection */ +#define CR_R (1 << 9) /* ROM MMU protection */ +#define CR_F (1 << 10) /* Implementation defined */ +#define CR_Z (1 << 11) /* Implementation defined */ +#define CR_I (1 << 12) /* Icache enable */ +#define CR_V (1 << 13) /* Vectors relocated to 0xffff0000 */ +#define CR_RR (1 << 14) /* Round Robin cache replacement */ +#define CR_L4 (1 << 15) /* LDR pc can set T bit */ +#define CR_DT (1 << 16) +#define CR_IT (1 << 18) +#define CR_ST (1 << 19) +#define CR_FI (1 << 21) /* Fast interrupt (lower latency mode) */ +#define CR_U (1 << 22) /* Unaligned access operation */ +#define CR_XP (1 << 23) /* Extended page tables */ +#define CR_VE (1 << 24) /* Vectored interrupts */ +#define CR_EE (1 << 25) /* Exception (Big) Endian */ +#define CR_TRE (1 << 28) /* TEX remap enable */ +#define CR_AFE (1 << 29) /* Access flag enable */ +#define CR_TE (1 << 30) /* Thumb exception enable */ + +/* + * This is used to ensure the compiler did actually allocate the register we + * asked it for some inline assembly sequences. Apparently we can't trust + * the compiler from one version to another so a bit of paranoia won't hurt. + * This string is meant to be concatenated with the inline asm string and + * will cause compilation to stop on mismatch. + * (for details, see gcc PR 15089) + */ +#define __asmeq(x, y) ".ifnc " x "," y " ; .err ; .endif\n\t" + +#ifndef __ASSEMBLY__ + +#include +#include + +#include + +#define __exception __attribute__((section(".exception.text"))) +#ifdef CONFIG_FUNCTION_GRAPH_TRACER +#define __exception_irq_entry __irq_entry +#else +#define __exception_irq_entry __exception +#endif + +struct thread_info; +struct task_struct; + +/* information about the system we're running on */ +extern unsigned int system_rev; +extern unsigned int system_serial_low; +extern unsigned int system_serial_high; +extern unsigned int mem_fclk_21285; + +struct pt_regs; + +void die(const char *msg, struct pt_regs *regs, int err); + +struct siginfo; +void arm_notify_die(const char *str, struct pt_regs *regs, struct siginfo *info, + unsigned long err, unsigned long trap); + +void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int, + struct pt_regs *), + int sig, int code, const char *name); + +void hook_ifault_code(int nr, int (*fn)(unsigned long, unsigned int, + struct pt_regs *), + int sig, int code, const char *name); + +#define xchg(ptr,x) \ + ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) + +extern asmlinkage void __backtrace(void); +extern asmlinkage void c_backtrace(unsigned long fp, int pmode); + +struct mm_struct; +extern void show_pte(struct mm_struct *mm, unsigned long addr); +extern void __show_regs(struct pt_regs *); + +extern int cpu_architecture(void); +extern void cpu_init(void); + +void arm_machine_restart(char mode, const char *cmd); +extern void (*arm_pm_restart)(char str, const char *cmd); + +#define UDBG_UNDEFINED (1 << 0) +#define UDBG_SYSCALL (1 << 1) +#define UDBG_BADABORT (1 << 2) +#define UDBG_SEGV (1 << 3) +#define UDBG_BUS (1 << 4) + +extern unsigned int user_debug; + +#if __LINUX_ARM_ARCH__ >= 4 +#define vectors_high() (cr_alignment & CR_V) +#else +#define vectors_high() (0) +#endif + +#if __LINUX_ARM_ARCH__ >= 7 || \ + (__LINUX_ARM_ARCH__ == 6 && defined(CONFIG_CPU_32v6K)) +#define sev() __asm__ __volatile__ ("sev" : : : "memory") +#define wfe() __asm__ __volatile__ ("wfe" : : : "memory") +#define wfi() __asm__ __volatile__ ("wfi" : : : "memory") +#endif + +#if __LINUX_ARM_ARCH__ >= 7 +#define isb() __asm__ __volatile__ ("isb" : : : "memory") +#define dsb() __asm__ __volatile__ ("dsb" : : : "memory") +#define dmb() __asm__ __volatile__ ("dmb" : : : "memory") +#elif defined(CONFIG_CPU_XSC3) || __LINUX_ARM_ARCH__ == 6 +#define isb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \ + : : "r" (0) : "memory") +#define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \ + : : "r" (0) : "memory") +#define dmb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \ + : : "r" (0) : "memory") +#elif defined(CONFIG_CPU_FA526) +#define isb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \ + : : "r" (0) : "memory") +#define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \ + : : "r" (0) : "memory") +#define dmb() __asm__ __volatile__ ("" : : : "memory") +#else +#define isb() __asm__ __volatile__ ("" : : : "memory") +#define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \ + : : "r" (0) : "memory") +#define dmb() __asm__ __volatile__ ("" : : : "memory") +#endif + +#ifdef CONFIG_ARCH_HAS_BARRIERS +#include +#elif defined(CONFIG_ARM_DMA_MEM_BUFFERABLE) || defined(CONFIG_SMP) +#define mb() do { dsb(); outer_sync(); } while (0) +#define rmb() dsb() +#define wmb() mb() +#else +#include +#define mb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0) +#define rmb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0) +#define wmb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0) +#endif + +#ifndef CONFIG_SMP +#define smp_mb() barrier() +#define smp_rmb() barrier() +#define smp_wmb() barrier() +#else +#define smp_mb() dmb() +#define smp_rmb() dmb() +#define smp_wmb() dmb() +#endif + +#define read_barrier_depends() do { } while(0) +#define smp_read_barrier_depends() do { } while(0) + +#define set_mb(var, value) do { var = value; smp_mb(); } while (0) +#define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t"); + +extern unsigned long cr_no_alignment; /* defined in entry-armv.S */ +extern unsigned long cr_alignment; /* defined in entry-armv.S */ + +static inline unsigned int get_cr(void) +{ + unsigned int val; + asm("mrc p15, 0, %0, c1, c0, 0 @ get CR" : "=r" (val) : : "cc"); + return val; +} + +static inline void set_cr(unsigned int val) +{ + asm volatile("mcr p15, 0, %0, c1, c0, 0 @ set CR" + : : "r" (val) : "cc"); + isb(); +} + +#ifndef CONFIG_SMP +extern void adjust_cr(unsigned long mask, unsigned long set); +#endif + +#define CPACC_FULL(n) (3 << (n * 2)) +#define CPACC_SVC(n) (1 << (n * 2)) +#define CPACC_DISABLE(n) (0 << (n * 2)) + +static inline unsigned int get_copro_access(void) +{ + unsigned int val; + asm("mrc p15, 0, %0, c1, c0, 2 @ get copro access" + : "=r" (val) : : "cc"); + return val; +} + +static inline void set_copro_access(unsigned int val) +{ + asm volatile("mcr p15, 0, %0, c1, c0, 2 @ set copro access" + : : "r" (val) : "cc"); + isb(); +} + +/* + * switch_mm() may do a full cache flush over the context switch, + * so enable interrupts over the context switch to avoid high + * latency. + */ +#define __ARCH_WANT_INTERRUPTS_ON_CTXSW + +/* + * switch_to(prev, next) should switch from task `prev' to `next' + * `prev' will never be the same as `next'. schedule() itself + * contains the memory barrier to tell GCC not to cache `current'. + */ +extern struct task_struct *__switch_to(struct task_struct *, struct thread_info *, struct thread_info *); + +#define switch_to(prev,next,last) \ +do { \ + last = __switch_to(prev,task_thread_info(prev), task_thread_info(next)); \ +} while (0) + +#if defined(CONFIG_CPU_SA1100) || defined(CONFIG_CPU_SA110) +/* + * On the StrongARM, "swp" is terminally broken since it bypasses the + * cache totally. This means that the cache becomes inconsistent, and, + * since we use normal loads/stores as well, this is really bad. + * Typically, this causes oopsen in filp_close, but could have other, + * more disastrous effects. There are two work-arounds: + * 1. Disable interrupts and emulate the atomic swap + * 2. Clean the cache, perform atomic swap, flush the cache + * + * We choose (1) since its the "easiest" to achieve here and is not + * dependent on the processor type. + * + * NOTE that this solution won't work on an SMP system, so explcitly + * forbid it here. + */ +#define swp_is_buggy +#endif + +static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size) +{ + extern void __bad_xchg(volatile void *, int); + unsigned long ret; +#ifdef swp_is_buggy + unsigned long flags; +#endif +#if __LINUX_ARM_ARCH__ >= 6 + unsigned int tmp; +#endif + + smp_mb(); + + switch (size) { +#if __LINUX_ARM_ARCH__ >= 6 + case 1: + asm volatile("@ __xchg1\n" + "1: ldrexb %0, [%3]\n" + " strexb %1, %2, [%3]\n" + " teq %1, #0\n" + " bne 1b" + : "=&r" (ret), "=&r" (tmp) + : "r" (x), "r" (ptr) + : "memory", "cc"); + break; + case 4: + asm volatile("@ __xchg4\n" + "1: ldrex %0, [%3]\n" + " strex %1, %2, [%3]\n" + " teq %1, #0\n" + " bne 1b" + : "=&r" (ret), "=&r" (tmp) + : "r" (x), "r" (ptr) + : "memory", "cc"); + break; +#elif defined(swp_is_buggy) +#ifdef CONFIG_SMP +#error SMP is not supported on this platform +#endif + case 1: + raw_local_irq_save(flags); + ret = *(volatile unsigned char *)ptr; + *(volatile unsigned char *)ptr = x; + raw_local_irq_restore(flags); + break; + + case 4: + raw_local_irq_save(flags); + ret = *(volatile unsigned long *)ptr; + *(volatile unsigned long *)ptr = x; + raw_local_irq_restore(flags); + break; +#else + case 1: + asm volatile("@ __xchg1\n" + " swpb %0, %1, [%2]" + : "=&r" (ret) + : "r" (x), "r" (ptr) + : "memory", "cc"); + break; + case 4: + asm volatile("@ __xchg4\n" + " swp %0, %1, [%2]" + : "=&r" (ret) + : "r" (x), "r" (ptr) + : "memory", "cc"); + break; +#endif + default: + __bad_xchg(ptr, size), ret = 0; + break; + } + smp_mb(); + + return ret; +} + +extern void disable_hlt(void); +extern void enable_hlt(void); + +void cpu_idle_wait(void); + +#include + +#if __LINUX_ARM_ARCH__ < 6 +/* min ARCH < ARMv6 */ + +#ifdef CONFIG_SMP +#error "SMP is not supported on this platform" +#endif + +/* + * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make + * them available. + */ +#define cmpxchg_local(ptr, o, n) \ + ((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), (unsigned long)(o),\ + (unsigned long)(n), sizeof(*(ptr)))) +#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) + +#ifndef CONFIG_SMP +#include +#endif + +#else /* min ARCH >= ARMv6 */ + +extern void __bad_cmpxchg(volatile void *ptr, int size); + +/* + * cmpxchg only support 32-bits operands on ARMv6. + */ + +static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, + unsigned long new, int size) +{ + unsigned long oldval, res; + + switch (size) { +#ifndef CONFIG_CPU_V6 /* min ARCH >= ARMv6K */ + case 1: + do { + asm volatile("@ __cmpxchg1\n" + " ldrexb %1, [%2]\n" + " mov %0, #0\n" + " teq %1, %3\n" + " strexbeq %0, %4, [%2]\n" + : "=&r" (res), "=&r" (oldval) + : "r" (ptr), "Ir" (old), "r" (new) + : "memory", "cc"); + } while (res); + break; + case 2: + do { + asm volatile("@ __cmpxchg1\n" + " ldrexh %1, [%2]\n" + " mov %0, #0\n" + " teq %1, %3\n" + " strexheq %0, %4, [%2]\n" + : "=&r" (res), "=&r" (oldval) + : "r" (ptr), "Ir" (old), "r" (new) + : "memory", "cc"); + } while (res); + break; +#endif + case 4: + do { + asm volatile("@ __cmpxchg4\n" + " ldrex %1, [%2]\n" + " mov %0, #0\n" + " teq %1, %3\n" + " strexeq %0, %4, [%2]\n" + : "=&r" (res), "=&r" (oldval) + : "r" (ptr), "Ir" (old), "r" (new) + : "memory", "cc"); + } while (res); + break; + default: + __bad_cmpxchg(ptr, size); + oldval = 0; + } + + return oldval; +} + +static inline unsigned long __cmpxchg_mb(volatile void *ptr, unsigned long old, + unsigned long new, int size) +{ + unsigned long ret; + + smp_mb(); + ret = __cmpxchg(ptr, old, new, size); + smp_mb(); + + return ret; +} + +#define cmpxchg(ptr,o,n) \ + ((__typeof__(*(ptr)))__cmpxchg_mb((ptr), \ + (unsigned long)(o), \ + (unsigned long)(n), \ + sizeof(*(ptr)))) + +static inline unsigned long __cmpxchg_local(volatile void *ptr, + unsigned long old, + unsigned long new, int size) +{ + unsigned long ret; + + switch (size) { +#ifdef CONFIG_CPU_V6 /* min ARCH == ARMv6 */ + case 1: + case 2: + ret = __cmpxchg_local_generic(ptr, old, new, size); + break; +#endif + default: + ret = __cmpxchg(ptr, old, new, size); + } + + return ret; +} + +#define cmpxchg_local(ptr,o,n) \ + ((__typeof__(*(ptr)))__cmpxchg_local((ptr), \ + (unsigned long)(o), \ + (unsigned long)(n), \ + sizeof(*(ptr)))) + +#ifndef CONFIG_CPU_V6 /* min ARCH >= ARMv6K */ + +/* + * Note : ARMv7-M (currently unsupported by Linux) does not support + * ldrexd/strexd. If ARMv7-M is ever supported by the Linux kernel, it should + * not be allowed to use __cmpxchg64. + */ +static inline unsigned long long __cmpxchg64(volatile void *ptr, + unsigned long long old, + unsigned long long new) +{ + register unsigned long long oldval asm("r0"); + register unsigned long long __old asm("r2") = old; + register unsigned long long __new asm("r4") = new; + unsigned long res; + + do { + asm volatile( + " @ __cmpxchg8\n" + " ldrexd %1, %H1, [%2]\n" + " mov %0, #0\n" + " teq %1, %3\n" + " teqeq %H1, %H3\n" + " strexdeq %0, %4, %H4, [%2]\n" + : "=&r" (res), "=&r" (oldval) + : "r" (ptr), "Ir" (__old), "r" (__new) + : "memory", "cc"); + } while (res); + + return oldval; +} + +static inline unsigned long long __cmpxchg64_mb(volatile void *ptr, + unsigned long long old, + unsigned long long new) +{ + unsigned long long ret; + + smp_mb(); + ret = __cmpxchg64(ptr, old, new); + smp_mb(); + + return ret; +} + +#define cmpxchg64(ptr,o,n) \ + ((__typeof__(*(ptr)))__cmpxchg64_mb((ptr), \ + (unsigned long long)(o), \ + (unsigned long long)(n))) + +#define cmpxchg64_local(ptr,o,n) \ + ((__typeof__(*(ptr)))__cmpxchg64((ptr), \ + (unsigned long long)(o), \ + (unsigned long long)(n))) + +#else /* min ARCH = ARMv6 */ + +#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) + +#endif + +#endif /* __LINUX_ARM_ARCH__ >= 6 */ + +#endif /* __ASSEMBLY__ */ + +#define arch_align_stack(x) (x) + +#endif /* __KERNEL__ */ + +#endif diff --git a/arch/arm/include/asm/tcm.h b/arch/arm/include/asm/tcm.h new file mode 100644 index 00000000..5929ef5d --- /dev/null +++ b/arch/arm/include/asm/tcm.h @@ -0,0 +1,31 @@ +/* + * + * Copyright (C) 2008-2009 ST-Ericsson AB + * License terms: GNU General Public License (GPL) version 2 + * + * Author: Rickard Andersson + * Author: Linus Walleij + * + */ +#ifndef __ASMARM_TCM_H +#define __ASMARM_TCM_H + +#ifndef CONFIG_HAVE_TCM +#error "You should not be including tcm.h unless you have a TCM!" +#endif + +#include + +/* Tag variables with this */ +#define __tcmdata __section(.tcm.data) +/* Tag constants with this */ +#define __tcmconst __section(.tcm.rodata) +/* Tag functions inside TCM called from outside TCM with this */ +#define __tcmfunc __attribute__((long_call)) __section(.tcm.text) noinline +/* Tag function inside TCM called from inside TCM with this */ +#define __tcmlocalfunc __section(.tcm.text) + +void *tcm_alloc(size_t len); +void tcm_free(void *addr, size_t len); + +#endif diff --git a/arch/arm/include/asm/termbits.h b/arch/arm/include/asm/termbits.h new file mode 100644 index 00000000..704135d2 --- /dev/null +++ b/arch/arm/include/asm/termbits.h @@ -0,0 +1,198 @@ +#ifndef __ASM_ARM_TERMBITS_H +#define __ASM_ARM_TERMBITS_H + +typedef unsigned char cc_t; +typedef unsigned int speed_t; +typedef unsigned int tcflag_t; + +#define NCCS 19 +struct termios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ +}; + +struct termios2 { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + +struct ktermios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + + +/* c_cc characters */ +#define VINTR 0 +#define VQUIT 1 +#define VERASE 2 +#define VKILL 3 +#define VEOF 4 +#define VTIME 5 +#define VMIN 6 +#define VSWTC 7 +#define VSTART 8 +#define VSTOP 9 +#define VSUSP 10 +#define VEOL 11 +#define VREPRINT 12 +#define VDISCARD 13 +#define VWERASE 14 +#define VLNEXT 15 +#define VEOL2 16 + +/* c_iflag bits */ +#define IGNBRK 0000001 +#define BRKINT 0000002 +#define IGNPAR 0000004 +#define PARMRK 0000010 +#define INPCK 0000020 +#define ISTRIP 0000040 +#define INLCR 0000100 +#define IGNCR 0000200 +#define ICRNL 0000400 +#define IUCLC 0001000 +#define IXON 0002000 +#define IXANY 0004000 +#define IXOFF 0010000 +#define IMAXBEL 0020000 +#define IUTF8 0040000 + +/* c_oflag bits */ +#define OPOST 0000001 +#define OLCUC 0000002 +#define ONLCR 0000004 +#define OCRNL 0000010 +#define ONOCR 0000020 +#define ONLRET 0000040 +#define OFILL 0000100 +#define OFDEL 0000200 +#define NLDLY 0000400 +#define NL0 0000000 +#define NL1 0000400 +#define CRDLY 0003000 +#define CR0 0000000 +#define CR1 0001000 +#define CR2 0002000 +#define CR3 0003000 +#define TABDLY 0014000 +#define TAB0 0000000 +#define TAB1 0004000 +#define TAB2 0010000 +#define TAB3 0014000 +#define XTABS 0014000 +#define BSDLY 0020000 +#define BS0 0000000 +#define BS1 0020000 +#define VTDLY 0040000 +#define VT0 0000000 +#define VT1 0040000 +#define FFDLY 0100000 +#define FF0 0000000 +#define FF1 0100000 + +/* c_cflag bit meaning */ +#define CBAUD 0010017 +#define B0 0000000 /* hang up */ +#define B50 0000001 +#define B75 0000002 +#define B110 0000003 +#define B134 0000004 +#define B150 0000005 +#define B200 0000006 +#define B300 0000007 +#define B600 0000010 +#define B1200 0000011 +#define B1800 0000012 +#define B2400 0000013 +#define B4800 0000014 +#define B9600 0000015 +#define B19200 0000016 +#define B38400 0000017 +#define EXTA B19200 +#define EXTB B38400 +#define CSIZE 0000060 +#define CS5 0000000 +#define CS6 0000020 +#define CS7 0000040 +#define CS8 0000060 +#define CSTOPB 0000100 +#define CREAD 0000200 +#define PARENB 0000400 +#define PARODD 0001000 +#define HUPCL 0002000 +#define CLOCAL 0004000 +#define CBAUDEX 0010000 +#define BOTHER 0010000 +#define B57600 0010001 +#define B115200 0010002 +#define B230400 0010003 +#define B460800 0010004 +#define B500000 0010005 +#define B576000 0010006 +#define B921600 0010007 +#define B1000000 0010010 +#define B1152000 0010011 +#define B1500000 0010012 +#define B2000000 0010013 +#define B2500000 0010014 +#define B3000000 0010015 +#define B3500000 0010016 +#define B4000000 0010017 +#define CIBAUD 002003600000 /* input baud rate */ +#define CMSPAR 010000000000 /* mark or space (stick) parity */ +#define CRTSCTS 020000000000 /* flow control */ + +#define IBSHIFT 16 + +/* c_lflag bits */ +#define ISIG 0000001 +#define ICANON 0000002 +#define XCASE 0000004 +#define ECHO 0000010 +#define ECHOE 0000020 +#define ECHOK 0000040 +#define ECHONL 0000100 +#define NOFLSH 0000200 +#define TOSTOP 0000400 +#define ECHOCTL 0001000 +#define ECHOPRT 0002000 +#define ECHOKE 0004000 +#define FLUSHO 0010000 +#define PENDIN 0040000 +#define IEXTEN 0100000 +#define EXTPROC 0200000 + +/* tcflow() and TCXONC use these */ +#define TCOOFF 0 +#define TCOON 1 +#define TCIOFF 2 +#define TCION 3 + +/* tcflush() and TCFLSH use these */ +#define TCIFLUSH 0 +#define TCOFLUSH 1 +#define TCIOFLUSH 2 + +/* tcsetattr uses these */ +#define TCSANOW 0 +#define TCSADRAIN 1 +#define TCSAFLUSH 2 + +#endif /* __ASM_ARM_TERMBITS_H */ diff --git a/arch/arm/include/asm/termios.h b/arch/arm/include/asm/termios.h new file mode 100644 index 00000000..293e3f1b --- /dev/null +++ b/arch/arm/include/asm/termios.h @@ -0,0 +1,92 @@ +#ifndef __ASM_ARM_TERMIOS_H +#define __ASM_ARM_TERMIOS_H + +#include +#include + +struct winsize { + unsigned short ws_row; + unsigned short ws_col; + unsigned short ws_xpixel; + unsigned short ws_ypixel; +}; + +#define NCC 8 +struct termio { + unsigned short c_iflag; /* input mode flags */ + unsigned short c_oflag; /* output mode flags */ + unsigned short c_cflag; /* control mode flags */ + unsigned short c_lflag; /* local mode flags */ + unsigned char c_line; /* line discipline */ + unsigned char c_cc[NCC]; /* control characters */ +}; + +#ifdef __KERNEL__ +/* intr=^C quit=^| erase=del kill=^U + eof=^D vtime=\0 vmin=\1 sxtc=\0 + start=^Q stop=^S susp=^Z eol=\0 + reprint=^R discard=^U werase=^W lnext=^V + eol2=\0 +*/ +#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0" +#endif + +/* modem lines */ +#define TIOCM_LE 0x001 +#define TIOCM_DTR 0x002 +#define TIOCM_RTS 0x004 +#define TIOCM_ST 0x008 +#define TIOCM_SR 0x010 +#define TIOCM_CTS 0x020 +#define TIOCM_CAR 0x040 +#define TIOCM_RNG 0x080 +#define TIOCM_DSR 0x100 +#define TIOCM_CD TIOCM_CAR +#define TIOCM_RI TIOCM_RNG +#define TIOCM_OUT1 0x2000 +#define TIOCM_OUT2 0x4000 +#define TIOCM_LOOP 0x8000 + +/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ + +#ifdef __KERNEL__ + +/* + * Translate a "termio" structure into a "termios". Ugh. + */ +#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \ + unsigned short __tmp; \ + get_user(__tmp,&(termio)->x); \ + *(unsigned short *) &(termios)->x = __tmp; \ +} + +#define user_termio_to_kernel_termios(termios, termio) \ +({ \ + SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \ + SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \ + SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \ + SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \ + copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \ +}) + +/* + * Translate a "termios" structure into a "termio". Ugh. + */ +#define kernel_termios_to_user_termio(termio, termios) \ +({ \ + put_user((termios)->c_iflag, &(termio)->c_iflag); \ + put_user((termios)->c_oflag, &(termio)->c_oflag); \ + put_user((termios)->c_cflag, &(termio)->c_cflag); \ + put_user((termios)->c_lflag, &(termio)->c_lflag); \ + put_user((termios)->c_line, &(termio)->c_line); \ + copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \ +}) + +#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios2)) +#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios2)) +#define user_termios_to_kernel_termios_1(k, u) copy_from_user(k, u, sizeof(struct termios)) +#define kernel_termios_to_user_termios_1(u, k) copy_to_user(u, k, sizeof(struct termios)) + +#endif /* __KERNEL__ */ + +#endif /* __ASM_ARM_TERMIOS_H */ diff --git a/arch/arm/include/asm/therm.h b/arch/arm/include/asm/therm.h new file mode 100644 index 00000000..f002f019 --- /dev/null +++ b/arch/arm/include/asm/therm.h @@ -0,0 +1,28 @@ +/* + * arch/arm/include/asm/therm.h: Definitions for Dallas Semiconductor + * DS1620 thermometer driver (as used in the Rebel.com NetWinder) + */ +#ifndef __ASM_THERM_H +#define __ASM_THERM_H + +/* ioctl numbers for /dev/therm */ +#define CMD_SET_THERMOSTATE 0x53 +#define CMD_GET_THERMOSTATE 0x54 +#define CMD_GET_STATUS 0x56 +#define CMD_GET_TEMPERATURE 0x57 +#define CMD_SET_THERMOSTATE2 0x58 +#define CMD_GET_THERMOSTATE2 0x59 +#define CMD_GET_TEMPERATURE2 0x5a +#define CMD_GET_FAN 0x5b +#define CMD_SET_FAN 0x5c + +#define FAN_OFF 0 +#define FAN_ON 1 +#define FAN_ALWAYS_ON 2 + +struct therm { + int hi; + int lo; +}; + +#endif diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h new file mode 100644 index 00000000..7b5cc8da --- /dev/null +++ b/arch/arm/include/asm/thread_info.h @@ -0,0 +1,165 @@ +/* + * arch/arm/include/asm/thread_info.h + * + * Copyright (C) 2002 Russell King. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __ASM_ARM_THREAD_INFO_H +#define __ASM_ARM_THREAD_INFO_H + +#ifdef __KERNEL__ + +#include +#include + +#define THREAD_SIZE_ORDER 1 +#define THREAD_SIZE 8192 +#define THREAD_START_SP (THREAD_SIZE - 8) + +#ifndef __ASSEMBLY__ + +struct task_struct; +struct exec_domain; + +#include +#include + +typedef unsigned long mm_segment_t; + +struct cpu_context_save { + __u32 r4; + __u32 r5; + __u32 r6; + __u32 r7; + __u32 r8; + __u32 r9; + __u32 sl; + __u32 fp; + __u32 sp; + __u32 pc; + __u32 extra[2]; /* Xscale 'acc' register, etc */ +}; + +/* + * low level task data that entry.S needs immediate access to. + * __switch_to() assumes cpu_context follows immediately after cpu_domain. + */ +struct thread_info { + unsigned long flags; /* low level flags */ + int preempt_count; /* 0 => preemptable, <0 => bug */ + mm_segment_t addr_limit; /* address limit */ + struct task_struct *task; /* main task structure */ + struct exec_domain *exec_domain; /* execution domain */ + __u32 cpu; /* cpu */ + __u32 cpu_domain; /* cpu domain */ + struct cpu_context_save cpu_context; /* cpu context */ + __u32 syscall; /* syscall number */ + __u8 used_cp[16]; /* thread used copro */ + unsigned long tp_value; + struct crunch_state crunchstate; + union fp_state fpstate __attribute__((aligned(8))); + union vfp_state vfpstate; +#ifdef CONFIG_ARM_THUMBEE + unsigned long thumbee_state; /* ThumbEE Handler Base register */ +#endif + struct restart_block restart_block; +}; + +#define INIT_THREAD_INFO(tsk) \ +{ \ + .task = &tsk, \ + .exec_domain = &default_exec_domain, \ + .flags = 0, \ + .preempt_count = INIT_PREEMPT_COUNT, \ + .addr_limit = KERNEL_DS, \ + .cpu_domain = domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \ + domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \ + domain_val(DOMAIN_IO, DOMAIN_CLIENT), \ + .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 + */ +static inline struct thread_info *current_thread_info(void) __attribute_const__; + +static inline struct thread_info *current_thread_info(void) +{ + register unsigned long sp asm ("sp"); + return (struct thread_info *)(sp & ~(THREAD_SIZE - 1)); +} + +#define thread_saved_pc(tsk) \ + ((unsigned long)(task_thread_info(tsk)->cpu_context.pc)) +#define thread_saved_sp(tsk) \ + ((unsigned long)(task_thread_info(tsk)->cpu_context.sp)) +#define thread_saved_fp(tsk) \ + ((unsigned long)(task_thread_info(tsk)->cpu_context.fp)) + +extern void crunch_task_disable(struct thread_info *); +extern void crunch_task_copy(struct thread_info *, void *); +extern void crunch_task_restore(struct thread_info *, void *); +extern void crunch_task_release(struct thread_info *); + +extern void iwmmxt_task_disable(struct thread_info *); +extern void iwmmxt_task_copy(struct thread_info *, void *); +extern void iwmmxt_task_restore(struct thread_info *, void *); +extern void iwmmxt_task_release(struct thread_info *); +extern void iwmmxt_task_switch(struct thread_info *); + +extern void vfp_sync_hwstate(struct thread_info *); +extern void vfp_flush_hwstate(struct thread_info *); + +#endif + +/* + * We use bit 30 of the preempt_count to indicate that kernel + * preemption is occurring. See . + */ +#define PREEMPT_ACTIVE 0x40000000 + +/* + * thread information flags: + * TIF_SYSCALL_TRACE - syscall trace active + * TIF_SIGPENDING - signal pending + * TIF_NEED_RESCHED - rescheduling necessary + * TIF_NOTIFY_RESUME - callback before returning to user + * TIF_USEDFPU - FPU was used by this task this quantum (SMP) + * TIF_POLLING_NRFLAG - true if poll_idle() is polling TIF_NEED_RESCHED + */ +#define TIF_SIGPENDING 0 +#define TIF_NEED_RESCHED 1 +#define TIF_NOTIFY_RESUME 2 /* callback before returning to user */ +#define TIF_SYSCALL_TRACE 8 +#define TIF_POLLING_NRFLAG 16 +#define TIF_USING_IWMMXT 17 +#define TIF_MEMDIE 18 /* is terminating due to OOM killer */ +#define TIF_FREEZE 19 +#define TIF_RESTORE_SIGMASK 20 +#define TIF_SECCOMP 21 + +#define _TIF_SIGPENDING (1 << TIF_SIGPENDING) +#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) +#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) +#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) +#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) +#define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT) +#define _TIF_FREEZE (1 << TIF_FREEZE) +#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) +#define _TIF_SECCOMP (1 << TIF_SECCOMP) + +/* + * Change these and you break ASM code in entry-common.S + */ +#define _TIF_WORK_MASK 0x000000ff + +#endif /* __KERNEL__ */ +#endif /* __ASM_ARM_THREAD_INFO_H */ diff --git a/arch/arm/include/asm/thread_notify.h b/arch/arm/include/asm/thread_notify.h new file mode 100644 index 00000000..1dc98067 --- /dev/null +++ b/arch/arm/include/asm/thread_notify.h @@ -0,0 +1,49 @@ +/* + * arch/arm/include/asm/thread_notify.h + * + * Copyright (C) 2006 Russell King. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef ASMARM_THREAD_NOTIFY_H +#define ASMARM_THREAD_NOTIFY_H + +#ifdef __KERNEL__ + +#ifndef __ASSEMBLY__ + +#include +#include + +static inline int thread_register_notifier(struct notifier_block *n) +{ + extern struct atomic_notifier_head thread_notify_head; + return atomic_notifier_chain_register(&thread_notify_head, n); +} + +static inline void thread_unregister_notifier(struct notifier_block *n) +{ + extern struct atomic_notifier_head thread_notify_head; + atomic_notifier_chain_unregister(&thread_notify_head, n); +} + +static inline void thread_notify(unsigned long rc, struct thread_info *thread) +{ + extern struct atomic_notifier_head thread_notify_head; + atomic_notifier_call_chain(&thread_notify_head, rc, thread); +} + +#endif + +/* + * These are the reason codes for the thread notifier. + */ +#define THREAD_NOTIFY_FLUSH 0 +#define THREAD_NOTIFY_EXIT 1 +#define THREAD_NOTIFY_SWITCH 2 +#define THREAD_NOTIFY_COPY 3 + +#endif +#endif diff --git a/arch/arm/include/asm/timex.h b/arch/arm/include/asm/timex.h new file mode 100644 index 00000000..3be8de3a --- /dev/null +++ b/arch/arm/include/asm/timex.h @@ -0,0 +1,24 @@ +/* + * arch/arm/include/asm/timex.h + * + * Copyright (C) 1997,1998 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Architecture Specific TIME specifications + */ +#ifndef _ASMARM_TIMEX_H +#define _ASMARM_TIMEX_H + +#include + +typedef unsigned long cycles_t; + +static inline cycles_t get_cycles (void) +{ + return 0; +} + +#endif diff --git a/arch/arm/include/asm/tlb.h b/arch/arm/include/asm/tlb.h new file mode 100644 index 00000000..265f908c --- /dev/null +++ b/arch/arm/include/asm/tlb.h @@ -0,0 +1,211 @@ +/* + * arch/arm/include/asm/tlb.h + * + * Copyright (C) 2002 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Experimentation shows that on a StrongARM, it appears to be faster + * to use the "invalidate whole tlb" rather than "invalidate single + * tlb" for this. + * + * This appears true for both the process fork+exit case, as well as + * the munmap-large-area case. + */ +#ifndef __ASMARM_TLB_H +#define __ASMARM_TLB_H + +#include + +#ifndef CONFIG_MMU + +#include + +#define tlb_flush(tlb) ((void) tlb) + +#include + +#else /* !CONFIG_MMU */ + +#include +#include +#include + +/* + * We need to delay page freeing for SMP as other CPUs can access pages + * which have been removed but not yet had their TLB entries invalidated. + * Also, as ARMv7 speculative prefetch can drag new entries into the TLB, + * we need to apply this same delaying tactic to ensure correct operation. + */ +#if defined(CONFIG_SMP) || defined(CONFIG_CPU_32v7) +#define tlb_fast_mode(tlb) 0 +#else +#define tlb_fast_mode(tlb) 1 +#endif + +#define MMU_GATHER_BUNDLE 8 + +/* + * TLB handling. This allows us to remove pages from the page + * tables, and efficiently handle the TLB issues. + */ +struct mmu_gather { + struct mm_struct *mm; + unsigned int fullmm; + struct vm_area_struct *vma; + unsigned long range_start; + unsigned long range_end; + unsigned int nr; + unsigned int max; + struct page **pages; + struct page *local[MMU_GATHER_BUNDLE]; +}; + +DECLARE_PER_CPU(struct mmu_gather, mmu_gathers); + +/* + * This is unnecessarily complex. There's three ways the TLB shootdown + * code is used: + * 1. Unmapping a range of vmas. See zap_page_range(), unmap_region(). + * tlb->fullmm = 0, and tlb_start_vma/tlb_end_vma will be called. + * tlb->vma will be non-NULL. + * 2. Unmapping all vmas. See exit_mmap(). + * tlb->fullmm = 1, and tlb_start_vma/tlb_end_vma will be called. + * tlb->vma will be non-NULL. Additionally, page tables will be freed. + * 3. Unmapping argument pages. See shift_arg_pages(). + * tlb->fullmm = 0, but tlb_start_vma/tlb_end_vma will not be called. + * tlb->vma will be NULL. + */ +static inline void tlb_flush(struct mmu_gather *tlb) +{ + if (tlb->fullmm || !tlb->vma) + flush_tlb_mm(tlb->mm); + else if (tlb->range_end > 0) { + flush_tlb_range(tlb->vma, tlb->range_start, tlb->range_end); + tlb->range_start = TASK_SIZE; + tlb->range_end = 0; + } +} + +static inline void tlb_add_flush(struct mmu_gather *tlb, unsigned long addr) +{ + if (!tlb->fullmm) { + if (addr < tlb->range_start) + tlb->range_start = addr; + if (addr + PAGE_SIZE > tlb->range_end) + tlb->range_end = addr + PAGE_SIZE; + } +} + +static inline void __tlb_alloc_page(struct mmu_gather *tlb) +{ + unsigned long addr = __get_free_pages(GFP_NOWAIT | __GFP_NOWARN, 0); + + if (addr) { + tlb->pages = (void *)addr; + tlb->max = PAGE_SIZE / sizeof(struct page *); + } +} + +static inline void tlb_flush_mmu(struct mmu_gather *tlb) +{ + tlb_flush(tlb); + if (!tlb_fast_mode(tlb)) { + free_pages_and_swap_cache(tlb->pages, tlb->nr); + tlb->nr = 0; + if (tlb->pages == tlb->local) + __tlb_alloc_page(tlb); + } +} + +static inline void +tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned int fullmm) +{ + tlb->mm = mm; + tlb->fullmm = fullmm; + tlb->vma = NULL; + tlb->max = ARRAY_SIZE(tlb->local); + tlb->pages = tlb->local; + tlb->nr = 0; + __tlb_alloc_page(tlb); +} + +static inline void +tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end) +{ + tlb_flush_mmu(tlb); + + /* keep the page table cache within bounds */ + check_pgt_cache(); + + if (tlb->pages != tlb->local) + free_pages((unsigned long)tlb->pages, 0); +} + +/* + * Memorize the range for the TLB flush. + */ +static inline void +tlb_remove_tlb_entry(struct mmu_gather *tlb, pte_t *ptep, unsigned long addr) +{ + tlb_add_flush(tlb, addr); +} + +/* + * In the case of tlb vma handling, we can optimise these away in the + * case where we're doing a full MM flush. When we're doing a munmap, + * the vmas are adjusted to only cover the region to be torn down. + */ +static inline void +tlb_start_vma(struct mmu_gather *tlb, struct vm_area_struct *vma) +{ + if (!tlb->fullmm) { + flush_cache_range(vma, vma->vm_start, vma->vm_end); + tlb->vma = vma; + tlb->range_start = TASK_SIZE; + tlb->range_end = 0; + } +} + +static inline void +tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vma) +{ + if (!tlb->fullmm) + tlb_flush(tlb); +} + +static inline int __tlb_remove_page(struct mmu_gather *tlb, struct page *page) +{ + if (tlb_fast_mode(tlb)) { + free_page_and_swap_cache(page); + return 1; /* avoid calling tlb_flush_mmu */ + } + + tlb->pages[tlb->nr++] = page; + VM_BUG_ON(tlb->nr > tlb->max); + return tlb->max - tlb->nr; +} + +static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page) +{ + if (!__tlb_remove_page(tlb, page)) + tlb_flush_mmu(tlb); +} + +static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte, + unsigned long addr) +{ + pgtable_page_dtor(pte); + tlb_add_flush(tlb, addr); + tlb_remove_page(tlb, pte); +} + +#define pte_free_tlb(tlb, ptep, addr) __pte_free_tlb(tlb, ptep, addr) +#define pmd_free_tlb(tlb, pmdp, addr) pmd_free((tlb)->mm, pmdp) + +#define tlb_migrate_finish(mm) do { } while (0) + +#endif /* CONFIG_MMU */ +#endif diff --git a/arch/arm/include/asm/tlbflush.h b/arch/arm/include/asm/tlbflush.h new file mode 100644 index 00000000..d2005de3 --- /dev/null +++ b/arch/arm/include/asm/tlbflush.h @@ -0,0 +1,587 @@ +/* + * arch/arm/include/asm/tlbflush.h + * + * Copyright (C) 1999-2003 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef _ASMARM_TLBFLUSH_H +#define _ASMARM_TLBFLUSH_H + +#ifdef CONFIG_MMU + +#include + +#define TLB_V3_PAGE (1 << 0) +#define TLB_V4_U_PAGE (1 << 1) +#define TLB_V4_D_PAGE (1 << 2) +#define TLB_V4_I_PAGE (1 << 3) +#define TLB_V6_U_PAGE (1 << 4) +#define TLB_V6_D_PAGE (1 << 5) +#define TLB_V6_I_PAGE (1 << 6) + +#define TLB_V3_FULL (1 << 8) +#define TLB_V4_U_FULL (1 << 9) +#define TLB_V4_D_FULL (1 << 10) +#define TLB_V4_I_FULL (1 << 11) +#define TLB_V6_U_FULL (1 << 12) +#define TLB_V6_D_FULL (1 << 13) +#define TLB_V6_I_FULL (1 << 14) + +#define TLB_V6_U_ASID (1 << 16) +#define TLB_V6_D_ASID (1 << 17) +#define TLB_V6_I_ASID (1 << 18) + +#define TLB_BTB (1 << 28) + +/* Unified Inner Shareable TLB operations (ARMv7 MP extensions) */ +#define TLB_V7_UIS_PAGE (1 << 19) +#define TLB_V7_UIS_FULL (1 << 20) +#define TLB_V7_UIS_ASID (1 << 21) + +/* Inner Shareable BTB operation (ARMv7 MP extensions) */ +#define TLB_V7_IS_BTB (1 << 22) + +#define TLB_L2CLEAN_FR (1 << 29) /* Feroceon */ +#define TLB_DCLEAN (1 << 30) +#define TLB_WB (1 << 31) + +/* + * MMU TLB Model + * ============= + * + * We have the following to choose from: + * v3 - ARMv3 + * v4 - ARMv4 without write buffer + * v4wb - ARMv4 with write buffer without I TLB flush entry instruction + * v4wbi - ARMv4 with write buffer with I TLB flush entry instruction + * fr - Feroceon (v4wbi with non-outer-cacheable page table walks) + * fa - Faraday (v4 with write buffer with UTLB and branch target buffer (BTB)) + * v6wbi - ARMv6 with write buffer with I TLB flush entry instruction + * v7wbi - identical to v6wbi + */ +#undef _TLB +#undef MULTI_TLB + +#ifdef CONFIG_SMP_ON_UP +#define MULTI_TLB 1 +#endif + +#define v3_tlb_flags (TLB_V3_FULL | TLB_V3_PAGE) + +#ifdef CONFIG_CPU_TLB_V3 +# define v3_possible_flags v3_tlb_flags +# define v3_always_flags v3_tlb_flags +# ifdef _TLB +# define MULTI_TLB 1 +# else +# define _TLB v3 +# endif +#else +# define v3_possible_flags 0 +# define v3_always_flags (-1UL) +#endif + +#define v4_tlb_flags (TLB_V4_U_FULL | TLB_V4_U_PAGE) + +#ifdef CONFIG_CPU_TLB_V4WT +# define v4_possible_flags v4_tlb_flags +# define v4_always_flags v4_tlb_flags +# ifdef _TLB +# define MULTI_TLB 1 +# else +# define _TLB v4 +# endif +#else +# define v4_possible_flags 0 +# define v4_always_flags (-1UL) +#endif + +#define fa_tlb_flags (TLB_WB | TLB_BTB | TLB_DCLEAN | \ + TLB_V4_U_FULL | TLB_V4_U_PAGE) + +#ifdef CONFIG_CPU_TLB_FA +# define fa_possible_flags fa_tlb_flags +# define fa_always_flags fa_tlb_flags +# ifdef _TLB +# define MULTI_TLB 1 +# else +# define _TLB fa +# endif +#else +# define fa_possible_flags 0 +# define fa_always_flags (-1UL) +#endif + +#define v4wbi_tlb_flags (TLB_WB | TLB_DCLEAN | \ + TLB_V4_I_FULL | TLB_V4_D_FULL | \ + TLB_V4_I_PAGE | TLB_V4_D_PAGE) + +#ifdef CONFIG_CPU_TLB_V4WBI +# define v4wbi_possible_flags v4wbi_tlb_flags +# define v4wbi_always_flags v4wbi_tlb_flags +# ifdef _TLB +# define MULTI_TLB 1 +# else +# define _TLB v4wbi +# endif +#else +# define v4wbi_possible_flags 0 +# define v4wbi_always_flags (-1UL) +#endif + +#define fr_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_L2CLEAN_FR | \ + TLB_V4_I_FULL | TLB_V4_D_FULL | \ + TLB_V4_I_PAGE | TLB_V4_D_PAGE) + +#ifdef CONFIG_CPU_TLB_FEROCEON +# define fr_possible_flags fr_tlb_flags +# define fr_always_flags fr_tlb_flags +# ifdef _TLB +# define MULTI_TLB 1 +# else +# define _TLB v4wbi +# endif +#else +# define fr_possible_flags 0 +# define fr_always_flags (-1UL) +#endif + +#define v4wb_tlb_flags (TLB_WB | TLB_DCLEAN | \ + TLB_V4_I_FULL | TLB_V4_D_FULL | \ + TLB_V4_D_PAGE) + +#ifdef CONFIG_CPU_TLB_V4WB +# define v4wb_possible_flags v4wb_tlb_flags +# define v4wb_always_flags v4wb_tlb_flags +# ifdef _TLB +# define MULTI_TLB 1 +# else +# define _TLB v4wb +# endif +#else +# define v4wb_possible_flags 0 +# define v4wb_always_flags (-1UL) +#endif + +#define v6wbi_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_BTB | \ + TLB_V6_I_FULL | TLB_V6_D_FULL | \ + TLB_V6_I_PAGE | TLB_V6_D_PAGE | \ + TLB_V6_I_ASID | TLB_V6_D_ASID) + +#ifdef CONFIG_CPU_TLB_V6 +# define v6wbi_possible_flags v6wbi_tlb_flags +# define v6wbi_always_flags v6wbi_tlb_flags +# ifdef _TLB +# define MULTI_TLB 1 +# else +# define _TLB v6wbi +# endif +#else +# define v6wbi_possible_flags 0 +# define v6wbi_always_flags (-1UL) +#endif + +#define v7wbi_tlb_flags_smp (TLB_WB | TLB_DCLEAN | TLB_V7_IS_BTB | \ + TLB_V7_UIS_FULL | TLB_V7_UIS_PAGE | TLB_V7_UIS_ASID) +#define v7wbi_tlb_flags_up (TLB_WB | TLB_DCLEAN | TLB_BTB | \ + TLB_V6_U_FULL | TLB_V6_U_PAGE | TLB_V6_U_ASID) + +#ifdef CONFIG_CPU_TLB_V7 + +# ifdef CONFIG_SMP_ON_UP +# define v7wbi_possible_flags (v7wbi_tlb_flags_smp | v7wbi_tlb_flags_up) +# define v7wbi_always_flags (v7wbi_tlb_flags_smp & v7wbi_tlb_flags_up) +# elif defined(CONFIG_SMP) +# define v7wbi_possible_flags v7wbi_tlb_flags_smp +# define v7wbi_always_flags v7wbi_tlb_flags_smp +# else +# define v7wbi_possible_flags v7wbi_tlb_flags_up +# define v7wbi_always_flags v7wbi_tlb_flags_up +# endif +# ifdef _TLB +# define MULTI_TLB 1 +# else +# define _TLB v7wbi +# endif +#else +# define v7wbi_possible_flags 0 +# define v7wbi_always_flags (-1UL) +#endif + +#ifndef _TLB +#error Unknown TLB model +#endif + +#ifndef __ASSEMBLY__ + +#include + +struct cpu_tlb_fns { + void (*flush_user_range)(unsigned long, unsigned long, struct vm_area_struct *); + void (*flush_kern_range)(unsigned long, unsigned long); + unsigned long tlb_flags; +}; + +/* + * Select the calling method + */ +#ifdef MULTI_TLB + +#define __cpu_flush_user_tlb_range cpu_tlb.flush_user_range +#define __cpu_flush_kern_tlb_range cpu_tlb.flush_kern_range + +#else + +#define __cpu_flush_user_tlb_range __glue(_TLB,_flush_user_tlb_range) +#define __cpu_flush_kern_tlb_range __glue(_TLB,_flush_kern_tlb_range) + +extern void __cpu_flush_user_tlb_range(unsigned long, unsigned long, struct vm_area_struct *); +extern void __cpu_flush_kern_tlb_range(unsigned long, unsigned long); + +#endif + +extern struct cpu_tlb_fns cpu_tlb; + +#define __cpu_tlb_flags cpu_tlb.tlb_flags + +/* + * TLB Management + * ============== + * + * The arch/arm/mm/tlb-*.S files implement these methods. + * + * The TLB specific code is expected to perform whatever tests it + * needs to determine if it should invalidate the TLB for each + * call. Start addresses are inclusive and end addresses are + * exclusive; it is safe to round these addresses down. + * + * flush_tlb_all() + * + * Invalidate the entire TLB. + * + * flush_tlb_mm(mm) + * + * Invalidate all TLB entries in a particular address + * space. + * - mm - mm_struct describing address space + * + * flush_tlb_range(mm,start,end) + * + * Invalidate a range of TLB entries in the specified + * address space. + * - mm - mm_struct describing address space + * - start - start address (may not be aligned) + * - end - end address (exclusive, may not be aligned) + * + * flush_tlb_page(vaddr,vma) + * + * Invalidate the specified page in the specified address range. + * - vaddr - virtual address (may not be aligned) + * - vma - vma_struct describing address range + * + * flush_kern_tlb_page(kaddr) + * + * Invalidate the TLB entry for the specified page. The address + * will be in the kernels virtual memory space. Current uses + * only require the D-TLB to be invalidated. + * - kaddr - Kernel virtual memory address + */ + +/* + * We optimise the code below by: + * - building a set of TLB flags that might be set in __cpu_tlb_flags + * - building a set of TLB flags that will always be set in __cpu_tlb_flags + * - if we're going to need __cpu_tlb_flags, access it once and only once + * + * This allows us to build optimal assembly for the single-CPU type case, + * and as close to optimal given the compiler constrants for multi-CPU + * case. We could do better for the multi-CPU case if the compiler + * implemented the "%?" method, but this has been discontinued due to too + * many people getting it wrong. + */ +#define possible_tlb_flags (v3_possible_flags | \ + v4_possible_flags | \ + v4wbi_possible_flags | \ + fr_possible_flags | \ + v4wb_possible_flags | \ + fa_possible_flags | \ + v6wbi_possible_flags | \ + v7wbi_possible_flags) + +#define always_tlb_flags (v3_always_flags & \ + v4_always_flags & \ + v4wbi_always_flags & \ + fr_always_flags & \ + v4wb_always_flags & \ + fa_always_flags & \ + v6wbi_always_flags & \ + v7wbi_always_flags) + +#define tlb_flag(f) ((always_tlb_flags & (f)) || (__tlb_flag & possible_tlb_flags & (f))) + +static inline void local_flush_tlb_all(void) +{ + const int zero = 0; + const unsigned int __tlb_flag = __cpu_tlb_flags; + + if (tlb_flag(TLB_WB)) + dsb(); + + if (tlb_flag(TLB_V3_FULL)) + asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (zero) : "cc"); + if (tlb_flag(TLB_V4_U_FULL | TLB_V6_U_FULL)) + asm("mcr p15, 0, %0, c8, c7, 0" : : "r" (zero) : "cc"); + if (tlb_flag(TLB_V4_D_FULL | TLB_V6_D_FULL)) + asm("mcr p15, 0, %0, c8, c6, 0" : : "r" (zero) : "cc"); + if (tlb_flag(TLB_V4_I_FULL | TLB_V6_I_FULL)) + asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc"); + if (tlb_flag(TLB_V7_UIS_FULL)) + asm("mcr p15, 0, %0, c8, c3, 0" : : "r" (zero) : "cc"); + + if (tlb_flag(TLB_BTB)) { + /* flush the branch target cache */ + asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc"); + dsb(); + isb(); + } + if (tlb_flag(TLB_V7_IS_BTB)) { + /* flush the branch target cache */ + asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero) : "cc"); + dsb(); + isb(); + } +} + +static inline void local_flush_tlb_mm(struct mm_struct *mm) +{ + const int zero = 0; + const int asid = ASID(mm); + const unsigned int __tlb_flag = __cpu_tlb_flags; + + if (tlb_flag(TLB_WB)) + dsb(); + + if (cpumask_test_cpu(get_cpu(), mm_cpumask(mm))) { + if (tlb_flag(TLB_V3_FULL)) + asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (zero) : "cc"); + if (tlb_flag(TLB_V4_U_FULL)) + asm("mcr p15, 0, %0, c8, c7, 0" : : "r" (zero) : "cc"); + if (tlb_flag(TLB_V4_D_FULL)) + asm("mcr p15, 0, %0, c8, c6, 0" : : "r" (zero) : "cc"); + if (tlb_flag(TLB_V4_I_FULL)) + asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc"); + } + put_cpu(); + + if (tlb_flag(TLB_V6_U_ASID)) + asm("mcr p15, 0, %0, c8, c7, 2" : : "r" (asid) : "cc"); + if (tlb_flag(TLB_V6_D_ASID)) + asm("mcr p15, 0, %0, c8, c6, 2" : : "r" (asid) : "cc"); + if (tlb_flag(TLB_V6_I_ASID)) + asm("mcr p15, 0, %0, c8, c5, 2" : : "r" (asid) : "cc"); + if (tlb_flag(TLB_V7_UIS_ASID)) +#ifdef CONFIG_ARM_ERRATA_720789 + asm("mcr p15, 0, %0, c8, c3, 0" : : "r" (zero) : "cc"); +#else + asm("mcr p15, 0, %0, c8, c3, 2" : : "r" (asid) : "cc"); +#endif + + if (tlb_flag(TLB_BTB)) { + /* flush the branch target cache */ + asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc"); + dsb(); + } + if (tlb_flag(TLB_V7_IS_BTB)) { + /* flush the branch target cache */ + asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero) : "cc"); + dsb(); + isb(); + } +} + +static inline void +local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) +{ + const int zero = 0; + const unsigned int __tlb_flag = __cpu_tlb_flags; + + uaddr = (uaddr & PAGE_MASK) | ASID(vma->vm_mm); + + if (tlb_flag(TLB_WB)) + dsb(); + + if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) { + if (tlb_flag(TLB_V3_PAGE)) + asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (uaddr) : "cc"); + if (tlb_flag(TLB_V4_U_PAGE)) + asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (uaddr) : "cc"); + if (tlb_flag(TLB_V4_D_PAGE)) + asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (uaddr) : "cc"); + if (tlb_flag(TLB_V4_I_PAGE)) + asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (uaddr) : "cc"); + if (!tlb_flag(TLB_V4_I_PAGE) && tlb_flag(TLB_V4_I_FULL)) + asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc"); + } + + if (tlb_flag(TLB_V6_U_PAGE)) + asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (uaddr) : "cc"); + if (tlb_flag(TLB_V6_D_PAGE)) + asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (uaddr) : "cc"); + if (tlb_flag(TLB_V6_I_PAGE)) + asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (uaddr) : "cc"); + if (tlb_flag(TLB_V7_UIS_PAGE)) +#ifdef CONFIG_ARM_ERRATA_720789 + asm("mcr p15, 0, %0, c8, c3, 3" : : "r" (uaddr & PAGE_MASK) : "cc"); +#else + asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (uaddr) : "cc"); +#endif + + if (tlb_flag(TLB_BTB)) { + /* flush the branch target cache */ + asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc"); + dsb(); + } + if (tlb_flag(TLB_V7_IS_BTB)) { + /* flush the branch target cache */ + asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero) : "cc"); + dsb(); + isb(); + } +} + +static inline void local_flush_tlb_kernel_page(unsigned long kaddr) +{ + const int zero = 0; + const unsigned int __tlb_flag = __cpu_tlb_flags; + + kaddr &= PAGE_MASK; + + if (tlb_flag(TLB_WB)) + dsb(); + + if (tlb_flag(TLB_V3_PAGE)) + asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (kaddr) : "cc"); + if (tlb_flag(TLB_V4_U_PAGE)) + asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (kaddr) : "cc"); + if (tlb_flag(TLB_V4_D_PAGE)) + asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (kaddr) : "cc"); + if (tlb_flag(TLB_V4_I_PAGE)) + asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (kaddr) : "cc"); + if (!tlb_flag(TLB_V4_I_PAGE) && tlb_flag(TLB_V4_I_FULL)) + asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc"); + + if (tlb_flag(TLB_V6_U_PAGE)) + asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (kaddr) : "cc"); + if (tlb_flag(TLB_V6_D_PAGE)) + asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (kaddr) : "cc"); + if (tlb_flag(TLB_V6_I_PAGE)) + asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (kaddr) : "cc"); + if (tlb_flag(TLB_V7_UIS_PAGE)) + asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (kaddr) : "cc"); + + if (tlb_flag(TLB_BTB)) { + /* flush the branch target cache */ + asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc"); + dsb(); + isb(); + } + if (tlb_flag(TLB_V7_IS_BTB)) { + /* flush the branch target cache */ + asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero) : "cc"); + dsb(); + isb(); + } +} + +/* + * flush_pmd_entry + * + * Flush a PMD entry (word aligned, or double-word aligned) to + * RAM if the TLB for the CPU we are running on requires this. + * This is typically used when we are creating PMD entries. + * + * clean_pmd_entry + * + * Clean (but don't drain the write buffer) if the CPU requires + * these operations. This is typically used when we are removing + * PMD entries. + */ +static inline void flush_pmd_entry(pmd_t *pmd) +{ + const unsigned int __tlb_flag = __cpu_tlb_flags; + + if (tlb_flag(TLB_DCLEAN)) + asm("mcr p15, 0, %0, c7, c10, 1 @ flush_pmd" + : : "r" (pmd) : "cc"); + + if (tlb_flag(TLB_L2CLEAN_FR)) + asm("mcr p15, 1, %0, c15, c9, 1 @ L2 flush_pmd" + : : "r" (pmd) : "cc"); + + if (tlb_flag(TLB_WB)) + dsb(); +} + +static inline void clean_pmd_entry(pmd_t *pmd) +{ + const unsigned int __tlb_flag = __cpu_tlb_flags; + + if (tlb_flag(TLB_DCLEAN)) + asm("mcr p15, 0, %0, c7, c10, 1 @ flush_pmd" + : : "r" (pmd) : "cc"); + + if (tlb_flag(TLB_L2CLEAN_FR)) + asm("mcr p15, 1, %0, c15, c9, 1 @ L2 flush_pmd" + : : "r" (pmd) : "cc"); +} + +#undef tlb_flag +#undef always_tlb_flags +#undef possible_tlb_flags + +/* + * Convert calls to our calling convention. + */ +#define local_flush_tlb_range(vma,start,end) __cpu_flush_user_tlb_range(start,end,vma) +#define local_flush_tlb_kernel_range(s,e) __cpu_flush_kern_tlb_range(s,e) + +#ifndef CONFIG_SMP +#define flush_tlb_all local_flush_tlb_all +#define flush_tlb_mm local_flush_tlb_mm +#define flush_tlb_page local_flush_tlb_page +#define flush_tlb_kernel_page local_flush_tlb_kernel_page +#define flush_tlb_range local_flush_tlb_range +#define flush_tlb_kernel_range local_flush_tlb_kernel_range +#else +extern void flush_tlb_all(void); +extern void flush_tlb_mm(struct mm_struct *mm); +extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr); +extern void flush_tlb_kernel_page(unsigned long kaddr); +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); +#endif + +/* + * If PG_dcache_clean is not set for the page, we need to ensure that any + * cache entries for the kernels virtual memory range are written + * back to the page. On ARMv6 and later, the cache coherency is handled via + * the set_pte_at() function. + */ +#if __LINUX_ARM_ARCH__ < 6 +extern void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, + pte_t *ptep); +#else +static inline void update_mmu_cache(struct vm_area_struct *vma, + unsigned long addr, pte_t *ptep) +{ +} +#endif + +#endif + +#endif /* CONFIG_MMU */ + +#endif diff --git a/arch/arm/include/asm/tls.h b/arch/arm/include/asm/tls.h new file mode 100644 index 00000000..73409e6c --- /dev/null +++ b/arch/arm/include/asm/tls.h @@ -0,0 +1,49 @@ +#ifndef __ASMARM_TLS_H +#define __ASMARM_TLS_H + +#ifdef __ASSEMBLY__ + .macro set_tls_none, tp, tmp1, tmp2 + .endm + + .macro set_tls_v6k, tp, tmp1, tmp2 + mcr p15, 0, \tp, c13, c0, 3 @ set TLS register + mov \tmp1, #0 + mcr p15, 0, \tmp1, c13, c0, 2 @ clear user r/w TLS register + .endm + + .macro set_tls_v6, tp, tmp1, tmp2 + ldr \tmp1, =elf_hwcap + ldr \tmp1, [\tmp1, #0] + mov \tmp2, #0xffff0fff + tst \tmp1, #HWCAP_TLS @ hardware TLS available? + mcrne p15, 0, \tp, c13, c0, 3 @ yes, set TLS register + movne \tmp1, #0 + mcrne p15, 0, \tmp1, c13, c0, 2 @ clear user r/w TLS register + streq \tp, [\tmp2, #-15] @ set TLS value at 0xffff0ff0 + .endm + + .macro set_tls_software, tp, tmp1, tmp2 + mov \tmp1, #0xffff0fff + str \tp, [\tmp1, #-15] @ set TLS value at 0xffff0ff0 + .endm +#endif + +#ifdef CONFIG_TLS_REG_EMUL +#define tls_emu 1 +#define has_tls_reg 1 +#define set_tls set_tls_none +#elif defined(CONFIG_CPU_V6) +#define tls_emu 0 +#define has_tls_reg (elf_hwcap & HWCAP_TLS) +#define set_tls set_tls_v6 +#elif defined(CONFIG_CPU_32v6K) +#define tls_emu 0 +#define has_tls_reg 1 +#define set_tls set_tls_v6k +#else +#define tls_emu 0 +#define has_tls_reg 0 +#define set_tls set_tls_software +#endif + +#endif /* __ASMARM_TLS_H */ diff --git a/arch/arm/include/asm/topology.h b/arch/arm/include/asm/topology.h new file mode 100644 index 00000000..accbd7ca --- /dev/null +++ b/arch/arm/include/asm/topology.h @@ -0,0 +1,6 @@ +#ifndef _ASM_ARM_TOPOLOGY_H +#define _ASM_ARM_TOPOLOGY_H + +#include + +#endif /* _ASM_ARM_TOPOLOGY_H */ diff --git a/arch/arm/include/asm/traps.h b/arch/arm/include/asm/traps.h new file mode 100644 index 00000000..f90756dc --- /dev/null +++ b/arch/arm/include/asm/traps.h @@ -0,0 +1,52 @@ +#ifndef _ASMARM_TRAP_H +#define _ASMARM_TRAP_H + +#include + +struct undef_hook { + struct list_head node; + u32 instr_mask; + u32 instr_val; + u32 cpsr_mask; + u32 cpsr_val; + int (*fn)(struct pt_regs *regs, unsigned int instr); +}; + +void register_undef_hook(struct undef_hook *hook); +void unregister_undef_hook(struct undef_hook *hook); + +#ifdef CONFIG_FUNCTION_GRAPH_TRACER +static inline int __in_irqentry_text(unsigned long ptr) +{ + extern char __irqentry_text_start[]; + extern char __irqentry_text_end[]; + + return ptr >= (unsigned long)&__irqentry_text_start && + ptr < (unsigned long)&__irqentry_text_end; +} +#else +static inline int __in_irqentry_text(unsigned long ptr) +{ + return 0; +} +#endif + +static inline int in_exception_text(unsigned long ptr) +{ + extern char __exception_text_start[]; + extern char __exception_text_end[]; + int in; + + in = ptr >= (unsigned long)&__exception_text_start && + ptr < (unsigned long)&__exception_text_end; + + return in ? : __in_irqentry_text(ptr); +} + +extern void __init early_trap_init(void); +extern void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame); +extern void ptrace_break(struct task_struct *tsk, struct pt_regs *regs); + +extern void *vectors_page; + +#endif diff --git a/arch/arm/include/asm/types.h b/arch/arm/include/asm/types.h new file mode 100644 index 00000000..48192ac3 --- /dev/null +++ b/arch/arm/include/asm/types.h @@ -0,0 +1,22 @@ +#ifndef __ASM_ARM_TYPES_H +#define __ASM_ARM_TYPES_H + +#include + +#ifndef __ASSEMBLY__ + +typedef unsigned short umode_t; + +#endif /* __ASSEMBLY__ */ + +/* + * These aren't exported outside the kernel to avoid name space clashes + */ +#ifdef __KERNEL__ + +#define BITS_PER_LONG 32 + +#endif /* __KERNEL__ */ + +#endif + diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h new file mode 100644 index 00000000..2958976d --- /dev/null +++ b/arch/arm/include/asm/uaccess.h @@ -0,0 +1,450 @@ +/* + * arch/arm/include/asm/uaccess.h + * + * 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. + */ +#ifndef _ASMARM_UACCESS_H +#define _ASMARM_UACCESS_H + +/* + * User space memory access functions + */ +#include +#include +#include +#include +#include +#include +#include + +#define VERIFY_READ 0 +#define VERIFY_WRITE 1 + +/* + * The exception table consists of pairs of addresses: the first is the + * address of an instruction that is allowed to fault, and the second is + * the address at which the program should continue. No registers are + * modified, so it is entirely up to the continuation code to figure out + * what to do. + * + * All the routines below use bits of fixup code that are out of line + * with the main instruction path. This means when everything is well, + * we don't even have to jump over them. Further, they do not intrude + * on our cache or tlb entries. + */ + +struct exception_table_entry +{ + unsigned long insn, fixup; +}; + +extern int fixup_exception(struct pt_regs *regs); + +/* + * These two are intentionally not defined anywhere - if the kernel + * code generates any references to them, that's a bug. + */ +extern int __get_user_bad(void); +extern int __put_user_bad(void); + +/* + * Note that this is actually 0x1,0000,0000 + */ +#define KERNEL_DS 0x00000000 +#define get_ds() (KERNEL_DS) + +#ifdef CONFIG_MMU + +#define USER_DS TASK_SIZE +#define get_fs() (current_thread_info()->addr_limit) + +static inline void set_fs(mm_segment_t fs) +{ + current_thread_info()->addr_limit = fs; + modify_domain(DOMAIN_KERNEL, fs ? DOMAIN_CLIENT : DOMAIN_MANAGER); +} + +#define segment_eq(a,b) ((a) == (b)) + +#define __addr_ok(addr) ({ \ + unsigned long flag; \ + __asm__("cmp %2, %0; movlo %0, #0" \ + : "=&r" (flag) \ + : "0" (current_thread_info()->addr_limit), "r" (addr) \ + : "cc"); \ + (flag == 0); }) + +/* We use 33-bit arithmetic here... */ +#define __range_ok(addr,size) ({ \ + unsigned long flag, roksum; \ + __chk_user_ptr(addr); \ + __asm__("adds %1, %2, %3; sbcccs %1, %1, %0; movcc %0, #0" \ + : "=&r" (flag), "=&r" (roksum) \ + : "r" (addr), "Ir" (size), "0" (current_thread_info()->addr_limit) \ + : "cc"); \ + flag; }) + +/* + * Single-value transfer routines. They automatically use the right + * size if we just have the right pointer type. Note that the functions + * which read from user space (*get_*) need to take care not to leak + * kernel data even if the calling code is buggy and fails to check + * the return value. This means zeroing out the destination variable + * or buffer on error. Normally this is done out of line by the + * fixup code, but there are a few places where it intrudes on the + * main code path. When we only write to user space, there is no + * problem. + */ +extern int __get_user_1(void *); +extern int __get_user_2(void *); +extern int __get_user_4(void *); + +#define __get_user_x(__r2,__p,__e,__s,__i...) \ + __asm__ __volatile__ ( \ + __asmeq("%0", "r0") __asmeq("%1", "r2") \ + "bl __get_user_" #__s \ + : "=&r" (__e), "=r" (__r2) \ + : "0" (__p) \ + : __i, "cc") + +#define get_user(x,p) \ + ({ \ + register const typeof(*(p)) __user *__p asm("r0") = (p);\ + register unsigned long __r2 asm("r2"); \ + register int __e asm("r0"); \ + switch (sizeof(*(__p))) { \ + case 1: \ + __get_user_x(__r2, __p, __e, 1, "lr"); \ + break; \ + case 2: \ + __get_user_x(__r2, __p, __e, 2, "r3", "lr"); \ + break; \ + case 4: \ + __get_user_x(__r2, __p, __e, 4, "lr"); \ + break; \ + default: __e = __get_user_bad(); break; \ + } \ + x = (typeof(*(p))) __r2; \ + __e; \ + }) + +extern int __put_user_1(void *, unsigned int); +extern int __put_user_2(void *, unsigned int); +extern int __put_user_4(void *, unsigned int); +extern int __put_user_8(void *, unsigned long long); + +#define __put_user_x(__r2,__p,__e,__s) \ + __asm__ __volatile__ ( \ + __asmeq("%0", "r0") __asmeq("%2", "r2") \ + "bl __put_user_" #__s \ + : "=&r" (__e) \ + : "0" (__p), "r" (__r2) \ + : "ip", "lr", "cc") + +#define put_user(x,p) \ + ({ \ + register const typeof(*(p)) __r2 asm("r2") = (x); \ + register const typeof(*(p)) __user *__p asm("r0") = (p);\ + register int __e asm("r0"); \ + switch (sizeof(*(__p))) { \ + case 1: \ + __put_user_x(__r2, __p, __e, 1); \ + break; \ + case 2: \ + __put_user_x(__r2, __p, __e, 2); \ + break; \ + case 4: \ + __put_user_x(__r2, __p, __e, 4); \ + break; \ + case 8: \ + __put_user_x(__r2, __p, __e, 8); \ + break; \ + default: __e = __put_user_bad(); break; \ + } \ + __e; \ + }) + +#else /* CONFIG_MMU */ + +/* + * uClinux has only one addr space, so has simplified address limits. + */ +#define USER_DS KERNEL_DS + +#define segment_eq(a,b) (1) +#define __addr_ok(addr) (1) +#define __range_ok(addr,size) (0) +#define get_fs() (KERNEL_DS) + +static inline void set_fs(mm_segment_t fs) +{ +} + +#define get_user(x,p) __get_user(x,p) +#define put_user(x,p) __put_user(x,p) + +#endif /* CONFIG_MMU */ + +#define access_ok(type,addr,size) (__range_ok(addr,size) == 0) + +/* + * The "__xxx" versions of the user access functions do not verify the + * address space - it must have been done previously with a separate + * "access_ok()" call. + * + * The "xxx_error" versions set the third argument to EFAULT if an + * error occurs, and leave it unchanged on success. Note that these + * versions are void (ie, don't return a value as such). + */ +#define __get_user(x,ptr) \ +({ \ + long __gu_err = 0; \ + __get_user_err((x),(ptr),__gu_err); \ + __gu_err; \ +}) + +#define __get_user_error(x,ptr,err) \ +({ \ + __get_user_err((x),(ptr),err); \ + (void) 0; \ +}) + +#define __get_user_err(x,ptr,err) \ +do { \ + unsigned long __gu_addr = (unsigned long)(ptr); \ + unsigned long __gu_val; \ + __chk_user_ptr(ptr); \ + switch (sizeof(*(ptr))) { \ + case 1: __get_user_asm_byte(__gu_val,__gu_addr,err); break; \ + case 2: __get_user_asm_half(__gu_val,__gu_addr,err); break; \ + case 4: __get_user_asm_word(__gu_val,__gu_addr,err); break; \ + default: (__gu_val) = __get_user_bad(); \ + } \ + (x) = (__typeof__(*(ptr)))__gu_val; \ +} while (0) + +#define __get_user_asm_byte(x,addr,err) \ + __asm__ __volatile__( \ + "1: " TUSER(ldrb) " %1,[%2],#0\n" \ + "2:\n" \ + " .pushsection .fixup,\"ax\"\n" \ + " .align 2\n" \ + "3: mov %0, %3\n" \ + " mov %1, #0\n" \ + " b 2b\n" \ + " .popsection\n" \ + " .pushsection __ex_table,\"a\"\n" \ + " .align 3\n" \ + " .long 1b, 3b\n" \ + " .popsection" \ + : "+r" (err), "=&r" (x) \ + : "r" (addr), "i" (-EFAULT) \ + : "cc") + +#ifndef __ARMEB__ +#define __get_user_asm_half(x,__gu_addr,err) \ +({ \ + unsigned long __b1, __b2; \ + __get_user_asm_byte(__b1, __gu_addr, err); \ + __get_user_asm_byte(__b2, __gu_addr + 1, err); \ + (x) = __b1 | (__b2 << 8); \ +}) +#else +#define __get_user_asm_half(x,__gu_addr,err) \ +({ \ + unsigned long __b1, __b2; \ + __get_user_asm_byte(__b1, __gu_addr, err); \ + __get_user_asm_byte(__b2, __gu_addr + 1, err); \ + (x) = (__b1 << 8) | __b2; \ +}) +#endif + +#define __get_user_asm_word(x,addr,err) \ + __asm__ __volatile__( \ + "1: " TUSER(ldr) " %1,[%2],#0\n" \ + "2:\n" \ + " .pushsection .fixup,\"ax\"\n" \ + " .align 2\n" \ + "3: mov %0, %3\n" \ + " mov %1, #0\n" \ + " b 2b\n" \ + " .popsection\n" \ + " .pushsection __ex_table,\"a\"\n" \ + " .align 3\n" \ + " .long 1b, 3b\n" \ + " .popsection" \ + : "+r" (err), "=&r" (x) \ + : "r" (addr), "i" (-EFAULT) \ + : "cc") + +#define __put_user(x,ptr) \ +({ \ + long __pu_err = 0; \ + __put_user_err((x),(ptr),__pu_err); \ + __pu_err; \ +}) + +#define __put_user_error(x,ptr,err) \ +({ \ + __put_user_err((x),(ptr),err); \ + (void) 0; \ +}) + +#define __put_user_err(x,ptr,err) \ +do { \ + unsigned long __pu_addr = (unsigned long)(ptr); \ + __typeof__(*(ptr)) __pu_val = (x); \ + __chk_user_ptr(ptr); \ + switch (sizeof(*(ptr))) { \ + case 1: __put_user_asm_byte(__pu_val,__pu_addr,err); break; \ + case 2: __put_user_asm_half(__pu_val,__pu_addr,err); break; \ + case 4: __put_user_asm_word(__pu_val,__pu_addr,err); break; \ + case 8: __put_user_asm_dword(__pu_val,__pu_addr,err); break; \ + default: __put_user_bad(); \ + } \ +} while (0) + +#define __put_user_asm_byte(x,__pu_addr,err) \ + __asm__ __volatile__( \ + "1: " TUSER(strb) " %1,[%2],#0\n" \ + "2:\n" \ + " .pushsection .fixup,\"ax\"\n" \ + " .align 2\n" \ + "3: mov %0, %3\n" \ + " b 2b\n" \ + " .popsection\n" \ + " .pushsection __ex_table,\"a\"\n" \ + " .align 3\n" \ + " .long 1b, 3b\n" \ + " .popsection" \ + : "+r" (err) \ + : "r" (x), "r" (__pu_addr), "i" (-EFAULT) \ + : "cc") + +#ifndef __ARMEB__ +#define __put_user_asm_half(x,__pu_addr,err) \ +({ \ + unsigned long __temp = (unsigned long)(x); \ + __put_user_asm_byte(__temp, __pu_addr, err); \ + __put_user_asm_byte(__temp >> 8, __pu_addr + 1, err); \ +}) +#else +#define __put_user_asm_half(x,__pu_addr,err) \ +({ \ + unsigned long __temp = (unsigned long)(x); \ + __put_user_asm_byte(__temp >> 8, __pu_addr, err); \ + __put_user_asm_byte(__temp, __pu_addr + 1, err); \ +}) +#endif + +#define __put_user_asm_word(x,__pu_addr,err) \ + __asm__ __volatile__( \ + "1: " TUSER(str) " %1,[%2],#0\n" \ + "2:\n" \ + " .pushsection .fixup,\"ax\"\n" \ + " .align 2\n" \ + "3: mov %0, %3\n" \ + " b 2b\n" \ + " .popsection\n" \ + " .pushsection __ex_table,\"a\"\n" \ + " .align 3\n" \ + " .long 1b, 3b\n" \ + " .popsection" \ + : "+r" (err) \ + : "r" (x), "r" (__pu_addr), "i" (-EFAULT) \ + : "cc") + +#ifndef __ARMEB__ +#define __reg_oper0 "%R2" +#define __reg_oper1 "%Q2" +#else +#define __reg_oper0 "%Q2" +#define __reg_oper1 "%R2" +#endif + +#define __put_user_asm_dword(x,__pu_addr,err) \ + __asm__ __volatile__( \ + ARM( "1: " TUSER(str) " " __reg_oper1 ", [%1], #4\n" ) \ + ARM( "2: " TUSER(str) " " __reg_oper0 ", [%1]\n" ) \ + THUMB( "1: " TUSER(str) " " __reg_oper1 ", [%1]\n" ) \ + THUMB( "2: " TUSER(str) " " __reg_oper0 ", [%1, #4]\n" ) \ + "3:\n" \ + " .pushsection .fixup,\"ax\"\n" \ + " .align 2\n" \ + "4: mov %0, %3\n" \ + " b 3b\n" \ + " .popsection\n" \ + " .pushsection __ex_table,\"a\"\n" \ + " .align 3\n" \ + " .long 1b, 4b\n" \ + " .long 2b, 4b\n" \ + " .popsection" \ + : "+r" (err), "+r" (__pu_addr) \ + : "r" (x), "i" (-EFAULT) \ + : "cc") + + +#ifdef CONFIG_MMU +extern unsigned long __must_check __copy_from_user(void *to, const void __user *from, unsigned long n); +extern unsigned long __must_check __copy_to_user(void __user *to, const void *from, unsigned long n); +extern unsigned long __must_check __copy_to_user_std(void __user *to, const void *from, unsigned long n); +extern unsigned long __must_check __clear_user(void __user *addr, unsigned long n); +extern unsigned long __must_check __clear_user_std(void __user *addr, unsigned long n); +#else +#define __copy_from_user(to,from,n) (memcpy(to, (void __force *)from, n), 0) +#define __copy_to_user(to,from,n) (memcpy((void __force *)to, from, n), 0) +#define __clear_user(addr,n) (memset((void __force *)addr, 0, n), 0) +#endif + +extern unsigned long __must_check __strncpy_from_user(char *to, const char __user *from, unsigned long count); +extern unsigned long __must_check __strnlen_user(const char __user *s, long n); + +static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n) +{ + if (access_ok(VERIFY_READ, from, n)) + n = __copy_from_user(to, from, n); + else /* security hole - plug it */ + memset(to, 0, n); + return n; +} + +static inline unsigned long __must_check copy_to_user(void __user *to, const void *from, unsigned long n) +{ + if (access_ok(VERIFY_WRITE, to, n)) + n = __copy_to_user(to, from, n); + return n; +} + +#define __copy_to_user_inatomic __copy_to_user +#define __copy_from_user_inatomic __copy_from_user + +static inline unsigned long __must_check clear_user(void __user *to, unsigned long n) +{ + if (access_ok(VERIFY_WRITE, to, n)) + n = __clear_user(to, n); + return n; +} + +static inline long __must_check strncpy_from_user(char *dst, const char __user *src, long count) +{ + long res = -EFAULT; + if (access_ok(VERIFY_READ, src, 1)) + res = __strncpy_from_user(dst, src, count); + return res; +} + +#define strlen_user(s) strnlen_user(s, ~0UL >> 1) + +static inline long __must_check strnlen_user(const char __user *s, long n) +{ + unsigned long res = 0; + + if (__addr_ok(s)) + res = __strnlen_user(s, n); + + return res; +} + +#endif /* _ASMARM_UACCESS_H */ diff --git a/arch/arm/include/asm/ucontext.h b/arch/arm/include/asm/ucontext.h new file mode 100644 index 00000000..14749aec --- /dev/null +++ b/arch/arm/include/asm/ucontext.h @@ -0,0 +1,102 @@ +#ifndef _ASMARM_UCONTEXT_H +#define _ASMARM_UCONTEXT_H + +#include + +/* + * struct sigcontext only has room for the basic registers, but struct + * ucontext now has room for all registers which need to be saved and + * restored. Coprocessor registers are stored in uc_regspace. Each + * coprocessor's saved state should start with a documented 32-bit magic + * number, followed by a 32-bit word giving the coproccesor's saved size. + * uc_regspace may be expanded if necessary, although this takes some + * coordination with glibc. + */ + +struct ucontext { + unsigned long uc_flags; + struct ucontext *uc_link; + stack_t uc_stack; + struct sigcontext uc_mcontext; + sigset_t uc_sigmask; + /* Allow for uc_sigmask growth. Glibc uses a 1024-bit sigset_t. */ + int __unused[32 - (sizeof (sigset_t) / sizeof (int))]; + /* Last for extensibility. Eight byte aligned because some + coprocessors require eight byte alignment. */ + unsigned long uc_regspace[128] __attribute__((__aligned__(8))); +}; + +#ifdef __KERNEL__ + +/* + * Coprocessor save state. The magic values and specific + * coprocessor's layouts are part of the userspace ABI. Each one of + * these should be a multiple of eight bytes and aligned to eight + * bytes, to prevent unpredictable padding in the signal frame. + */ + +#ifdef CONFIG_CRUNCH +#define CRUNCH_MAGIC 0x5065cf03 +#define CRUNCH_STORAGE_SIZE (CRUNCH_SIZE + 8) + +struct crunch_sigframe { + unsigned long magic; + unsigned long size; + struct crunch_state storage; +} __attribute__((__aligned__(8))); +#endif + +#ifdef CONFIG_IWMMXT +/* iwmmxt_area is 0x98 bytes long, preceded by 8 bytes of signature */ +#define IWMMXT_MAGIC 0x12ef842a +#define IWMMXT_STORAGE_SIZE (IWMMXT_SIZE + 8) + +struct iwmmxt_sigframe { + unsigned long magic; + unsigned long size; + struct iwmmxt_struct storage; +} __attribute__((__aligned__(8))); +#endif /* CONFIG_IWMMXT */ + +#ifdef CONFIG_VFP +#define VFP_MAGIC 0x56465001 + +struct vfp_sigframe +{ + unsigned long magic; + unsigned long size; + struct user_vfp ufp; + struct user_vfp_exc ufp_exc; +} __attribute__((__aligned__(8))); + +/* + * 8 byte for magic and size, 264 byte for ufp, 12 bytes for ufp_exc, + * 4 bytes padding. + */ +#define VFP_STORAGE_SIZE sizeof(struct vfp_sigframe) + +#endif /* CONFIG_VFP */ + +/* + * Auxiliary signal frame. This saves stuff like FP state. + * The layout of this structure is not part of the user ABI, + * because the config options aren't. uc_regspace is really + * one of these. + */ +struct aux_sigframe { +#ifdef CONFIG_CRUNCH + struct crunch_sigframe crunch; +#endif +#ifdef CONFIG_IWMMXT + struct iwmmxt_sigframe iwmmxt; +#endif +#ifdef CONFIG_VFP + struct vfp_sigframe vfp; +#endif + /* Something that isn't a valid magic number for any coprocessor. */ + unsigned long end_magic; +} __attribute__((__aligned__(8))); + +#endif + +#endif /* !_ASMARM_UCONTEXT_H */ diff --git a/arch/arm/include/asm/unaligned.h b/arch/arm/include/asm/unaligned.h new file mode 100644 index 00000000..44593a89 --- /dev/null +++ b/arch/arm/include/asm/unaligned.h @@ -0,0 +1,19 @@ +#ifndef _ASM_ARM_UNALIGNED_H +#define _ASM_ARM_UNALIGNED_H + +#include +#include +#include + +/* + * Select endianness + */ +#ifndef __ARMEB__ +#define get_unaligned __get_unaligned_le +#define put_unaligned __put_unaligned_le +#else +#define get_unaligned __get_unaligned_be +#define put_unaligned __put_unaligned_be +#endif + +#endif /* _ASM_ARM_UNALIGNED_H */ diff --git a/arch/arm/include/asm/unified.h b/arch/arm/include/asm/unified.h new file mode 100644 index 00000000..bc631161 --- /dev/null +++ b/arch/arm/include/asm/unified.h @@ -0,0 +1,130 @@ +/* + * include/asm-arm/unified.h - Unified Assembler Syntax helper macros + * + * Copyright (C) 2008 ARM Limited + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This 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_UNIFIED_H +#define __ASM_UNIFIED_H + +#if defined(__ASSEMBLY__) && defined(CONFIG_ARM_ASM_UNIFIED) + .syntax unified +#endif + +#ifdef CONFIG_THUMB2_KERNEL + +#if __GNUC__ < 4 +#error Thumb-2 kernel requires gcc >= 4 +#endif + +/* The CPSR bit describing the instruction set (Thumb) */ +#define PSR_ISETSTATE PSR_T_BIT + +#define ARM(x...) +#define THUMB(x...) x +#ifdef __ASSEMBLY__ +#define W(instr) instr.w +#endif +#define BSYM(sym) sym + 1 + +#else /* !CONFIG_THUMB2_KERNEL */ + +/* The CPSR bit describing the instruction set (ARM) */ +#define PSR_ISETSTATE 0 + +#define ARM(x...) x +#define THUMB(x...) +#ifdef __ASSEMBLY__ +#define W(instr) instr +#endif +#define BSYM(sym) sym + +#endif /* CONFIG_THUMB2_KERNEL */ + +#ifndef CONFIG_ARM_ASM_UNIFIED + +/* + * If the unified assembly syntax isn't used (in ARM mode), these + * macros expand to an empty string + */ +#ifdef __ASSEMBLY__ + .macro it, cond + .endm + .macro itt, cond + .endm + .macro ite, cond + .endm + .macro ittt, cond + .endm + .macro itte, cond + .endm + .macro itet, cond + .endm + .macro itee, cond + .endm + .macro itttt, cond + .endm + .macro ittte, cond + .endm + .macro ittet, cond + .endm + .macro ittee, cond + .endm + .macro itett, cond + .endm + .macro itete, cond + .endm + .macro iteet, cond + .endm + .macro iteee, cond + .endm +#else /* !__ASSEMBLY__ */ +__asm__( +" .macro it, cond\n" +" .endm\n" +" .macro itt, cond\n" +" .endm\n" +" .macro ite, cond\n" +" .endm\n" +" .macro ittt, cond\n" +" .endm\n" +" .macro itte, cond\n" +" .endm\n" +" .macro itet, cond\n" +" .endm\n" +" .macro itee, cond\n" +" .endm\n" +" .macro itttt, cond\n" +" .endm\n" +" .macro ittte, cond\n" +" .endm\n" +" .macro ittet, cond\n" +" .endm\n" +" .macro ittee, cond\n" +" .endm\n" +" .macro itett, cond\n" +" .endm\n" +" .macro itete, cond\n" +" .endm\n" +" .macro iteet, cond\n" +" .endm\n" +" .macro iteee, cond\n" +" .endm\n"); +#endif /* __ASSEMBLY__ */ + +#endif /* CONFIG_ARM_ASM_UNIFIED */ + +#endif /* !__ASM_UNIFIED_H */ diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h new file mode 100644 index 00000000..2c04ed5e --- /dev/null +++ b/arch/arm/include/asm/unistd.h @@ -0,0 +1,485 @@ +/* + * arch/arm/include/asm/unistd.h + * + * Copyright (C) 2001-2005 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Please forward _all_ changes to this file to rmk@arm.linux.org.uk, + * no matter what the change is. Thanks! + */ +#ifndef __ASM_ARM_UNISTD_H +#define __ASM_ARM_UNISTD_H + +#define __NR_OABI_SYSCALL_BASE 0x900000 + +#if defined(__thumb__) || defined(__ARM_EABI__) +#define __NR_SYSCALL_BASE 0 +#else +#define __NR_SYSCALL_BASE __NR_OABI_SYSCALL_BASE +#endif + +/* + * This file contains the system call numbers. + */ + +#define __NR_restart_syscall (__NR_SYSCALL_BASE+ 0) +#define __NR_exit (__NR_SYSCALL_BASE+ 1) +#define __NR_fork (__NR_SYSCALL_BASE+ 2) +#define __NR_read (__NR_SYSCALL_BASE+ 3) +#define __NR_write (__NR_SYSCALL_BASE+ 4) +#define __NR_open (__NR_SYSCALL_BASE+ 5) +#define __NR_close (__NR_SYSCALL_BASE+ 6) + /* 7 was sys_waitpid */ +#define __NR_creat (__NR_SYSCALL_BASE+ 8) +#define __NR_link (__NR_SYSCALL_BASE+ 9) +#define __NR_unlink (__NR_SYSCALL_BASE+ 10) +#define __NR_execve (__NR_SYSCALL_BASE+ 11) +#define __NR_chdir (__NR_SYSCALL_BASE+ 12) +#define __NR_time (__NR_SYSCALL_BASE+ 13) +#define __NR_mknod (__NR_SYSCALL_BASE+ 14) +#define __NR_chmod (__NR_SYSCALL_BASE+ 15) +#define __NR_lchown (__NR_SYSCALL_BASE+ 16) + /* 17 was sys_break */ + /* 18 was sys_stat */ +#define __NR_lseek (__NR_SYSCALL_BASE+ 19) +#define __NR_getpid (__NR_SYSCALL_BASE+ 20) +#define __NR_mount (__NR_SYSCALL_BASE+ 21) +#define __NR_umount (__NR_SYSCALL_BASE+ 22) +#define __NR_setuid (__NR_SYSCALL_BASE+ 23) +#define __NR_getuid (__NR_SYSCALL_BASE+ 24) +#define __NR_stime (__NR_SYSCALL_BASE+ 25) +#define __NR_ptrace (__NR_SYSCALL_BASE+ 26) +#define __NR_alarm (__NR_SYSCALL_BASE+ 27) + /* 28 was sys_fstat */ +#define __NR_pause (__NR_SYSCALL_BASE+ 29) +#define __NR_utime (__NR_SYSCALL_BASE+ 30) + /* 31 was sys_stty */ + /* 32 was sys_gtty */ +#define __NR_access (__NR_SYSCALL_BASE+ 33) +#define __NR_nice (__NR_SYSCALL_BASE+ 34) + /* 35 was sys_ftime */ +#define __NR_sync (__NR_SYSCALL_BASE+ 36) +#define __NR_kill (__NR_SYSCALL_BASE+ 37) +#define __NR_rename (__NR_SYSCALL_BASE+ 38) +#define __NR_mkdir (__NR_SYSCALL_BASE+ 39) +#define __NR_rmdir (__NR_SYSCALL_BASE+ 40) +#define __NR_dup (__NR_SYSCALL_BASE+ 41) +#define __NR_pipe (__NR_SYSCALL_BASE+ 42) +#define __NR_times (__NR_SYSCALL_BASE+ 43) + /* 44 was sys_prof */ +#define __NR_brk (__NR_SYSCALL_BASE+ 45) +#define __NR_setgid (__NR_SYSCALL_BASE+ 46) +#define __NR_getgid (__NR_SYSCALL_BASE+ 47) + /* 48 was sys_signal */ +#define __NR_geteuid (__NR_SYSCALL_BASE+ 49) +#define __NR_getegid (__NR_SYSCALL_BASE+ 50) +#define __NR_acct (__NR_SYSCALL_BASE+ 51) +#define __NR_umount2 (__NR_SYSCALL_BASE+ 52) + /* 53 was sys_lock */ +#define __NR_ioctl (__NR_SYSCALL_BASE+ 54) +#define __NR_fcntl (__NR_SYSCALL_BASE+ 55) + /* 56 was sys_mpx */ +#define __NR_setpgid (__NR_SYSCALL_BASE+ 57) + /* 58 was sys_ulimit */ + /* 59 was sys_olduname */ +#define __NR_umask (__NR_SYSCALL_BASE+ 60) +#define __NR_chroot (__NR_SYSCALL_BASE+ 61) +#define __NR_ustat (__NR_SYSCALL_BASE+ 62) +#define __NR_dup2 (__NR_SYSCALL_BASE+ 63) +#define __NR_getppid (__NR_SYSCALL_BASE+ 64) +#define __NR_getpgrp (__NR_SYSCALL_BASE+ 65) +#define __NR_setsid (__NR_SYSCALL_BASE+ 66) +#define __NR_sigaction (__NR_SYSCALL_BASE+ 67) + /* 68 was sys_sgetmask */ + /* 69 was sys_ssetmask */ +#define __NR_setreuid (__NR_SYSCALL_BASE+ 70) +#define __NR_setregid (__NR_SYSCALL_BASE+ 71) +#define __NR_sigsuspend (__NR_SYSCALL_BASE+ 72) +#define __NR_sigpending (__NR_SYSCALL_BASE+ 73) +#define __NR_sethostname (__NR_SYSCALL_BASE+ 74) +#define __NR_setrlimit (__NR_SYSCALL_BASE+ 75) +#define __NR_getrlimit (__NR_SYSCALL_BASE+ 76) /* Back compat 2GB limited rlimit */ +#define __NR_getrusage (__NR_SYSCALL_BASE+ 77) +#define __NR_gettimeofday (__NR_SYSCALL_BASE+ 78) +#define __NR_settimeofday (__NR_SYSCALL_BASE+ 79) +#define __NR_getgroups (__NR_SYSCALL_BASE+ 80) +#define __NR_setgroups (__NR_SYSCALL_BASE+ 81) +#define __NR_select (__NR_SYSCALL_BASE+ 82) +#define __NR_symlink (__NR_SYSCALL_BASE+ 83) + /* 84 was sys_lstat */ +#define __NR_readlink (__NR_SYSCALL_BASE+ 85) +#define __NR_uselib (__NR_SYSCALL_BASE+ 86) +#define __NR_swapon (__NR_SYSCALL_BASE+ 87) +#define __NR_reboot (__NR_SYSCALL_BASE+ 88) +#define __NR_readdir (__NR_SYSCALL_BASE+ 89) +#define __NR_mmap (__NR_SYSCALL_BASE+ 90) +#define __NR_munmap (__NR_SYSCALL_BASE+ 91) +#define __NR_truncate (__NR_SYSCALL_BASE+ 92) +#define __NR_ftruncate (__NR_SYSCALL_BASE+ 93) +#define __NR_fchmod (__NR_SYSCALL_BASE+ 94) +#define __NR_fchown (__NR_SYSCALL_BASE+ 95) +#define __NR_getpriority (__NR_SYSCALL_BASE+ 96) +#define __NR_setpriority (__NR_SYSCALL_BASE+ 97) + /* 98 was sys_profil */ +#define __NR_statfs (__NR_SYSCALL_BASE+ 99) +#define __NR_fstatfs (__NR_SYSCALL_BASE+100) + /* 101 was sys_ioperm */ +#define __NR_socketcall (__NR_SYSCALL_BASE+102) +#define __NR_syslog (__NR_SYSCALL_BASE+103) +#define __NR_setitimer (__NR_SYSCALL_BASE+104) +#define __NR_getitimer (__NR_SYSCALL_BASE+105) +#define __NR_stat (__NR_SYSCALL_BASE+106) +#define __NR_lstat (__NR_SYSCALL_BASE+107) +#define __NR_fstat (__NR_SYSCALL_BASE+108) + /* 109 was sys_uname */ + /* 110 was sys_iopl */ +#define __NR_vhangup (__NR_SYSCALL_BASE+111) + /* 112 was sys_idle */ +#define __NR_syscall (__NR_SYSCALL_BASE+113) /* syscall to call a syscall! */ +#define __NR_wait4 (__NR_SYSCALL_BASE+114) +#define __NR_swapoff (__NR_SYSCALL_BASE+115) +#define __NR_sysinfo (__NR_SYSCALL_BASE+116) +#define __NR_ipc (__NR_SYSCALL_BASE+117) +#define __NR_fsync (__NR_SYSCALL_BASE+118) +#define __NR_sigreturn (__NR_SYSCALL_BASE+119) +#define __NR_clone (__NR_SYSCALL_BASE+120) +#define __NR_setdomainname (__NR_SYSCALL_BASE+121) +#define __NR_uname (__NR_SYSCALL_BASE+122) + /* 123 was sys_modify_ldt */ +#define __NR_adjtimex (__NR_SYSCALL_BASE+124) +#define __NR_mprotect (__NR_SYSCALL_BASE+125) +#define __NR_sigprocmask (__NR_SYSCALL_BASE+126) + /* 127 was sys_create_module */ +#define __NR_init_module (__NR_SYSCALL_BASE+128) +#define __NR_delete_module (__NR_SYSCALL_BASE+129) + /* 130 was sys_get_kernel_syms */ +#define __NR_quotactl (__NR_SYSCALL_BASE+131) +#define __NR_getpgid (__NR_SYSCALL_BASE+132) +#define __NR_fchdir (__NR_SYSCALL_BASE+133) +#define __NR_bdflush (__NR_SYSCALL_BASE+134) +#define __NR_sysfs (__NR_SYSCALL_BASE+135) +#define __NR_personality (__NR_SYSCALL_BASE+136) + /* 137 was sys_afs_syscall */ +#define __NR_setfsuid (__NR_SYSCALL_BASE+138) +#define __NR_setfsgid (__NR_SYSCALL_BASE+139) +#define __NR__llseek (__NR_SYSCALL_BASE+140) +#define __NR_getdents (__NR_SYSCALL_BASE+141) +#define __NR__newselect (__NR_SYSCALL_BASE+142) +#define __NR_flock (__NR_SYSCALL_BASE+143) +#define __NR_msync (__NR_SYSCALL_BASE+144) +#define __NR_readv (__NR_SYSCALL_BASE+145) +#define __NR_writev (__NR_SYSCALL_BASE+146) +#define __NR_getsid (__NR_SYSCALL_BASE+147) +#define __NR_fdatasync (__NR_SYSCALL_BASE+148) +#define __NR__sysctl (__NR_SYSCALL_BASE+149) +#define __NR_mlock (__NR_SYSCALL_BASE+150) +#define __NR_munlock (__NR_SYSCALL_BASE+151) +#define __NR_mlockall (__NR_SYSCALL_BASE+152) +#define __NR_munlockall (__NR_SYSCALL_BASE+153) +#define __NR_sched_setparam (__NR_SYSCALL_BASE+154) +#define __NR_sched_getparam (__NR_SYSCALL_BASE+155) +#define __NR_sched_setscheduler (__NR_SYSCALL_BASE+156) +#define __NR_sched_getscheduler (__NR_SYSCALL_BASE+157) +#define __NR_sched_yield (__NR_SYSCALL_BASE+158) +#define __NR_sched_get_priority_max (__NR_SYSCALL_BASE+159) +#define __NR_sched_get_priority_min (__NR_SYSCALL_BASE+160) +#define __NR_sched_rr_get_interval (__NR_SYSCALL_BASE+161) +#define __NR_nanosleep (__NR_SYSCALL_BASE+162) +#define __NR_mremap (__NR_SYSCALL_BASE+163) +#define __NR_setresuid (__NR_SYSCALL_BASE+164) +#define __NR_getresuid (__NR_SYSCALL_BASE+165) + /* 166 was sys_vm86 */ + /* 167 was sys_query_module */ +#define __NR_poll (__NR_SYSCALL_BASE+168) +#define __NR_nfsservctl (__NR_SYSCALL_BASE+169) +#define __NR_setresgid (__NR_SYSCALL_BASE+170) +#define __NR_getresgid (__NR_SYSCALL_BASE+171) +#define __NR_prctl (__NR_SYSCALL_BASE+172) +#define __NR_rt_sigreturn (__NR_SYSCALL_BASE+173) +#define __NR_rt_sigaction (__NR_SYSCALL_BASE+174) +#define __NR_rt_sigprocmask (__NR_SYSCALL_BASE+175) +#define __NR_rt_sigpending (__NR_SYSCALL_BASE+176) +#define __NR_rt_sigtimedwait (__NR_SYSCALL_BASE+177) +#define __NR_rt_sigqueueinfo (__NR_SYSCALL_BASE+178) +#define __NR_rt_sigsuspend (__NR_SYSCALL_BASE+179) +#define __NR_pread64 (__NR_SYSCALL_BASE+180) +#define __NR_pwrite64 (__NR_SYSCALL_BASE+181) +#define __NR_chown (__NR_SYSCALL_BASE+182) +#define __NR_getcwd (__NR_SYSCALL_BASE+183) +#define __NR_capget (__NR_SYSCALL_BASE+184) +#define __NR_capset (__NR_SYSCALL_BASE+185) +#define __NR_sigaltstack (__NR_SYSCALL_BASE+186) +#define __NR_sendfile (__NR_SYSCALL_BASE+187) + /* 188 reserved */ + /* 189 reserved */ +#define __NR_vfork (__NR_SYSCALL_BASE+190) +#define __NR_ugetrlimit (__NR_SYSCALL_BASE+191) /* SuS compliant getrlimit */ +#define __NR_mmap2 (__NR_SYSCALL_BASE+192) +#define __NR_truncate64 (__NR_SYSCALL_BASE+193) +#define __NR_ftruncate64 (__NR_SYSCALL_BASE+194) +#define __NR_stat64 (__NR_SYSCALL_BASE+195) +#define __NR_lstat64 (__NR_SYSCALL_BASE+196) +#define __NR_fstat64 (__NR_SYSCALL_BASE+197) +#define __NR_lchown32 (__NR_SYSCALL_BASE+198) +#define __NR_getuid32 (__NR_SYSCALL_BASE+199) +#define __NR_getgid32 (__NR_SYSCALL_BASE+200) +#define __NR_geteuid32 (__NR_SYSCALL_BASE+201) +#define __NR_getegid32 (__NR_SYSCALL_BASE+202) +#define __NR_setreuid32 (__NR_SYSCALL_BASE+203) +#define __NR_setregid32 (__NR_SYSCALL_BASE+204) +#define __NR_getgroups32 (__NR_SYSCALL_BASE+205) +#define __NR_setgroups32 (__NR_SYSCALL_BASE+206) +#define __NR_fchown32 (__NR_SYSCALL_BASE+207) +#define __NR_setresuid32 (__NR_SYSCALL_BASE+208) +#define __NR_getresuid32 (__NR_SYSCALL_BASE+209) +#define __NR_setresgid32 (__NR_SYSCALL_BASE+210) +#define __NR_getresgid32 (__NR_SYSCALL_BASE+211) +#define __NR_chown32 (__NR_SYSCALL_BASE+212) +#define __NR_setuid32 (__NR_SYSCALL_BASE+213) +#define __NR_setgid32 (__NR_SYSCALL_BASE+214) +#define __NR_setfsuid32 (__NR_SYSCALL_BASE+215) +#define __NR_setfsgid32 (__NR_SYSCALL_BASE+216) +#define __NR_getdents64 (__NR_SYSCALL_BASE+217) +#define __NR_pivot_root (__NR_SYSCALL_BASE+218) +#define __NR_mincore (__NR_SYSCALL_BASE+219) +#define __NR_madvise (__NR_SYSCALL_BASE+220) +#define __NR_fcntl64 (__NR_SYSCALL_BASE+221) + /* 222 for tux */ + /* 223 is unused */ +#define __NR_gettid (__NR_SYSCALL_BASE+224) +#define __NR_readahead (__NR_SYSCALL_BASE+225) +#define __NR_setxattr (__NR_SYSCALL_BASE+226) +#define __NR_lsetxattr (__NR_SYSCALL_BASE+227) +#define __NR_fsetxattr (__NR_SYSCALL_BASE+228) +#define __NR_getxattr (__NR_SYSCALL_BASE+229) +#define __NR_lgetxattr (__NR_SYSCALL_BASE+230) +#define __NR_fgetxattr (__NR_SYSCALL_BASE+231) +#define __NR_listxattr (__NR_SYSCALL_BASE+232) +#define __NR_llistxattr (__NR_SYSCALL_BASE+233) +#define __NR_flistxattr (__NR_SYSCALL_BASE+234) +#define __NR_removexattr (__NR_SYSCALL_BASE+235) +#define __NR_lremovexattr (__NR_SYSCALL_BASE+236) +#define __NR_fremovexattr (__NR_SYSCALL_BASE+237) +#define __NR_tkill (__NR_SYSCALL_BASE+238) +#define __NR_sendfile64 (__NR_SYSCALL_BASE+239) +#define __NR_futex (__NR_SYSCALL_BASE+240) +#define __NR_sched_setaffinity (__NR_SYSCALL_BASE+241) +#define __NR_sched_getaffinity (__NR_SYSCALL_BASE+242) +#define __NR_io_setup (__NR_SYSCALL_BASE+243) +#define __NR_io_destroy (__NR_SYSCALL_BASE+244) +#define __NR_io_getevents (__NR_SYSCALL_BASE+245) +#define __NR_io_submit (__NR_SYSCALL_BASE+246) +#define __NR_io_cancel (__NR_SYSCALL_BASE+247) +#define __NR_exit_group (__NR_SYSCALL_BASE+248) +#define __NR_lookup_dcookie (__NR_SYSCALL_BASE+249) +#define __NR_epoll_create (__NR_SYSCALL_BASE+250) +#define __NR_epoll_ctl (__NR_SYSCALL_BASE+251) +#define __NR_epoll_wait (__NR_SYSCALL_BASE+252) +#define __NR_remap_file_pages (__NR_SYSCALL_BASE+253) + /* 254 for set_thread_area */ + /* 255 for get_thread_area */ +#define __NR_set_tid_address (__NR_SYSCALL_BASE+256) +#define __NR_timer_create (__NR_SYSCALL_BASE+257) +#define __NR_timer_settime (__NR_SYSCALL_BASE+258) +#define __NR_timer_gettime (__NR_SYSCALL_BASE+259) +#define __NR_timer_getoverrun (__NR_SYSCALL_BASE+260) +#define __NR_timer_delete (__NR_SYSCALL_BASE+261) +#define __NR_clock_settime (__NR_SYSCALL_BASE+262) +#define __NR_clock_gettime (__NR_SYSCALL_BASE+263) +#define __NR_clock_getres (__NR_SYSCALL_BASE+264) +#define __NR_clock_nanosleep (__NR_SYSCALL_BASE+265) +#define __NR_statfs64 (__NR_SYSCALL_BASE+266) +#define __NR_fstatfs64 (__NR_SYSCALL_BASE+267) +#define __NR_tgkill (__NR_SYSCALL_BASE+268) +#define __NR_utimes (__NR_SYSCALL_BASE+269) +#define __NR_arm_fadvise64_64 (__NR_SYSCALL_BASE+270) +#define __NR_pciconfig_iobase (__NR_SYSCALL_BASE+271) +#define __NR_pciconfig_read (__NR_SYSCALL_BASE+272) +#define __NR_pciconfig_write (__NR_SYSCALL_BASE+273) +#define __NR_mq_open (__NR_SYSCALL_BASE+274) +#define __NR_mq_unlink (__NR_SYSCALL_BASE+275) +#define __NR_mq_timedsend (__NR_SYSCALL_BASE+276) +#define __NR_mq_timedreceive (__NR_SYSCALL_BASE+277) +#define __NR_mq_notify (__NR_SYSCALL_BASE+278) +#define __NR_mq_getsetattr (__NR_SYSCALL_BASE+279) +#define __NR_waitid (__NR_SYSCALL_BASE+280) +#define __NR_socket (__NR_SYSCALL_BASE+281) +#define __NR_bind (__NR_SYSCALL_BASE+282) +#define __NR_connect (__NR_SYSCALL_BASE+283) +#define __NR_listen (__NR_SYSCALL_BASE+284) +#define __NR_accept (__NR_SYSCALL_BASE+285) +#define __NR_getsockname (__NR_SYSCALL_BASE+286) +#define __NR_getpeername (__NR_SYSCALL_BASE+287) +#define __NR_socketpair (__NR_SYSCALL_BASE+288) +#define __NR_send (__NR_SYSCALL_BASE+289) +#define __NR_sendto (__NR_SYSCALL_BASE+290) +#define __NR_recv (__NR_SYSCALL_BASE+291) +#define __NR_recvfrom (__NR_SYSCALL_BASE+292) +#define __NR_shutdown (__NR_SYSCALL_BASE+293) +#define __NR_setsockopt (__NR_SYSCALL_BASE+294) +#define __NR_getsockopt (__NR_SYSCALL_BASE+295) +#define __NR_sendmsg (__NR_SYSCALL_BASE+296) +#define __NR_recvmsg (__NR_SYSCALL_BASE+297) +#define __NR_semop (__NR_SYSCALL_BASE+298) +#define __NR_semget (__NR_SYSCALL_BASE+299) +#define __NR_semctl (__NR_SYSCALL_BASE+300) +#define __NR_msgsnd (__NR_SYSCALL_BASE+301) +#define __NR_msgrcv (__NR_SYSCALL_BASE+302) +#define __NR_msgget (__NR_SYSCALL_BASE+303) +#define __NR_msgctl (__NR_SYSCALL_BASE+304) +#define __NR_shmat (__NR_SYSCALL_BASE+305) +#define __NR_shmdt (__NR_SYSCALL_BASE+306) +#define __NR_shmget (__NR_SYSCALL_BASE+307) +#define __NR_shmctl (__NR_SYSCALL_BASE+308) +#define __NR_add_key (__NR_SYSCALL_BASE+309) +#define __NR_request_key (__NR_SYSCALL_BASE+310) +#define __NR_keyctl (__NR_SYSCALL_BASE+311) +#define __NR_semtimedop (__NR_SYSCALL_BASE+312) +#define __NR_vserver (__NR_SYSCALL_BASE+313) +#define __NR_ioprio_set (__NR_SYSCALL_BASE+314) +#define __NR_ioprio_get (__NR_SYSCALL_BASE+315) +#define __NR_inotify_init (__NR_SYSCALL_BASE+316) +#define __NR_inotify_add_watch (__NR_SYSCALL_BASE+317) +#define __NR_inotify_rm_watch (__NR_SYSCALL_BASE+318) +#define __NR_mbind (__NR_SYSCALL_BASE+319) +#define __NR_get_mempolicy (__NR_SYSCALL_BASE+320) +#define __NR_set_mempolicy (__NR_SYSCALL_BASE+321) +#define __NR_openat (__NR_SYSCALL_BASE+322) +#define __NR_mkdirat (__NR_SYSCALL_BASE+323) +#define __NR_mknodat (__NR_SYSCALL_BASE+324) +#define __NR_fchownat (__NR_SYSCALL_BASE+325) +#define __NR_futimesat (__NR_SYSCALL_BASE+326) +#define __NR_fstatat64 (__NR_SYSCALL_BASE+327) +#define __NR_unlinkat (__NR_SYSCALL_BASE+328) +#define __NR_renameat (__NR_SYSCALL_BASE+329) +#define __NR_linkat (__NR_SYSCALL_BASE+330) +#define __NR_symlinkat (__NR_SYSCALL_BASE+331) +#define __NR_readlinkat (__NR_SYSCALL_BASE+332) +#define __NR_fchmodat (__NR_SYSCALL_BASE+333) +#define __NR_faccessat (__NR_SYSCALL_BASE+334) +#define __NR_pselect6 (__NR_SYSCALL_BASE+335) +#define __NR_ppoll (__NR_SYSCALL_BASE+336) +#define __NR_unshare (__NR_SYSCALL_BASE+337) +#define __NR_set_robust_list (__NR_SYSCALL_BASE+338) +#define __NR_get_robust_list (__NR_SYSCALL_BASE+339) +#define __NR_splice (__NR_SYSCALL_BASE+340) +#define __NR_arm_sync_file_range (__NR_SYSCALL_BASE+341) +#define __NR_sync_file_range2 __NR_arm_sync_file_range +#define __NR_tee (__NR_SYSCALL_BASE+342) +#define __NR_vmsplice (__NR_SYSCALL_BASE+343) +#define __NR_move_pages (__NR_SYSCALL_BASE+344) +#define __NR_getcpu (__NR_SYSCALL_BASE+345) +#define __NR_epoll_pwait (__NR_SYSCALL_BASE+346) +#define __NR_kexec_load (__NR_SYSCALL_BASE+347) +#define __NR_utimensat (__NR_SYSCALL_BASE+348) +#define __NR_signalfd (__NR_SYSCALL_BASE+349) +#define __NR_timerfd_create (__NR_SYSCALL_BASE+350) +#define __NR_eventfd (__NR_SYSCALL_BASE+351) +#define __NR_fallocate (__NR_SYSCALL_BASE+352) +#define __NR_timerfd_settime (__NR_SYSCALL_BASE+353) +#define __NR_timerfd_gettime (__NR_SYSCALL_BASE+354) +#define __NR_signalfd4 (__NR_SYSCALL_BASE+355) +#define __NR_eventfd2 (__NR_SYSCALL_BASE+356) +#define __NR_epoll_create1 (__NR_SYSCALL_BASE+357) +#define __NR_dup3 (__NR_SYSCALL_BASE+358) +#define __NR_pipe2 (__NR_SYSCALL_BASE+359) +#define __NR_inotify_init1 (__NR_SYSCALL_BASE+360) +#define __NR_preadv (__NR_SYSCALL_BASE+361) +#define __NR_pwritev (__NR_SYSCALL_BASE+362) +#define __NR_rt_tgsigqueueinfo (__NR_SYSCALL_BASE+363) +#define __NR_perf_event_open (__NR_SYSCALL_BASE+364) +#define __NR_recvmmsg (__NR_SYSCALL_BASE+365) +#define __NR_accept4 (__NR_SYSCALL_BASE+366) +#define __NR_fanotify_init (__NR_SYSCALL_BASE+367) +#define __NR_fanotify_mark (__NR_SYSCALL_BASE+368) +#define __NR_prlimit64 (__NR_SYSCALL_BASE+369) +#define __NR_name_to_handle_at (__NR_SYSCALL_BASE+370) +#define __NR_open_by_handle_at (__NR_SYSCALL_BASE+371) +#define __NR_clock_adjtime (__NR_SYSCALL_BASE+372) +#define __NR_syncfs (__NR_SYSCALL_BASE+373) +#define __NR_sendmmsg (__NR_SYSCALL_BASE+374) +#define __NR_setns (__NR_SYSCALL_BASE+375) + +/* + * The following SWIs are ARM private. + */ +#define __ARM_NR_BASE (__NR_SYSCALL_BASE+0x0f0000) +#define __ARM_NR_breakpoint (__ARM_NR_BASE+1) +#define __ARM_NR_cacheflush (__ARM_NR_BASE+2) +#define __ARM_NR_usr26 (__ARM_NR_BASE+3) +#define __ARM_NR_usr32 (__ARM_NR_BASE+4) +#define __ARM_NR_set_tls (__ARM_NR_BASE+5) + +/* + * *NOTE*: This is a ghost syscall private to the kernel. Only the + * __kuser_cmpxchg code in entry-armv.S should be aware of its + * existence. Don't ever use this from user code. + */ +#ifdef __KERNEL__ +#define __ARM_NR_cmpxchg (__ARM_NR_BASE+0x00fff0) +#endif + +/* + * The following syscalls are obsolete and no longer available for EABI. + */ +#if defined(__ARM_EABI__) && !defined(__KERNEL__) +#undef __NR_time +#undef __NR_umount +#undef __NR_stime +#undef __NR_alarm +#undef __NR_utime +#undef __NR_getrlimit +#undef __NR_select +#undef __NR_readdir +#undef __NR_mmap +#undef __NR_socketcall +#undef __NR_syscall +#undef __NR_ipc +#endif + +#ifdef __KERNEL__ + +#define __ARCH_WANT_IPC_PARSE_VERSION +#define __ARCH_WANT_STAT64 +#define __ARCH_WANT_SYS_GETHOSTNAME +#define __ARCH_WANT_SYS_PAUSE +#define __ARCH_WANT_SYS_GETPGRP +#define __ARCH_WANT_SYS_LLSEEK +#define __ARCH_WANT_SYS_NICE +#define __ARCH_WANT_SYS_SIGPENDING +#define __ARCH_WANT_SYS_SIGPROCMASK +#define __ARCH_WANT_SYS_RT_SIGACTION +#define __ARCH_WANT_SYS_RT_SIGSUSPEND +#define __ARCH_WANT_SYS_OLD_MMAP +#define __ARCH_WANT_SYS_OLD_SELECT + +#if !defined(CONFIG_AEABI) || defined(CONFIG_OABI_COMPAT) +#define __ARCH_WANT_SYS_TIME +#define __ARCH_WANT_SYS_IPC +#define __ARCH_WANT_SYS_OLDUMOUNT +#define __ARCH_WANT_SYS_ALARM +#define __ARCH_WANT_SYS_UTIME +#define __ARCH_WANT_SYS_OLD_GETRLIMIT +#define __ARCH_WANT_OLD_READDIR +#define __ARCH_WANT_SYS_SOCKETCALL +#endif + +/* + * "Conditional" syscalls + * + * 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") + +/* + * Unimplemented (or alternatively implemented) syscalls + */ +#define __IGNORE_fadvise64_64 1 +#define __IGNORE_migrate_pages 1 + +#endif /* __KERNEL__ */ +#endif /* __ASM_ARM_UNISTD_H */ diff --git a/arch/arm/include/asm/unwind.h b/arch/arm/include/asm/unwind.h new file mode 100644 index 00000000..a5edf421 --- /dev/null +++ b/arch/arm/include/asm/unwind.h @@ -0,0 +1,69 @@ +/* + * arch/arm/include/asm/unwind.h + * + * Copyright (C) 2008 ARM Limited + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This 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_UNWIND_H +#define __ASM_UNWIND_H + +#ifndef __ASSEMBLY__ + +/* Unwind reason code according the the ARM EABI documents */ +enum unwind_reason_code { + URC_OK = 0, /* operation completed successfully */ + URC_CONTINUE_UNWIND = 8, + URC_FAILURE = 9 /* unspecified failure of some kind */ +}; + +struct unwind_idx { + unsigned long addr; + unsigned long insn; +}; + +struct unwind_table { + struct list_head list; + struct unwind_idx *start; + struct unwind_idx *stop; + unsigned long begin_addr; + unsigned long end_addr; +}; + +extern struct unwind_table *unwind_table_add(unsigned long start, + unsigned long size, + unsigned long text_addr, + unsigned long text_size); +extern void unwind_table_del(struct unwind_table *tab); +extern void unwind_backtrace(struct pt_regs *regs, struct task_struct *tsk); + +#ifdef CONFIG_ARM_UNWIND +extern int __init unwind_init(void); +#else +static inline int __init unwind_init(void) +{ + return 0; +} +#endif + +#endif /* !__ASSEMBLY__ */ + +#ifdef CONFIG_ARM_UNWIND +#define UNWIND(code...) code +#else +#define UNWIND(code...) +#endif + +#endif /* __ASM_UNWIND_H */ diff --git a/arch/arm/include/asm/user.h b/arch/arm/include/asm/user.h new file mode 100644 index 00000000..35917b3a --- /dev/null +++ b/arch/arm/include/asm/user.h @@ -0,0 +1,103 @@ +#ifndef _ARM_USER_H +#define _ARM_USER_H + +#include +#include +/* Core file format: The core file is written in such a way that gdb + can understand it and provide useful information to the user (under + linux we use the 'trad-core' bfd). There are quite a number of + obstacles to being able to view the contents of the floating point + registers, and until these are solved you will not be able to view the + contents of them. Actually, you can read in the core file and look at + the contents of the user struct to find out what the floating point + registers contain. + The actual file contents are as follows: + UPAGE: 1 page consisting of a user struct that tells gdb what is present + in the file. Directly after this is a copy of the task_struct, which + is currently not used by gdb, but it may come in useful at some point. + All of the registers are stored as part of the upage. The upage should + always be only one page. + DATA: The data area is stored. We use current->end_text to + current->brk to pick up all of the user variables, plus any memory + that may have been malloced. No attempt is made to determine if a page + is demand-zero or if a page is totally unused, we just cover the entire + range. All of the addresses are rounded in such a way that an integral + number of pages is written. + STACK: We need the stack information in order to get a meaningful + backtrace. We need to write the data from (esp) to + current->start_stack, so we round each of these off in order to be able + to write an integer number of pages. + The minimum core file size is 3 pages, or 12288 bytes. +*/ + +struct user_fp { + struct fp_reg { + unsigned int sign1:1; + unsigned int unused:15; + unsigned int sign2:1; + unsigned int exponent:14; + unsigned int j:1; + unsigned int mantissa1:31; + unsigned int mantissa0:32; + } fpregs[8]; + unsigned int fpsr:32; + unsigned int fpcr:32; + unsigned char ftype[8]; + unsigned int init_flag; +}; + +/* When the kernel dumps core, it starts by dumping the user struct - + this will be used by gdb to figure out where the data and stack segments + are within the file, and what virtual addresses to use. */ +struct user{ +/* We start with the registers, to mimic the way that "memory" is returned + from the ptrace(3,...) function. */ + struct pt_regs regs; /* Where the registers are actually stored */ +/* ptrace does not yet supply these. Someday.... */ + int u_fpvalid; /* True if math co-processor being used. */ + /* for this mess. Not yet used. */ +/* The rest of this junk is to help gdb figure out what goes where */ + unsigned long int u_tsize; /* Text segment size (pages). */ + unsigned long int u_dsize; /* Data segment size (pages). */ + unsigned long int u_ssize; /* Stack segment size (pages). */ + unsigned long start_code; /* Starting virtual address of text. */ + unsigned long start_stack; /* Starting virtual address of stack area. + This is actually the bottom of the stack, + the top of the stack is always found in the + esp register. */ + long int signal; /* Signal that caused the core dump. */ + int reserved; /* No longer used */ + unsigned long u_ar0; /* Used by gdb to help find the values for */ + /* the registers. */ + unsigned long magic; /* To uniquely identify a core file */ + char u_comm[32]; /* User command that was responsible */ + int u_debugreg[8]; /* No longer used */ + struct user_fp u_fp; /* FP state */ + struct user_fp_struct * u_fp0;/* Used by gdb to help find the values for */ + /* the FP registers. */ +}; +#define NBPG PAGE_SIZE +#define UPAGES 1 +#define HOST_TEXT_START_ADDR (u.start_code) +#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) + +/* + * User specific VFP registers. If only VFPv2 is present, registers 16 to 31 + * are ignored by the ptrace system call and the signal handler. + */ +struct user_vfp { + unsigned long long fpregs[32]; + unsigned long fpscr; +}; + +/* + * VFP exception registers exposed to user space during signal delivery. + * Fields not relavant to the current VFP architecture are ignored. + */ +struct user_vfp_exc { + unsigned long fpexc; + unsigned long fpinst; + unsigned long fpinst2; +}; + +#endif /* _ARM_USER_H */ diff --git a/arch/arm/include/asm/vfp.h b/arch/arm/include/asm/vfp.h new file mode 100644 index 00000000..f4ab34fd --- /dev/null +++ b/arch/arm/include/asm/vfp.h @@ -0,0 +1,84 @@ +/* + * arch/arm/include/asm/vfp.h + * + * VFP register definitions. + * First, the standard VFP set. + */ + +#define FPSID cr0 +#define FPSCR cr1 +#define MVFR1 cr6 +#define MVFR0 cr7 +#define FPEXC cr8 +#define FPINST cr9 +#define FPINST2 cr10 + +/* FPSID bits */ +#define FPSID_IMPLEMENTER_BIT (24) +#define FPSID_IMPLEMENTER_MASK (0xff << FPSID_IMPLEMENTER_BIT) +#define FPSID_SOFTWARE (1<<23) +#define FPSID_FORMAT_BIT (21) +#define FPSID_FORMAT_MASK (0x3 << FPSID_FORMAT_BIT) +#define FPSID_NODOUBLE (1<<20) +#define FPSID_ARCH_BIT (16) +#define FPSID_ARCH_MASK (0xF << FPSID_ARCH_BIT) +#define FPSID_PART_BIT (8) +#define FPSID_PART_MASK (0xFF << FPSID_PART_BIT) +#define FPSID_VARIANT_BIT (4) +#define FPSID_VARIANT_MASK (0xF << FPSID_VARIANT_BIT) +#define FPSID_REV_BIT (0) +#define FPSID_REV_MASK (0xF << FPSID_REV_BIT) + +/* FPEXC bits */ +#define FPEXC_EX (1 << 31) +#define FPEXC_EN (1 << 30) +#define FPEXC_DEX (1 << 29) +#define FPEXC_FP2V (1 << 28) +#define FPEXC_VV (1 << 27) +#define FPEXC_TFV (1 << 26) +#define FPEXC_LENGTH_BIT (8) +#define FPEXC_LENGTH_MASK (7 << FPEXC_LENGTH_BIT) +#define FPEXC_IDF (1 << 7) +#define FPEXC_IXF (1 << 4) +#define FPEXC_UFF (1 << 3) +#define FPEXC_OFF (1 << 2) +#define FPEXC_DZF (1 << 1) +#define FPEXC_IOF (1 << 0) +#define FPEXC_TRAP_MASK (FPEXC_IDF|FPEXC_IXF|FPEXC_UFF|FPEXC_OFF|FPEXC_DZF|FPEXC_IOF) + +/* FPSCR bits */ +#define FPSCR_DEFAULT_NAN (1<<25) +#define FPSCR_FLUSHTOZERO (1<<24) +#define FPSCR_ROUND_NEAREST (0<<22) +#define FPSCR_ROUND_PLUSINF (1<<22) +#define FPSCR_ROUND_MINUSINF (2<<22) +#define FPSCR_ROUND_TOZERO (3<<22) +#define FPSCR_RMODE_BIT (22) +#define FPSCR_RMODE_MASK (3 << FPSCR_RMODE_BIT) +#define FPSCR_STRIDE_BIT (20) +#define FPSCR_STRIDE_MASK (3 << FPSCR_STRIDE_BIT) +#define FPSCR_LENGTH_BIT (16) +#define FPSCR_LENGTH_MASK (7 << FPSCR_LENGTH_BIT) +#define FPSCR_IOE (1<<8) +#define FPSCR_DZE (1<<9) +#define FPSCR_OFE (1<<10) +#define FPSCR_UFE (1<<11) +#define FPSCR_IXE (1<<12) +#define FPSCR_IDE (1<<15) +#define FPSCR_IOC (1<<0) +#define FPSCR_DZC (1<<1) +#define FPSCR_OFC (1<<2) +#define FPSCR_UFC (1<<3) +#define FPSCR_IXC (1<<4) +#define FPSCR_IDC (1<<7) + +/* MVFR0 bits */ +#define MVFR0_A_SIMD_BIT (0) +#define MVFR0_A_SIMD_MASK (0xf << MVFR0_A_SIMD_BIT) + +/* Bit patterns for decoding the packaged operation descriptors */ +#define VFPOPDESC_LENGTH_BIT (9) +#define VFPOPDESC_LENGTH_MASK (0x07 << VFPOPDESC_LENGTH_BIT) +#define VFPOPDESC_UNUSED_BIT (24) +#define VFPOPDESC_UNUSED_MASK (0xFF << VFPOPDESC_UNUSED_BIT) +#define VFPOPDESC_OPDESC_MASK (~(VFPOPDESC_LENGTH_MASK | VFPOPDESC_UNUSED_MASK)) diff --git a/arch/arm/include/asm/vfpmacros.h b/arch/arm/include/asm/vfpmacros.h new file mode 100644 index 00000000..3d5fc41a --- /dev/null +++ b/arch/arm/include/asm/vfpmacros.h @@ -0,0 +1,65 @@ +/* + * arch/arm/include/asm/vfpmacros.h + * + * Assembler-only file containing VFP macros and register definitions. + */ +#include + +#include "vfp.h" + +@ Macros to allow building with old toolkits (with no VFP support) + .macro VFPFMRX, rd, sysreg, cond + MRC\cond p10, 7, \rd, \sysreg, cr0, 0 @ FMRX \rd, \sysreg + .endm + + .macro VFPFMXR, sysreg, rd, cond + MCR\cond p10, 7, \rd, \sysreg, cr0, 0 @ FMXR \sysreg, \rd + .endm + + @ read all the working registers back into the VFP + .macro VFPFLDMIA, base, tmp +#if __LINUX_ARM_ARCH__ < 6 + LDC p11, cr0, [\base],#33*4 @ FLDMIAX \base!, {d0-d15} +#else + LDC p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d0-d15} +#endif +#ifdef CONFIG_VFPv3 +#if __LINUX_ARM_ARCH__ <= 6 + ldr \tmp, =elf_hwcap @ may not have MVFR regs + ldr \tmp, [\tmp, #0] + tst \tmp, #HWCAP_VFPv3D16 + ldceq p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d16-d31} + addne \base, \base, #32*4 @ step over unused register space +#else + VFPFMRX \tmp, MVFR0 @ Media and VFP Feature Register 0 + and \tmp, \tmp, #MVFR0_A_SIMD_MASK @ A_SIMD field + cmp \tmp, #2 @ 32 x 64bit registers? + ldceql p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d16-d31} + addne \base, \base, #32*4 @ step over unused register space +#endif +#endif + .endm + + @ write all the working registers out of the VFP + .macro VFPFSTMIA, base, tmp +#if __LINUX_ARM_ARCH__ < 6 + STC p11, cr0, [\base],#33*4 @ FSTMIAX \base!, {d0-d15} +#else + STC p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d0-d15} +#endif +#ifdef CONFIG_VFPv3 +#if __LINUX_ARM_ARCH__ <= 6 + ldr \tmp, =elf_hwcap @ may not have MVFR regs + ldr \tmp, [\tmp, #0] + tst \tmp, #HWCAP_VFPv3D16 + stceq p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d16-d31} + addne \base, \base, #32*4 @ step over unused register space +#else + VFPFMRX \tmp, MVFR0 @ Media and VFP Feature Register 0 + and \tmp, \tmp, #MVFR0_A_SIMD_MASK @ A_SIMD field + cmp \tmp, #2 @ 32 x 64bit registers? + stceql p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d16-d31} + addne \base, \base, #32*4 @ step over unused register space +#endif +#endif + .endm diff --git a/arch/arm/include/asm/vga.h b/arch/arm/include/asm/vga.h new file mode 100644 index 00000000..250a4dd0 --- /dev/null +++ b/arch/arm/include/asm/vga.h @@ -0,0 +1,12 @@ +#ifndef ASMARM_VGA_H +#define ASMARM_VGA_H + +#include +#include + +#define VGA_MAP_MEM(x,s) (PCIMEM_BASE + (x)) + +#define vga_readb(x) (*((volatile unsigned char *)x)) +#define vga_writeb(x,y) (*((volatile unsigned char *)y) = (x)) + +#endif diff --git a/arch/arm/include/asm/xor.h b/arch/arm/include/asm/xor.h new file mode 100644 index 00000000..7604673d --- /dev/null +++ b/arch/arm/include/asm/xor.h @@ -0,0 +1,141 @@ +/* + * arch/arm/include/asm/xor.h + * + * Copyright (C) 2001 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include + +#define __XOR(a1, a2) a1 ^= a2 + +#define GET_BLOCK_2(dst) \ + __asm__("ldmia %0, {%1, %2}" \ + : "=r" (dst), "=r" (a1), "=r" (a2) \ + : "0" (dst)) + +#define GET_BLOCK_4(dst) \ + __asm__("ldmia %0, {%1, %2, %3, %4}" \ + : "=r" (dst), "=r" (a1), "=r" (a2), "=r" (a3), "=r" (a4) \ + : "0" (dst)) + +#define XOR_BLOCK_2(src) \ + __asm__("ldmia %0!, {%1, %2}" \ + : "=r" (src), "=r" (b1), "=r" (b2) \ + : "0" (src)); \ + __XOR(a1, b1); __XOR(a2, b2); + +#define XOR_BLOCK_4(src) \ + __asm__("ldmia %0!, {%1, %2, %3, %4}" \ + : "=r" (src), "=r" (b1), "=r" (b2), "=r" (b3), "=r" (b4) \ + : "0" (src)); \ + __XOR(a1, b1); __XOR(a2, b2); __XOR(a3, b3); __XOR(a4, b4) + +#define PUT_BLOCK_2(dst) \ + __asm__ __volatile__("stmia %0!, {%2, %3}" \ + : "=r" (dst) \ + : "0" (dst), "r" (a1), "r" (a2)) + +#define PUT_BLOCK_4(dst) \ + __asm__ __volatile__("stmia %0!, {%2, %3, %4, %5}" \ + : "=r" (dst) \ + : "0" (dst), "r" (a1), "r" (a2), "r" (a3), "r" (a4)) + +static void +xor_arm4regs_2(unsigned long bytes, unsigned long *p1, unsigned long *p2) +{ + unsigned int lines = bytes / sizeof(unsigned long) / 4; + register unsigned int a1 __asm__("r4"); + register unsigned int a2 __asm__("r5"); + register unsigned int a3 __asm__("r6"); + register unsigned int a4 __asm__("r7"); + register unsigned int b1 __asm__("r8"); + register unsigned int b2 __asm__("r9"); + register unsigned int b3 __asm__("ip"); + register unsigned int b4 __asm__("lr"); + + do { + GET_BLOCK_4(p1); + XOR_BLOCK_4(p2); + PUT_BLOCK_4(p1); + } while (--lines); +} + +static void +xor_arm4regs_3(unsigned long bytes, unsigned long *p1, unsigned long *p2, + unsigned long *p3) +{ + unsigned int lines = bytes / sizeof(unsigned long) / 4; + register unsigned int a1 __asm__("r4"); + register unsigned int a2 __asm__("r5"); + register unsigned int a3 __asm__("r6"); + register unsigned int a4 __asm__("r7"); + register unsigned int b1 __asm__("r8"); + register unsigned int b2 __asm__("r9"); + register unsigned int b3 __asm__("ip"); + register unsigned int b4 __asm__("lr"); + + do { + GET_BLOCK_4(p1); + XOR_BLOCK_4(p2); + XOR_BLOCK_4(p3); + PUT_BLOCK_4(p1); + } while (--lines); +} + +static void +xor_arm4regs_4(unsigned long bytes, unsigned long *p1, unsigned long *p2, + unsigned long *p3, unsigned long *p4) +{ + unsigned int lines = bytes / sizeof(unsigned long) / 2; + register unsigned int a1 __asm__("r8"); + register unsigned int a2 __asm__("r9"); + register unsigned int b1 __asm__("ip"); + register unsigned int b2 __asm__("lr"); + + do { + GET_BLOCK_2(p1); + XOR_BLOCK_2(p2); + XOR_BLOCK_2(p3); + XOR_BLOCK_2(p4); + PUT_BLOCK_2(p1); + } while (--lines); +} + +static void +xor_arm4regs_5(unsigned long bytes, unsigned long *p1, unsigned long *p2, + unsigned long *p3, unsigned long *p4, unsigned long *p5) +{ + unsigned int lines = bytes / sizeof(unsigned long) / 2; + register unsigned int a1 __asm__("r8"); + register unsigned int a2 __asm__("r9"); + register unsigned int b1 __asm__("ip"); + register unsigned int b2 __asm__("lr"); + + do { + GET_BLOCK_2(p1); + XOR_BLOCK_2(p2); + XOR_BLOCK_2(p3); + XOR_BLOCK_2(p4); + XOR_BLOCK_2(p5); + PUT_BLOCK_2(p1); + } while (--lines); +} + +static struct xor_block_template xor_block_arm4regs = { + .name = "arm4regs", + .do_2 = xor_arm4regs_2, + .do_3 = xor_arm4regs_3, + .do_4 = xor_arm4regs_4, + .do_5 = xor_arm4regs_5, +}; + +#undef XOR_TRY_TEMPLATES +#define XOR_TRY_TEMPLATES \ + do { \ + xor_speed(&xor_block_arm4regs); \ + xor_speed(&xor_block_8regs); \ + xor_speed(&xor_block_32regs); \ + } while (0) -- cgit v1.2.3