aboutsummaryrefslogtreecommitdiff
path: root/arch/frv
diff options
context:
space:
mode:
Diffstat (limited to 'arch/frv')
-rw-r--r--arch/frv/Kconfig82
-rw-r--r--arch/frv/Kconfig.debug4
-rw-r--r--arch/frv/Makefile64
-rw-r--r--arch/frv/boot/Makefile21
-rw-r--r--arch/frv/defconfig600
-rw-r--r--arch/frv/include/asm/Kbuild8
-rw-r--r--arch/frv/include/asm/asm-offsets.h1
-rw-r--r--arch/frv/include/asm/atomic.h200
-rw-r--r--arch/frv/include/asm/ax88796.h22
-rw-r--r--arch/frv/include/asm/barrier.h23
-rw-r--r--arch/frv/include/asm/bitops.h404
-rw-r--r--arch/frv/include/asm/bug.h56
-rw-r--r--arch/frv/include/asm/bugs.h14
-rw-r--r--arch/frv/include/asm/busctl-regs.h41
-rw-r--r--arch/frv/include/asm/cache.h23
-rw-r--r--arch/frv/include/asm/cacheflush.h105
-rw-r--r--arch/frv/include/asm/checksum.h180
-rw-r--r--arch/frv/include/asm/cmpxchg.h172
-rw-r--r--arch/frv/include/asm/cpu-irqs.h81
-rw-r--r--arch/frv/include/asm/current.h30
-rw-r--r--arch/frv/include/asm/delay.h50
-rw-r--r--arch/frv/include/asm/device.h7
-rw-r--r--arch/frv/include/asm/div64.h1
-rw-r--r--arch/frv/include/asm/dm9000.h37
-rw-r--r--arch/frv/include/asm/dma-mapping.h150
-rw-r--r--arch/frv/include/asm/dma.h125
-rw-r--r--arch/frv/include/asm/elf.h140
-rw-r--r--arch/frv/include/asm/emergency-restart.h6
-rw-r--r--arch/frv/include/asm/fb.h12
-rw-r--r--arch/frv/include/asm/fpu.h11
-rw-r--r--arch/frv/include/asm/ftrace.h1
-rw-r--r--arch/frv/include/asm/futex.h20
-rw-r--r--arch/frv/include/asm/gdb-stub.h146
-rw-r--r--arch/frv/include/asm/gpio-regs.h116
-rw-r--r--arch/frv/include/asm/hardirq.h26
-rw-r--r--arch/frv/include/asm/highmem.h151
-rw-r--r--arch/frv/include/asm/hw_irq.h16
-rw-r--r--arch/frv/include/asm/io.h392
-rw-r--r--arch/frv/include/asm/irc-regs.h53
-rw-r--r--arch/frv/include/asm/irq.h30
-rw-r--r--arch/frv/include/asm/irq_regs.h27
-rw-r--r--arch/frv/include/asm/irqflags.h158
-rw-r--r--arch/frv/include/asm/kdebug.h1
-rw-r--r--arch/frv/include/asm/kmap_types.h7
-rw-r--r--arch/frv/include/asm/linkage.h7
-rw-r--r--arch/frv/include/asm/local.h6
-rw-r--r--arch/frv/include/asm/local64.h1
-rw-r--r--arch/frv/include/asm/math-emu.h301
-rw-r--r--arch/frv/include/asm/mb-regs.h200
-rw-r--r--arch/frv/include/asm/mb86943a.h42
-rw-r--r--arch/frv/include/asm/mb93091-fpga-irqs.h42
-rw-r--r--arch/frv/include/asm/mb93093-fpga-irqs.h29
-rw-r--r--arch/frv/include/asm/mb93493-irqs.h50
-rw-r--r--arch/frv/include/asm/mb93493-regs.h281
-rw-r--r--arch/frv/include/asm/mc146818rtc.h16
-rw-r--r--arch/frv/include/asm/mem-layout.h86
-rw-r--r--arch/frv/include/asm/mmu.h41
-rw-r--r--arch/frv/include/asm/mmu_context.h50
-rw-r--r--arch/frv/include/asm/module.h22
-rw-r--r--arch/frv/include/asm/mutex.h9
-rw-r--r--arch/frv/include/asm/page.h76
-rw-r--r--arch/frv/include/asm/pci.h61
-rw-r--r--arch/frv/include/asm/percpu.h6
-rw-r--r--arch/frv/include/asm/perf_event.h15
-rw-r--r--arch/frv/include/asm/pgalloc.h69
-rw-r--r--arch/frv/include/asm/pgtable.h541
-rw-r--r--arch/frv/include/asm/processor.h142
-rw-r--r--arch/frv/include/asm/ptrace.h41
-rw-r--r--arch/frv/include/asm/scatterlist.h6
-rw-r--r--arch/frv/include/asm/sections.h46
-rw-r--r--arch/frv/include/asm/segment.h45
-rw-r--r--arch/frv/include/asm/serial-regs.h44
-rw-r--r--arch/frv/include/asm/serial.h18
-rw-r--r--arch/frv/include/asm/setup.h26
-rw-r--r--arch/frv/include/asm/shmparam.h7
-rw-r--r--arch/frv/include/asm/signal.h6
-rw-r--r--arch/frv/include/asm/smp.h9
-rw-r--r--arch/frv/include/asm/spinlock.h17
-rw-r--r--arch/frv/include/asm/spr-regs.h416
-rw-r--r--arch/frv/include/asm/string.h51
-rw-r--r--arch/frv/include/asm/switch_to.h35
-rw-r--r--arch/frv/include/asm/syscall.h123
-rw-r--r--arch/frv/include/asm/termios.h14
-rw-r--r--arch/frv/include/asm/thread_info.h125
-rw-r--r--arch/frv/include/asm/timer-regs.h106
-rw-r--r--arch/frv/include/asm/timex.h20
-rw-r--r--arch/frv/include/asm/tlb.h27
-rw-r--r--arch/frv/include/asm/tlbflush.h73
-rw-r--r--arch/frv/include/asm/topology.h12
-rw-r--r--arch/frv/include/asm/types.h22
-rw-r--r--arch/frv/include/asm/uaccess.h319
-rw-r--r--arch/frv/include/asm/ucontext.h12
-rw-r--r--arch/frv/include/asm/unaligned.h22
-rw-r--r--arch/frv/include/asm/unistd.h33
-rw-r--r--arch/frv/include/asm/user.h80
-rw-r--r--arch/frv/include/asm/vga.h17
-rw-r--r--arch/frv/include/asm/virtconvert.h41
-rw-r--r--arch/frv/include/asm/xor.h1
-rw-r--r--arch/frv/include/uapi/asm/Kbuild35
-rw-r--r--arch/frv/include/uapi/asm/auxvec.h4
-rw-r--r--arch/frv/include/uapi/asm/bitsperlong.h1
-rw-r--r--arch/frv/include/uapi/asm/byteorder.h6
-rw-r--r--arch/frv/include/uapi/asm/errno.h7
-rw-r--r--arch/frv/include/uapi/asm/fcntl.h1
-rw-r--r--arch/frv/include/uapi/asm/ioctl.h1
-rw-r--r--arch/frv/include/uapi/asm/ioctls.h10
-rw-r--r--arch/frv/include/uapi/asm/ipcbuf.h1
-rw-r--r--arch/frv/include/uapi/asm/kvm_para.h1
-rw-r--r--arch/frv/include/uapi/asm/mman.h1
-rw-r--r--arch/frv/include/uapi/asm/msgbuf.h32
-rw-r--r--arch/frv/include/uapi/asm/param.h8
-rw-r--r--arch/frv/include/uapi/asm/poll.h12
-rw-r--r--arch/frv/include/uapi/asm/posix_types.h26
-rw-r--r--arch/frv/include/uapi/asm/ptrace.h60
-rw-r--r--arch/frv/include/uapi/asm/registers.h232
-rw-r--r--arch/frv/include/uapi/asm/resource.h7
-rw-r--r--arch/frv/include/uapi/asm/sembuf.h26
-rw-r--r--arch/frv/include/uapi/asm/setup.h18
-rw-r--r--arch/frv/include/uapi/asm/shmbuf.h43
-rw-r--r--arch/frv/include/uapi/asm/sigcontext.h26
-rw-r--r--arch/frv/include/uapi/asm/siginfo.h12
-rw-r--r--arch/frv/include/uapi/asm/signal.h36
-rw-r--r--arch/frv/include/uapi/asm/socket.h84
-rw-r--r--arch/frv/include/uapi/asm/sockios.h14
-rw-r--r--arch/frv/include/uapi/asm/stat.h100
-rw-r--r--arch/frv/include/uapi/asm/statfs.h7
-rw-r--r--arch/frv/include/uapi/asm/swab.h10
-rw-r--r--arch/frv/include/uapi/asm/termbits.h203
-rw-r--r--arch/frv/include/uapi/asm/termios.h46
-rw-r--r--arch/frv/include/uapi/asm/types.h11
-rw-r--r--arch/frv/include/uapi/asm/unistd.h348
-rw-r--r--arch/frv/kernel/Makefile11
-rw-r--r--arch/frv/kernel/asm-offsets.c109
-rw-r--r--arch/frv/kernel/break.S116
-rw-r--r--arch/frv/kernel/cmode.S3
-rw-r--r--arch/frv/kernel/debug-stub.c15
-rw-r--r--arch/frv/kernel/dma.c5
-rw-r--r--arch/frv/kernel/entry-table.S52
-rw-r--r--arch/frv/kernel/entry.S249
-rw-r--r--arch/frv/kernel/frv_ksyms.c27
-rw-r--r--arch/frv/kernel/futex.c20
-rw-r--r--arch/frv/kernel/gdb-io.c5
-rw-r--r--arch/frv/kernel/gdb-stub.c343
-rw-r--r--arch/frv/kernel/head-mmu-fr451.S4
-rw-r--r--arch/frv/kernel/head-uc-fr401.S4
-rw-r--r--arch/frv/kernel/head-uc-fr451.S4
-rw-r--r--arch/frv/kernel/head-uc-fr555.S4
-rw-r--r--arch/frv/kernel/head.S15
-rw-r--r--arch/frv/kernel/head.inc2
-rw-r--r--arch/frv/kernel/init_task.c39
-rw-r--r--arch/frv/kernel/irq-mb93091.c157
-rw-r--r--arch/frv/kernel/irq-mb93093.c117
-rw-r--r--arch/frv/kernel/irq-mb93493.c163
-rw-r--r--arch/frv/kernel/irq-routing.c291
-rw-r--r--arch/frv/kernel/irq.c770
-rw-r--r--arch/frv/kernel/kernel_thread.S77
-rw-r--r--arch/frv/kernel/local.h3
-rw-r--r--arch/frv/kernel/local64.h1
-rw-r--r--arch/frv/kernel/module.c59
-rw-r--r--arch/frv/kernel/pm-mb93093.c1
-rw-r--r--arch/frv/kernel/pm.c195
-rw-r--r--arch/frv/kernel/process.c175
-rw-r--r--arch/frv/kernel/ptrace.c811
-rw-r--r--arch/frv/kernel/semaphore.c156
-rw-r--r--arch/frv/kernel/setup.c90
-rw-r--r--arch/frv/kernel/signal.c228
-rw-r--r--arch/frv/kernel/sleep.S3
-rw-r--r--arch/frv/kernel/switch_to.S11
-rw-r--r--arch/frv/kernel/sys_frv.c180
-rw-r--r--arch/frv/kernel/sysctl.c49
-rw-r--r--arch/frv/kernel/time.c147
-rw-r--r--arch/frv/kernel/traps.c290
-rw-r--r--arch/frv/kernel/uaccess.c12
-rw-r--r--arch/frv/kernel/vmlinux.lds.S114
-rw-r--r--arch/frv/lib/Makefile2
-rw-r--r--arch/frv/lib/atomic-ops.S5
-rw-r--r--arch/frv/lib/atomic64-ops.S162
-rw-r--r--arch/frv/lib/cache.S2
-rw-r--r--arch/frv/lib/checksum.c25
-rw-r--r--arch/frv/mb93090-mb00/Makefile4
-rw-r--r--arch/frv/mb93090-mb00/flash.c90
-rw-r--r--arch/frv/mb93090-mb00/pci-dma-nommu.c42
-rw-r--r--arch/frv/mb93090-mb00/pci-dma.c36
-rw-r--r--arch/frv/mb93090-mb00/pci-frv.c114
-rw-r--r--arch/frv/mb93090-mb00/pci-frv.h7
-rw-r--r--arch/frv/mb93090-mb00/pci-iomap.c29
-rw-r--r--arch/frv/mb93090-mb00/pci-irq.c19
-rw-r--r--arch/frv/mb93090-mb00/pci-vdk.c176
-rw-r--r--arch/frv/mm/Makefile2
-rw-r--r--arch/frv/mm/cache-page.c8
-rw-r--r--arch/frv/mm/dma-alloc.c8
-rw-r--r--arch/frv/mm/elf-fdpic.c58
-rw-r--r--arch/frv/mm/extable.c1
-rw-r--r--arch/frv/mm/fault.c42
-rw-r--r--arch/frv/mm/highmem.c50
-rw-r--r--arch/frv/mm/init.c131
-rw-r--r--arch/frv/mm/kmap.c17
-rw-r--r--arch/frv/mm/mmu-context.c8
-rw-r--r--arch/frv/mm/pgalloc.c48
-rw-r--r--arch/frv/mm/tlb-flush.S1
-rw-r--r--arch/frv/mm/tlb-miss.S4
-rw-r--r--arch/frv/mm/unaligned.c218
202 files changed, 10802 insertions, 4784 deletions
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig
index 60a617aff8b..34aa19352dc 100644
--- a/arch/frv/Kconfig
+++ b/arch/frv/Kconfig
@@ -1,10 +1,23 @@
-#
-# For a description of the syntax of this configuration file,
-# see Documentation/kbuild/kconfig-language.txt.
-#
config FRV
bool
default y
+ select HAVE_IDE
+ select HAVE_ARCH_TRACEHOOK
+ select HAVE_PERF_EVENTS
+ select HAVE_UID16
+ select VIRT_TO_BUS
+ select GENERIC_IRQ_SHOW
+ select HAVE_DEBUG_BUGVERBOSE
+ select ARCH_HAVE_NMI_SAFE_CMPXCHG
+ select GENERIC_CPU_DEVICES
+ select ARCH_WANT_IPC_PARSE_VERSION
+ select OLD_SIGSUSPEND3
+ select OLD_SIGACTION
+ select HAVE_DEBUG_STACKOVERFLOW
+
+config ZONE_DMA
+ bool
+ default y
config RWSEM_GENERIC_SPINLOCK
bool
@@ -13,7 +26,7 @@ config RWSEM_GENERIC_SPINLOCK
config RWSEM_XCHGADD_ALGORITHM
bool
-config GENERIC_FIND_NEXT_BIT
+config GENERIC_HWEIGHT
bool
default y
@@ -21,14 +34,30 @@ config GENERIC_CALIBRATE_DELAY
bool
default n
-config GENERIC_HARDIRQS
+config TIME_LOW_RES
bool
- default n
+ default y
+
+config QUICKLIST
+ bool
+ default y
+
+config ARCH_HAS_ILOG2_U32
+ bool
+ default y
+
+config ARCH_HAS_ILOG2_U64
+ bool
+ default y
-mainmenu "Fujitsu FR-V Kernel Configuration"
+config HZ
+ int
+ default 1000
source "init/Kconfig"
+source "kernel/Kconfig.freezer"
+
menu "Fujitsu FR-V system setup"
@@ -47,7 +76,7 @@ config FRV_OUTOFLINE_ATOMIC_OPS
Setting this option causes the FR-V atomic operations to be mostly
implemented out-of-line.
- See Documentation/fujitsu/frv/atomic-ops.txt for more information.
+ See Documentation/frv/atomic-ops.txt for more information.
config HIGHMEM
bool "High memory support"
@@ -106,6 +135,15 @@ config UCPAGE_OFFSET_C0000000
endchoice
+config PAGE_OFFSET
+ hex
+ default 0x20000000 if UCPAGE_OFFSET_20000000
+ default 0x40000000 if UCPAGE_OFFSET_40000000
+ default 0x60000000 if UCPAGE_OFFSET_60000000
+ default 0x80000000 if UCPAGE_OFFSET_80000000
+ default 0xA0000000 if UCPAGE_OFFSET_A0000000
+ default 0xC0000000
+
config PROTECT_KERNEL
bool "Protect core kernel against userspace"
depends on !MMU
@@ -239,6 +277,12 @@ config MB93091_NO_MB
endchoice
endif
+config FUJITSU_MB93493
+ bool "MB93493 Multimedia chip"
+ help
+ Select this option if the MB93493 multimedia chip is going to be
+ used.
+
choice
prompt "GP-Relative data support"
default GPREL_DATA_8
@@ -279,16 +323,12 @@ config PCI
bool "Use PCI"
depends on MB93090_MB00
default y
+ select GENERIC_PCI_IOMAP
help
Some FR-V systems (such as the MB93090-MB00 VDK) have PCI
onboard. If you have one of these boards and you wish to use the PCI
facilities, say Y here.
- The PCI-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>, contains valuable
- information about which PCI hardware does work under Linux and which
- doesn't.
-
config RESERVE_DMA_COHERENT
bool "Reserve DMA coherent memory"
depends on PCI && !MMU
@@ -308,17 +348,11 @@ source "drivers/pci/Kconfig"
source "drivers/pcmcia/Kconfig"
-#config MATH_EMULATION
-# bool "Math emulation support (EXPERIMENTAL)"
-# depends on EXPERIMENTAL
-# help
-# At some point in the future, this will cause floating-point math
-# instructions to be emulated by the kernel on machines that lack a
-# floating-point math coprocessor. Thrill-seekers and chronically
-# sleep-deprived psychotic hacker types can say Y now, everyone else
-# should probably wait a while.
-
menu "Power management options"
+
+config ARCH_SUSPEND_POSSIBLE
+ def_bool y
+
source kernel/power/Kconfig
endmenu
diff --git a/arch/frv/Kconfig.debug b/arch/frv/Kconfig.debug
index 211f01bc4ca..98c99a3ed2b 100644
--- a/arch/frv/Kconfig.debug
+++ b/arch/frv/Kconfig.debug
@@ -2,10 +2,6 @@ menu "Kernel hacking"
source "lib/Kconfig.debug"
-config DEBUG_STACKOVERFLOW
- bool "Check for stack overflows"
- depends on DEBUG_KERNEL
-
config GDBSTUB
bool "Remote GDB kernel debugging"
depends on DEBUG_KERNEL
diff --git a/arch/frv/Makefile b/arch/frv/Makefile
index 90c0fb8d9dc..2a8fb730d1c 100644
--- a/arch/frv/Makefile
+++ b/arch/frv/Makefile
@@ -23,29 +23,23 @@
# Copyright (C) 1994 by Hamish Macdonald
#
-CCSPECS := $(shell $(CC) -v 2>&1 | grep "^Reading specs from " | head -1 | cut -c20-)
-CCDIR := $(strip $(patsubst %/specs,%,$(CCSPECS)))
-CPUCLASS := fr400
-
-# test for cross compiling
-COMPILE_ARCH = $(shell uname -m)
-
ifdef CONFIG_MMU
UTS_SYSNAME = -DUTS_SYSNAME=\"Linux\"
else
UTS_SYSNAME = -DUTS_SYSNAME=\"uClinux\"
endif
-ARCHMODFLAGS += -G0 -mlong-calls
+KBUILD_AFLAGS_MODULE += -G0 -mlong-calls
+KBUILD_CFLAGS_MODULE += -G0 -mlong-calls
ifdef CONFIG_GPREL_DATA_8
-CFLAGS += -G8
+KBUILD_CFLAGS += -G8
else
ifdef CONFIG_GPREL_DATA_4
-CFLAGS += -G4
+KBUILD_CFLAGS += -G4
else
ifdef CONFIG_GPREL_DATA_NONE
-CFLAGS += -G0
+KBUILD_CFLAGS += -G0
endif
endif
endif
@@ -53,47 +47,34 @@ endif
#LDFLAGS_vmlinux := -Map linkmap.txt
ifdef CONFIG_GC_SECTIONS
-CFLAGS += -ffunction-sections -fdata-sections
-LINKFLAGS += --gc-sections
+KBUILD_CFLAGS += -ffunction-sections -fdata-sections
endif
ifndef CONFIG_FRAME_POINTER
-CFLAGS += -mno-linked-fp
+KBUILD_CFLAGS += -mno-linked-fp
endif
ifdef CONFIG_CPU_FR451_COMPILE
-CFLAGS += -mcpu=fr450
-AFLAGS += -mcpu=fr450
-ASFLAGS += -mcpu=fr450
+KBUILD_CFLAGS += -mcpu=fr450
+KBUILD_AFLAGS += -mcpu=fr450
else
ifdef CONFIG_CPU_FR551_COMPILE
-CFLAGS += -mcpu=fr550
-AFLAGS += -mcpu=fr550
-ASFLAGS += -mcpu=fr550
+KBUILD_CFLAGS += -mcpu=fr550
+KBUILD_AFLAGS += -mcpu=fr550
else
-CFLAGS += -mcpu=fr400
-AFLAGS += -mcpu=fr400
-ASFLAGS += -mcpu=fr400
+KBUILD_CFLAGS += -mcpu=fr400
+KBUILD_AFLAGS += -mcpu=fr400
endif
endif
# pretend the kernel is going to run on an FR400 with no media-fp unit
# - reserve CC3 for use with atomic ops
# - all the extra registers are dealt with only at context switch time
-CFLAGS += -mno-fdpic -mgpr-32 -msoft-float -mno-media
-CFLAGS += -ffixed-fcc3 -ffixed-cc3 -ffixed-gr15
-AFLAGS += -mno-fdpic
-ASFLAGS += -mno-fdpic
-
-# make sure the .S files get compiled with debug info
-# and disable optimisations that are unhelpful whilst debugging
-ifdef CONFIG_DEBUG_INFO
-CFLAGS += -O1
-AFLAGS += -Wa,--gdwarf2
-ASFLAGS += -Wa,--gdwarf2
-endif
+KBUILD_CFLAGS += -mno-fdpic -mgpr-32 -msoft-float -mno-media
+KBUILD_CFLAGS += -ffixed-fcc3 -ffixed-cc3 -ffixed-gr15 -ffixed-icc2
+KBUILD_AFLAGS += -mno-fdpic
-head-y := arch/frv/kernel/head.o arch/frv/kernel/init_task.o
+head-y := arch/frv/kernel/head.o
core-y += arch/frv/kernel/ arch/frv/mm/
libs-y += arch/frv/lib/
@@ -105,14 +86,5 @@ all: Image
Image: vmlinux
$(Q)$(MAKE) $(build)=arch/frv/boot $@
-bootstrap:
- $(Q)$(MAKEBOOT) bootstrap
-
-archmrproper:
- $(Q)$(MAKE) $(build)=arch/frv/boot mrproper
-
archclean:
- $(Q)$(MAKE) $(build)=arch/frv/boot clean
-
-archdep: scripts/mkdep symlinks
- $(Q)$(MAKE) $(build)=arch/frv/boot dep
+ $(Q)$(MAKE) $(clean)=arch/frv/boot
diff --git a/arch/frv/boot/Makefile b/arch/frv/boot/Makefile
index 5dfc93fd945..636d5bbcd53 100644
--- a/arch/frv/boot/Makefile
+++ b/arch/frv/boot/Makefile
@@ -8,13 +8,17 @@
# Copyright (C) 1995-2000 Russell King
#
-SYSTEM =$(TOPDIR)/$(LINUX)
+targets := Image zImage bootpImage
+
+SYSTEM =$(LINUX)
ZTEXTADDR = 0x02080000
PARAMS_PHYS = 0x0207c000
INITRD_PHYS = 0x02180000
INITRD_VIRT = 0x02180000
+OBJCOPYFLAGS :=-O binary -R .note -R .note.gnu.build-id -R .comment
+
#
# If you don't define ZRELADDR above,
# then it defaults to ZTEXTADDR
@@ -30,20 +34,20 @@ Image: $(obj)/Image
targets: $(obj)/Image
$(obj)/Image: vmlinux FORCE
- $(OBJCOPY) -O binary -R .note -R .comment -S vmlinux $@
+ $(OBJCOPY) $(OBJCOPYFLAGS) -S vmlinux $@
#$(obj)/Image: $(CONFIGURE) $(SYSTEM)
-# $(OBJCOPY) -O binary -R .note -R .comment -g -S $(SYSTEM) $@
+# $(OBJCOPY) $(OBJCOPYFLAGS) -g -S $(SYSTEM) $@
bzImage: zImage
zImage: $(CONFIGURE) compressed/$(LINUX)
- $(OBJCOPY) -O binary -R .note -R .comment -S compressed/$(LINUX) $@
+ $(OBJCOPY) $(OBJCOPYFLAGS) -S compressed/$(LINUX) $@
bootpImage: bootp/bootp
- $(OBJCOPY) -O binary -R .note -R .comment -S bootp/bootp $@
+ $(OBJCOPY) $(OBJCOPYFLAGS) -S bootp/bootp $@
-compressed/$(LINUX): $(TOPDIR)/$(LINUX) dep
+compressed/$(LINUX): $(LINUX) dep
@$(MAKE) -C compressed $(LINUX)
bootp/bootp: zImage initrd
@@ -57,16 +61,15 @@ initrd:
# installation
#
install: $(CONFIGURE) Image
- sh ./install.sh $(KERNELRELEASE) Image $(TOPDIR)/System.map "$(INSTALL_PATH)"
+ sh ./install.sh $(KERNELRELEASE) Image System.map "$(INSTALL_PATH)"
zinstall: $(CONFIGURE) zImage
- sh ./install.sh $(KERNELRELEASE) zImage $(TOPDIR)/System.map "$(INSTALL_PATH)"
+ sh ./install.sh $(KERNELRELEASE) zImage System.map "$(INSTALL_PATH)"
#
# miscellany
#
mrproper clean:
- $(RM) Image zImage bootpImage
# @$(MAKE) -C compressed clean
# @$(MAKE) -C bootp clean
diff --git a/arch/frv/defconfig b/arch/frv/defconfig
index b6e4ca5efb5..b1b792610fd 100644
--- a/arch/frv/defconfig
+++ b/arch/frv/defconfig
@@ -1,627 +1,39 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11.8
-# Fri May 13 17:16:03 2005
-#
-CONFIG_FRV=y
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-CONFIG_GENERIC_FIND_NEXT_BIT=y
-# CONFIG_GENERIC_CALIBRATE_DELAY is not set
-# CONFIG_GENERIC_HARDIRQS is not set
-
-#
-# Code maturity level options
-#
CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-# CONFIG_KOBJECT_UEVENT is not set
-# CONFIG_IKCONFIG is not set
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_ALL is not set
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
+CONFIG_LOG_BUF_SHIFT=14
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-# CONFIG_MODULES is not set
-
-#
-# Fujitsu FR-V system setup
-#
+CONFIG_EXPERT=y
+# CONFIG_HOTPLUG is not set
CONFIG_MMU=y
CONFIG_FRV_OUTOFLINE_ATOMIC_OPS=y
-CONFIG_HIGHMEM=y
-CONFIG_HIGHPTE=y
-CONFIG_SELECT_MEMORY_MODEL=y
-CONFIG_FLATMEM_MANUAL=y
-# CONFIG_DISCONTIGMEM_MANUAL is not set
-# CONFIG_SPARSEMEM_MANUAL is not set
-CONFIG_FLATMEM=y
-CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_FRV_DEFL_CACHE_WBACK is not set
-# CONFIG_FRV_DEFL_CACHE_WBEHIND is not set
CONFIG_FRV_DEFL_CACHE_WTHRU=y
-# CONFIG_FRV_DEFL_CACHE_DISABLED is not set
-
-#
-# CPU core support
-#
-CONFIG_CPU_FR451=y
-CONFIG_CPU_FR451_COMPILE=y
-CONFIG_FRV_L1_CACHE_SHIFT=5
-CONFIG_MB93091_VDK=y
-# CONFIG_MB93093_PDK is not set
-CONFIG_MB93090_MB00=y
-# CONFIG_MB93091_NO_MB is not set
-# CONFIG_GPREL_DATA_8 is not set
CONFIG_GPREL_DATA_4=y
-# CONFIG_GPREL_DATA_NONE is not set
-CONFIG_PCI=y
-# CONFIG_PCI_LEGACY_PROC is not set
-# CONFIG_PCI_NAMES is not set
-# CONFIG_PCI_DEBUG is not set
-# CONFIG_PCMCIA is not set
-
-#
-# Power management options
-#
-# CONFIG_PM is not set
-
-#
-# Executable formats
-#
-# CONFIG_BINFMT_ELF is not set
-CONFIG_BINFMT_ELF_FDPIC=y
-# CONFIG_BINFMT_MISC is not set
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-# CONFIG_STANDALONE is not set
-# CONFIG_PREVENT_FIRMWARE_BUILD is not set
-# CONFIG_FW_LOADER is not set
-# CONFIG_DEBUG_DRIVER is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
-# CONFIG_CONNECTOR is not set
-# CONFIG_FORK_CONNECTOR is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
-# CONFIG_BLK_DEV_COW_COMMON is not set
-# CONFIG_BLK_DEV_LOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_SX8 is not set
-# CONFIG_BLK_DEV_RAM is not set
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-# CONFIG_ATA_OVER_ETH is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-# CONFIG_IDE is not set
-
-#
-# SCSI device support
-#
-# CONFIG_SCSI is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-# CONFIG_IEEE1394 is not set
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-
-#
-# Networking support
-#
CONFIG_NET=y
-
-#
-# Networking options
-#
CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-# CONFIG_IP_PNP_BOOTP is not set
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-# CONFIG_IP_TCPDIAG is not set
-# CONFIG_IP_TCPDIAG_IPV6 is not set
# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_KGDBOE is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NETPOLL_RX is not set
-# CONFIG_NETPOLL_TRAP is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
-# CONFIG_HAPPYMEAL is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_NET_VENDOR_3COM is not set
-
-#
-# Tulip family network device support
-#
-# CONFIG_NET_TULIP is not set
-# CONFIG_HP100 is not set
CONFIG_NET_PCI=y
-# CONFIG_PCNET32 is not set
-# CONFIG_AMD8111_ETH is not set
-# CONFIG_ADAPTEC_STARFIRE is not set
-# CONFIG_B44 is not set
-# CONFIG_FORCEDETH is not set
-# CONFIG_DGRS is not set
-# CONFIG_EEPRO100 is not set
-# CONFIG_E100 is not set
-# CONFIG_FEALNX is not set
-# CONFIG_NATSEMI is not set
CONFIG_NE2K_PCI=y
-# CONFIG_8139CP is not set
-# CONFIG_8139TOO is not set
-# CONFIG_SIS900 is not set
-# CONFIG_EPIC100 is not set
-# CONFIG_SUNDANCE is not set
-# CONFIG_TLAN is not set
-# CONFIG_VIA_RHINE is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_E1000 is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_R8169 is not set
-# CONFIG_SKGE is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_VIA_VELOCITY is not set
-# CONFIG_TIGON3 is not set
-
-#
-# Ethernet (10000 Mbit)
-#
-# CONFIG_CHELSIO_T1 is not set
-# CONFIG_IXGB is not set
-# CONFIG_S2IO is not set
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-# CONFIG_SHAPER is not set
-# CONFIG_NETCONSOLE is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
-# CONFIG_PHONE is not set
-
-#
-# Input device support
-#
# CONFIG_INPUT is not set
-
-#
-# Hardware I/O ports
-#
# CONFIG_SERIO is not set
-# CONFIG_GAMEPORT is not set
-
-#
-# Character devices
-#
# CONFIG_VT is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_NR_UARTS=1
+CONFIG_SERIAL_8250_RUNTIME_UARTS=1
CONFIG_SERIAL_8250_EXTENDED=y
-# CONFIG_SERIAL_8250_MANY_PORTS is not set
CONFIG_SERIAL_8250_SHARE_IRQ=y
-# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_MULTIPORT is not set
-# CONFIG_SERIAL_8250_RSA is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
-CONFIG_UNIX98_PTYS=y
# CONFIG_LEGACY_PTYS is not set
-
-#
-# IPMI
-#
-# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_DRM is not set
-# CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
-# CONFIG_TCG_TPM is not set
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# Dallas's 1-wire bus
-#
-# CONFIG_W1 is not set
-
-#
-# Misc devices
-#
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
-
-#
-# Graphics support
-#
-# CONFIG_FB is not set
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# USB support
-#
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
-# CONFIG_USB is not set
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
-# CONFIG_MMC is not set
-
-#
-# InfiniBand support
-#
-# CONFIG_INFINIBAND is not set
-
-#
-# File systems
-#
-# CONFIG_EXT2_FS is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
-# CONFIG_REISER4_FS is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
-# CONFIG_XFS_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_INOTIFY=y
-# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-
-#
-# Caches
-#
-# CONFIG_FSCACHE is not set
-# CONFIG_FUSE_FS is not set
-
-#
-# CD-ROM/DVD Filesystems
-#
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-# CONFIG_MSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-# CONFIG_PROC_KCORE is not set
-CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
-# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
CONFIG_NFS_FS=y
-# CONFIG_NFS_V3 is not set
-# CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
-# CONFIG_NFSD is not set
CONFIG_ROOT_NFS=y
-CONFIG_LOCKD=y
-CONFIG_NFS_COMMON=y
-CONFIG_SUNRPC=y
-# CONFIG_RPCSEC_GSS_KRB5 is not set
-# CONFIG_RPCSEC_GSS_SPKM3 is not set
-# CONFIG_SMB_FS is not set
-# CONFIG_CIFS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_AFS_FS is not set
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
-# CONFIG_NLS is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_PRINTK_TIME is not set
CONFIG_DEBUG_KERNEL=y
-# CONFIG_MAGIC_SYSRQ is not set
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_DETECT_SOFTLOCKUP=y
-# CONFIG_SCHEDSTATS is not set
-# CONFIG_DEBUG_SLAB is not set
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
-# CONFIG_DEBUG_KOBJECT is not set
-# CONFIG_DEBUG_HIGHMEM is not set
# CONFIG_DEBUG_BUGVERBOSE is not set
-# CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_FS is not set
-# CONFIG_FRAME_POINTER is not set
-# CONFIG_EARLY_PRINTK is not set
CONFIG_DEBUG_STACKOVERFLOW=y
-# CONFIG_DEBUG_PAGEALLOC is not set
-# CONFIG_GDBSTUB is not set
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-# CONFIG_CRYPTO is not set
-
-#
-# Hardware crypto devices
-#
-
-#
-# Library routines
-#
-# CONFIG_CRC_CCITT is not set
-CONFIG_CRC32=y
-# CONFIG_LIBCRC32C is not set
diff --git a/arch/frv/include/asm/Kbuild b/arch/frv/include/asm/Kbuild
new file mode 100644
index 00000000000..87b95eb8aee
--- /dev/null
+++ b/arch/frv/include/asm/Kbuild
@@ -0,0 +1,8 @@
+
+generic-y += clkdev.h
+generic-y += cputime.h
+generic-y += exec.h
+generic-y += hash.h
+generic-y += mcs_spinlock.h
+generic-y += preempt.h
+generic-y += trace_clock.h
diff --git a/arch/frv/include/asm/asm-offsets.h b/arch/frv/include/asm/asm-offsets.h
new file mode 100644
index 00000000000..d370ee36a18
--- /dev/null
+++ b/arch/frv/include/asm/asm-offsets.h
@@ -0,0 +1 @@
+#include <generated/asm-offsets.h>
diff --git a/arch/frv/include/asm/atomic.h b/arch/frv/include/asm/atomic.h
new file mode 100644
index 00000000000..f6c3a169010
--- /dev/null
+++ b/arch/frv/include/asm/atomic.h
@@ -0,0 +1,200 @@
+/* atomic.h: atomic operation emulation for FR-V
+ *
+ * For an explanation of how atomic ops work in this arch, see:
+ * Documentation/frv/atomic-ops.txt
+ *
+ * Copyright (C) 2004 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _ASM_ATOMIC_H
+#define _ASM_ATOMIC_H
+
+#include <linux/types.h>
+#include <asm/spr-regs.h>
+#include <asm/cmpxchg.h>
+#include <asm/barrier.h>
+
+#ifdef CONFIG_SMP
+#error not SMP safe
+#endif
+
+/*
+ * Atomic operations that C can't guarantee us. Useful for
+ * resource counting etc..
+ *
+ * We do not have SMP systems, so we don't have to deal with that.
+ */
+
+#define ATOMIC_INIT(i) { (i) }
+#define atomic_read(v) (*(volatile int *)&(v)->counter)
+#define atomic_set(v, i) (((v)->counter) = (i))
+
+#ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS
+static inline int atomic_add_return(int i, atomic_t *v)
+{
+ unsigned long val;
+
+ asm("0: \n"
+ " orcc gr0,gr0,gr0,icc3 \n" /* set ICC3.Z */
+ " ckeq icc3,cc7 \n"
+ " ld.p %M0,%1 \n" /* LD.P/ORCR must be atomic */
+ " orcr cc7,cc7,cc3 \n" /* set CC3 to true */
+ " add%I2 %1,%2,%1 \n"
+ " cst.p %1,%M0 ,cc3,#1 \n"
+ " corcc gr29,gr29,gr0 ,cc3,#1 \n" /* clear ICC3.Z if store happens */
+ " beq icc3,#0,0b \n"
+ : "+U"(v->counter), "=&r"(val)
+ : "NPr"(i)
+ : "memory", "cc7", "cc3", "icc3"
+ );
+
+ return val;
+}
+
+static inline int atomic_sub_return(int i, atomic_t *v)
+{
+ unsigned long val;
+
+ asm("0: \n"
+ " orcc gr0,gr0,gr0,icc3 \n" /* set ICC3.Z */
+ " ckeq icc3,cc7 \n"
+ " ld.p %M0,%1 \n" /* LD.P/ORCR must be atomic */
+ " orcr cc7,cc7,cc3 \n" /* set CC3 to true */
+ " sub%I2 %1,%2,%1 \n"
+ " cst.p %1,%M0 ,cc3,#1 \n"
+ " corcc gr29,gr29,gr0 ,cc3,#1 \n" /* clear ICC3.Z if store happens */
+ " beq icc3,#0,0b \n"
+ : "+U"(v->counter), "=&r"(val)
+ : "NPr"(i)
+ : "memory", "cc7", "cc3", "icc3"
+ );
+
+ return val;
+}
+
+#else
+
+extern int atomic_add_return(int i, atomic_t *v);
+extern int atomic_sub_return(int i, atomic_t *v);
+
+#endif
+
+static inline int atomic_add_negative(int i, atomic_t *v)
+{
+ return atomic_add_return(i, v) < 0;
+}
+
+static inline void atomic_add(int i, atomic_t *v)
+{
+ atomic_add_return(i, v);
+}
+
+static inline void atomic_sub(int i, atomic_t *v)
+{
+ atomic_sub_return(i, v);
+}
+
+static inline void atomic_inc(atomic_t *v)
+{
+ atomic_add_return(1, v);
+}
+
+static inline void atomic_dec(atomic_t *v)
+{
+ atomic_sub_return(1, v);
+}
+
+#define atomic_dec_return(v) atomic_sub_return(1, (v))
+#define atomic_inc_return(v) atomic_add_return(1, (v))
+
+#define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0)
+#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
+#define atomic_inc_and_test(v) (atomic_add_return(1, (v)) == 0)
+
+/*
+ * 64-bit atomic ops
+ */
+typedef struct {
+ volatile long long counter;
+} atomic64_t;
+
+#define ATOMIC64_INIT(i) { (i) }
+
+static inline long long atomic64_read(atomic64_t *v)
+{
+ long long counter;
+
+ asm("ldd%I1 %M1,%0"
+ : "=e"(counter)
+ : "m"(v->counter));
+ return counter;
+}
+
+static inline void atomic64_set(atomic64_t *v, long long i)
+{
+ asm volatile("std%I0 %1,%M0"
+ : "=m"(v->counter)
+ : "e"(i));
+}
+
+extern long long atomic64_inc_return(atomic64_t *v);
+extern long long atomic64_dec_return(atomic64_t *v);
+extern long long atomic64_add_return(long long i, atomic64_t *v);
+extern long long atomic64_sub_return(long long i, atomic64_t *v);
+
+static inline long long atomic64_add_negative(long long i, atomic64_t *v)
+{
+ return atomic64_add_return(i, v) < 0;
+}
+
+static inline void atomic64_add(long long i, atomic64_t *v)
+{
+ atomic64_add_return(i, v);
+}
+
+static inline void atomic64_sub(long long i, atomic64_t *v)
+{
+ atomic64_sub_return(i, v);
+}
+
+static inline void atomic64_inc(atomic64_t *v)
+{
+ atomic64_inc_return(v);
+}
+
+static inline void atomic64_dec(atomic64_t *v)
+{
+ atomic64_dec_return(v);
+}
+
+#define atomic64_sub_and_test(i,v) (atomic64_sub_return((i), (v)) == 0)
+#define atomic64_dec_and_test(v) (atomic64_dec_return((v)) == 0)
+#define atomic64_inc_and_test(v) (atomic64_inc_return((v)) == 0)
+
+#define atomic_cmpxchg(v, old, new) (cmpxchg(&(v)->counter, old, new))
+#define atomic_xchg(v, new) (xchg(&(v)->counter, new))
+#define atomic64_cmpxchg(v, old, new) (__cmpxchg_64(old, new, &(v)->counter))
+#define atomic64_xchg(v, new) (__xchg_64(new, &(v)->counter))
+
+static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u)
+{
+ int c, old;
+ c = atomic_read(v);
+ for (;;) {
+ if (unlikely(c == (u)))
+ break;
+ old = atomic_cmpxchg((v), c, c + (a));
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+ return c;
+}
+
+
+#endif /* _ASM_ATOMIC_H */
diff --git a/arch/frv/include/asm/ax88796.h b/arch/frv/include/asm/ax88796.h
new file mode 100644
index 00000000000..637e980393c
--- /dev/null
+++ b/arch/frv/include/asm/ax88796.h
@@ -0,0 +1,22 @@
+/* ax88796.h: access points to the driver for the AX88796 NE2000 clone
+ *
+ * Copyright (C) 2004 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_AX88796_H
+#define _ASM_AX88796_H
+
+#include <asm/mb-regs.h>
+
+#define AX88796_IOADDR (__region_CS1 + 0x200)
+#define AX88796_IRQ IRQ_CPU_EXTERNAL7
+#define AX88796_FULL_DUPLEX 0 /* force full duplex */
+#define AX88796_BUS_INFO "CS1#+0x200" /* bus info for ethtool */
+
+#endif /* _ASM_AX88796_H */
diff --git a/arch/frv/include/asm/barrier.h b/arch/frv/include/asm/barrier.h
new file mode 100644
index 00000000000..abbef470154
--- /dev/null
+++ b/arch/frv/include/asm/barrier.h
@@ -0,0 +1,23 @@
+/* FR-V CPU memory barrier definitions
+ *
+ * Copyright (C) 2003 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_BARRIER_H
+#define _ASM_BARRIER_H
+
+#define nop() asm volatile ("nop"::)
+
+#define mb() asm volatile ("membar" : : :"memory")
+#define rmb() asm volatile ("membar" : : :"memory")
+#define wmb() asm volatile ("membar" : : :"memory")
+
+#include <asm-generic/barrier.h>
+
+#endif /* _ASM_BARRIER_H */
diff --git a/arch/frv/include/asm/bitops.h b/arch/frv/include/asm/bitops.h
new file mode 100644
index 00000000000..96de220ef13
--- /dev/null
+++ b/arch/frv/include/asm/bitops.h
@@ -0,0 +1,404 @@
+/* bitops.h: bit operations for the Fujitsu FR-V CPUs
+ *
+ * For an explanation of how atomic ops work in this arch, see:
+ * Documentation/frv/atomic-ops.txt
+ *
+ * Copyright (C) 2004 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _ASM_BITOPS_H
+#define _ASM_BITOPS_H
+
+#include <linux/compiler.h>
+#include <asm/byteorder.h>
+
+#ifdef __KERNEL__
+
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
+#include <asm-generic/bitops/ffz.h>
+
+#ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS
+static inline
+unsigned long atomic_test_and_ANDNOT_mask(unsigned long mask, volatile unsigned long *v)
+{
+ unsigned long old, tmp;
+
+ asm volatile(
+ "0: \n"
+ " orcc gr0,gr0,gr0,icc3 \n" /* set ICC3.Z */
+ " ckeq icc3,cc7 \n"
+ " ld.p %M0,%1 \n" /* LD.P/ORCR are atomic */
+ " orcr cc7,cc7,cc3 \n" /* set CC3 to true */
+ " and%I3 %1,%3,%2 \n"
+ " cst.p %2,%M0 ,cc3,#1 \n" /* if store happens... */
+ " corcc gr29,gr29,gr0 ,cc3,#1 \n" /* ... clear ICC3.Z */
+ " beq icc3,#0,0b \n"
+ : "+U"(*v), "=&r"(old), "=r"(tmp)
+ : "NPr"(~mask)
+ : "memory", "cc7", "cc3", "icc3"
+ );
+
+ return old;
+}
+
+static inline
+unsigned long atomic_test_and_OR_mask(unsigned long mask, volatile unsigned long *v)
+{
+ unsigned long old, tmp;
+
+ asm volatile(
+ "0: \n"
+ " orcc gr0,gr0,gr0,icc3 \n" /* set ICC3.Z */
+ " ckeq icc3,cc7 \n"
+ " ld.p %M0,%1 \n" /* LD.P/ORCR are atomic */
+ " orcr cc7,cc7,cc3 \n" /* set CC3 to true */
+ " or%I3 %1,%3,%2 \n"
+ " cst.p %2,%M0 ,cc3,#1 \n" /* if store happens... */
+ " corcc gr29,gr29,gr0 ,cc3,#1 \n" /* ... clear ICC3.Z */
+ " beq icc3,#0,0b \n"
+ : "+U"(*v), "=&r"(old), "=r"(tmp)
+ : "NPr"(mask)
+ : "memory", "cc7", "cc3", "icc3"
+ );
+
+ return old;
+}
+
+static inline
+unsigned long atomic_test_and_XOR_mask(unsigned long mask, volatile unsigned long *v)
+{
+ unsigned long old, tmp;
+
+ asm volatile(
+ "0: \n"
+ " orcc gr0,gr0,gr0,icc3 \n" /* set ICC3.Z */
+ " ckeq icc3,cc7 \n"
+ " ld.p %M0,%1 \n" /* LD.P/ORCR are atomic */
+ " orcr cc7,cc7,cc3 \n" /* set CC3 to true */
+ " xor%I3 %1,%3,%2 \n"
+ " cst.p %2,%M0 ,cc3,#1 \n" /* if store happens... */
+ " corcc gr29,gr29,gr0 ,cc3,#1 \n" /* ... clear ICC3.Z */
+ " beq icc3,#0,0b \n"
+ : "+U"(*v), "=&r"(old), "=r"(tmp)
+ : "NPr"(mask)
+ : "memory", "cc7", "cc3", "icc3"
+ );
+
+ return old;
+}
+
+#else
+
+extern unsigned long atomic_test_and_ANDNOT_mask(unsigned long mask, volatile unsigned long *v);
+extern unsigned long atomic_test_and_OR_mask(unsigned long mask, volatile unsigned long *v);
+extern unsigned long atomic_test_and_XOR_mask(unsigned long mask, volatile unsigned long *v);
+
+#endif
+
+#define atomic_clear_mask(mask, v) atomic_test_and_ANDNOT_mask((mask), (v))
+#define atomic_set_mask(mask, v) atomic_test_and_OR_mask((mask), (v))
+
+static inline int test_and_clear_bit(unsigned long nr, volatile void *addr)
+{
+ volatile unsigned long *ptr = addr;
+ unsigned long mask = 1UL << (nr & 31);
+ ptr += nr >> 5;
+ return (atomic_test_and_ANDNOT_mask(mask, ptr) & mask) != 0;
+}
+
+static inline int test_and_set_bit(unsigned long nr, volatile void *addr)
+{
+ volatile unsigned long *ptr = addr;
+ unsigned long mask = 1UL << (nr & 31);
+ ptr += nr >> 5;
+ return (atomic_test_and_OR_mask(mask, ptr) & mask) != 0;
+}
+
+static inline int test_and_change_bit(unsigned long nr, volatile void *addr)
+{
+ volatile unsigned long *ptr = addr;
+ unsigned long mask = 1UL << (nr & 31);
+ ptr += nr >> 5;
+ return (atomic_test_and_XOR_mask(mask, ptr) & mask) != 0;
+}
+
+static inline void clear_bit(unsigned long nr, volatile void *addr)
+{
+ test_and_clear_bit(nr, addr);
+}
+
+static inline void set_bit(unsigned long nr, volatile void *addr)
+{
+ test_and_set_bit(nr, addr);
+}
+
+static inline void change_bit(unsigned long nr, volatile void *addr)
+{
+ test_and_change_bit(nr, addr);
+}
+
+static inline void __clear_bit(unsigned long nr, volatile void *addr)
+{
+ volatile unsigned long *a = addr;
+ int mask;
+
+ a += nr >> 5;
+ mask = 1 << (nr & 31);
+ *a &= ~mask;
+}
+
+static inline void __set_bit(unsigned long nr, volatile void *addr)
+{
+ volatile unsigned long *a = addr;
+ int mask;
+
+ a += nr >> 5;
+ mask = 1 << (nr & 31);
+ *a |= mask;
+}
+
+static inline void __change_bit(unsigned long nr, volatile void *addr)
+{
+ volatile unsigned long *a = addr;
+ int mask;
+
+ a += nr >> 5;
+ mask = 1 << (nr & 31);
+ *a ^= mask;
+}
+
+static inline int __test_and_clear_bit(unsigned long nr, volatile void *addr)
+{
+ volatile unsigned long *a = addr;
+ int mask, retval;
+
+ a += nr >> 5;
+ mask = 1 << (nr & 31);
+ retval = (mask & *a) != 0;
+ *a &= ~mask;
+ return retval;
+}
+
+static inline int __test_and_set_bit(unsigned long nr, volatile void *addr)
+{
+ volatile unsigned long *a = addr;
+ int mask, retval;
+
+ a += nr >> 5;
+ mask = 1 << (nr & 31);
+ retval = (mask & *a) != 0;
+ *a |= mask;
+ return retval;
+}
+
+static inline int __test_and_change_bit(unsigned long nr, volatile void *addr)
+{
+ volatile unsigned long *a = addr;
+ int mask, retval;
+
+ a += nr >> 5;
+ mask = 1 << (nr & 31);
+ retval = (mask & *a) != 0;
+ *a ^= mask;
+ return retval;
+}
+
+/*
+ * This routine doesn't need to be atomic.
+ */
+static inline int
+__constant_test_bit(unsigned long nr, const volatile void *addr)
+{
+ return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0;
+}
+
+static inline int __test_bit(unsigned long nr, const volatile void *addr)
+{
+ int * a = (int *) addr;
+ int mask;
+
+ a += nr >> 5;
+ mask = 1 << (nr & 0x1f);
+ return ((mask & *a) != 0);
+}
+
+#define test_bit(nr,addr) \
+(__builtin_constant_p(nr) ? \
+ __constant_test_bit((nr),(addr)) : \
+ __test_bit((nr),(addr)))
+
+#include <asm-generic/bitops/find.h>
+
+/**
+ * fls - find last bit set
+ * @x: the word to search
+ *
+ * This is defined the same way as ffs:
+ * - return 32..1 to indicate bit 31..0 most significant bit set
+ * - return 0 to indicate no bits set
+ */
+#define fls(x) \
+({ \
+ int bit; \
+ \
+ asm(" subcc %1,gr0,gr0,icc0 \n" \
+ " ckne icc0,cc4 \n" \
+ " cscan.p %1,gr0,%0 ,cc4,#1 \n" \
+ " csub %0,%0,%0 ,cc4,#0 \n" \
+ " csub %2,%0,%0 ,cc4,#1 \n" \
+ : "=&r"(bit) \
+ : "r"(x), "r"(32) \
+ : "icc0", "cc4" \
+ ); \
+ \
+ bit; \
+})
+
+/**
+ * fls64 - find last bit set in a 64-bit value
+ * @n: the value to search
+ *
+ * This is defined the same way as ffs:
+ * - return 64..1 to indicate bit 63..0 most significant bit set
+ * - return 0 to indicate no bits set
+ */
+static inline __attribute__((const))
+int fls64(u64 n)
+{
+ union {
+ u64 ll;
+ struct { u32 h, l; };
+ } _;
+ int bit, x, y;
+
+ _.ll = n;
+
+ asm(" subcc.p %3,gr0,gr0,icc0 \n"
+ " subcc %4,gr0,gr0,icc1 \n"
+ " ckne icc0,cc4 \n"
+ " ckne icc1,cc5 \n"
+ " norcr cc4,cc5,cc6 \n"
+ " csub.p %0,%0,%0 ,cc6,1 \n"
+ " orcr cc5,cc4,cc4 \n"
+ " andcr cc4,cc5,cc4 \n"
+ " cscan.p %3,gr0,%0 ,cc4,0 \n"
+ " setlos #64,%1 \n"
+ " cscan.p %4,gr0,%0 ,cc4,1 \n"
+ " setlos #32,%2 \n"
+ " csub.p %1,%0,%0 ,cc4,0 \n"
+ " csub %2,%0,%0 ,cc4,1 \n"
+ : "=&r"(bit), "=r"(x), "=r"(y)
+ : "0r"(_.h), "r"(_.l)
+ : "icc0", "icc1", "cc4", "cc5", "cc6"
+ );
+ return bit;
+
+}
+
+/**
+ * ffs - find first bit set
+ * @x: the word to search
+ *
+ * - return 32..1 to indicate bit 31..0 most least significant bit set
+ * - return 0 to indicate no bits set
+ */
+static inline __attribute__((const))
+int ffs(int x)
+{
+ /* Note: (x & -x) gives us a mask that is the least significant
+ * (rightmost) 1-bit of the value in x.
+ */
+ return fls(x & -x);
+}
+
+/**
+ * __ffs - find first bit set
+ * @x: the word to search
+ *
+ * - return 31..0 to indicate bit 31..0 most least significant bit set
+ * - if no bits are set in x, the result is undefined
+ */
+static inline __attribute__((const))
+int __ffs(unsigned long x)
+{
+ int bit;
+ asm("scan %1,gr0,%0" : "=r"(bit) : "r"(x & -x));
+ return 31 - bit;
+}
+
+/**
+ * __fls - find last (most-significant) set bit in a long word
+ * @word: the word to search
+ *
+ * Undefined if no set bit exists, so code should check against 0 first.
+ */
+static inline unsigned long __fls(unsigned long word)
+{
+ unsigned long bit;
+ asm("scan %1,gr0,%0" : "=r"(bit) : "r"(word));
+ return bit;
+}
+
+/*
+ * special slimline version of fls() for calculating ilog2_u32()
+ * - note: no protection against n == 0
+ */
+#define ARCH_HAS_ILOG2_U32
+static inline __attribute__((const))
+int __ilog2_u32(u32 n)
+{
+ int bit;
+ asm("scan %1,gr0,%0" : "=r"(bit) : "r"(n));
+ return 31 - bit;
+}
+
+/*
+ * special slimline version of fls64() for calculating ilog2_u64()
+ * - note: no protection against n == 0
+ */
+#define ARCH_HAS_ILOG2_U64
+static inline __attribute__((const))
+int __ilog2_u64(u64 n)
+{
+ union {
+ u64 ll;
+ struct { u32 h, l; };
+ } _;
+ int bit, x, y;
+
+ _.ll = n;
+
+ asm(" subcc %3,gr0,gr0,icc0 \n"
+ " ckeq icc0,cc4 \n"
+ " cscan.p %3,gr0,%0 ,cc4,0 \n"
+ " setlos #63,%1 \n"
+ " cscan.p %4,gr0,%0 ,cc4,1 \n"
+ " setlos #31,%2 \n"
+ " csub.p %1,%0,%0 ,cc4,0 \n"
+ " csub %2,%0,%0 ,cc4,1 \n"
+ : "=&r"(bit), "=r"(x), "=r"(y)
+ : "0r"(_.h), "r"(_.l)
+ : "icc0", "cc4"
+ );
+ return bit;
+}
+
+#include <asm-generic/bitops/sched.h>
+#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
+
+#include <asm-generic/bitops/le.h>
+
+#include <asm-generic/bitops/ext2-atomic-setbit.h>
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_BITOPS_H */
diff --git a/arch/frv/include/asm/bug.h b/arch/frv/include/asm/bug.h
new file mode 100644
index 00000000000..dd01bcf42ee
--- /dev/null
+++ b/arch/frv/include/asm/bug.h
@@ -0,0 +1,56 @@
+/* bug.h: FRV bug trapping
+ *
+ * Copyright (C) 2004 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _ASM_BUG_H
+#define _ASM_BUG_H
+
+#include <linux/linkage.h>
+
+#ifdef CONFIG_BUG
+/*
+ * Tell the user there is some problem.
+ */
+extern asmlinkage void __debug_bug_trap(int signr);
+
+#ifdef CONFIG_NO_KERNEL_MSG
+#define _debug_bug_printk()
+#else
+extern void __debug_bug_printk(const char *file, unsigned line);
+#define _debug_bug_printk() __debug_bug_printk(__FILE__, __LINE__)
+#endif
+
+#define _debug_bug_trap(signr) \
+do { \
+ __debug_bug_trap(signr); \
+ asm volatile("nop"); \
+} while(1)
+
+#define HAVE_ARCH_BUG
+#define BUG() \
+do { \
+ _debug_bug_printk(); \
+ _debug_bug_trap(6 /*SIGABRT*/); \
+} while (0)
+
+#ifdef CONFIG_GDBSTUB
+#define HAVE_ARCH_KGDB_RAISE
+#define kgdb_raise(signr) do { _debug_bug_trap(signr); } while(0)
+
+#define HAVE_ARCH_KGDB_BAD_PAGE
+#define kgdb_bad_page(page) do { kgdb_raise(SIGABRT); } while(0)
+#endif
+
+#endif /* CONFIG_BUG */
+
+#include <asm-generic/bug.h>
+
+extern void die_if_kernel(const char *, ...) __attribute__((format(printf, 1, 2)));
+
+#endif
diff --git a/arch/frv/include/asm/bugs.h b/arch/frv/include/asm/bugs.h
new file mode 100644
index 00000000000..f2382be2b46
--- /dev/null
+++ b/arch/frv/include/asm/bugs.h
@@ -0,0 +1,14 @@
+/* bugs.h: arch bug checking entry
+ *
+ * Copyright (C) 2003 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+static inline void check_bugs(void)
+{
+}
diff --git a/arch/frv/include/asm/busctl-regs.h b/arch/frv/include/asm/busctl-regs.h
new file mode 100644
index 00000000000..bb0ff4816e2
--- /dev/null
+++ b/arch/frv/include/asm/busctl-regs.h
@@ -0,0 +1,41 @@
+/* busctl-regs.h: FR400-series CPU bus controller registers
+ *
+ * Copyright (C) 2003 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_BUSCTL_REGS_H
+#define _ASM_BUSCTL_REGS_H
+
+/* bus controller registers */
+#define __get_LGCR() ({ *(volatile unsigned long *)(0xfe000010); })
+#define __get_LMAICR() ({ *(volatile unsigned long *)(0xfe000030); })
+#define __get_LEMBR() ({ *(volatile unsigned long *)(0xfe000040); })
+#define __get_LEMAM() ({ *(volatile unsigned long *)(0xfe000048); })
+#define __get_LCR(R) ({ *(volatile unsigned long *)(0xfe000100 + 8*(R)); })
+#define __get_LSBR(R) ({ *(volatile unsigned long *)(0xfe000c00 + 8*(R)); })
+#define __get_LSAM(R) ({ *(volatile unsigned long *)(0xfe000d00 + 8*(R)); })
+
+#define __set_LGCR(V) do { *(volatile unsigned long *)(0xfe000010) = (V); } while(0)
+#define __set_LMAICR(V) do { *(volatile unsigned long *)(0xfe000030) = (V); } while(0)
+#define __set_LEMBR(V) do { *(volatile unsigned long *)(0xfe000040) = (V); } while(0)
+#define __set_LEMAM(V) do { *(volatile unsigned long *)(0xfe000048) = (V); } while(0)
+#define __set_LCR(R,V) do { *(volatile unsigned long *)(0xfe000100 + 8*(R)) = (V); } while(0)
+#define __set_LSBR(R,V) do { *(volatile unsigned long *)(0xfe000c00 + 8*(R)) = (V); } while(0)
+#define __set_LSAM(R,V) do { *(volatile unsigned long *)(0xfe000d00 + 8*(R)) = (V); } while(0)
+
+/* FR401 SDRAM controller registers */
+#define __get_DBR(R) ({ *(volatile unsigned long *)(0xfe000e00 + 8*(R)); })
+#define __get_DAM(R) ({ *(volatile unsigned long *)(0xfe000f00 + 8*(R)); })
+
+/* FR551 SDRAM controller registers */
+#define __get_DARS(R) ({ *(volatile unsigned long *)(0xfeff0100 + 8*(R)); })
+#define __get_DAMK(R) ({ *(volatile unsigned long *)(0xfeff0110 + 8*(R)); })
+
+
+#endif /* _ASM_BUSCTL_REGS_H */
diff --git a/arch/frv/include/asm/cache.h b/arch/frv/include/asm/cache.h
new file mode 100644
index 00000000000..2797163b8f4
--- /dev/null
+++ b/arch/frv/include/asm/cache.h
@@ -0,0 +1,23 @@
+/* cache.h: FRV cache definitions
+ *
+ * Copyright (C) 2004 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef __ASM_CACHE_H
+#define __ASM_CACHE_H
+
+
+/* bytes per L1 cache line */
+#define L1_CACHE_SHIFT (CONFIG_FRV_L1_CACHE_SHIFT)
+#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
+
+#define __cacheline_aligned __attribute__((aligned(L1_CACHE_BYTES)))
+#define ____cacheline_aligned __attribute__((aligned(L1_CACHE_BYTES)))
+
+#endif
diff --git a/arch/frv/include/asm/cacheflush.h b/arch/frv/include/asm/cacheflush.h
new file mode 100644
index 00000000000..edbac54ae01
--- /dev/null
+++ b/arch/frv/include/asm/cacheflush.h
@@ -0,0 +1,105 @@
+/* cacheflush.h: FRV cache flushing routines
+ *
+ * Copyright (C) 2004 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_CACHEFLUSH_H
+#define _ASM_CACHEFLUSH_H
+
+/* Keep includes the same across arches. */
+#include <linux/mm.h>
+
+/*
+ * virtually-indexed cache management (our cache is physically indexed)
+ */
+#define flush_cache_all() do {} while(0)
+#define flush_cache_mm(mm) do {} while(0)
+#define flush_cache_dup_mm(mm) do {} while(0)
+#define flush_cache_range(mm, start, end) do {} while(0)
+#define flush_cache_page(vma, vmaddr, pfn) do {} while(0)
+#define flush_cache_vmap(start, end) do {} while(0)
+#define flush_cache_vunmap(start, end) do {} while(0)
+#define flush_dcache_mmap_lock(mapping) do {} while(0)
+#define flush_dcache_mmap_unlock(mapping) do {} while(0)
+
+/*
+ * physically-indexed cache management
+ * - see arch/frv/lib/cache.S
+ */
+extern void frv_dcache_writeback(unsigned long start, unsigned long size);
+extern void frv_cache_invalidate(unsigned long start, unsigned long size);
+extern void frv_icache_invalidate(unsigned long start, unsigned long size);
+extern void frv_cache_wback_inv(unsigned long start, unsigned long size);
+
+static inline void __flush_cache_all(void)
+{
+ asm volatile(" dcef @(gr0,gr0),#1 \n"
+ " icei @(gr0,gr0),#1 \n"
+ " membar \n"
+ : : : "memory"
+ );
+}
+
+/* dcache/icache coherency... */
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
+#ifdef CONFIG_MMU
+extern void flush_dcache_page(struct page *page);
+#else
+static inline void flush_dcache_page(struct page *page)
+{
+ unsigned long addr = page_to_phys(page);
+ frv_dcache_writeback(addr, addr + PAGE_SIZE);
+}
+#endif
+
+static inline void flush_page_to_ram(struct page *page)
+{
+ flush_dcache_page(page);
+}
+
+static inline void flush_icache(void)
+{
+ __flush_cache_all();
+}
+
+static inline void flush_icache_range(unsigned long start, unsigned long end)
+{
+ frv_cache_wback_inv(start, end);
+}
+
+#ifdef CONFIG_MMU
+extern void flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
+ unsigned long start, unsigned long len);
+#else
+static inline void flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
+ unsigned long start, unsigned long len)
+{
+ frv_cache_wback_inv(start, start + len);
+}
+#endif
+
+static inline void flush_icache_page(struct vm_area_struct *vma, struct page *page)
+{
+ flush_icache_user_range(vma, page, page_to_phys(page), PAGE_SIZE);
+}
+
+/*
+ * permit ptrace to access another process's address space through the icache
+ * and the dcache
+ */
+#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
+do { \
+ memcpy((dst), (src), (len)); \
+ flush_icache_user_range((vma), (page), (vaddr), (len)); \
+} while(0)
+
+#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
+ memcpy((dst), (src), (len))
+
+#endif /* _ASM_CACHEFLUSH_H */
diff --git a/arch/frv/include/asm/checksum.h b/arch/frv/include/asm/checksum.h
new file mode 100644
index 00000000000..269da09ff63
--- /dev/null
+++ b/arch/frv/include/asm/checksum.h
@@ -0,0 +1,180 @@
+/* checksum.h: FRV checksumming
+ *
+ * Copyright (C) 2004 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_CHECKSUM_H
+#define _ASM_CHECKSUM_H
+
+#include <linux/in6.h>
+
+/*
+ * 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
+ *
+ * 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);
+
+/*
+ * the same as csum_partial_copy, but copies from user space.
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+extern __wsum csum_partial_copy_from_user(const void __user *src, void *dst,
+ int len, __wsum sum, int *csum_err);
+
+/*
+ * 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 tmp, inc, sum = 0;
+
+ asm(" addcc gr0,gr0,gr0,icc0\n" /* clear icc0.C */
+ " subi %1,#4,%1 \n"
+ "0: \n"
+ " ldu.p @(%1,%3),%4 \n"
+ " subicc %2,#1,%2,icc1 \n"
+ " addxcc.p %4,%0,%0,icc0 \n"
+ " bhi icc1,#2,0b \n"
+
+ /* fold the 33-bit result into 16-bits */
+ " addxcc gr0,%0,%0,icc0 \n"
+ " srli %0,#16,%1 \n"
+ " sethi #0,%0 \n"
+ " add %1,%0,%0 \n"
+ " srli %0,#16,%1 \n"
+ " add %1,%0,%0 \n"
+
+ : "=r" (sum), "=r" (iph), "=r" (ihl), "=r" (inc), "=&r"(tmp)
+ : "0" (sum), "1" (iph), "2" (ihl), "3" (4),
+ "m"(*(volatile struct { int _[100]; } *)iph)
+ : "icc0", "icc1", "memory"
+ );
+
+ return (__force __sum16)~sum;
+}
+
+/*
+ * Fold a partial checksum
+ */
+static inline __sum16 csum_fold(__wsum sum)
+{
+ unsigned int tmp;
+
+ asm(" srli %0,#16,%1 \n"
+ " sethi #0,%0 \n"
+ " add %1,%0,%0 \n"
+ " srli %0,#16,%1 \n"
+ " add %1,%0,%0 \n"
+ : "=r"(sum), "=&r"(tmp)
+ : "0"(sum)
+ );
+
+ return (__force __sum16)~sum;
+}
+
+/*
+ * computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+static inline __wsum
+csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
+ unsigned short proto, __wsum sum)
+{
+ asm(" addcc %1,%0,%0,icc0 \n"
+ " addxcc %2,%0,%0,icc0 \n"
+ " addxcc %3,%0,%0,icc0 \n"
+ " addxcc gr0,%0,%0,icc0 \n"
+ : "=r" (sum)
+ : "r" (daddr), "r" (saddr), "r" (len + proto), "0"(sum)
+ : "icc0"
+ );
+ return sum;
+}
+
+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
+ */
+extern __sum16 ip_compute_csum(const void *buff, int len);
+
+#define _HAVE_ARCH_IPV6_CSUM
+static inline __sum16
+csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr,
+ __u32 len, unsigned short proto, __wsum sum)
+{
+ unsigned long tmp, tmp2;
+
+ asm(" addcc %2,%0,%0,icc0 \n"
+
+ /* add up the source addr */
+ " ldi @(%3,0),%1 \n"
+ " addxcc %1,%0,%0,icc0 \n"
+ " ldi @(%3,4),%2 \n"
+ " addxcc %2,%0,%0,icc0 \n"
+ " ldi @(%3,8),%1 \n"
+ " addxcc %1,%0,%0,icc0 \n"
+ " ldi @(%3,12),%2 \n"
+ " addxcc %2,%0,%0,icc0 \n"
+
+ /* add up the dest addr */
+ " ldi @(%4,0),%1 \n"
+ " addxcc %1,%0,%0,icc0 \n"
+ " ldi @(%4,4),%2 \n"
+ " addxcc %2,%0,%0,icc0 \n"
+ " ldi @(%4,8),%1 \n"
+ " addxcc %1,%0,%0,icc0 \n"
+ " ldi @(%4,12),%2 \n"
+ " addxcc %2,%0,%0,icc0 \n"
+
+ /* fold the 33-bit result into 16-bits */
+ " addxcc gr0,%0,%0,icc0 \n"
+ " srli %0,#16,%1 \n"
+ " sethi #0,%0 \n"
+ " add %1,%0,%0 \n"
+ " srli %0,#16,%1 \n"
+ " add %1,%0,%0 \n"
+
+ : "=r" (sum), "=&r" (tmp), "=r" (tmp2)
+ : "r" (saddr), "r" (daddr), "0" (sum), "2" (len + proto)
+ : "icc0"
+ );
+
+ return (__force __sum16)~sum;
+}
+
+#endif /* _ASM_CHECKSUM_H */
diff --git a/arch/frv/include/asm/cmpxchg.h b/arch/frv/include/asm/cmpxchg.h
new file mode 100644
index 00000000000..5b04dd0aeca
--- /dev/null
+++ b/arch/frv/include/asm/cmpxchg.h
@@ -0,0 +1,172 @@
+/* xchg and cmpxchg operation emulation for FR-V
+ *
+ * For an explanation of how atomic ops work in this arch, see:
+ * Documentation/frv/atomic-ops.txt
+ *
+ * Copyright (C) 2004 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _ASM_CMPXCHG_H
+#define _ASM_CMPXCHG_H
+
+#include <linux/types.h>
+
+/*****************************************************************************/
+/*
+ * exchange value with memory
+ */
+extern uint64_t __xchg_64(uint64_t i, volatile void *v);
+
+#ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS
+
+#define xchg(ptr, x) \
+({ \
+ __typeof__(ptr) __xg_ptr = (ptr); \
+ __typeof__(*(ptr)) __xg_orig; \
+ \
+ switch (sizeof(__xg_orig)) { \
+ case 4: \
+ asm volatile( \
+ "swap%I0 %M0,%1" \
+ : "+m"(*__xg_ptr), "=r"(__xg_orig) \
+ : "1"(x) \
+ : "memory" \
+ ); \
+ break; \
+ \
+ default: \
+ __xg_orig = (__typeof__(__xg_orig))0; \
+ asm volatile("break"); \
+ break; \
+ } \
+ \
+ __xg_orig; \
+})
+
+#else
+
+extern uint32_t __xchg_32(uint32_t i, volatile void *v);
+
+#define xchg(ptr, x) \
+({ \
+ __typeof__(ptr) __xg_ptr = (ptr); \
+ __typeof__(*(ptr)) __xg_orig; \
+ \
+ switch (sizeof(__xg_orig)) { \
+ case 4: __xg_orig = (__typeof__(*(ptr))) __xchg_32((uint32_t) x, __xg_ptr); break; \
+ default: \
+ __xg_orig = (__typeof__(__xg_orig))0; \
+ asm volatile("break"); \
+ break; \
+ } \
+ __xg_orig; \
+})
+
+#endif
+
+#define tas(ptr) (xchg((ptr), 1))
+
+/*****************************************************************************/
+/*
+ * compare and conditionally exchange value with memory
+ * - if (*ptr == test) then orig = *ptr; *ptr = test;
+ * - if (*ptr != test) then orig = *ptr;
+ */
+extern uint64_t __cmpxchg_64(uint64_t test, uint64_t new, volatile uint64_t *v);
+
+#ifndef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS
+
+#define cmpxchg(ptr, test, new) \
+({ \
+ __typeof__(ptr) __xg_ptr = (ptr); \
+ __typeof__(*(ptr)) __xg_orig, __xg_tmp; \
+ __typeof__(*(ptr)) __xg_test = (test); \
+ __typeof__(*(ptr)) __xg_new = (new); \
+ \
+ switch (sizeof(__xg_orig)) { \
+ case 4: \
+ asm volatile( \
+ "0: \n" \
+ " orcc gr0,gr0,gr0,icc3 \n" \
+ " ckeq icc3,cc7 \n" \
+ " ld.p %M0,%1 \n" \
+ " orcr cc7,cc7,cc3 \n" \
+ " sub%I4cc %1,%4,%2,icc0 \n" \
+ " bne icc0,#0,1f \n" \
+ " cst.p %3,%M0 ,cc3,#1 \n" \
+ " corcc gr29,gr29,gr0 ,cc3,#1 \n" \
+ " beq icc3,#0,0b \n" \
+ "1: \n" \
+ : "+U"(*__xg_ptr), "=&r"(__xg_orig), "=&r"(__xg_tmp) \
+ : "r"(__xg_new), "NPr"(__xg_test) \
+ : "memory", "cc7", "cc3", "icc3", "icc0" \
+ ); \
+ break; \
+ \
+ default: \
+ __xg_orig = (__typeof__(__xg_orig))0; \
+ asm volatile("break"); \
+ break; \
+ } \
+ \
+ __xg_orig; \
+})
+
+#else
+
+extern uint32_t __cmpxchg_32(uint32_t *v, uint32_t test, uint32_t new);
+
+#define cmpxchg(ptr, test, new) \
+({ \
+ __typeof__(ptr) __xg_ptr = (ptr); \
+ __typeof__(*(ptr)) __xg_orig; \
+ __typeof__(*(ptr)) __xg_test = (test); \
+ __typeof__(*(ptr)) __xg_new = (new); \
+ \
+ switch (sizeof(__xg_orig)) { \
+ case 4: __xg_orig = (__force __typeof__(*ptr)) \
+ __cmpxchg_32((__force uint32_t *)__xg_ptr, \
+ (__force uint32_t)__xg_test, \
+ (__force uint32_t)__xg_new); break; \
+ default: \
+ __xg_orig = (__typeof__(__xg_orig))0; \
+ asm volatile("break"); \
+ break; \
+ } \
+ \
+ __xg_orig; \
+})
+
+#endif
+
+#include <asm-generic/cmpxchg-local.h>
+
+static inline unsigned long __cmpxchg_local(volatile void *ptr,
+ unsigned long old,
+ unsigned long new, int size)
+{
+ switch (size) {
+ case 4:
+ return cmpxchg((unsigned long *)ptr, old, new);
+ default:
+ return __cmpxchg_local_generic(ptr, old, new, size);
+ }
+
+ return old;
+}
+
+/*
+ * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
+ * them available.
+ */
+#define cmpxchg_local(ptr, o, n) \
+ ((__typeof__(*(ptr)))__cmpxchg_local((ptr), (unsigned long)(o), \
+ (unsigned long)(n), sizeof(*(ptr))))
+#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
+
+#endif /* _ASM_CMPXCHG_H */
diff --git a/arch/frv/include/asm/cpu-irqs.h b/arch/frv/include/asm/cpu-irqs.h
new file mode 100644
index 00000000000..478f3498fcf
--- /dev/null
+++ b/arch/frv/include/asm/cpu-irqs.h
@@ -0,0 +1,81 @@
+/* cpu-irqs.h: on-CPU peripheral irqs
+ *
+ * Copyright (C) 2004 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_CPU_IRQS_H
+#define _ASM_CPU_IRQS_H
+
+#ifndef __ASSEMBLY__
+
+/* IRQ to level mappings */
+#define IRQ_GDBSTUB_LEVEL 15
+#define IRQ_UART_LEVEL 13
+
+#ifdef CONFIG_GDBSTUB_UART0
+#define IRQ_UART0_LEVEL IRQ_GDBSTUB_LEVEL
+#else
+#define IRQ_UART0_LEVEL IRQ_UART_LEVEL
+#endif
+
+#ifdef CONFIG_GDBSTUB_UART1
+#define IRQ_UART1_LEVEL IRQ_GDBSTUB_LEVEL
+#else
+#define IRQ_UART1_LEVEL IRQ_UART_LEVEL
+#endif
+
+#define IRQ_DMA0_LEVEL 14
+#define IRQ_DMA1_LEVEL 14
+#define IRQ_DMA2_LEVEL 14
+#define IRQ_DMA3_LEVEL 14
+#define IRQ_DMA4_LEVEL 14
+#define IRQ_DMA5_LEVEL 14
+#define IRQ_DMA6_LEVEL 14
+#define IRQ_DMA7_LEVEL 14
+
+#define IRQ_TIMER0_LEVEL 12
+#define IRQ_TIMER1_LEVEL 11
+#define IRQ_TIMER2_LEVEL 10
+
+#define IRQ_XIRQ0_LEVEL 1
+#define IRQ_XIRQ1_LEVEL 2
+#define IRQ_XIRQ2_LEVEL 3
+#define IRQ_XIRQ3_LEVEL 4
+#define IRQ_XIRQ4_LEVEL 5
+#define IRQ_XIRQ5_LEVEL 6
+#define IRQ_XIRQ6_LEVEL 7
+#define IRQ_XIRQ7_LEVEL 8
+
+/* IRQ IDs presented to drivers */
+#define IRQ_CPU__UNUSED IRQ_BASE_CPU
+#define IRQ_CPU_UART0 (IRQ_BASE_CPU + IRQ_UART0_LEVEL)
+#define IRQ_CPU_UART1 (IRQ_BASE_CPU + IRQ_UART1_LEVEL)
+#define IRQ_CPU_TIMER0 (IRQ_BASE_CPU + IRQ_TIMER0_LEVEL)
+#define IRQ_CPU_TIMER1 (IRQ_BASE_CPU + IRQ_TIMER1_LEVEL)
+#define IRQ_CPU_TIMER2 (IRQ_BASE_CPU + IRQ_TIMER2_LEVEL)
+#define IRQ_CPU_DMA0 (IRQ_BASE_CPU + IRQ_DMA0_LEVEL)
+#define IRQ_CPU_DMA1 (IRQ_BASE_CPU + IRQ_DMA1_LEVEL)
+#define IRQ_CPU_DMA2 (IRQ_BASE_CPU + IRQ_DMA2_LEVEL)
+#define IRQ_CPU_DMA3 (IRQ_BASE_CPU + IRQ_DMA3_LEVEL)
+#define IRQ_CPU_DMA4 (IRQ_BASE_CPU + IRQ_DMA4_LEVEL)
+#define IRQ_CPU_DMA5 (IRQ_BASE_CPU + IRQ_DMA5_LEVEL)
+#define IRQ_CPU_DMA6 (IRQ_BASE_CPU + IRQ_DMA6_LEVEL)
+#define IRQ_CPU_DMA7 (IRQ_BASE_CPU + IRQ_DMA7_LEVEL)
+#define IRQ_CPU_EXTERNAL0 (IRQ_BASE_CPU + IRQ_XIRQ0_LEVEL)
+#define IRQ_CPU_EXTERNAL1 (IRQ_BASE_CPU + IRQ_XIRQ1_LEVEL)
+#define IRQ_CPU_EXTERNAL2 (IRQ_BASE_CPU + IRQ_XIRQ2_LEVEL)
+#define IRQ_CPU_EXTERNAL3 (IRQ_BASE_CPU + IRQ_XIRQ3_LEVEL)
+#define IRQ_CPU_EXTERNAL4 (IRQ_BASE_CPU + IRQ_XIRQ4_LEVEL)
+#define IRQ_CPU_EXTERNAL5 (IRQ_BASE_CPU + IRQ_XIRQ5_LEVEL)
+#define IRQ_CPU_EXTERNAL6 (IRQ_BASE_CPU + IRQ_XIRQ6_LEVEL)
+#define IRQ_CPU_EXTERNAL7 (IRQ_BASE_CPU + IRQ_XIRQ7_LEVEL)
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_CPU_IRQS_H */
diff --git a/arch/frv/include/asm/current.h b/arch/frv/include/asm/current.h
new file mode 100644
index 00000000000..86b027491b0
--- /dev/null
+++ b/arch/frv/include/asm/current.h
@@ -0,0 +1,30 @@
+/* current.h: FRV current task pointer
+ *
+ * Copyright (C) 2004 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_CURRENT_H
+#define _ASM_CURRENT_H
+
+#ifndef __ASSEMBLY__
+
+/*
+ * dedicate GR29 to keeping the current task pointer
+ */
+register struct task_struct *current asm("gr29");
+
+#define get_current() current
+
+#else
+
+#define CURRENT gr29
+
+#endif
+
+#endif /* _ASM_CURRENT_H */
diff --git a/arch/frv/include/asm/delay.h b/arch/frv/include/asm/delay.h
new file mode 100644
index 00000000000..597b4ebf03b
--- /dev/null
+++ b/arch/frv/include/asm/delay.h
@@ -0,0 +1,50 @@
+/* delay.h: FRV delay code
+ *
+ * Copyright (C) 2003 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_DELAY_H
+#define _ASM_DELAY_H
+
+#include <asm/param.h>
+#include <asm/timer-regs.h>
+
+/*
+ * delay loop - runs at __core_clock_speed_HZ / 2 [there are 2 insns in the loop]
+ */
+extern unsigned long __delay_loops_MHz;
+
+static inline void __delay(unsigned long loops)
+{
+ asm volatile("1: subicc %0,#1,%0,icc0 \n"
+ " bnc icc0,#2,1b \n"
+ : "=r" (loops)
+ : "0" (loops)
+ : "icc0"
+ );
+}
+
+/*
+ * 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 unsigned long loops_per_jiffy;
+
+static inline void udelay(unsigned long usecs)
+{
+ __delay(usecs * __delay_loops_MHz);
+}
+
+#define ndelay(n) udelay((n) * 5)
+
+#endif /* _ASM_DELAY_H */
diff --git a/arch/frv/include/asm/device.h b/arch/frv/include/asm/device.h
new file mode 100644
index 00000000000..d8f9872b0e2
--- /dev/null
+++ b/arch/frv/include/asm/device.h
@@ -0,0 +1,7 @@
+/*
+ * Arch specific extensions to struct device
+ *
+ * This file is released under the GPLv2
+ */
+#include <asm-generic/device.h>
+
diff --git a/arch/frv/include/asm/div64.h b/arch/frv/include/asm/div64.h
new file mode 100644
index 00000000000..6cd978cefb2
--- /dev/null
+++ b/arch/frv/include/asm/div64.h
@@ -0,0 +1 @@
+#include <asm-generic/div64.h>
diff --git a/arch/frv/include/asm/dm9000.h b/arch/frv/include/asm/dm9000.h
new file mode 100644
index 00000000000..f6f48fd9ec6
--- /dev/null
+++ b/arch/frv/include/asm/dm9000.h
@@ -0,0 +1,37 @@
+/* dm9000.h: Davicom DM9000 adapter configuration
+ *
+ * Copyright (C) 2004 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_DM9000_H
+#define _ASM_DM9000_H
+
+#include <asm/mb-regs.h>
+
+#define DM9000_ARCH_IOBASE (__region_CS6 + 0x300)
+#define DM9000_ARCH_IRQ IRQ_CPU_EXTERNAL3 /* XIRQ #3 (shared with FPGA) */
+#undef DM9000_ARCH_IRQ_ACTLOW /* IRQ pin active high */
+#define DM9000_ARCH_BUS_INFO "CS6#+0x300" /* bus info for ethtool */
+
+#undef __is_PCI_IO
+#define __is_PCI_IO(addr) 0 /* not PCI */
+
+#undef inl
+#define inl(addr) \
+({ \
+ unsigned long __ioaddr = (unsigned long) addr; \
+ uint32_t x = readl(__ioaddr); \
+ ((x & 0xff) << 24) | ((x & 0xff00) << 8) | ((x >> 8) & 0xff00) | ((x >> 24) & 0xff); \
+})
+
+#undef insl
+#define insl(a,b,l) __insl(a,b,l,0) /* don't byte-swap */
+
+
+#endif /* _ASM_DM9000_H */
diff --git a/arch/frv/include/asm/dma-mapping.h b/arch/frv/include/asm/dma-mapping.h
new file mode 100644
index 00000000000..1746a2b8e6e
--- /dev/null
+++ b/arch/frv/include/asm/dma-mapping.h
@@ -0,0 +1,150 @@
+#ifndef _ASM_DMA_MAPPING_H
+#define _ASM_DMA_MAPPING_H
+
+#include <linux/device.h>
+#include <asm/cache.h>
+#include <asm/cacheflush.h>
+#include <asm/scatterlist.h>
+#include <asm/io.h>
+
+/*
+ * See Documentation/DMA-API.txt for the description of how the
+ * following DMA API should work.
+ */
+
+#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
+#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+
+extern unsigned long __nongprelbss dma_coherent_mem_start;
+extern unsigned long __nongprelbss dma_coherent_mem_end;
+
+void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp);
+void dma_free_coherent(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle);
+
+extern dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
+ enum dma_data_direction direction);
+
+static inline
+void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
+ enum dma_data_direction direction)
+{
+ BUG_ON(direction == DMA_NONE);
+}
+
+extern int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+ enum dma_data_direction direction);
+
+static inline
+void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
+ enum dma_data_direction direction)
+{
+ BUG_ON(direction == DMA_NONE);
+}
+
+extern
+dma_addr_t dma_map_page(struct device *dev, struct page *page, unsigned long offset,
+ size_t size, enum dma_data_direction direction);
+
+static inline
+void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
+ enum dma_data_direction direction)
+{
+ BUG_ON(direction == DMA_NONE);
+}
+
+
+static inline
+void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
+ enum dma_data_direction direction)
+{
+}
+
+static inline
+void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size,
+ enum dma_data_direction direction)
+{
+ flush_write_buffers();
+}
+
+static inline
+void dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
+ unsigned long offset, size_t size,
+ enum dma_data_direction direction)
+{
+}
+
+static inline
+void dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
+ unsigned long offset, size_t size,
+ enum dma_data_direction direction)
+{
+ flush_write_buffers();
+}
+
+static inline
+void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
+ enum dma_data_direction direction)
+{
+}
+
+static inline
+void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
+ enum dma_data_direction direction)
+{
+ flush_write_buffers();
+}
+
+static inline
+int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
+{
+ return 0;
+}
+
+static inline
+int dma_supported(struct device *dev, u64 mask)
+{
+ /*
+ * we fall back to GFP_DMA when the mask isn't all 1s,
+ * so we can't guarantee allocations that must be
+ * within a tighter range than GFP_DMA..
+ */
+ if (mask < 0x00ffffff)
+ return 0;
+
+ return 1;
+}
+
+static inline
+int dma_set_mask(struct device *dev, u64 mask)
+{
+ if (!dev->dma_mask || !dma_supported(dev, mask))
+ return -EIO;
+
+ *dev->dma_mask = mask;
+
+ return 0;
+}
+
+static inline
+void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
+ enum dma_data_direction direction)
+{
+ flush_write_buffers();
+}
+
+/* Not supported for now */
+static inline int dma_mmap_coherent(struct device *dev,
+ struct vm_area_struct *vma, void *cpu_addr,
+ dma_addr_t dma_addr, size_t size)
+{
+ return -EINVAL;
+}
+
+static inline int dma_get_sgtable(struct device *dev, struct sg_table *sgt,
+ void *cpu_addr, dma_addr_t dma_addr,
+ size_t size)
+{
+ return -EINVAL;
+}
+
+#endif /* _ASM_DMA_MAPPING_H */
diff --git a/arch/frv/include/asm/dma.h b/arch/frv/include/asm/dma.h
new file mode 100644
index 00000000000..683c47d48a5
--- /dev/null
+++ b/arch/frv/include/asm/dma.h
@@ -0,0 +1,125 @@
+/* dma.h: FRV DMA controller management
+ *
+ * Copyright (C) 2004 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_DMA_H
+#define _ASM_DMA_H
+
+//#define DMA_DEBUG 1
+
+#include <linux/interrupt.h>
+
+#undef MAX_DMA_CHANNELS /* don't use kernel/dma.c */
+
+/* under 2.4 this is actually needed by the new bootmem allocator */
+#define MAX_DMA_ADDRESS PAGE_OFFSET
+
+/*
+ * FRV DMA controller management
+ */
+typedef irqreturn_t (*dma_irq_handler_t)(int dmachan, unsigned long cstr, void *data);
+
+extern void frv_dma_init(void);
+
+extern int frv_dma_open(const char *devname,
+ unsigned long dmamask,
+ int dmacap,
+ dma_irq_handler_t handler,
+ unsigned long irq_flags,
+ void *data);
+
+/* channels required */
+#define FRV_DMA_MASK_ANY ULONG_MAX /* any channel */
+
+/* capabilities required */
+#define FRV_DMA_CAP_DREQ 0x01 /* DMA request pin */
+#define FRV_DMA_CAP_DACK 0x02 /* DMA ACK pin */
+#define FRV_DMA_CAP_DONE 0x04 /* DMA done pin */
+
+extern void frv_dma_close(int dma);
+
+extern void frv_dma_config(int dma, unsigned long ccfr, unsigned long cctr, unsigned long apr);
+
+extern void frv_dma_start(int dma,
+ unsigned long sba, unsigned long dba,
+ unsigned long pix, unsigned long six, unsigned long bcl);
+
+extern void frv_dma_restart_circular(int dma, unsigned long six);
+
+extern void frv_dma_stop(int dma);
+
+extern int is_frv_dma_interrupting(int dma);
+
+extern void frv_dma_dump(int dma);
+
+extern void frv_dma_status_clear(int dma);
+
+#define FRV_DMA_NCHANS 8
+#define FRV_DMA_4CHANS 4
+#define FRV_DMA_8CHANS 8
+
+#define DMAC_CCFRx 0x00 /* channel configuration reg */
+#define DMAC_CCFRx_CM_SHIFT 16
+#define DMAC_CCFRx_CM_DA 0x00000000
+#define DMAC_CCFRx_CM_SCA 0x00010000
+#define DMAC_CCFRx_CM_DCA 0x00020000
+#define DMAC_CCFRx_CM_2D 0x00030000
+#define DMAC_CCFRx_ATS_SHIFT 8
+#define DMAC_CCFRx_RS_INTERN 0x00000000
+#define DMAC_CCFRx_RS_EXTERN 0x00000001
+#define DMAC_CCFRx_RS_SHIFT 0
+
+#define DMAC_CSTRx 0x08 /* channel status reg */
+#define DMAC_CSTRx_FS 0x0000003f
+#define DMAC_CSTRx_NE 0x00000100
+#define DMAC_CSTRx_FED 0x00000200
+#define DMAC_CSTRx_WER 0x00000800
+#define DMAC_CSTRx_RER 0x00001000
+#define DMAC_CSTRx_CE 0x00002000
+#define DMAC_CSTRx_INT 0x00800000
+#define DMAC_CSTRx_BUSY 0x80000000
+
+#define DMAC_CCTRx 0x10 /* channel control reg */
+#define DMAC_CCTRx_DSIZ_1 0x00000000
+#define DMAC_CCTRx_DSIZ_2 0x00000001
+#define DMAC_CCTRx_DSIZ_4 0x00000002
+#define DMAC_CCTRx_DSIZ_32 0x00000005
+#define DMAC_CCTRx_DAU_HOLD 0x00000000
+#define DMAC_CCTRx_DAU_INC 0x00000010
+#define DMAC_CCTRx_DAU_DEC 0x00000020
+#define DMAC_CCTRx_SSIZ_1 0x00000000
+#define DMAC_CCTRx_SSIZ_2 0x00000100
+#define DMAC_CCTRx_SSIZ_4 0x00000200
+#define DMAC_CCTRx_SSIZ_32 0x00000500
+#define DMAC_CCTRx_SAU_HOLD 0x00000000
+#define DMAC_CCTRx_SAU_INC 0x00001000
+#define DMAC_CCTRx_SAU_DEC 0x00002000
+#define DMAC_CCTRx_FC 0x08000000
+#define DMAC_CCTRx_ICE 0x10000000
+#define DMAC_CCTRx_IE 0x40000000
+#define DMAC_CCTRx_ACT 0x80000000
+
+#define DMAC_SBAx 0x18 /* source base address reg */
+#define DMAC_DBAx 0x20 /* data base address reg */
+#define DMAC_PIXx 0x28 /* primary index reg */
+#define DMAC_SIXx 0x30 /* secondary index reg */
+#define DMAC_BCLx 0x38 /* byte count limit reg */
+#define DMAC_APRx 0x40 /* alternate pointer reg */
+
+/*
+ * required for PCI + MODULES
+ */
+#ifdef CONFIG_PCI
+extern int isa_dma_bridge_buggy;
+#else
+#define isa_dma_bridge_buggy (0)
+#endif
+
+#endif /* _ASM_DMA_H */
diff --git a/arch/frv/include/asm/elf.h b/arch/frv/include/asm/elf.h
new file mode 100644
index 00000000000..2bac6446db4
--- /dev/null
+++ b/arch/frv/include/asm/elf.h
@@ -0,0 +1,140 @@
+/* elf.h: FR-V ELF definitions
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ * - Derived from include/asm-m68knommu/elf.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef __ASM_ELF_H
+#define __ASM_ELF_H
+
+#include <asm/ptrace.h>
+#include <asm/user.h>
+
+struct elf32_hdr;
+
+/*
+ * ELF header e_flags defines.
+ */
+#define EF_FRV_GPR_MASK 0x00000003 /* mask for # of gprs */
+#define EF_FRV_GPR32 0x00000001 /* Only uses GR on 32-register */
+#define EF_FRV_GPR64 0x00000002 /* Only uses GR on 64-register */
+#define EF_FRV_FPR_MASK 0x0000000c /* mask for # of fprs */
+#define EF_FRV_FPR32 0x00000004 /* Only uses FR on 32-register */
+#define EF_FRV_FPR64 0x00000008 /* Only uses FR on 64-register */
+#define EF_FRV_FPR_NONE 0x0000000C /* Uses software floating-point */
+#define EF_FRV_DWORD_MASK 0x00000030 /* mask for dword support */
+#define EF_FRV_DWORD_YES 0x00000010 /* Assumes stack aligned to 8-byte boundaries. */
+#define EF_FRV_DWORD_NO 0x00000020 /* Assumes stack aligned to 4-byte boundaries. */
+#define EF_FRV_DOUBLE 0x00000040 /* Uses double instructions. */
+#define EF_FRV_MEDIA 0x00000080 /* Uses media instructions. */
+#define EF_FRV_PIC 0x00000100 /* Uses position independent code. */
+#define EF_FRV_NON_PIC_RELOCS 0x00000200 /* Does not use position Independent code. */
+#define EF_FRV_MULADD 0x00000400 /* -mmuladd */
+#define EF_FRV_BIGPIC 0x00000800 /* -fPIC */
+#define EF_FRV_LIBPIC 0x00001000 /* -mlibrary-pic */
+#define EF_FRV_G0 0x00002000 /* -G 0, no small data ptr */
+#define EF_FRV_NOPACK 0x00004000 /* -mnopack */
+#define EF_FRV_FDPIC 0x00008000 /* -mfdpic */
+#define EF_FRV_CPU_MASK 0xff000000 /* specific cpu bits */
+#define EF_FRV_CPU_GENERIC 0x00000000 /* Set CPU type is FR-V */
+#define EF_FRV_CPU_FR500 0x01000000 /* Set CPU type is FR500 */
+#define EF_FRV_CPU_FR300 0x02000000 /* Set CPU type is FR300 */
+#define EF_FRV_CPU_SIMPLE 0x03000000 /* SIMPLE */
+#define EF_FRV_CPU_TOMCAT 0x04000000 /* Tomcat, FR500 prototype */
+#define EF_FRV_CPU_FR400 0x05000000 /* Set CPU type is FR400 */
+#define EF_FRV_CPU_FR550 0x06000000 /* Set CPU type is FR550 */
+#define EF_FRV_CPU_FR405 0x07000000 /* Set CPU type is FR405 */
+#define EF_FRV_CPU_FR450 0x08000000 /* Set CPU type is FR450 */
+
+/*
+ * FR-V ELF relocation types
+ */
+
+
+/*
+ * ELF register definitions..
+ */
+typedef unsigned long elf_greg_t;
+
+#define ELF_NGREG (sizeof(struct pt_regs) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef struct user_fpmedia_regs elf_fpregset_t;
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+extern int elf_check_arch(const struct elf32_hdr *hdr);
+
+#define elf_check_fdpic(x) ((x)->e_flags & EF_FRV_FDPIC && !((x)->e_flags & EF_FRV_NON_PIC_RELOCS))
+#define elf_check_const_displacement(x) ((x)->e_flags & EF_FRV_PIC)
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_CLASS ELFCLASS32
+#define ELF_DATA ELFDATA2MSB
+#define ELF_ARCH EM_FRV
+
+#define ELF_PLAT_INIT(_r) \
+do { \
+ __kernel_frame0_ptr->gr16 = 0; \
+ __kernel_frame0_ptr->gr17 = 0; \
+ __kernel_frame0_ptr->gr18 = 0; \
+ __kernel_frame0_ptr->gr19 = 0; \
+ __kernel_frame0_ptr->gr20 = 0; \
+ __kernel_frame0_ptr->gr21 = 0; \
+ __kernel_frame0_ptr->gr22 = 0; \
+ __kernel_frame0_ptr->gr23 = 0; \
+ __kernel_frame0_ptr->gr24 = 0; \
+ __kernel_frame0_ptr->gr25 = 0; \
+ __kernel_frame0_ptr->gr26 = 0; \
+ __kernel_frame0_ptr->gr27 = 0; \
+ __kernel_frame0_ptr->gr29 = 0; \
+} while(0)
+
+#define ELF_FDPIC_PLAT_INIT(_regs, _exec_map_addr, _interp_map_addr, _dynamic_addr) \
+do { \
+ __kernel_frame0_ptr->gr16 = _exec_map_addr; \
+ __kernel_frame0_ptr->gr17 = _interp_map_addr; \
+ __kernel_frame0_ptr->gr18 = _dynamic_addr; \
+ __kernel_frame0_ptr->gr19 = 0; \
+ __kernel_frame0_ptr->gr20 = 0; \
+ __kernel_frame0_ptr->gr21 = 0; \
+ __kernel_frame0_ptr->gr22 = 0; \
+ __kernel_frame0_ptr->gr23 = 0; \
+ __kernel_frame0_ptr->gr24 = 0; \
+ __kernel_frame0_ptr->gr25 = 0; \
+ __kernel_frame0_ptr->gr26 = 0; \
+ __kernel_frame0_ptr->gr27 = 0; \
+ __kernel_frame0_ptr->gr29 = 0; \
+} while(0)
+
+#define CORE_DUMP_USE_REGSET
+#define ELF_FDPIC_CORE_EFLAGS EF_FRV_FDPIC
+#define ELF_EXEC_PAGESIZE 16384
+
+/* 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 0x08000000UL
+
+/* This yields a mask that user programs can use to figure out what
+ instruction set this cpu supports. */
+
+#define ELF_HWCAP (0)
+
+/* 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. */
+
+#define ELF_PLATFORM (NULL)
+
+#endif
diff --git a/arch/frv/include/asm/emergency-restart.h b/arch/frv/include/asm/emergency-restart.h
new file mode 100644
index 00000000000..108d8c48e42
--- /dev/null
+++ b/arch/frv/include/asm/emergency-restart.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_EMERGENCY_RESTART_H
+#define _ASM_EMERGENCY_RESTART_H
+
+#include <asm-generic/emergency-restart.h>
+
+#endif /* _ASM_EMERGENCY_RESTART_H */
diff --git a/arch/frv/include/asm/fb.h b/arch/frv/include/asm/fb.h
new file mode 100644
index 00000000000..c7df3803099
--- /dev/null
+++ b/arch/frv/include/asm/fb.h
@@ -0,0 +1,12 @@
+#ifndef _ASM_FB_H_
+#define _ASM_FB_H_
+#include <linux/fb.h>
+
+#define fb_pgprotect(...) do {} while (0)
+
+static inline int fb_is_primary_device(struct fb_info *info)
+{
+ return 0;
+}
+
+#endif /* _ASM_FB_H_ */
diff --git a/arch/frv/include/asm/fpu.h b/arch/frv/include/asm/fpu.h
new file mode 100644
index 00000000000..d73c60b5664
--- /dev/null
+++ b/arch/frv/include/asm/fpu.h
@@ -0,0 +1,11 @@
+#ifndef __ASM_FPU_H
+#define __ASM_FPU_H
+
+
+/*
+ * MAX floating point unit state size (FSAVE/FRESTORE)
+ */
+
+#define kernel_fpu_end() do { asm volatile("bar":::"memory"); preempt_enable(); } while(0)
+
+#endif /* __ASM_FPU_H */
diff --git a/arch/frv/include/asm/ftrace.h b/arch/frv/include/asm/ftrace.h
new file mode 100644
index 00000000000..40a8c178f10
--- /dev/null
+++ b/arch/frv/include/asm/ftrace.h
@@ -0,0 +1 @@
+/* empty */
diff --git a/arch/frv/include/asm/futex.h b/arch/frv/include/asm/futex.h
new file mode 100644
index 00000000000..4bea27f50a7
--- /dev/null
+++ b/arch/frv/include/asm/futex.h
@@ -0,0 +1,20 @@
+#ifndef _ASM_FUTEX_H
+#define _ASM_FUTEX_H
+
+#ifdef __KERNEL__
+
+#include <linux/futex.h>
+#include <asm/errno.h>
+#include <asm/uaccess.h>
+
+extern int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr);
+
+static inline int
+futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
+ u32 oldval, u32 newval)
+{
+ return -ENOSYS;
+}
+
+#endif
+#endif
diff --git a/arch/frv/include/asm/gdb-stub.h b/arch/frv/include/asm/gdb-stub.h
new file mode 100644
index 00000000000..e6bedd0cd9a
--- /dev/null
+++ b/arch/frv/include/asm/gdb-stub.h
@@ -0,0 +1,146 @@
+/* gdb-stub.h: FRV GDB stub
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ * - Derived from asm-mips/gdb-stub.h (c) 1995 Andreas Busse
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef __ASM_GDB_STUB_H
+#define __ASM_GDB_STUB_H
+
+#undef GDBSTUB_DEBUG_IO
+#undef GDBSTUB_DEBUG_PROTOCOL
+
+#include <asm/ptrace.h>
+
+/*
+ * important register numbers in GDB protocol
+ * - GR0, GR1, GR2, GR3, GR4, GR5, GR6, GR7,
+ * - GR8, GR9, GR10, GR11, GR12, GR13, GR14, GR15,
+ * - GR16, GR17, GR18, GR19, GR20, GR21, GR22, GR23,
+ * - GR24, GR25, GR26, GR27, GR28, GR29, GR30, GR31,
+ * - GR32, GR33, GR34, GR35, GR36, GR37, GR38, GR39,
+ * - GR40, GR41, GR42, GR43, GR44, GR45, GR46, GR47,
+ * - GR48, GR49, GR50, GR51, GR52, GR53, GR54, GR55,
+ * - GR56, GR57, GR58, GR59, GR60, GR61, GR62, GR63,
+ * - FR0, FR1, FR2, FR3, FR4, FR5, FR6, FR7,
+ * - FR8, FR9, FR10, FR11, FR12, FR13, FR14, FR15,
+ * - FR16, FR17, FR18, FR19, FR20, FR21, FR22, FR23,
+ * - FR24, FR25, FR26, FR27, FR28, FR29, FR30, FR31,
+ * - FR32, FR33, FR34, FR35, FR36, FR37, FR38, FR39,
+ * - FR40, FR41, FR42, FR43, FR44, FR45, FR46, FR47,
+ * - FR48, FR49, FR50, FR51, FR52, FR53, FR54, FR55,
+ * - FR56, FR57, FR58, FR59, FR60, FR61, FR62, FR63,
+ * - PC, PSR, CCR, CCCR,
+ * - _X132, _X133, _X134
+ * - TBR, BRR, DBAR0, DBAR1, DBAR2, DBAR3,
+ * - SCR0, SCR1, SCR2, SCR3,
+ * - LR, LCR,
+ * - IACC0H, IACC0L,
+ * - FSR0,
+ * - ACC0, ACC1, ACC2, ACC3, ACC4, ACC5, ACC6, ACC7,
+ * - ACCG0123, ACCG4567,
+ * - MSR0, MSR1,
+ * - GNER0, GNER1,
+ * - FNER0, FNER1,
+ */
+#define GDB_REG_GR(N) (N)
+#define GDB_REG_FR(N) (64+(N))
+#define GDB_REG_PC 128
+#define GDB_REG_PSR 129
+#define GDB_REG_CCR 130
+#define GDB_REG_CCCR 131
+#define GDB_REG_TBR 135
+#define GDB_REG_BRR 136
+#define GDB_REG_DBAR(N) (137+(N))
+#define GDB_REG_SCR(N) (141+(N))
+#define GDB_REG_LR 145
+#define GDB_REG_LCR 146
+#define GDB_REG_FSR0 149
+#define GDB_REG_ACC(N) (150+(N))
+#define GDB_REG_ACCG(N) (158+(N)/4)
+#define GDB_REG_MSR(N) (160+(N))
+#define GDB_REG_GNER(N) (162+(N))
+#define GDB_REG_FNER(N) (164+(N))
+
+#define GDB_REG_SP GDB_REG_GR(1)
+#define GDB_REG_FP GDB_REG_GR(2)
+
+#ifndef _LANGUAGE_ASSEMBLY
+
+/*
+ * Prototypes
+ */
+extern void show_registers_only(struct pt_regs *regs);
+
+extern void gdbstub_init(void);
+extern void gdbstub(int type);
+extern void gdbstub_exit(int status);
+
+extern void gdbstub_io_init(void);
+extern void gdbstub_set_baud(unsigned baud);
+extern int gdbstub_rx_char(unsigned char *_ch, int nonblock);
+extern void gdbstub_tx_char(unsigned char ch);
+extern void gdbstub_tx_flush(void);
+extern void gdbstub_do_rx(void);
+
+extern asmlinkage void __debug_stub_init_break(void);
+extern asmlinkage void __break_hijack_kernel_event(void);
+extern asmlinkage void __break_hijack_kernel_event_breaks_here(void);
+
+extern asmlinkage void gdbstub_rx_handler(void);
+extern asmlinkage void gdbstub_rx_irq(void);
+extern asmlinkage void gdbstub_intercept(void);
+
+extern uint32_t __entry_usertrap_table[];
+extern uint32_t __entry_kerneltrap_table[];
+
+extern volatile u8 gdbstub_rx_buffer[PAGE_SIZE];
+extern volatile u32 gdbstub_rx_inp;
+extern volatile u32 gdbstub_rx_outp;
+extern volatile u8 gdbstub_rx_overflow;
+extern u8 gdbstub_rx_unget;
+
+extern void gdbstub_printk(const char *fmt, ...);
+extern void debug_to_serial(const char *p, int n);
+extern void console_set_baud(unsigned baud);
+
+#ifdef GDBSTUB_DEBUG_IO
+#define gdbstub_io(FMT,...) gdbstub_printk(FMT, ##__VA_ARGS__)
+#else
+#define gdbstub_io(FMT,...) ({ 0; })
+#endif
+
+#ifdef GDBSTUB_DEBUG_PROTOCOL
+#define gdbstub_proto(FMT,...) gdbstub_printk(FMT,##__VA_ARGS__)
+#else
+#define gdbstub_proto(FMT,...) ({ 0; })
+#endif
+
+/*
+ * we dedicate GR31 to keeping a pointer to the gdbstub exception frame
+ * - gr31 is destroyed on entry to the gdbstub if !MMU
+ * - gr31 is saved in scr3 on entry to the gdbstub if in !MMU
+ */
+register struct frv_frame0 *__debug_frame0 asm("gr31");
+
+#define __debug_frame (&__debug_frame0->regs)
+#define __debug_user_context (&__debug_frame0->uc)
+#define __debug_regs (&__debug_frame0->debug)
+#define __debug_reg(X) ((unsigned long *) ((unsigned long) &__debug_frame0 + (X)))
+
+struct frv_debug_status {
+ unsigned long bpsr;
+ unsigned long dcr;
+ unsigned long brr;
+ unsigned long nmar;
+};
+
+extern struct frv_debug_status __debug_status;
+
+#endif /* _LANGUAGE_ASSEMBLY */
+#endif /* __ASM_GDB_STUB_H */
diff --git a/arch/frv/include/asm/gpio-regs.h b/arch/frv/include/asm/gpio-regs.h
new file mode 100644
index 00000000000..9edf5d5d4d3
--- /dev/null
+++ b/arch/frv/include/asm/gpio-regs.h
@@ -0,0 +1,116 @@
+/* gpio-regs.h: on-chip general purpose I/O registers
+ *
+ * Copyright (C) 2003 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_GPIO_REGS
+#define _ASM_GPIO_REGS
+
+#define __reg(ADDR) (*(volatile unsigned long *)(ADDR))
+
+#define __get_PDR() ({ __reg(0xfeff0400); })
+#define __set_PDR(V) do { __reg(0xfeff0400) = (V); mb(); } while(0)
+
+#define __get_GPDR() ({ __reg(0xfeff0408); })
+#define __set_GPDR(V) do { __reg(0xfeff0408) = (V); mb(); } while(0)
+
+#define __get_SIR() ({ __reg(0xfeff0410); })
+#define __set_SIR(V) do { __reg(0xfeff0410) = (V); mb(); } while(0)
+
+#define __get_SOR() ({ __reg(0xfeff0418); })
+#define __set_SOR(V) do { __reg(0xfeff0418) = (V); mb(); } while(0)
+
+#define __set_PDSR(V) do { __reg(0xfeff0420) = (V); mb(); } while(0)
+
+#define __set_PDCR(V) do { __reg(0xfeff0428) = (V); mb(); } while(0)
+
+#define __get_RSTR() ({ __reg(0xfeff0500); })
+#define __set_RSTR(V) do { __reg(0xfeff0500) = (V); mb(); } while(0)
+
+
+
+/* PDR definitions */
+#define PDR_GPIO_DATA(X) (1 << (X))
+
+/* GPDR definitions */
+#define GPDR_INPUT 0
+#define GPDR_OUTPUT 1
+#define GPDR_DREQ0_BIT 0x00001000
+#define GPDR_DREQ1_BIT 0x00008000
+#define GPDR_DREQ2_BIT 0x00040000
+#define GPDR_DREQ3_BIT 0x00080000
+#define GPDR_DREQ4_BIT 0x00004000
+#define GPDR_DREQ5_BIT 0x00020000
+#define GPDR_DREQ6_BIT 0x00100000
+#define GPDR_DREQ7_BIT 0x00200000
+#define GPDR_DACK0_BIT 0x00002000
+#define GPDR_DACK1_BIT 0x00010000
+#define GPDR_DACK2_BIT 0x00100000
+#define GPDR_DACK3_BIT 0x00200000
+#define GPDR_DONE0_BIT 0x00004000
+#define GPDR_DONE1_BIT 0x00020000
+#define GPDR_GPIO_DIR(X,D) ((D) << (X))
+
+/* SIR definitions */
+#define SIR_GPIO_INPUT 0
+#define SIR_DREQ7_INPUT 0x00200000
+#define SIR_DREQ6_INPUT 0x00100000
+#define SIR_DREQ3_INPUT 0x00080000
+#define SIR_DREQ2_INPUT 0x00040000
+#define SIR_DREQ5_INPUT 0x00020000
+#define SIR_DREQ1_INPUT 0x00008000
+#define SIR_DREQ4_INPUT 0x00004000
+#define SIR_DREQ0_INPUT 0x00001000
+#define SIR_RXD1_INPUT 0x00000400
+#define SIR_CTS0_INPUT 0x00000100
+#define SIR_RXD0_INPUT 0x00000040
+#define SIR_GATE1_INPUT 0x00000020
+#define SIR_GATE0_INPUT 0x00000010
+#define SIR_IRQ3_INPUT 0x00000008
+#define SIR_IRQ2_INPUT 0x00000004
+#define SIR_IRQ1_INPUT 0x00000002
+#define SIR_IRQ0_INPUT 0x00000001
+#define SIR_DREQ_BITS (SIR_DREQ0_INPUT | SIR_DREQ1_INPUT | \
+ SIR_DREQ2_INPUT | SIR_DREQ3_INPUT | \
+ SIR_DREQ4_INPUT | SIR_DREQ5_INPUT | \
+ SIR_DREQ6_INPUT | SIR_DREQ7_INPUT)
+
+/* SOR definitions */
+#define SOR_GPIO_OUTPUT 0
+#define SOR_DACK3_OUTPUT 0x00200000
+#define SOR_DACK2_OUTPUT 0x00100000
+#define SOR_DONE1_OUTPUT 0x00020000
+#define SOR_DACK1_OUTPUT 0x00010000
+#define SOR_DONE0_OUTPUT 0x00004000
+#define SOR_DACK0_OUTPUT 0x00002000
+#define SOR_TXD1_OUTPUT 0x00000800
+#define SOR_RTS0_OUTPUT 0x00000200
+#define SOR_TXD0_OUTPUT 0x00000080
+#define SOR_TOUT1_OUTPUT 0x00000020
+#define SOR_TOUT0_OUTPUT 0x00000010
+#define SOR_DONE_BITS (SOR_DONE0_OUTPUT | SOR_DONE1_OUTPUT)
+#define SOR_DACK_BITS (SOR_DACK0_OUTPUT | SOR_DACK1_OUTPUT | \
+ SOR_DACK2_OUTPUT | SOR_DACK3_OUTPUT)
+
+/* PDSR definitions */
+#define PDSR_UNCHANGED 0
+#define PDSR_SET_BIT(X) (1 << (X))
+
+/* PDCR definitions */
+#define PDCR_UNCHANGED 0
+#define PDCR_CLEAR_BIT(X) (1 << (X))
+
+/* RSTR definitions */
+/* Read Only */
+#define RSTR_POWERON 0x00000400
+#define RSTR_SOFTRESET_STATUS 0x00000100
+/* Write Only */
+#define RSTR_SOFTRESET 0x00000001
+
+#endif /* _ASM_GPIO_REGS */
diff --git a/arch/frv/include/asm/hardirq.h b/arch/frv/include/asm/hardirq.h
new file mode 100644
index 00000000000..c62833d6ebb
--- /dev/null
+++ b/arch/frv/include/asm/hardirq.h
@@ -0,0 +1,26 @@
+/* hardirq.h: FRV hardware IRQ management
+ *
+ * Copyright (C) 2004 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef __ASM_HARDIRQ_H
+#define __ASM_HARDIRQ_H
+
+#include <linux/atomic.h>
+
+extern atomic_t irq_err_count;
+static inline void ack_bad_irq(int irq)
+{
+ atomic_inc(&irq_err_count);
+}
+#define ack_bad_irq ack_bad_irq
+
+#include <asm-generic/hardirq.h>
+
+#endif
diff --git a/arch/frv/include/asm/highmem.h b/arch/frv/include/asm/highmem.h
new file mode 100644
index 00000000000..b3adc93611f
--- /dev/null
+++ b/arch/frv/include/asm/highmem.h
@@ -0,0 +1,151 @@
+/* highmem.h: virtual kernel memory mappings for high memory
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ * - Derived from include/asm-i386/highmem.h
+ *
+ * See Documentation/frv/mmu-layout.txt for more information.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_HIGHMEM_H
+#define _ASM_HIGHMEM_H
+
+#ifdef __KERNEL__
+
+#include <linux/init.h>
+#include <linux/highmem.h>
+#include <asm/mem-layout.h>
+#include <asm/spr-regs.h>
+#include <asm/mb-regs.h>
+
+#define NR_TLB_LINES 64 /* number of lines in the TLB */
+
+#ifndef __ASSEMBLY__
+
+#include <linux/interrupt.h>
+#include <asm/kmap_types.h>
+#include <asm/pgtable.h>
+
+#ifdef CONFIG_DEBUG_HIGHMEM
+#define HIGHMEM_DEBUG 1
+#else
+#define HIGHMEM_DEBUG 0
+#endif
+
+/* declarations for highmem.c */
+extern unsigned long highstart_pfn, highend_pfn;
+
+#define kmap_prot PAGE_KERNEL
+#define kmap_pte ______kmap_pte_in_TLB
+extern pte_t *pkmap_page_table;
+
+#define flush_cache_kmaps() do { } while (0)
+
+/*
+ * Right now we initialize only a single pte table. It can be extended
+ * easily, subsequent pte tables have to be allocated in one physical
+ * chunk of RAM.
+ */
+#define 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))
+
+extern void *kmap_high(struct page *page);
+extern void kunmap_high(struct page *page);
+
+extern void *kmap(struct page *page);
+extern void kunmap(struct page *page);
+
+extern struct page *kmap_atomic_to_page(void *ptr);
+
+#endif /* !__ASSEMBLY__ */
+
+/*
+ * The use of kmap_atomic/kunmap_atomic is discouraged - kmap/kunmap
+ * gives a more generic (and caching) interface. But kmap_atomic can
+ * be used in IRQ contexts, so in some (very limited) cases we need
+ * it.
+ */
+#define KMAP_ATOMIC_CACHE_DAMR 8
+
+#ifndef __ASSEMBLY__
+
+#define __kmap_atomic_primary(cached, paddr, ampr) \
+({ \
+ unsigned long damlr, dampr; \
+ \
+ dampr = paddr | xAMPRx_L | xAMPRx_M | xAMPRx_S | xAMPRx_SS_16Kb | xAMPRx_V; \
+ \
+ if (!cached) \
+ asm volatile("movgs %0,dampr"#ampr :: "r"(dampr) : "memory"); \
+ else \
+ /* cache flush page attachment point */ \
+ asm volatile("movgs %0,iampr"#ampr"\n" \
+ "movgs %0,dampr"#ampr"\n" \
+ :: "r"(dampr) : "memory" \
+ ); \
+ \
+ asm("movsg damlr"#ampr",%0" : "=r"(damlr)); \
+ \
+ /*printk("DAMR"#ampr": PRIM sl=%d L=%08lx P=%08lx\n", type, damlr, dampr);*/ \
+ \
+ (void *) damlr; \
+})
+
+#define __kmap_atomic_secondary(slot, paddr) \
+({ \
+ unsigned long damlr = KMAP_ATOMIC_SECONDARY_FRAME + (slot) * PAGE_SIZE; \
+ unsigned long dampr = paddr | xAMPRx_L | xAMPRx_M | xAMPRx_S | xAMPRx_SS_16Kb | xAMPRx_V; \
+ \
+ asm volatile("movgs %0,tplr \n" \
+ "movgs %1,tppr \n" \
+ "tlbpr %0,gr0,#2,#1" \
+ : : "r"(damlr), "r"(dampr) : "memory"); \
+ \
+ /*printk("TLB: SECN sl=%d L=%08lx P=%08lx\n", slot, damlr, dampr);*/ \
+ \
+ (void *) damlr; \
+})
+
+static inline void *kmap_atomic_primary(struct page *page)
+{
+ unsigned long paddr;
+
+ pagefault_disable();
+ paddr = page_to_phys(page);
+
+ return __kmap_atomic_primary(1, paddr, 2);
+}
+
+#define __kunmap_atomic_primary(cached, ampr) \
+do { \
+ asm volatile("movgs gr0,dampr"#ampr"\n" ::: "memory"); \
+ if (cached) \
+ asm volatile("movgs gr0,iampr"#ampr"\n" ::: "memory"); \
+} while(0)
+
+#define __kunmap_atomic_secondary(slot, vaddr) \
+do { \
+ asm volatile("tlbpr %0,gr0,#4,#1" : : "r"(vaddr) : "memory"); \
+} while(0)
+
+static inline void kunmap_atomic_primary(void *kvaddr)
+{
+ __kunmap_atomic_primary(1, 2);
+ pagefault_enable();
+}
+
+void *kmap_atomic(struct page *page);
+void __kunmap_atomic(void *kvaddr);
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_HIGHMEM_H */
diff --git a/arch/frv/include/asm/hw_irq.h b/arch/frv/include/asm/hw_irq.h
new file mode 100644
index 00000000000..522ad37923d
--- /dev/null
+++ b/arch/frv/include/asm/hw_irq.h
@@ -0,0 +1,16 @@
+/* hw_irq.h: FR-V specific h/w IRQ stuff
+ *
+ * Copyright (C) 2003 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_HW_IRQ_H
+#define _ASM_HW_IRQ_H
+
+
+#endif /* _ASM_HW_IRQ_H */
diff --git a/arch/frv/include/asm/io.h b/arch/frv/include/asm/io.h
new file mode 100644
index 00000000000..8cb50a2fbcb
--- /dev/null
+++ b/arch/frv/include/asm/io.h
@@ -0,0 +1,392 @@
+/* io.h: FRV I/O operations
+ *
+ * Copyright (C) 2004 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * This gets interesting when talking to the PCI bus - the CPU is in big endian
+ * mode, the PCI bus is little endian and the hardware in the middle can do
+ * byte swapping
+ */
+#ifndef _ASM_IO_H
+#define _ASM_IO_H
+
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+#include <asm/virtconvert.h>
+#include <asm/string.h>
+#include <asm/mb-regs.h>
+#include <asm-generic/pci_iomap.h>
+#include <linux/delay.h>
+
+/*
+ * swap functions are sometimes needed to interface little-endian hardware
+ */
+
+static inline unsigned short _swapw(unsigned short v)
+{
+ return ((v << 8) | (v >> 8));
+}
+
+static inline unsigned long _swapl(unsigned long v)
+{
+ return ((v << 24) | ((v & 0xff00) << 8) | ((v & 0xff0000) >> 8) | (v >> 24));
+}
+
+//#define __iormb() asm volatile("membar")
+//#define __iowmb() asm volatile("membar")
+
+#define __raw_readb __builtin_read8
+#define __raw_readw __builtin_read16
+#define __raw_readl __builtin_read32
+
+#define __raw_writeb(datum, addr) __builtin_write8(addr, datum)
+#define __raw_writew(datum, addr) __builtin_write16(addr, datum)
+#define __raw_writel(datum, addr) __builtin_write32(addr, datum)
+
+static inline void io_outsb(unsigned int addr, const void *buf, int len)
+{
+ unsigned long __ioaddr = (unsigned long) addr;
+ const uint8_t *bp = buf;
+
+ while (len--)
+ __builtin_write8((volatile void __iomem *) __ioaddr, *bp++);
+}
+
+static inline void io_outsw(unsigned int addr, const void *buf, int len)
+{
+ unsigned long __ioaddr = (unsigned long) addr;
+ const uint16_t *bp = buf;
+
+ while (len--)
+ __builtin_write16((volatile void __iomem *) __ioaddr, (*bp++));
+}
+
+extern void __outsl_ns(unsigned int addr, const void *buf, int len);
+extern void __outsl_sw(unsigned int addr, const void *buf, int len);
+static inline void __outsl(unsigned int addr, const void *buf, int len, int swap)
+{
+ unsigned long __ioaddr = (unsigned long) addr;
+
+ if (!swap)
+ __outsl_ns(__ioaddr, buf, len);
+ else
+ __outsl_sw(__ioaddr, buf, len);
+}
+
+static inline void io_insb(unsigned long addr, void *buf, int len)
+{
+ uint8_t *bp = buf;
+
+ while (len--)
+ *bp++ = __builtin_read8((volatile void __iomem *) addr);
+}
+
+static inline void io_insw(unsigned long addr, void *buf, int len)
+{
+ uint16_t *bp = buf;
+
+ while (len--)
+ *bp++ = __builtin_read16((volatile void __iomem *) addr);
+}
+
+extern void __insl_ns(unsigned long addr, void *buf, int len);
+extern void __insl_sw(unsigned long addr, void *buf, int len);
+static inline void __insl(unsigned long addr, void *buf, int len, int swap)
+{
+ if (!swap)
+ __insl_ns(addr, buf, len);
+ else
+ __insl_sw(addr, buf, len);
+}
+
+#define mmiowb() mb()
+
+/*
+ * make the short names macros so specific devices
+ * can override them as required
+ */
+
+static inline void memset_io(volatile void __iomem *addr, unsigned char val, int count)
+{
+ memset((void __force *) addr, val, count);
+}
+
+static inline void memcpy_fromio(void *dst, const volatile void __iomem *src, int count)
+{
+ memcpy(dst, (void __force *) src, count);
+}
+
+static inline void memcpy_toio(volatile void __iomem *dst, const void *src, int count)
+{
+ memcpy((void __force *) dst, src, count);
+}
+
+static inline uint8_t inb(unsigned long addr)
+{
+ return __builtin_read8((void __iomem *)addr);
+}
+
+static inline uint16_t inw(unsigned long addr)
+{
+ uint16_t ret = __builtin_read16((void __iomem *)addr);
+
+ if (__is_PCI_IO(addr))
+ ret = _swapw(ret);
+
+ return ret;
+}
+
+static inline uint32_t inl(unsigned long addr)
+{
+ uint32_t ret = __builtin_read32((void __iomem *)addr);
+
+ if (__is_PCI_IO(addr))
+ ret = _swapl(ret);
+
+ return ret;
+}
+
+static inline void outb(uint8_t datum, unsigned long addr)
+{
+ __builtin_write8((void __iomem *)addr, datum);
+}
+
+static inline void outw(uint16_t datum, unsigned long addr)
+{
+ if (__is_PCI_IO(addr))
+ datum = _swapw(datum);
+ __builtin_write16((void __iomem *)addr, datum);
+}
+
+static inline void outl(uint32_t datum, unsigned long addr)
+{
+ if (__is_PCI_IO(addr))
+ datum = _swapl(datum);
+ __builtin_write32((void __iomem *)addr, datum);
+}
+
+#define inb_p(addr) inb(addr)
+#define inw_p(addr) inw(addr)
+#define inl_p(addr) inl(addr)
+#define outb_p(x,addr) outb(x,addr)
+#define outw_p(x,addr) outw(x,addr)
+#define outl_p(x,addr) outl(x,addr)
+
+#define outsb(a,b,l) io_outsb(a,b,l)
+#define outsw(a,b,l) io_outsw(a,b,l)
+#define outsl(a,b,l) __outsl(a,b,l,0)
+
+#define insb(a,b,l) io_insb(a,b,l)
+#define insw(a,b,l) io_insw(a,b,l)
+#define insl(a,b,l) __insl(a,b,l,0)
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+static inline uint8_t readb(const volatile void __iomem *addr)
+{
+ return __builtin_read8((__force void volatile __iomem *) addr);
+}
+
+static inline uint16_t readw(const volatile void __iomem *addr)
+{
+ uint16_t ret = __builtin_read16((__force void volatile __iomem *)addr);
+
+ if (__is_PCI_MEM(addr))
+ ret = _swapw(ret);
+ return ret;
+}
+
+static inline uint32_t readl(const volatile void __iomem *addr)
+{
+ uint32_t ret = __builtin_read32((__force void volatile __iomem *)addr);
+
+ if (__is_PCI_MEM(addr))
+ ret = _swapl(ret);
+
+ return ret;
+}
+
+#define readb_relaxed readb
+#define readw_relaxed readw
+#define readl_relaxed readl
+
+static inline void writeb(uint8_t datum, volatile void __iomem *addr)
+{
+ __builtin_write8(addr, datum);
+ if (__is_PCI_MEM(addr))
+ __flush_PCI_writes();
+}
+
+static inline void writew(uint16_t datum, volatile void __iomem *addr)
+{
+ if (__is_PCI_MEM(addr))
+ datum = _swapw(datum);
+
+ __builtin_write16(addr, datum);
+ if (__is_PCI_MEM(addr))
+ __flush_PCI_writes();
+}
+
+static inline void writel(uint32_t datum, volatile void __iomem *addr)
+{
+ if (__is_PCI_MEM(addr))
+ datum = _swapl(datum);
+
+ __builtin_write32(addr, datum);
+ if (__is_PCI_MEM(addr))
+ __flush_PCI_writes();
+}
+
+
+/* Values for nocacheflag and cmode */
+#define IOMAP_FULL_CACHING 0
+#define IOMAP_NOCACHE_SER 1
+#define IOMAP_NOCACHE_NONSER 2
+#define IOMAP_WRITETHROUGH 3
+
+extern void __iomem *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag);
+
+static inline void __iomem *ioremap(unsigned long physaddr, unsigned long size)
+{
+ return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
+}
+
+static inline void __iomem *ioremap_nocache(unsigned long physaddr, unsigned long size)
+{
+ return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
+}
+
+static inline void __iomem *ioremap_writethrough(unsigned long physaddr, unsigned long size)
+{
+ return __ioremap(physaddr, size, IOMAP_WRITETHROUGH);
+}
+
+static inline void __iomem *ioremap_fullcache(unsigned long physaddr, unsigned long size)
+{
+ return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
+}
+
+#define ioremap_wc ioremap_nocache
+
+extern void iounmap(void volatile __iomem *addr);
+
+static inline void __iomem *ioport_map(unsigned long port, unsigned int nr)
+{
+ return (void __iomem *) port;
+}
+
+static inline void ioport_unmap(void __iomem *p)
+{
+}
+
+static inline void flush_write_buffers(void)
+{
+ __asm__ __volatile__ ("membar" : : :"memory");
+}
+
+/*
+ * do appropriate I/O accesses for token type
+ */
+static inline unsigned int ioread8(void __iomem *p)
+{
+ return __builtin_read8(p);
+}
+
+static inline unsigned int ioread16(void __iomem *p)
+{
+ uint16_t ret = __builtin_read16(p);
+ if (__is_PCI_addr(p))
+ ret = _swapw(ret);
+ return ret;
+}
+
+static inline unsigned int ioread32(void __iomem *p)
+{
+ uint32_t ret = __builtin_read32(p);
+ if (__is_PCI_addr(p))
+ ret = _swapl(ret);
+ return ret;
+}
+
+static inline void iowrite8(u8 val, void __iomem *p)
+{
+ __builtin_write8(p, val);
+ if (__is_PCI_MEM(p))
+ __flush_PCI_writes();
+}
+
+static inline void iowrite16(u16 val, void __iomem *p)
+{
+ if (__is_PCI_addr(p))
+ val = _swapw(val);
+ __builtin_write16(p, val);
+ if (__is_PCI_MEM(p))
+ __flush_PCI_writes();
+}
+
+static inline void iowrite32(u32 val, void __iomem *p)
+{
+ if (__is_PCI_addr(p))
+ val = _swapl(val);
+ __builtin_write32(p, val);
+ if (__is_PCI_MEM(p))
+ __flush_PCI_writes();
+}
+
+static inline void ioread8_rep(void __iomem *p, void *dst, unsigned long count)
+{
+ io_insb((unsigned long) p, dst, count);
+}
+
+static inline void ioread16_rep(void __iomem *p, void *dst, unsigned long count)
+{
+ io_insw((unsigned long) p, dst, count);
+}
+
+static inline void ioread32_rep(void __iomem *p, void *dst, unsigned long count)
+{
+ __insl_ns((unsigned long) p, dst, count);
+}
+
+static inline void iowrite8_rep(void __iomem *p, const void *src, unsigned long count)
+{
+ io_outsb((unsigned long) p, src, count);
+}
+
+static inline void iowrite16_rep(void __iomem *p, const void *src, unsigned long count)
+{
+ io_outsw((unsigned long) p, src, count);
+}
+
+static inline void iowrite32_rep(void __iomem *p, const void *src, unsigned long count)
+{
+ __outsl_ns((unsigned long) p, src, count);
+}
+
+/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
+struct pci_dev;
+static inline void pci_iounmap(struct pci_dev *dev, void __iomem *p)
+{
+}
+
+
+/*
+ * 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
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_IO_H */
diff --git a/arch/frv/include/asm/irc-regs.h b/arch/frv/include/asm/irc-regs.h
new file mode 100644
index 00000000000..afa30aeacc8
--- /dev/null
+++ b/arch/frv/include/asm/irc-regs.h
@@ -0,0 +1,53 @@
+/* irc-regs.h: on-chip interrupt controller registers
+ *
+ * Copyright (C) 2003 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_IRC_REGS
+#define _ASM_IRC_REGS
+
+#define __reg(ADDR) (*(volatile unsigned long *)(ADDR))
+
+#define __get_TM0() ({ __reg(0xfeff9800); })
+#define __get_TM1() ({ __reg(0xfeff9808); })
+#define __set_TM1(V) do { __reg(0xfeff9808) = (V); mb(); } while(0)
+
+#define __set_TM1x(XI,V) \
+do { \
+ int shift = (XI) * 2 + 16; \
+ unsigned long tm1 = __reg(0xfeff9808); \
+ tm1 &= ~(0x3 << shift); \
+ tm1 |= (V) << shift; \
+ __reg(0xfeff9808) = tm1; \
+ mb(); \
+} while(0)
+
+#define __get_RS(C) ({ (__reg(0xfeff9810) >> ((C)+16)) & 1; })
+
+#define __clr_RC(C) do { __reg(0xfeff9818) = 1 << ((C)+16); mb(); } while(0)
+
+#define __get_MASK(C) ({ (__reg(0xfeff9820) >> ((C)+16)) & 1; })
+#define __set_MASK(C) do { __reg(0xfeff9820) |= 1 << ((C)+16); mb(); } while(0)
+#define __clr_MASK(C) do { __reg(0xfeff9820) &= ~(1 << ((C)+16)); mb(); } while(0)
+
+#define __get_MASK_all() __get_MASK(0)
+#define __set_MASK_all() __set_MASK(0)
+#define __clr_MASK_all() __clr_MASK(0)
+
+#define __get_IRL() ({ (__reg(0xfeff9828) >> 16) & 0xf; })
+#define __clr_IRL() do { __reg(0xfeff9828) = 0x100000; mb(); } while(0)
+
+#define __get_IRR(N) ({ __reg(0xfeff9840 + (N) * 8); })
+#define __set_IRR(N,V) do { __reg(0xfeff9840 + (N) * 8) = (V); } while(0)
+
+#define __get_IITMR(N) ({ __reg(0xfeff9880 + (N) * 8); })
+#define __set_IITMR(N,V) do { __reg(0xfeff9880 + (N) * 8) = (V); } while(0)
+
+
+#endif /* _ASM_IRC_REGS */
diff --git a/arch/frv/include/asm/irq.h b/arch/frv/include/asm/irq.h
new file mode 100644
index 00000000000..3a66ebd754b
--- /dev/null
+++ b/arch/frv/include/asm/irq.h
@@ -0,0 +1,30 @@
+/* irq.h: FRV IRQ definitions
+ *
+ * Copyright (C) 2006 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_IRQ_H_
+#define _ASM_IRQ_H_
+
+#define NR_IRQS 48
+#define IRQ_BASE_CPU (0 * 16)
+#define IRQ_BASE_FPGA (1 * 16)
+#define IRQ_BASE_MB93493 (2 * 16)
+
+/* probe returns a 32-bit IRQ mask:-/ */
+#define MIN_PROBE_IRQ (NR_IRQS - 32)
+
+#ifndef __ASSEMBLY__
+static inline int irq_canonicalize(int irq)
+{
+ return irq;
+}
+#endif
+
+#endif /* _ASM_IRQ_H_ */
diff --git a/arch/frv/include/asm/irq_regs.h b/arch/frv/include/asm/irq_regs.h
new file mode 100644
index 00000000000..d22e83289ad
--- /dev/null
+++ b/arch/frv/include/asm/irq_regs.h
@@ -0,0 +1,27 @@
+/* FRV per-CPU frame pointer holder
+ *
+ * Copyright (C) 2006 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_IRQ_REGS_H
+#define _ASM_IRQ_REGS_H
+
+/*
+ * Per-cpu current frame pointer - the location of the last exception frame on
+ * the stack
+ * - on FRV, GR28 is dedicated to keeping a pointer to the current exception
+ * frame
+ */
+#define ARCH_HAS_OWN_IRQ_REGS
+
+#ifndef __ASSEMBLY__
+#define get_irq_regs() (__frame)
+#endif
+
+#endif /* _ASM_IRQ_REGS_H */
diff --git a/arch/frv/include/asm/irqflags.h b/arch/frv/include/asm/irqflags.h
new file mode 100644
index 00000000000..82f0b5363f4
--- /dev/null
+++ b/arch/frv/include/asm/irqflags.h
@@ -0,0 +1,158 @@
+/* FR-V interrupt handling
+ *
+ * Copyright (C) 2010 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_IRQFLAGS_H
+#define _ASM_IRQFLAGS_H
+
+/*
+ * interrupt flag manipulation
+ * - use virtual interrupt management since touching the PSR is slow
+ * - ICC2.Z: T if interrupts virtually disabled
+ * - ICC2.C: F if interrupts really disabled
+ * - if Z==1 upon interrupt:
+ * - C is set to 0
+ * - interrupts are really disabled
+ * - entry.S returns immediately
+ * - uses TIHI (TRAP if Z==0 && C==0) #2 to really reenable interrupts
+ * - if taken, the trap:
+ * - sets ICC2.C
+ * - enables interrupts
+ */
+static inline void arch_local_irq_disable(void)
+{
+ /* set Z flag, but don't change the C flag */
+ asm volatile(" andcc gr0,gr0,gr0,icc2 \n"
+ :
+ :
+ : "memory", "icc2"
+ );
+}
+
+static inline void arch_local_irq_enable(void)
+{
+ /* clear Z flag and then test the C flag */
+ asm volatile(" oricc gr0,#1,gr0,icc2 \n"
+ " tihi icc2,gr0,#2 \n"
+ :
+ :
+ : "memory", "icc2"
+ );
+}
+
+static inline unsigned long arch_local_save_flags(void)
+{
+ unsigned long flags;
+
+ asm volatile("movsg ccr,%0"
+ : "=r"(flags)
+ :
+ : "memory");
+
+ /* shift ICC2.Z to bit 0 */
+ flags >>= 26;
+
+ /* make flags 1 if interrupts disabled, 0 otherwise */
+ return flags & 1UL;
+
+}
+
+static inline unsigned long arch_local_irq_save(void)
+{
+ unsigned long flags = arch_local_save_flags();
+ arch_local_irq_disable();
+ return flags;
+}
+
+static inline void arch_local_irq_restore(unsigned long flags)
+{
+ /* load the Z flag by turning 1 if disabled into 0 if disabled
+ * and thus setting the Z flag but not the C flag */
+ asm volatile(" xoricc %0,#1,gr0,icc2 \n"
+ /* then trap if Z=0 and C=0 */
+ " tihi icc2,gr0,#2 \n"
+ :
+ : "r"(flags)
+ : "memory", "icc2"
+ );
+
+}
+
+static inline bool arch_irqs_disabled_flags(unsigned long flags)
+{
+ return flags;
+}
+
+static inline bool arch_irqs_disabled(void)
+{
+ return arch_irqs_disabled_flags(arch_local_save_flags());
+}
+
+/*
+ * real interrupt flag manipulation
+ */
+#define __arch_local_irq_disable() \
+do { \
+ unsigned long psr; \
+ asm volatile(" movsg psr,%0 \n" \
+ " andi %0,%2,%0 \n" \
+ " ori %0,%1,%0 \n" \
+ " movgs %0,psr \n" \
+ : "=r"(psr) \
+ : "i" (PSR_PIL_14), "i" (~PSR_PIL) \
+ : "memory"); \
+} while (0)
+
+#define __arch_local_irq_enable() \
+do { \
+ unsigned long psr; \
+ asm volatile(" movsg psr,%0 \n" \
+ " andi %0,%1,%0 \n" \
+ " movgs %0,psr \n" \
+ : "=r"(psr) \
+ : "i" (~PSR_PIL) \
+ : "memory"); \
+} while (0)
+
+#define __arch_local_save_flags(flags) \
+do { \
+ typecheck(unsigned long, flags); \
+ asm("movsg psr,%0" \
+ : "=r"(flags) \
+ : \
+ : "memory"); \
+} while (0)
+
+#define __arch_local_irq_save(flags) \
+do { \
+ unsigned long npsr; \
+ typecheck(unsigned long, flags); \
+ asm volatile(" movsg psr,%0 \n" \
+ " andi %0,%3,%1 \n" \
+ " ori %1,%2,%1 \n" \
+ " movgs %1,psr \n" \
+ : "=r"(flags), "=r"(npsr) \
+ : "i" (PSR_PIL_14), "i" (~PSR_PIL) \
+ : "memory"); \
+} while (0)
+
+#define __arch_local_irq_restore(flags) \
+do { \
+ typecheck(unsigned long, flags); \
+ asm volatile(" movgs %0,psr \n" \
+ : \
+ : "r" (flags) \
+ : "memory"); \
+} while (0)
+
+#define __arch_irqs_disabled() \
+ ((__get_PSR() & PSR_PIL) >= PSR_PIL_14)
+
+#endif /* _ASM_IRQFLAGS_H */
diff --git a/arch/frv/include/asm/kdebug.h b/arch/frv/include/asm/kdebug.h
new file mode 100644
index 00000000000..6ece1b03766
--- /dev/null
+++ b/arch/frv/include/asm/kdebug.h
@@ -0,0 +1 @@
+#include <asm-generic/kdebug.h>
diff --git a/arch/frv/include/asm/kmap_types.h b/arch/frv/include/asm/kmap_types.h
new file mode 100644
index 00000000000..43901f22096
--- /dev/null
+++ b/arch/frv/include/asm/kmap_types.h
@@ -0,0 +1,7 @@
+
+#ifndef _ASM_KMAP_TYPES_H
+#define _ASM_KMAP_TYPES_H
+
+#define KM_TYPE_NR 17
+
+#endif
diff --git a/arch/frv/include/asm/linkage.h b/arch/frv/include/asm/linkage.h
new file mode 100644
index 00000000000..636c1bced7d
--- /dev/null
+++ b/arch/frv/include/asm/linkage.h
@@ -0,0 +1,7 @@
+#ifndef __ASM_LINKAGE_H
+#define __ASM_LINKAGE_H
+
+#define __ALIGN .align 4
+#define __ALIGN_STR ".align 4"
+
+#endif
diff --git a/arch/frv/include/asm/local.h b/arch/frv/include/asm/local.h
new file mode 100644
index 00000000000..c27bdf04630
--- /dev/null
+++ b/arch/frv/include/asm/local.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_LOCAL_H
+#define _ASM_LOCAL_H
+
+#include <asm-generic/local.h>
+
+#endif /* _ASM_LOCAL_H */
diff --git a/arch/frv/include/asm/local64.h b/arch/frv/include/asm/local64.h
new file mode 100644
index 00000000000..36c93b5cc23
--- /dev/null
+++ b/arch/frv/include/asm/local64.h
@@ -0,0 +1 @@
+#include <asm-generic/local64.h>
diff --git a/arch/frv/include/asm/math-emu.h b/arch/frv/include/asm/math-emu.h
new file mode 100644
index 00000000000..0c8f731b218
--- /dev/null
+++ b/arch/frv/include/asm/math-emu.h
@@ -0,0 +1,301 @@
+#ifndef _ASM_MATH_EMU_H
+#define _ASM_MATH_EMU_H
+
+#include <asm/setup.h>
+#include <linux/linkage.h>
+
+/* Status Register bits */
+
+/* accrued exception bits */
+#define FPSR_AEXC_INEX 3
+#define FPSR_AEXC_DZ 4
+#define FPSR_AEXC_UNFL 5
+#define FPSR_AEXC_OVFL 6
+#define FPSR_AEXC_IOP 7
+
+/* exception status bits */
+#define FPSR_EXC_INEX1 8
+#define FPSR_EXC_INEX2 9
+#define FPSR_EXC_DZ 10
+#define FPSR_EXC_UNFL 11
+#define FPSR_EXC_OVFL 12
+#define FPSR_EXC_OPERR 13
+#define FPSR_EXC_SNAN 14
+#define FPSR_EXC_BSUN 15
+
+/* quotient byte, assumes big-endian, of course */
+#define FPSR_QUOTIENT(fpsr) (*((signed char *) &(fpsr) + 1))
+
+/* condition code bits */
+#define FPSR_CC_NAN 24
+#define FPSR_CC_INF 25
+#define FPSR_CC_Z 26
+#define FPSR_CC_NEG 27
+
+
+/* Control register bits */
+
+/* rounding mode */
+#define FPCR_ROUND_RN 0 /* round to nearest/even */
+#define FPCR_ROUND_RZ 1 /* round to zero */
+#define FPCR_ROUND_RM 2 /* minus infinity */
+#define FPCR_ROUND_RP 3 /* plus infinity */
+
+/* rounding precision */
+#define FPCR_PRECISION_X 0 /* long double */
+#define FPCR_PRECISION_S 1 /* double */
+#define FPCR_PRECISION_D 2 /* float */
+
+
+/* Flags to select the debugging output */
+#define PDECODE 0
+#define PEXECUTE 1
+#define PCONV 2
+#define PNORM 3
+#define PREGISTER 4
+#define PINSTR 5
+#define PUNIMPL 6
+#define PMOVEM 7
+
+#define PMDECODE (1<<PDECODE)
+#define PMEXECUTE (1<<PEXECUTE)
+#define PMCONV (1<<PCONV)
+#define PMNORM (1<<PNORM)
+#define PMREGISTER (1<<PREGISTER)
+#define PMINSTR (1<<PINSTR)
+#define PMUNIMPL (1<<PUNIMPL)
+#define PMMOVEM (1<<PMOVEM)
+
+#ifndef __ASSEMBLY__
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+union fp_mant64 {
+ unsigned long long m64;
+ unsigned long m32[2];
+};
+
+union fp_mant128 {
+ unsigned long long m64[2];
+ unsigned long m32[4];
+};
+
+/* internal representation of extended fp numbers */
+struct fp_ext {
+ unsigned char lowmant;
+ unsigned char sign;
+ unsigned short exp;
+ union fp_mant64 mant;
+};
+
+/* C representation of FPU registers */
+/* NOTE: if you change this, you have to change the assembler offsets
+ below and the size in <asm/fpu.h>, too */
+struct fp_data {
+ struct fp_ext fpreg[8];
+ unsigned int fpcr;
+ unsigned int fpsr;
+ unsigned int fpiar;
+ unsigned short prec;
+ unsigned short rnd;
+ struct fp_ext temp[2];
+};
+
+#if FPU_EMU_DEBUG
+extern unsigned int fp_debugprint;
+
+#define dprint(bit, fmt, args...) ({ \
+ if (fp_debugprint & (1 << (bit))) \
+ printk(fmt, ## args); \
+})
+#else
+#define dprint(bit, fmt, args...)
+#endif
+
+#define uprint(str) ({ \
+ static int __count = 3; \
+ \
+ if (__count > 0) { \
+ printk("You just hit an unimplemented " \
+ "fpu instruction (%s)\n", str); \
+ printk("Please report this to ....\n"); \
+ __count--; \
+ } \
+})
+
+#define FPDATA ((struct fp_data *)current->thread.fp)
+
+#else /* __ASSEMBLY__ */
+
+#define FPDATA %a2
+
+/* offsets from the base register to the floating point data in the task struct */
+#define FPD_FPREG (TASK_THREAD+THREAD_FPREG+0)
+#define FPD_FPCR (TASK_THREAD+THREAD_FPREG+96)
+#define FPD_FPSR (TASK_THREAD+THREAD_FPREG+100)
+#define FPD_FPIAR (TASK_THREAD+THREAD_FPREG+104)
+#define FPD_PREC (TASK_THREAD+THREAD_FPREG+108)
+#define FPD_RND (TASK_THREAD+THREAD_FPREG+110)
+#define FPD_TEMPFP1 (TASK_THREAD+THREAD_FPREG+112)
+#define FPD_TEMPFP2 (TASK_THREAD+THREAD_FPREG+124)
+#define FPD_SIZEOF (TASK_THREAD+THREAD_FPREG+136)
+
+/* offsets on the stack to access saved registers,
+ * these are only used during instruction decoding
+ * where we always know how deep we're on the stack.
+ */
+#define FPS_DO (PT_D0)
+#define FPS_D1 (PT_D1)
+#define FPS_D2 (PT_D2)
+#define FPS_A0 (PT_A0)
+#define FPS_A1 (PT_A1)
+#define FPS_A2 (PT_A2)
+#define FPS_SR (PT_SR)
+#define FPS_PC (PT_PC)
+#define FPS_EA (PT_PC+6)
+#define FPS_PC2 (PT_PC+10)
+
+.macro fp_get_fp_reg
+ lea (FPD_FPREG,FPDATA,%d0.w*4),%a0
+ lea (%a0,%d0.w*8),%a0
+.endm
+
+/* Macros used to get/put the current program counter.
+ * 020/030 use a different stack frame then 040/060, for the
+ * 040/060 the return pc points already to the next location,
+ * so this only needs to be modified for jump instructions.
+ */
+.macro fp_get_pc dest
+ move.l (FPS_PC+4,%sp),\dest
+.endm
+
+.macro fp_put_pc src,jump=0
+ move.l \src,(FPS_PC+4,%sp)
+.endm
+
+.macro fp_get_instr_data f,s,dest,label
+ getuser \f,%sp@(FPS_PC+4)@(0),\dest,\label,%sp@(FPS_PC+4)
+ addq.l #\s,%sp@(FPS_PC+4)
+.endm
+
+.macro fp_get_instr_word dest,label,addr
+ fp_get_instr_data w,2,\dest,\label,\addr
+.endm
+
+.macro fp_get_instr_long dest,label,addr
+ fp_get_instr_data l,4,\dest,\label,\addr
+.endm
+
+/* These macros are used to read from/write to user space
+ * on error we jump to the fixup section, load the fault
+ * address into %a0 and jump to the exit.
+ * (derived from <asm/uaccess.h>)
+ */
+.macro getuser size,src,dest,label,addr
+| printf ,"[\size<%08x]",1,\addr
+.Lu1\@: moves\size \src,\dest
+
+ .section .fixup,"ax"
+ .even
+.Lu2\@: move.l \addr,%a0
+ jra \label
+ .previous
+
+ .section __ex_table,"a"
+ .align 4
+ .long .Lu1\@,.Lu2\@
+ .previous
+.endm
+
+.macro putuser size,src,dest,label,addr
+| printf ,"[\size>%08x]",1,\addr
+.Lu1\@: moves\size \src,\dest
+.Lu2\@:
+
+ .section .fixup,"ax"
+ .even
+.Lu3\@: move.l \addr,%a0
+ jra \label
+ .previous
+
+ .section __ex_table,"a"
+ .align 4
+ .long .Lu1\@,.Lu3\@
+ .long .Lu2\@,.Lu3\@
+ .previous
+.endm
+
+
+.macro movestack nr,arg1,arg2,arg3,arg4,arg5
+ .if \nr
+ movestack (\nr-1),\arg2,\arg3,\arg4,\arg5
+ move.l \arg1,-(%sp)
+ .endif
+.endm
+
+.macro printf bit=-1,string,nr=0,arg1,arg2,arg3,arg4,arg5
+#ifdef FPU_EMU_DEBUG
+ .data
+.Lpdata\@:
+ .string "\string"
+ .previous
+
+ movem.l %d0/%d1/%a0/%a1,-(%sp)
+ .if \bit+1
+#if 0
+ moveq #\bit,%d0
+ andw #7,%d0
+ btst %d0,fp_debugprint+((31-\bit)/8)
+#else
+ btst #\bit,fp_debugprint+((31-\bit)/8)
+#endif
+ jeq .Lpskip\@
+ .endif
+ movestack \nr,\arg1,\arg2,\arg3,\arg4,\arg5
+ pea .Lpdata\@
+ jsr printk
+ lea ((\nr+1)*4,%sp),%sp
+.Lpskip\@:
+ movem.l (%sp)+,%d0/%d1/%a0/%a1
+#endif
+.endm
+
+.macro printx bit,fp
+#ifdef FPU_EMU_DEBUG
+ movem.l %d0/%a0,-(%sp)
+ lea \fp,%a0
+#if 0
+ moveq #'+',%d0
+ tst.w (%a0)
+ jeq .Lx1\@
+ moveq #'-',%d0
+.Lx1\@: printf \bit," %c",1,%d0
+ move.l (4,%a0),%d0
+ bclr #31,%d0
+ jne .Lx2\@
+ printf \bit,"0."
+ jra .Lx3\@
+.Lx2\@: printf \bit,"1."
+.Lx3\@: printf \bit,"%08x%08x",2,%d0,%a0@(8)
+ move.w (2,%a0),%d0
+ ext.l %d0
+ printf \bit,"E%04x",1,%d0
+#else
+ printf \bit," %08x%08x%08x",3,%a0@,%a0@(4),%a0@(8)
+#endif
+ movem.l (%sp)+,%d0/%a0
+#endif
+.endm
+
+.macro debug instr,args
+#ifdef FPU_EMU_DEBUG
+ \instr \args
+#endif
+.endm
+
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_FRV_MATH_EMU_H */
+
diff --git a/arch/frv/include/asm/mb-regs.h b/arch/frv/include/asm/mb-regs.h
new file mode 100644
index 00000000000..219e5f926f1
--- /dev/null
+++ b/arch/frv/include/asm/mb-regs.h
@@ -0,0 +1,200 @@
+/* mb-regs.h: motherboard registers
+ *
+ * Copyright (C) 2003, 2004 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_MB_REGS_H
+#define _ASM_MB_REGS_H
+
+#include <asm/cpu-irqs.h>
+#include <asm/sections.h>
+#include <asm/mem-layout.h>
+
+#ifndef __ASSEMBLY__
+/* gcc builtins, annotated */
+
+unsigned long __builtin_read8(volatile void __iomem *);
+unsigned long __builtin_read16(volatile void __iomem *);
+unsigned long __builtin_read32(volatile void __iomem *);
+void __builtin_write8(volatile void __iomem *, unsigned char);
+void __builtin_write16(volatile void __iomem *, unsigned short);
+void __builtin_write32(volatile void __iomem *, unsigned long);
+#endif
+
+#define __region_IO KERNEL_IO_START /* the region from 0xe0000000 to 0xffffffff has suitable
+ * protection laid over the top for use in memory-mapped
+ * I/O
+ */
+
+#define __region_CS0 0xff000000 /* Boot ROMs area */
+
+#ifdef CONFIG_MB93091_VDK
+/*
+ * VDK motherboard and CPU card specific stuff
+ */
+
+#include <asm/mb93091-fpga-irqs.h>
+
+#define IRQ_CPU_MB93493_0 IRQ_CPU_EXTERNAL0
+#define IRQ_CPU_MB93493_1 IRQ_CPU_EXTERNAL1
+
+#define __region_CS2 0xe0000000 /* SLBUS/PCI I/O space */
+#define __region_CS2_M 0x0fffffff /* mask */
+#define __region_CS2_C 0x00000000 /* control */
+#define __region_CS5 0xf0000000 /* MB93493 CSC area (DAV daughter board) */
+#define __region_CS5_M 0x00ffffff
+#define __region_CS5_C 0x00010000
+#define __region_CS7 0xf1000000 /* CB70 CPU-card PCMCIA port I/O space */
+#define __region_CS7_M 0x00ffffff
+#define __region_CS7_C 0x00410701
+#define __region_CS1 0xfc000000 /* SLBUS/PCI bridge control registers */
+#define __region_CS1_M 0x000fffff
+#define __region_CS1_C 0x00000000
+#define __region_CS6 0xfc100000 /* CB70 CPU-card DM9000 LAN I/O space */
+#define __region_CS6_M 0x000fffff
+#define __region_CS6_C 0x00400707
+#define __region_CS3 0xfc200000 /* MB93493 CSR area (DAV daughter board) */
+#define __region_CS3_M 0x000fffff
+#define __region_CS3_C 0xc8100000
+#define __region_CS4 0xfd000000 /* CB70 CPU-card extra flash space */
+#define __region_CS4_M 0x00ffffff
+#define __region_CS4_C 0x00000f07
+
+#define __region_PCI_IO (__region_CS2 + 0x04000000UL)
+#define __region_PCI_MEM (__region_CS2 + 0x08000000UL)
+#define __flush_PCI_writes() \
+do { \
+ __builtin_write8((volatile void __iomem *) __region_PCI_MEM, 0); \
+} while(0)
+
+#define __is_PCI_IO(addr) \
+ (((unsigned long)(addr) >> 24) - (__region_PCI_IO >> 24) < (0x04000000UL >> 24))
+
+#define __is_PCI_MEM(addr) \
+ ((unsigned long)(addr) - __region_PCI_MEM < 0x08000000UL)
+
+#define __is_PCI_addr(addr) \
+ ((unsigned long)(addr) - __region_PCI_IO < 0x0c000000UL)
+
+#define __get_CLKSW() ({ *(volatile unsigned long *)(__region_CS2 + 0x0130000cUL) & 0xffUL; })
+#define __get_CLKIN() (__get_CLKSW() * 125U * 100000U / 24U)
+
+#ifndef __ASSEMBLY__
+extern int __nongprelbss mb93090_mb00_detected;
+#endif
+
+#define __addr_LEDS() (__region_CS2 + 0x01200004UL)
+#ifdef CONFIG_MB93090_MB00
+#define __set_LEDS(X) \
+do { \
+ if (mb93090_mb00_detected) \
+ __builtin_write32((void __iomem *) __addr_LEDS(), ~(X)); \
+} while (0)
+#else
+#define __set_LEDS(X)
+#endif
+
+#define __addr_LCD() (__region_CS2 + 0x01200008UL)
+#define __get_LCD(B) __builtin_read32((volatile void __iomem *) (B))
+#define __set_LCD(B,X) __builtin_write32((volatile void __iomem *) (B), (X))
+
+#define LCD_D 0x000000ff /* LCD data bus */
+#define LCD_RW 0x00000100 /* LCD R/W signal */
+#define LCD_RS 0x00000200 /* LCD Register Select */
+#define LCD_E 0x00000400 /* LCD Start Enable Signal */
+
+#define LCD_CMD_CLEAR (LCD_E|0x001)
+#define LCD_CMD_HOME (LCD_E|0x002)
+#define LCD_CMD_CURSOR_INC (LCD_E|0x004)
+#define LCD_CMD_SCROLL_INC (LCD_E|0x005)
+#define LCD_CMD_CURSOR_DEC (LCD_E|0x006)
+#define LCD_CMD_SCROLL_DEC (LCD_E|0x007)
+#define LCD_CMD_OFF (LCD_E|0x008)
+#define LCD_CMD_ON(CRSR,BLINK) (LCD_E|0x00c|(CRSR<<1)|BLINK)
+#define LCD_CMD_CURSOR_MOVE_L (LCD_E|0x010)
+#define LCD_CMD_CURSOR_MOVE_R (LCD_E|0x014)
+#define LCD_CMD_DISPLAY_SHIFT_L (LCD_E|0x018)
+#define LCD_CMD_DISPLAY_SHIFT_R (LCD_E|0x01c)
+#define LCD_CMD_FUNCSET(DL,N,F) (LCD_E|0x020|(DL<<4)|(N<<3)|(F<<2))
+#define LCD_CMD_SET_CG_ADDR(X) (LCD_E|0x040|X)
+#define LCD_CMD_SET_DD_ADDR(X) (LCD_E|0x080|X)
+#define LCD_CMD_READ_BUSY (LCD_E|LCD_RW)
+#define LCD_DATA_WRITE(X) (LCD_E|LCD_RS|(X))
+#define LCD_DATA_READ (LCD_E|LCD_RS|LCD_RW)
+
+#else
+/*
+ * PDK unit specific stuff
+ */
+
+#include <asm/mb93093-fpga-irqs.h>
+
+#define IRQ_CPU_MB93493_0 IRQ_CPU_EXTERNAL0
+#define IRQ_CPU_MB93493_1 IRQ_CPU_EXTERNAL1
+
+#define __region_CS5 0xf0000000 /* MB93493 CSC area (DAV daughter board) */
+#define __region_CS5_M 0x00ffffff /* mask */
+#define __region_CS5_C 0x00010000 /* control */
+#define __region_CS2 0x20000000 /* FPGA registers */
+#define __region_CS2_M 0x000fffff
+#define __region_CS2_C 0x00000000
+#define __region_CS1 0xfc100000 /* LAN registers */
+#define __region_CS1_M 0x000fffff
+#define __region_CS1_C 0x00010404
+#define __region_CS3 0xfc200000 /* MB93493 CSR area (DAV daughter board) */
+#define __region_CS3_M 0x000fffff
+#define __region_CS3_C 0xc8000000
+#define __region_CS4 0xfd000000 /* extra ROMs area */
+#define __region_CS4_M 0x00ffffff
+#define __region_CS4_C 0x00000f07
+
+#define __region_CS6 0xfe000000 /* not used - hide behind CPU resource I/O regs */
+#define __region_CS6_M 0x000fffff
+#define __region_CS6_C 0x00000f07
+#define __region_CS7 0xfe000000 /* not used - hide behind CPU resource I/O regs */
+#define __region_CS7_M 0x000fffff
+#define __region_CS7_C 0x00000f07
+
+#define __is_PCI_IO(addr) 0 /* no PCI */
+#define __is_PCI_MEM(addr) 0
+#define __is_PCI_addr(addr) 0
+#define __region_PCI_IO 0
+#define __region_PCI_MEM 0
+#define __flush_PCI_writes() do { } while(0)
+
+#define __get_CLKSW() 0UL
+#define __get_CLKIN() 66000000UL
+
+#define __addr_LEDS() (__region_CS2 + 0x00000023UL)
+#define __set_LEDS(X) __builtin_write8((volatile void __iomem *) __addr_LEDS(), (X))
+
+#define __addr_FPGATR() (__region_CS2 + 0x00000030UL)
+#define __set_FPGATR(X) __builtin_write32((volatile void __iomem *) __addr_FPGATR(), (X))
+#define __get_FPGATR() __builtin_read32((volatile void __iomem *) __addr_FPGATR())
+
+#define MB93093_FPGA_FPGATR_AUDIO_CLK 0x00000003
+
+#define __set_FPGATR_AUDIO_CLK(V) \
+ __set_FPGATR((__get_FPGATR() & ~MB93093_FPGA_FPGATR_AUDIO_CLK) | (V))
+
+#define MB93093_FPGA_FPGATR_AUDIO_CLK_OFF 0x0
+#define MB93093_FPGA_FPGATR_AUDIO_CLK_11MHz 0x1
+#define MB93093_FPGA_FPGATR_AUDIO_CLK_12MHz 0x2
+#define MB93093_FPGA_FPGATR_AUDIO_CLK_02MHz 0x3
+
+#define MB93093_FPGA_SWR_PUSHSWMASK (0x1F<<26)
+#define MB93093_FPGA_SWR_PUSHSW4 (1<<29)
+
+#define __addr_FPGA_SWR ((volatile void __iomem *)(__region_CS2 + 0x28UL))
+#define __get_FPGA_PUSHSW1_5() (__builtin_read32(__addr_FPGA_SWR) & MB93093_FPGA_SWR_PUSHSWMASK)
+
+
+#endif
+
+#endif /* _ASM_MB_REGS_H */
diff --git a/arch/frv/include/asm/mb86943a.h b/arch/frv/include/asm/mb86943a.h
new file mode 100644
index 00000000000..e87ef924bfb
--- /dev/null
+++ b/arch/frv/include/asm/mb86943a.h
@@ -0,0 +1,42 @@
+/* mb86943a.h: MB86943 SPARClite <-> PCI bridge registers
+ *
+ * Copyright (C) 2003 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_MB86943A_H
+#define _ASM_MB86943A_H
+
+#include <asm/mb-regs.h>
+
+#define __reg_MB86943_sl_ctl *(volatile uint32_t *) (__region_CS1 + 0x00)
+
+#define MB86943_SL_CTL_BUS_WIDTH_64 0x00000001
+#define MB86943_SL_CTL_AS_HOST 0x00000002
+#define MB86943_SL_CTL_DRCT_MASTER_SWAP 0x00000004
+#define MB86943_SL_CTL_DRCT_SLAVE_SWAP 0x00000008
+#define MB86943_SL_CTL_PCI_CONFIG_SWAP 0x00000010
+#define MB86943_SL_CTL_ECS0_ENABLE 0x00000020
+#define MB86943_SL_CTL_ECS1_ENABLE 0x00000040
+#define MB86943_SL_CTL_ECS2_ENABLE 0x00000080
+
+#define __reg_MB86943_ecs_ctl(N) *(volatile uint32_t *) (__region_CS1 + 0x08 + (0x08*(N)))
+#define __reg_MB86943_ecs_range(N) *(volatile uint32_t *) (__region_CS1 + 0x20 + (0x10*(N)))
+#define __reg_MB86943_ecs_base(N) *(volatile uint32_t *) (__region_CS1 + 0x28 + (0x10*(N)))
+
+#define __reg_MB86943_sl_pci_io_range *(volatile uint32_t *) (__region_CS1 + 0x50)
+#define __reg_MB86943_sl_pci_io_base *(volatile uint32_t *) (__region_CS1 + 0x58)
+#define __reg_MB86943_sl_pci_mem_range *(volatile uint32_t *) (__region_CS1 + 0x60)
+#define __reg_MB86943_sl_pci_mem_base *(volatile uint32_t *) (__region_CS1 + 0x68)
+#define __reg_MB86943_pci_sl_io_base *(volatile uint32_t *) (__region_CS1 + 0x70)
+#define __reg_MB86943_pci_sl_mem_base *(volatile uint32_t *) (__region_CS1 + 0x78)
+
+#define __reg_MB86943_pci_arbiter *(volatile uint32_t *) (__region_CS2 + 0x01300014)
+#define MB86943_PCIARB_EN 0x00000001
+
+#endif /* _ASM_MB86943A_H */
diff --git a/arch/frv/include/asm/mb93091-fpga-irqs.h b/arch/frv/include/asm/mb93091-fpga-irqs.h
new file mode 100644
index 00000000000..19778c5ba9d
--- /dev/null
+++ b/arch/frv/include/asm/mb93091-fpga-irqs.h
@@ -0,0 +1,42 @@
+/* mb93091-fpga-irqs.h: MB93091 CPU board FPGA IRQs
+ *
+ * Copyright (C) 2004 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_MB93091_FPGA_IRQS_H
+#define _ASM_MB93091_FPGA_IRQS_H
+
+#include <asm/irq.h>
+
+#ifndef __ASSEMBLY__
+
+/* IRQ IDs presented to drivers */
+enum {
+ IRQ_FPGA__UNUSED = IRQ_BASE_FPGA,
+ IRQ_FPGA_SYSINT_BUS_EXPANSION_1,
+ IRQ_FPGA_SL_BUS_EXPANSION_2,
+ IRQ_FPGA_PCI_INTD,
+ IRQ_FPGA_PCI_INTC,
+ IRQ_FPGA_PCI_INTB,
+ IRQ_FPGA_PCI_INTA,
+ IRQ_FPGA_SL_BUS_EXPANSION_7,
+ IRQ_FPGA_SYSINT_BUS_EXPANSION_8,
+ IRQ_FPGA_SL_BUS_EXPANSION_9,
+ IRQ_FPGA_MB86943_PCI_INTA,
+ IRQ_FPGA_MB86943_SLBUS_SIDE,
+ IRQ_FPGA_RTL8029_INTA,
+ IRQ_FPGA_SYSINT_BUS_EXPANSION_13,
+ IRQ_FPGA_SL_BUS_EXPANSION_14,
+ IRQ_FPGA_NMI,
+};
+
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_MB93091_FPGA_IRQS_H */
diff --git a/arch/frv/include/asm/mb93093-fpga-irqs.h b/arch/frv/include/asm/mb93093-fpga-irqs.h
new file mode 100644
index 00000000000..590266b1a6d
--- /dev/null
+++ b/arch/frv/include/asm/mb93093-fpga-irqs.h
@@ -0,0 +1,29 @@
+/* mb93093-fpga-irqs.h: MB93093 CPU board FPGA IRQs
+ *
+ * Copyright (C) 2004 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_MB93093_FPGA_IRQS_H
+#define _ASM_MB93093_FPGA_IRQS_H
+
+#include <asm/irq.h>
+
+#ifndef __ASSEMBLY__
+
+/* IRQ IDs presented to drivers */
+enum {
+ IRQ_FPGA_PUSH_BUTTON_SW1_5 = IRQ_BASE_FPGA + 8,
+ IRQ_FPGA_ROCKER_C_SW8 = IRQ_BASE_FPGA + 9,
+ IRQ_FPGA_ROCKER_C_SW9 = IRQ_BASE_FPGA + 10,
+};
+
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_MB93093_FPGA_IRQS_H */
diff --git a/arch/frv/include/asm/mb93493-irqs.h b/arch/frv/include/asm/mb93493-irqs.h
new file mode 100644
index 00000000000..82c7aeddd33
--- /dev/null
+++ b/arch/frv/include/asm/mb93493-irqs.h
@@ -0,0 +1,50 @@
+/* mb93493-irqs.h: MB93493 companion chip IRQs
+ *
+ * Copyright (C) 2004 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_MB93493_IRQS_H
+#define _ASM_MB93493_IRQS_H
+
+#include <asm/irq.h>
+
+#ifndef __ASSEMBLY__
+
+/* IRQ IDs presented to drivers */
+enum {
+ IRQ_MB93493_VDC = IRQ_BASE_MB93493 + 0,
+ IRQ_MB93493_VCC = IRQ_BASE_MB93493 + 1,
+ IRQ_MB93493_AUDIO_OUT = IRQ_BASE_MB93493 + 2,
+ IRQ_MB93493_I2C_0 = IRQ_BASE_MB93493 + 3,
+ IRQ_MB93493_I2C_1 = IRQ_BASE_MB93493 + 4,
+ IRQ_MB93493_USB = IRQ_BASE_MB93493 + 5,
+ IRQ_MB93493_LOCAL_BUS = IRQ_BASE_MB93493 + 7,
+ IRQ_MB93493_PCMCIA = IRQ_BASE_MB93493 + 8,
+ IRQ_MB93493_GPIO = IRQ_BASE_MB93493 + 9,
+ IRQ_MB93493_AUDIO_IN = IRQ_BASE_MB93493 + 10,
+};
+
+/* IRQ multiplexor mappings */
+#define ROUTE_VIA_IRQ0 0 /* route IRQ by way of CPU external IRQ 0 */
+#define ROUTE_VIA_IRQ1 1 /* route IRQ by way of CPU external IRQ 1 */
+
+#define IRQ_MB93493_VDC_ROUTE ROUTE_VIA_IRQ0
+#define IRQ_MB93493_VCC_ROUTE ROUTE_VIA_IRQ1
+#define IRQ_MB93493_AUDIO_OUT_ROUTE ROUTE_VIA_IRQ1
+#define IRQ_MB93493_I2C_0_ROUTE ROUTE_VIA_IRQ1
+#define IRQ_MB93493_I2C_1_ROUTE ROUTE_VIA_IRQ1
+#define IRQ_MB93493_USB_ROUTE ROUTE_VIA_IRQ1
+#define IRQ_MB93493_LOCAL_BUS_ROUTE ROUTE_VIA_IRQ1
+#define IRQ_MB93493_PCMCIA_ROUTE ROUTE_VIA_IRQ1
+#define IRQ_MB93493_GPIO_ROUTE ROUTE_VIA_IRQ1
+#define IRQ_MB93493_AUDIO_IN_ROUTE ROUTE_VIA_IRQ1
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_MB93493_IRQS_H */
diff --git a/arch/frv/include/asm/mb93493-regs.h b/arch/frv/include/asm/mb93493-regs.h
new file mode 100644
index 00000000000..8a1f6aac8cf
--- /dev/null
+++ b/arch/frv/include/asm/mb93493-regs.h
@@ -0,0 +1,281 @@
+/* mb93493-regs.h: MB93493 companion chip registers
+ *
+ * Copyright (C) 2004 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_MB93493_REGS_H
+#define _ASM_MB93493_REGS_H
+
+#include <asm/mb-regs.h>
+#include <asm/mb93493-irqs.h>
+
+#define __addr_MB93493(X) ((volatile unsigned long *)(__region_CS3 + (X)))
+#define __get_MB93493(X) ({ *(volatile unsigned long *)(__region_CS3 + (X)); })
+
+#define __set_MB93493(X,V) \
+do { \
+ *(volatile unsigned long *)(__region_CS3 + (X)) = (V); mb(); \
+} while(0)
+
+#define __get_MB93493_STSR(X) __get_MB93493(0x3c0 + (X) * 4)
+#define __set_MB93493_STSR(X,V) __set_MB93493(0x3c0 + (X) * 4, (V))
+#define MB93493_STSR_EN
+
+#define __addr_MB93493_IQSR(X) __addr_MB93493(0x3d0 + (X) * 4)
+#define __get_MB93493_IQSR(X) __get_MB93493(0x3d0 + (X) * 4)
+#define __set_MB93493_IQSR(X,V) __set_MB93493(0x3d0 + (X) * 4, (V))
+
+#define __get_MB93493_DQSR(X) __get_MB93493(0x3e0 + (X) * 4)
+#define __set_MB93493_DQSR(X,V) __set_MB93493(0x3e0 + (X) * 4, (V))
+
+#define __get_MB93493_LBSER() __get_MB93493(0x3f0)
+#define __set_MB93493_LBSER(V) __set_MB93493(0x3f0, (V))
+
+#define MB93493_LBSER_VDC 0x00010000
+#define MB93493_LBSER_VCC 0x00020000
+#define MB93493_LBSER_AUDIO 0x00040000
+#define MB93493_LBSER_I2C_0 0x00080000
+#define MB93493_LBSER_I2C_1 0x00100000
+#define MB93493_LBSER_USB 0x00200000
+#define MB93493_LBSER_GPIO 0x00800000
+#define MB93493_LBSER_PCMCIA 0x01000000
+
+#define __get_MB93493_LBSR() __get_MB93493(0x3fc)
+#define __set_MB93493_LBSR(V) __set_MB93493(0x3fc, (V))
+
+/*
+ * video display controller
+ */
+#define __get_MB93493_VDC(X) __get_MB93493(MB93493_VDC_##X)
+#define __set_MB93493_VDC(X,V) __set_MB93493(MB93493_VDC_##X, (V))
+
+#define MB93493_VDC_RCURSOR 0x140 /* cursor position */
+#define MB93493_VDC_RCT1 0x144 /* cursor colour 1 */
+#define MB93493_VDC_RCT2 0x148 /* cursor colour 2 */
+#define MB93493_VDC_RHDC 0x150 /* horizontal display period */
+#define MB93493_VDC_RH_MARGINS 0x154 /* horizontal margin sizes */
+#define MB93493_VDC_RVDC 0x158 /* vertical display period */
+#define MB93493_VDC_RV_MARGINS 0x15c /* vertical margin sizes */
+#define MB93493_VDC_RC 0x170 /* VDC control */
+#define MB93493_VDC_RCLOCK 0x174 /* clock divider, DMA req delay */
+#define MB93493_VDC_RBLACK 0x178 /* black insert sizes */
+#define MB93493_VDC_RS 0x17c /* VDC status */
+
+#define __addr_MB93493_VDC_BCI(X) ({ (volatile unsigned long *)(__region_CS3 + 0x000 + (X)); })
+#define __addr_MB93493_VDC_TPO(X) (__region_CS3 + 0x1c0 + (X))
+
+#define VDC_TPO_WIDTH 32
+
+#define VDC_RC_DSR 0x00000080 /* VDC master reset */
+
+#define VDC_RS_IT 0x00060000 /* interrupt indicators */
+#define VDC_RS_IT_UNDERFLOW 0x00040000 /* - underflow event */
+#define VDC_RS_IT_VSYNC 0x00020000 /* - VSYNC event */
+#define VDC_RS_DFI 0x00010000 /* current interlace field number */
+#define VDC_RS_DFI_TOP 0x00000000 /* - top field */
+#define VDC_RS_DFI_BOTTOM 0x00010000 /* - bottom field */
+#define VDC_RS_DCSR 0x00000010 /* cursor state */
+#define VDC_RS_DCM 0x00000003 /* display mode */
+#define VDC_RS_DCM_DISABLED 0x00000000 /* - display disabled */
+#define VDC_RS_DCM_STOPPED 0x00000001 /* - VDC stopped */
+#define VDC_RS_DCM_FREERUNNING 0x00000002 /* - VDC free-running */
+#define VDC_RS_DCM_TRANSFERRING 0x00000003 /* - data being transferred to VDC */
+
+/*
+ * video capture controller
+ */
+#define __get_MB93493_VCC(X) __get_MB93493(MB93493_VCC_##X)
+#define __set_MB93493_VCC(X,V) __set_MB93493(MB93493_VCC_##X, (V))
+
+#define MB93493_VCC_RREDUCT 0x104 /* reduction rate */
+#define MB93493_VCC_RHY 0x108 /* horizontal brightness filter coefficients */
+#define MB93493_VCC_RHC 0x10c /* horizontal colour-difference filter coefficients */
+#define MB93493_VCC_RHSIZE 0x110 /* horizontal cycle sizes */
+#define MB93493_VCC_RHBC 0x114 /* horizontal back porch size */
+#define MB93493_VCC_RVCC 0x118 /* vertical capture period */
+#define MB93493_VCC_RVBC 0x11c /* vertical back porch period */
+#define MB93493_VCC_RV 0x120 /* vertical filter coefficients */
+#define MB93493_VCC_RDTS 0x128 /* DMA transfer size */
+#define MB93493_VCC_RDTS_4B 0x01000000 /* 4-byte transfer */
+#define MB93493_VCC_RDTS_32B 0x03000000 /* 32-byte transfer */
+#define MB93493_VCC_RDTS_SHIFT 24
+#define MB93493_VCC_RCC 0x130 /* VCC control */
+#define MB93493_VCC_RIS 0x134 /* VCC interrupt status */
+
+#define __addr_MB93493_VCC_TPI(X) (__region_CS3 + 0x180 + (X))
+
+#define VCC_RHSIZE_RHCC 0x000007ff
+#define VCC_RHSIZE_RHCC_SHIFT 0
+#define VCC_RHSIZE_RHTCC 0x0fff0000
+#define VCC_RHSIZE_RHTCC_SHIFT 16
+
+#define VCC_RVBC_RVBC 0x00003f00
+#define VCC_RVBC_RVBC_SHIFT 8
+
+#define VCC_RREDUCT_RHR 0x07ff0000
+#define VCC_RREDUCT_RHR_SHIFT 16
+#define VCC_RREDUCT_RVR 0x000007ff
+#define VCC_RREDUCT_RVR_SHIFT 0
+
+#define VCC_RCC_CE 0x00000001 /* VCC enable */
+#define VCC_RCC_CS 0x00000002 /* request video capture start */
+#define VCC_RCC_CPF 0x0000000c /* pixel format */
+#define VCC_RCC_CPF_YCBCR_16 0x00000000 /* - YCbCr 4:2:2 16-bit format */
+#define VCC_RCC_CPF_RGB 0x00000004 /* - RGB 4:4:4 format */
+#define VCC_RCC_CPF_YCBCR_24 0x00000008 /* - YCbCr 4:2:2 24-bit format */
+#define VCC_RCC_CPF_BT656 0x0000000c /* - ITU R-BT.656 format */
+#define VCC_RCC_CPF_SHIFT 2
+#define VCC_RCC_CSR 0x00000080 /* request reset */
+#define VCC_RCC_HSIP 0x00000100 /* HSYNC polarity */
+#define VCC_RCC_HSIP_LOACT 0x00000000 /* - low active */
+#define VCC_RCC_HSIP_HIACT 0x00000100 /* - high active */
+#define VCC_RCC_VSIP 0x00000200 /* VSYNC polarity */
+#define VCC_RCC_VSIP_LOACT 0x00000000 /* - low active */
+#define VCC_RCC_VSIP_HIACT 0x00000200 /* - high active */
+#define VCC_RCC_CIE 0x00000800 /* interrupt enable */
+#define VCC_RCC_CFP 0x00001000 /* RGB pixel packing */
+#define VCC_RCC_CFP_4TO3 0x00000000 /* - pack 4 pixels into 3 words */
+#define VCC_RCC_CFP_1TO1 0x00001000 /* - pack 1 pixel into 1 words */
+#define VCC_RCC_CSM 0x00006000 /* interlace specification */
+#define VCC_RCC_CSM_ONEPASS 0x00002000 /* - non-interlaced */
+#define VCC_RCC_CSM_INTERLACE 0x00004000 /* - interlaced */
+#define VCC_RCC_CSM_SHIFT 13
+#define VCC_RCC_ES 0x00008000 /* capture start polarity */
+#define VCC_RCC_ES_NEG 0x00000000 /* - negative edge */
+#define VCC_RCC_ES_POS 0x00008000 /* - positive edge */
+#define VCC_RCC_IFI 0x00080000 /* inferlace field evaluation reverse */
+#define VCC_RCC_FDTS 0x00300000 /* interlace field start */
+#define VCC_RCC_FDTS_3_8 0x00000000 /* - 3/8 of horizontal entire cycle */
+#define VCC_RCC_FDTS_1_4 0x00100000 /* - 1/4 of horizontal entire cycle */
+#define VCC_RCC_FDTS_7_16 0x00200000 /* - 7/16 of horizontal entire cycle */
+#define VCC_RCC_FDTS_SHIFT 20
+#define VCC_RCC_MOV 0x00400000 /* test bit - always set to 1 */
+#define VCC_RCC_STP 0x00800000 /* request video capture stop */
+#define VCC_RCC_TO 0x01000000 /* input during top-field only */
+
+#define VCC_RIS_VSYNC 0x01000000 /* VSYNC interrupt */
+#define VCC_RIS_OV 0x02000000 /* overflow interrupt */
+#define VCC_RIS_BOTTOM 0x08000000 /* interlace bottom field */
+#define VCC_RIS_STARTED 0x10000000 /* capture started */
+
+/*
+ * I2C
+ */
+#define MB93493_I2C_BSR 0x340 /* bus status */
+#define MB93493_I2C_BCR 0x344 /* bus control */
+#define MB93493_I2C_CCR 0x348 /* clock control */
+#define MB93493_I2C_ADR 0x34c /* address */
+#define MB93493_I2C_DTR 0x350 /* data */
+#define MB93493_I2C_BC2R 0x35c /* bus control 2 */
+
+#define __addr_MB93493_I2C(port,X) (__region_CS3 + MB93493_I2C_##X + ((port)*0x20))
+#define __get_MB93493_I2C(port,X) __get_MB93493(MB93493_I2C_##X + ((port)*0x20))
+#define __set_MB93493_I2C(port,X,V) __set_MB93493(MB93493_I2C_##X + ((port)*0x20), (V))
+
+#define I2C_BSR_BB (1 << 7)
+
+/*
+ * audio controller (I2S) registers
+ */
+#define __get_MB93493_I2S(X) __get_MB93493(MB93493_I2S_##X)
+#define __set_MB93493_I2S(X,V) __set_MB93493(MB93493_I2S_##X, (V))
+
+#define MB93493_I2S_ALDR 0x300 /* L-channel data */
+#define MB93493_I2S_ARDR 0x304 /* R-channel data */
+#define MB93493_I2S_APDR 0x308 /* 16-bit packed data */
+#define MB93493_I2S_AISTR 0x310 /* status */
+#define MB93493_I2S_AICR 0x314 /* control */
+
+#define __addr_MB93493_I2S_ALDR(X) (__region_CS3 + MB93493_I2S_ALDR + (X))
+#define __addr_MB93493_I2S_ARDR(X) (__region_CS3 + MB93493_I2S_ARDR + (X))
+#define __addr_MB93493_I2S_APDR(X) (__region_CS3 + MB93493_I2S_APDR + (X))
+#define __addr_MB93493_I2S_ADR(X) (__region_CS3 + 0x320 + (X))
+
+#define I2S_AISTR_OTST 0x00000003 /* status of output data transfer */
+#define I2S_AISTR_OTR 0x00000010 /* output transfer request pending */
+#define I2S_AISTR_OUR 0x00000020 /* output FIFO underrun detected */
+#define I2S_AISTR_OOR 0x00000040 /* output FIFO overrun detected */
+#define I2S_AISTR_ODS 0x00000100 /* output DMA transfer size */
+#define I2S_AISTR_ODE 0x00000400 /* output DMA transfer request enable */
+#define I2S_AISTR_OTRIE 0x00001000 /* output transfer request interrupt enable */
+#define I2S_AISTR_OURIE 0x00002000 /* output FIFO underrun interrupt enable */
+#define I2S_AISTR_OORIE 0x00004000 /* output FIFO overrun interrupt enable */
+#define I2S_AISTR__OUT_MASK 0x00007570
+#define I2S_AISTR_ITST 0x00030000 /* status of input data transfer */
+#define I2S_AISTR_ITST_SHIFT 16
+#define I2S_AISTR_ITR 0x00100000 /* input transfer request pending */
+#define I2S_AISTR_IUR 0x00200000 /* input FIFO underrun detected */
+#define I2S_AISTR_IOR 0x00400000 /* input FIFO overrun detected */
+#define I2S_AISTR_IDS 0x01000000 /* input DMA transfer size */
+#define I2S_AISTR_IDE 0x04000000 /* input DMA transfer request enable */
+#define I2S_AISTR_ITRIE 0x10000000 /* input transfer request interrupt enable */
+#define I2S_AISTR_IURIE 0x20000000 /* input FIFO underrun interrupt enable */
+#define I2S_AISTR_IORIE 0x40000000 /* input FIFO overrun interrupt enable */
+#define I2S_AISTR__IN_MASK 0x75700000
+
+#define I2S_AICR_MI 0x00000001 /* mono input requested */
+#define I2S_AICR_AMI 0x00000002 /* relation between LRCKI/FS1 and SDI */
+#define I2S_AICR_LRI 0x00000004 /* function of LRCKI pin */
+#define I2S_AICR_SDMI 0x00000070 /* format of input audio data */
+#define I2S_AICR_SDMI_SHIFT 4
+#define I2S_AICR_CLI 0x00000080 /* input FIFO clearing control */
+#define I2S_AICR_IM 0x00000300 /* input state control */
+#define I2S_AICR_IM_SHIFT 8
+#define I2S_AICR__IN_MASK 0x000003f7
+#define I2S_AICR_MO 0x00001000 /* mono output requested */
+#define I2S_AICR_AMO 0x00002000 /* relation between LRCKO/FS0 and SDO */
+#define I2S_AICR_AMO_SHIFT 13
+#define I2S_AICR_LRO 0x00004000 /* function of LRCKO pin */
+#define I2S_AICR_SDMO 0x00070000 /* format of output audio data */
+#define I2S_AICR_SDMO_SHIFT 16
+#define I2S_AICR_CLO 0x00080000 /* output FIFO clearing control */
+#define I2S_AICR_OM 0x00100000 /* output state control */
+#define I2S_AICR__OUT_MASK 0x001f7000
+#define I2S_AICR_DIV 0x03000000 /* frequency division rate */
+#define I2S_AICR_DIV_SHIFT 24
+#define I2S_AICR_FL 0x20000000 /* frame length */
+#define I2S_AICR_FS 0x40000000 /* frame sync method */
+#define I2S_AICR_ME 0x80000000 /* master enable */
+
+/*
+ * PCMCIA
+ */
+#define __addr_MB93493_PCMCIA(X) ((volatile unsigned long *)(__region_CS5 + (X)))
+
+/*
+ * GPIO
+ */
+#define __get_MB93493_GPIO_PDR(X) __get_MB93493(0x380 + (X) * 0xc0)
+#define __set_MB93493_GPIO_PDR(X,V) __set_MB93493(0x380 + (X) * 0xc0, (V))
+
+#define __get_MB93493_GPIO_GPDR(X) __get_MB93493(0x384 + (X) * 0xc0)
+#define __set_MB93493_GPIO_GPDR(X,V) __set_MB93493(0x384 + (X) * 0xc0, (V))
+
+#define __get_MB93493_GPIO_SIR(X) __get_MB93493(0x388 + (X) * 0xc0)
+#define __set_MB93493_GPIO_SIR(X,V) __set_MB93493(0x388 + (X) * 0xc0, (V))
+
+#define __get_MB93493_GPIO_SOR(X) __get_MB93493(0x38c + (X) * 0xc0)
+#define __set_MB93493_GPIO_SOR(X,V) __set_MB93493(0x38c + (X) * 0xc0, (V))
+
+#define __get_MB93493_GPIO_PDSR(X) __get_MB93493(0x390 + (X) * 0xc0)
+#define __set_MB93493_GPIO_PDSR(X,V) __set_MB93493(0x390 + (X) * 0xc0, (V))
+
+#define __get_MB93493_GPIO_PDCR(X) __get_MB93493(0x394 + (X) * 0xc0)
+#define __set_MB93493_GPIO_PDCR(X,V) __set_MB93493(0x394 + (X) * 0xc0, (V))
+
+#define __get_MB93493_GPIO_INTST(X) __get_MB93493(0x398 + (X) * 0xc0)
+#define __set_MB93493_GPIO_INTST(X,V) __set_MB93493(0x398 + (X) * 0xc0, (V))
+
+#define __get_MB93493_GPIO_IEHL(X) __get_MB93493(0x39c + (X) * 0xc0)
+#define __set_MB93493_GPIO_IEHL(X,V) __set_MB93493(0x39c + (X) * 0xc0, (V))
+
+#define __get_MB93493_GPIO_IELH(X) __get_MB93493(0x3a0 + (X) * 0xc0)
+#define __set_MB93493_GPIO_IELH(X,V) __set_MB93493(0x3a0 + (X) * 0xc0, (V))
+
+#endif /* _ASM_MB93493_REGS_H */
diff --git a/arch/frv/include/asm/mc146818rtc.h b/arch/frv/include/asm/mc146818rtc.h
new file mode 100644
index 00000000000..90dfb7a633d
--- /dev/null
+++ b/arch/frv/include/asm/mc146818rtc.h
@@ -0,0 +1,16 @@
+/* mc146818rtc.h: RTC defs
+ *
+ * Copyright (C) 2005 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_MC146818RTC_H
+#define _ASM_MC146818RTC_H
+
+
+#endif /* _ASM_MC146818RTC_H */
diff --git a/arch/frv/include/asm/mem-layout.h b/arch/frv/include/asm/mem-layout.h
new file mode 100644
index 00000000000..e9a0ec85a40
--- /dev/null
+++ b/arch/frv/include/asm/mem-layout.h
@@ -0,0 +1,86 @@
+/* mem-layout.h: memory layout
+ *
+ * Copyright (C) 2004 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_MEM_LAYOUT_H
+#define _ASM_MEM_LAYOUT_H
+
+#ifndef __ASSEMBLY__
+#define __UL(X) ((unsigned long) (X))
+#else
+#define __UL(X) (X)
+#endif
+
+/*
+ * PAGE_SHIFT determines the page size
+ */
+#define PAGE_SHIFT 14
+
+#ifndef __ASSEMBLY__
+#define PAGE_SIZE (1UL << PAGE_SHIFT)
+#else
+#define PAGE_SIZE (1 << PAGE_SHIFT)
+#endif
+
+#define PAGE_MASK (~(PAGE_SIZE-1))
+
+/*
+ * the slab must be aligned such that load- and store-double instructions don't
+ * fault if used
+ */
+#define ARCH_DMA_MINALIGN L1_CACHE_BYTES
+#define ARCH_SLAB_MINALIGN L1_CACHE_BYTES
+
+/*****************************************************************************/
+/*
+ * virtual memory layout from kernel's point of view
+ */
+#define PAGE_OFFSET ((unsigned long) &__page_offset)
+
+#ifdef CONFIG_MMU
+
+/* see Documentation/frv/mmu-layout.txt */
+#define KERNEL_LOWMEM_START __UL(0xc0000000)
+#define KERNEL_LOWMEM_END __UL(0xd0000000)
+#define VMALLOC_START __UL(0xd0000000)
+#define VMALLOC_END __UL(0xd8000000)
+#define PKMAP_BASE __UL(0xd8000000)
+#define PKMAP_END __UL(0xdc000000)
+#define KMAP_ATOMIC_SECONDARY_FRAME __UL(0xdc000000)
+#define KMAP_ATOMIC_PRIMARY_FRAME __UL(0xdd000000)
+
+#endif
+
+#define KERNEL_IO_START __UL(0xe0000000)
+
+
+/*****************************************************************************/
+/*
+ * memory layout from userspace's point of view
+ */
+#define BRK_BASE __UL(2 * 1024 * 1024 + PAGE_SIZE)
+#define STACK_TOP __UL(2 * 1024 * 1024)
+#define STACK_TOP_MAX __UL(0xc0000000)
+
+/* userspace process size */
+#ifdef CONFIG_MMU
+#define TASK_SIZE (PAGE_OFFSET)
+#else
+#define TASK_SIZE __UL(0xFFFFFFFFUL)
+#endif
+
+/* base of area at which unspecified mmaps will start */
+#ifdef CONFIG_BINFMT_ELF_FDPIC
+#define TASK_UNMAPPED_BASE __UL(16 * 1024 * 1024)
+#else
+#define TASK_UNMAPPED_BASE __UL(TASK_SIZE / 3)
+#endif
+
+#endif /* _ASM_MEM_LAYOUT_H */
diff --git a/arch/frv/include/asm/mmu.h b/arch/frv/include/asm/mmu.h
new file mode 100644
index 00000000000..86ca0e86e7d
--- /dev/null
+++ b/arch/frv/include/asm/mmu.h
@@ -0,0 +1,41 @@
+/* mmu.h: memory management context for FR-V with or without MMU support
+ *
+ * Copyright (C) 2004 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _ASM_MMU_H
+#define _ASM_MMU_H
+
+typedef struct {
+#ifdef CONFIG_MMU
+ struct list_head id_link; /* link in list of context ID owners */
+ unsigned short id; /* MMU context ID */
+ unsigned short id_busy; /* true if ID is in CXNR */
+ unsigned long itlb_cached_pge; /* [SCR0] PGE cached for insn TLB handler */
+ unsigned long itlb_ptd_mapping; /* [DAMR4] PTD mapping for itlb cached PGE */
+ unsigned long dtlb_cached_pge; /* [SCR1] PGE cached for data TLB handler */
+ unsigned long dtlb_ptd_mapping; /* [DAMR5] PTD mapping for dtlb cached PGE */
+
+#else
+ unsigned long end_brk;
+
+#endif
+
+#ifdef CONFIG_BINFMT_ELF_FDPIC
+ unsigned long exec_fdpic_loadmap;
+ unsigned long interp_fdpic_loadmap;
+#endif
+
+} mm_context_t;
+
+#ifdef CONFIG_MMU
+extern int __nongpreldata cxn_pinned;
+extern int cxn_pin_by_pid(pid_t pid);
+#endif
+
+#endif /* _ASM_MMU_H */
diff --git a/arch/frv/include/asm/mmu_context.h b/arch/frv/include/asm/mmu_context.h
new file mode 100644
index 00000000000..c7daa395156
--- /dev/null
+++ b/arch/frv/include/asm/mmu_context.h
@@ -0,0 +1,50 @@
+/* mmu_context.h: MMU context management routines
+ *
+ * Copyright (C) 2004 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_MMU_CONTEXT_H
+#define _ASM_MMU_CONTEXT_H
+
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+#include <asm-generic/mm_hooks.h>
+
+static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
+{
+}
+
+#ifdef CONFIG_MMU
+extern int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
+extern void change_mm_context(mm_context_t *old, mm_context_t *ctx, pgd_t *_pgd);
+extern void destroy_context(struct mm_struct *mm);
+
+#else
+#define init_new_context(tsk, mm) ({ 0; })
+#define change_mm_context(old, ctx, _pml4) do {} while(0)
+#define destroy_context(mm) do {} while(0)
+#endif
+
+#define switch_mm(prev, next, tsk) \
+do { \
+ if (prev != next) \
+ change_mm_context(&prev->context, &next->context, next->pgd); \
+} while(0)
+
+#define activate_mm(prev, next) \
+do { \
+ change_mm_context(&prev->context, &next->context, next->pgd); \
+} while(0)
+
+#define deactivate_mm(tsk, mm) \
+do { \
+} while(0)
+
+#endif
diff --git a/arch/frv/include/asm/module.h b/arch/frv/include/asm/module.h
new file mode 100644
index 00000000000..a8848f09a21
--- /dev/null
+++ b/arch/frv/include/asm/module.h
@@ -0,0 +1,22 @@
+/* module.h: FRV module stuff
+ *
+ * Copyright (C) 2004 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _ASM_MODULE_H
+#define _ASM_MODULE_H
+
+#include <asm-generic/module.h>
+
+/*
+ * Include the architecture version.
+ */
+#define MODULE_ARCH_VERMAGIC __stringify(PROCESSOR_MODEL_NAME) " "
+
+#endif /* _ASM_MODULE_H */
+
diff --git a/arch/frv/include/asm/mutex.h b/arch/frv/include/asm/mutex.h
new file mode 100644
index 00000000000..458c1f7fbc1
--- /dev/null
+++ b/arch/frv/include/asm/mutex.h
@@ -0,0 +1,9 @@
+/*
+ * Pull in the generic implementation for the mutex fastpath.
+ *
+ * TODO: implement optimized primitives instead, or leave the generic
+ * implementation in place, or pick the atomic_xchg() based generic
+ * implementation. (see asm-generic/mutex-xchg.h for details)
+ */
+
+#include <asm-generic/mutex-dec.h>
diff --git a/arch/frv/include/asm/page.h b/arch/frv/include/asm/page.h
new file mode 100644
index 00000000000..8c97068ac8f
--- /dev/null
+++ b/arch/frv/include/asm/page.h
@@ -0,0 +1,76 @@
+#ifndef _ASM_PAGE_H
+#define _ASM_PAGE_H
+
+#include <asm/virtconvert.h>
+#include <asm/mem-layout.h>
+#include <asm/sections.h>
+#include <asm/setup.h>
+
+#ifndef __ASSEMBLY__
+
+#define get_user_page(vaddr) __get_free_page(GFP_KERNEL)
+#define free_user_page(page, addr) free_page(addr)
+
+#define clear_page(pgaddr) memset((pgaddr), 0, PAGE_SIZE)
+#define copy_page(to,from) memcpy((to), (from), PAGE_SIZE)
+
+#define clear_user_page(pgaddr, vaddr, page) memset((pgaddr), 0, PAGE_SIZE)
+#define copy_user_page(vto, vfrom, vaddr, topg) memcpy((vto), (vfrom), PAGE_SIZE)
+
+/*
+ * These are used to make use of C type-checking..
+ */
+typedef struct { unsigned long pte; } pte_t;
+typedef struct { unsigned long ste[64];} pmd_t;
+typedef struct { pmd_t pue[1]; } pud_t;
+typedef struct { pud_t pge[1]; } pgd_t;
+typedef struct { unsigned long pgprot; } pgprot_t;
+typedef struct page *pgtable_t;
+
+#define pte_val(x) ((x).pte)
+#define pmd_val(x) ((x).ste[0])
+#define pud_val(x) ((x).pue[0])
+#define pgd_val(x) ((x).pge[0])
+#define pgprot_val(x) ((x).pgprot)
+
+#define __pte(x) ((pte_t) { (x) } )
+#define __pmd(x) ((pmd_t) { (x) } )
+#define __pud(x) ((pud_t) { (x) } )
+#define __pgd(x) ((pgd_t) { (x) } )
+#define __pgprot(x) ((pgprot_t) { (x) } )
+#define PTE_MASK PAGE_MASK
+
+#define devmem_is_allowed(pfn) 1
+
+#define __pa(vaddr) virt_to_phys((void *) (unsigned long) (vaddr))
+#define __va(paddr) phys_to_virt((unsigned long) (paddr))
+
+#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
+
+extern unsigned long max_low_pfn;
+extern unsigned long min_low_pfn;
+extern unsigned long max_pfn;
+
+#ifdef CONFIG_MMU
+#define pfn_valid(pfn) ((pfn) < max_mapnr)
+#else
+#define ARCH_PFN_OFFSET (PAGE_OFFSET >> PAGE_SHIFT)
+#define pfn_valid(pfn) ((pfn) >= min_low_pfn && (pfn) < max_low_pfn)
+
+#endif
+
+#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
+#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
+
+
+#define VM_DATA_DEFAULT_FLAGS \
+ (VM_READ | VM_WRITE | \
+ ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
+ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
+#endif /* __ASSEMBLY__ */
+
+#include <asm-generic/memory_model.h>
+#include <asm-generic/getorder.h>
+
+#endif /* _ASM_PAGE_H */
diff --git a/arch/frv/include/asm/pci.h b/arch/frv/include/asm/pci.h
new file mode 100644
index 00000000000..2035a4d3f9b
--- /dev/null
+++ b/arch/frv/include/asm/pci.h
@@ -0,0 +1,61 @@
+/* pci.h: FR-V specific PCI declarations
+ *
+ * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ * - Derived from include/asm-m68k/pci.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_FRV_PCI_H
+#define _ASM_FRV_PCI_H
+
+#include <linux/mm.h>
+#include <asm/scatterlist.h>
+#include <asm-generic/pci-dma-compat.h>
+#include <asm-generic/pci.h>
+
+struct pci_dev;
+
+#define pcibios_assign_all_busses() 0
+
+extern void pcibios_set_master(struct pci_dev *dev);
+
+#ifdef CONFIG_MMU
+extern void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *dma_handle);
+extern void consistent_free(void *vaddr);
+extern void consistent_sync(void *vaddr, size_t size, int direction);
+extern void consistent_sync_page(struct page *page, unsigned long offset,
+ size_t size, int direction);
+#endif
+
+extern void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
+ dma_addr_t *dma_handle);
+
+extern void pci_free_consistent(struct pci_dev *hwdev, size_t size,
+ void *vaddr, dma_addr_t dma_handle);
+
+/* Return the index of the PCI controller for device PDEV. */
+#define pci_controller_num(PDEV) (0)
+
+#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
+
+/*
+ * These are pretty much arbitrary with the CoMEM implementation.
+ * We have the whole address space to ourselves.
+ */
+#define PCIBIOS_MIN_IO 0x100
+#define PCIBIOS_MIN_MEM 0x00010000
+
+#endif /* _ASM_FRV_PCI_H */
diff --git a/arch/frv/include/asm/percpu.h b/arch/frv/include/asm/percpu.h
new file mode 100644
index 00000000000..2cad3f874de
--- /dev/null
+++ b/arch/frv/include/asm/percpu.h
@@ -0,0 +1,6 @@
+#ifndef __ASM_PERCPU_H
+#define __ASM_PERCPU_H
+
+#include <asm-generic/percpu.h>
+
+#endif /* __ASM_PERCPU_H */
diff --git a/arch/frv/include/asm/perf_event.h b/arch/frv/include/asm/perf_event.h
new file mode 100644
index 00000000000..c52ea5546b5
--- /dev/null
+++ b/arch/frv/include/asm/perf_event.h
@@ -0,0 +1,15 @@
+/* FRV performance event support
+ *
+ * Copyright (C) 2009 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_PERF_EVENT_H
+#define _ASM_PERF_EVENT_H
+
+#endif /* _ASM_PERF_EVENT_H */
diff --git a/arch/frv/include/asm/pgalloc.h b/arch/frv/include/asm/pgalloc.h
new file mode 100644
index 00000000000..416d19a632f
--- /dev/null
+++ b/arch/frv/include/asm/pgalloc.h
@@ -0,0 +1,69 @@
+/* pgalloc.h: Page allocation routines for FRV
+ *
+ * Copyright (C) 2004 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Derived from:
+ * include/asm-m68knommu/pgalloc.h
+ * include/asm-i386/pgalloc.h
+ */
+#ifndef _ASM_PGALLOC_H
+#define _ASM_PGALLOC_H
+
+#include <asm/setup.h>
+#include <asm/virtconvert.h>
+
+#ifdef CONFIG_MMU
+
+#define pmd_populate_kernel(mm, pmd, pte) __set_pmd(pmd, __pa(pte) | _PAGE_TABLE)
+#define pmd_populate(MM, PMD, PAGE) \
+do { \
+ __set_pmd((PMD), page_to_pfn(PAGE) << PAGE_SHIFT | _PAGE_TABLE); \
+} while(0)
+#define pmd_pgtable(pmd) pmd_page(pmd)
+
+/*
+ * Allocate and free page tables.
+ */
+
+extern pgd_t *pgd_alloc(struct mm_struct *);
+extern void pgd_free(struct mm_struct *mm, pgd_t *);
+
+extern pte_t *pte_alloc_one_kernel(struct mm_struct *, unsigned long);
+
+extern pgtable_t pte_alloc_one(struct mm_struct *, unsigned long);
+
+static inline void pte_free_kernel(struct mm_struct *mm, pte_t *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);
+}
+
+#define __pte_free_tlb(tlb,pte,address) \
+do { \
+ pgtable_page_dtor(pte); \
+ tlb_remove_page((tlb),(pte)); \
+} while (0)
+
+/*
+ * allocating and freeing a pmd is trivial: the 1-entry pmd is
+ * inside the pgd, so has no extra memory associated with it.
+ * (In the PAE case we free the pmds as part of the pgd.)
+ */
+#define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *) 2); })
+#define pmd_free(mm, x) do { } while (0)
+#define __pmd_free_tlb(tlb,x,a) do { } while (0)
+
+#endif /* CONFIG_MMU */
+
+#endif /* _ASM_PGALLOC_H */
diff --git a/arch/frv/include/asm/pgtable.h b/arch/frv/include/asm/pgtable.h
new file mode 100644
index 00000000000..eb0110acd19
--- /dev/null
+++ b/arch/frv/include/asm/pgtable.h
@@ -0,0 +1,541 @@
+/* pgtable.h: FR-V page table mangling
+ *
+ * Copyright (C) 2004 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Derived from:
+ * include/asm-m68knommu/pgtable.h
+ * include/asm-i386/pgtable.h
+ */
+
+#ifndef _ASM_PGTABLE_H
+#define _ASM_PGTABLE_H
+
+#include <asm/mem-layout.h>
+#include <asm/setup.h>
+#include <asm/processor.h>
+
+#ifndef __ASSEMBLY__
+#include <linux/threads.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/sched.h>
+struct vm_area_struct;
+#endif
+
+#ifndef __ASSEMBLY__
+#if defined(CONFIG_HIGHPTE)
+typedef unsigned long pte_addr_t;
+#else
+typedef pte_t *pte_addr_t;
+#endif
+#endif
+
+/*****************************************************************************/
+/*
+ * MMU-less operation case first
+ */
+#ifndef CONFIG_MMU
+
+#define pgd_present(pgd) (1) /* pages are always present on NO_MM */
+#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)
+
+#define PAGE_NONE __pgprot(0) /* these mean nothing to NO_MM */
+#define PAGE_SHARED __pgprot(0) /* these mean nothing to NO_MM */
+#define PAGE_COPY __pgprot(0) /* these mean nothing to NO_MM */
+#define PAGE_READONLY __pgprot(0) /* these mean nothing to NO_MM */
+#define PAGE_KERNEL __pgprot(0) /* these mean nothing to NO_MM */
+
+#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 })
+
+#ifndef __ASSEMBLY__
+static inline int pte_file(pte_t pte) { return 0; }
+#endif
+
+#define ZERO_PAGE(vaddr) ({ BUG(); NULL; })
+
+#define swapper_pg_dir ((pgd_t *) NULL)
+
+#define pgtable_cache_init() do {} while (0)
+
+#include <asm-generic/pgtable.h>
+
+#else /* !CONFIG_MMU */
+/*****************************************************************************/
+/*
+ * then MMU operation
+ */
+
+/*
+ * ZERO_PAGE is a global shared page that is always zero: used
+ * for zero-mapped memory areas etc..
+ */
+#ifndef __ASSEMBLY__
+extern unsigned long empty_zero_page;
+#define ZERO_PAGE(vaddr) virt_to_page(empty_zero_page)
+#endif
+
+/*
+ * we use 2-level page tables, folding the PMD (mid-level table) into the PGE (top-level entry)
+ * [see Documentation/frv/mmu-layout.txt]
+ *
+ * Page Directory:
+ * - Size: 16KB
+ * - 64 PGEs per PGD
+ * - Each PGE holds 1 PUD and covers 64MB
+ *
+ * Page Upper Directory:
+ * - Size: 256B
+ * - 1 PUE per PUD
+ * - Each PUE holds 1 PMD and covers 64MB
+ *
+ * Page Mid-Level Directory
+ * - Size: 256B
+ * - 1 PME per PMD
+ * - Each PME holds 64 STEs, all of which point to separate chunks of the same Page Table
+ * - All STEs are instantiated at the same time
+ *
+ * Page Table
+ * - Size: 16KB
+ * - 4096 PTEs per PT
+ * - Each Linux PT is subdivided into 64 FR451 PT's, each of which holds 64 entries
+ *
+ * Pages
+ * - Size: 4KB
+ *
+ * total PTEs
+ * = 1 PML4E * 64 PGEs * 1 PUEs * 1 PMEs * 4096 PTEs
+ * = 1 PML4E * 64 PGEs * 64 STEs * 64 PTEs/FR451-PT
+ * = 262144 (or 256 * 1024)
+ */
+#define PGDIR_SHIFT 26
+#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
+#define PGDIR_MASK (~(PGDIR_SIZE - 1))
+#define PTRS_PER_PGD 64
+
+#define PUD_SHIFT 26
+#define PTRS_PER_PUD 1
+#define PUD_SIZE (1UL << PUD_SHIFT)
+#define PUD_MASK (~(PUD_SIZE - 1))
+#define PUE_SIZE 256
+
+#define PMD_SHIFT 26
+#define PMD_SIZE (1UL << PMD_SHIFT)
+#define PMD_MASK (~(PMD_SIZE - 1))
+#define PTRS_PER_PMD 1
+#define PME_SIZE 256
+
+#define __frv_PT_SIZE 256
+
+#define PTRS_PER_PTE 4096
+
+#define USER_PGDS_IN_LAST_PML4 (TASK_SIZE / PGDIR_SIZE)
+#define FIRST_USER_ADDRESS 0
+
+#define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT)
+#define KERNEL_PGD_PTRS (PTRS_PER_PGD - USER_PGD_PTRS)
+
+#define TWOLEVEL_PGDIR_SHIFT 26
+#define BOOT_USER_PGD_PTRS (__PAGE_OFFSET >> TWOLEVEL_PGDIR_SHIFT)
+#define BOOT_KERNEL_PGD_PTRS (PTRS_PER_PGD - BOOT_USER_PGD_PTRS)
+
+#ifndef __ASSEMBLY__
+
+extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
+
+#define pte_ERROR(e) \
+ printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, (e).pte)
+#define pmd_ERROR(e) \
+ printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
+#define pud_ERROR(e) \
+ printk("%s:%d: bad pud %08lx.\n", __FILE__, __LINE__, pmd_val(pud_val(e)))
+#define pgd_ERROR(e) \
+ printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pmd_val(pud_val(pgd_val(e))))
+
+/*
+ * Certain architectures need to do special things when PTEs
+ * within a page table are directly modified. Thus, the following
+ * hook is made available.
+ */
+#define set_pte(pteptr, pteval) \
+do { \
+ *(pteptr) = (pteval); \
+ asm volatile("dcf %M0" :: "U"(*pteptr)); \
+} while(0)
+#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
+
+/*
+ * pgd_offset() returns a (pgd_t *)
+ * pgd_index() is used get the offset into the pgd page's array of pgd_t's;
+ */
+#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
+
+/*
+ * a shortcut which implies the use of the kernel's pgd, instead
+ * of a process's
+ */
+#define pgd_offset_k(address) pgd_offset(&init_mm, address)
+
+/*
+ * The "pgd_xxx()" functions here are trivial for a folded two-level
+ * setup: the pud is never bad, and a pud always exists (as it's folded
+ * into the pgd entry)
+ */
+static inline int pgd_none(pgd_t pgd) { return 0; }
+static inline int pgd_bad(pgd_t pgd) { return 0; }
+static inline int pgd_present(pgd_t pgd) { return 1; }
+static inline void pgd_clear(pgd_t *pgd) { }
+
+#define pgd_populate(mm, pgd, pud) do { } while (0)
+/*
+ * (puds are folded into pgds so this doesn't get actually called,
+ * but the define is needed for a generic inline function.)
+ */
+#define set_pgd(pgdptr, pgdval) \
+do { \
+ memcpy((pgdptr), &(pgdval), sizeof(pgd_t)); \
+ asm volatile("dcf %M0" :: "U"(*(pgdptr))); \
+} while(0)
+
+static inline pud_t *pud_offset(pgd_t *pgd, unsigned long address)
+{
+ return (pud_t *) pgd;
+}
+
+#define pgd_page(pgd) (pud_page((pud_t){ pgd }))
+#define pgd_page_vaddr(pgd) (pud_page_vaddr((pud_t){ pgd }))
+
+/*
+ * allocating and freeing a pud is trivial: the 1-entry pud is
+ * inside the pgd, so has no extra memory associated with it.
+ */
+#define pud_alloc_one(mm, address) NULL
+#define pud_free(mm, x) do { } while (0)
+#define __pud_free_tlb(tlb, x, address) do { } while (0)
+
+/*
+ * The "pud_xxx()" functions here are trivial for a folded two-level
+ * setup: the pmd is never bad, and a pmd always exists (as it's folded
+ * into the pud entry)
+ */
+static inline int pud_none(pud_t pud) { return 0; }
+static inline int pud_bad(pud_t pud) { return 0; }
+static inline int pud_present(pud_t pud) { return 1; }
+static inline void pud_clear(pud_t *pud) { }
+
+#define pud_populate(mm, pmd, pte) do { } while (0)
+
+/*
+ * (pmds are folded into puds so this doesn't get actually called,
+ * but the define is needed for a generic inline function.)
+ */
+#define set_pud(pudptr, pudval) set_pmd((pmd_t *)(pudptr), (pmd_t) { pudval })
+
+#define pud_page(pud) (pmd_page((pmd_t){ pud }))
+#define pud_page_vaddr(pud) (pmd_page_vaddr((pmd_t){ pud }))
+
+/*
+ * (pmds are folded into pgds so this doesn't get actually called,
+ * but the define is needed for a generic inline function.)
+ */
+extern void __set_pmd(pmd_t *pmdptr, unsigned long __pmd);
+
+#define set_pmd(pmdptr, pmdval) \
+do { \
+ __set_pmd((pmdptr), (pmdval).ste[0]); \
+} while(0)
+
+#define __pmd_index(address) 0
+
+static inline pmd_t *pmd_offset(pud_t *dir, unsigned long address)
+{
+ return (pmd_t *) dir + __pmd_index(address);
+}
+
+#define pte_same(a, b) ((a).pte == (b).pte)
+#define pte_page(x) (mem_map + ((unsigned long)(((x).pte >> PAGE_SHIFT))))
+#define pte_none(x) (!(x).pte)
+#define pte_pfn(x) ((unsigned long)(((x).pte >> PAGE_SHIFT)))
+#define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
+#define pfn_pmd(pfn, prot) __pmd(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
+
+#define VMALLOC_VMADDR(x) ((unsigned long) (x))
+
+#endif /* !__ASSEMBLY__ */
+
+/*
+ * control flags in AMPR registers and TLB entries
+ */
+#define _PAGE_BIT_PRESENT xAMPRx_V_BIT
+#define _PAGE_BIT_WP DAMPRx_WP_BIT
+#define _PAGE_BIT_NOCACHE xAMPRx_C_BIT
+#define _PAGE_BIT_SUPER xAMPRx_S_BIT
+#define _PAGE_BIT_ACCESSED xAMPRx_RESERVED8_BIT
+#define _PAGE_BIT_DIRTY xAMPRx_M_BIT
+#define _PAGE_BIT_NOTGLOBAL xAMPRx_NG_BIT
+
+#define _PAGE_PRESENT xAMPRx_V
+#define _PAGE_WP DAMPRx_WP
+#define _PAGE_NOCACHE xAMPRx_C
+#define _PAGE_SUPER xAMPRx_S
+#define _PAGE_ACCESSED xAMPRx_RESERVED8 /* accessed if set */
+#define _PAGE_DIRTY xAMPRx_M
+#define _PAGE_NOTGLOBAL xAMPRx_NG
+
+#define _PAGE_RESERVED_MASK (xAMPRx_RESERVED8 | xAMPRx_RESERVED13)
+
+#define _PAGE_FILE 0x002 /* set:pagecache unset:swap */
+#define _PAGE_PROTNONE 0x000 /* If not present */
+
+#define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
+
+#define __PGPROT_BASE \
+ (_PAGE_PRESENT | xAMPRx_SS_16Kb | xAMPRx_D | _PAGE_NOTGLOBAL | _PAGE_ACCESSED)
+
+#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
+#define PAGE_SHARED __pgprot(__PGPROT_BASE)
+#define PAGE_COPY __pgprot(__PGPROT_BASE | _PAGE_WP)
+#define PAGE_READONLY __pgprot(__PGPROT_BASE | _PAGE_WP)
+
+#define __PAGE_KERNEL (__PGPROT_BASE | _PAGE_SUPER | _PAGE_DIRTY)
+#define __PAGE_KERNEL_NOCACHE (__PGPROT_BASE | _PAGE_SUPER | _PAGE_DIRTY | _PAGE_NOCACHE)
+#define __PAGE_KERNEL_RO (__PGPROT_BASE | _PAGE_SUPER | _PAGE_DIRTY | _PAGE_WP)
+
+#define MAKE_GLOBAL(x) __pgprot((x) & ~_PAGE_NOTGLOBAL)
+
+#define PAGE_KERNEL MAKE_GLOBAL(__PAGE_KERNEL)
+#define PAGE_KERNEL_RO MAKE_GLOBAL(__PAGE_KERNEL_RO)
+#define PAGE_KERNEL_NOCACHE MAKE_GLOBAL(__PAGE_KERNEL_NOCACHE)
+
+#define _PAGE_TABLE (_PAGE_PRESENT | xAMPRx_SS_16Kb)
+
+#ifndef __ASSEMBLY__
+
+/*
+ * The FR451 can do execute protection by virtue of having separate TLB miss handlers for
+ * instruction access and for data access. However, we don't have enough reserved bits to say
+ * "execute only", so we don't bother. If you can read it, you can execute it and vice versa.
+ */
+#define __P000 PAGE_NONE
+#define __P001 PAGE_READONLY
+#define __P010 PAGE_COPY
+#define __P011 PAGE_COPY
+#define __P100 PAGE_READONLY
+#define __P101 PAGE_READONLY
+#define __P110 PAGE_COPY
+#define __P111 PAGE_COPY
+
+#define __S000 PAGE_NONE
+#define __S001 PAGE_READONLY
+#define __S010 PAGE_SHARED
+#define __S011 PAGE_SHARED
+#define __S100 PAGE_READONLY
+#define __S101 PAGE_READONLY
+#define __S110 PAGE_SHARED
+#define __S111 PAGE_SHARED
+
+/*
+ * Define this to warn about kernel memory accesses that are
+ * done without a 'access_ok(VERIFY_WRITE,..)'
+ */
+#undef TEST_ACCESS_OK
+
+#define pte_present(x) (pte_val(x) & _PAGE_PRESENT)
+#define pte_clear(mm,addr,xp) do { set_pte_at(mm, addr, xp, __pte(0)); } while (0)
+
+#define pmd_none(x) (!pmd_val(x))
+#define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT)
+#define pmd_bad(x) (pmd_val(x) & xAMPRx_SS)
+#define pmd_clear(xp) do { __set_pmd(xp, 0); } while(0)
+
+#define pmd_page_vaddr(pmd) \
+ ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
+
+#ifndef CONFIG_DISCONTIGMEM
+#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
+#endif
+
+#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
+
+/*
+ * The following only work if pte_present() is true.
+ * Undefined behaviour if not..
+ */
+static inline int pte_dirty(pte_t pte) { return (pte).pte & _PAGE_DIRTY; }
+static inline int pte_young(pte_t pte) { return (pte).pte & _PAGE_ACCESSED; }
+static inline int pte_write(pte_t pte) { return !((pte).pte & _PAGE_WP); }
+static inline int pte_special(pte_t pte) { return 0; }
+
+static inline pte_t pte_mkclean(pte_t pte) { (pte).pte &= ~_PAGE_DIRTY; return pte; }
+static inline pte_t pte_mkold(pte_t pte) { (pte).pte &= ~_PAGE_ACCESSED; return pte; }
+static inline pte_t pte_wrprotect(pte_t pte) { (pte).pte |= _PAGE_WP; return pte; }
+static inline pte_t pte_mkdirty(pte_t pte) { (pte).pte |= _PAGE_DIRTY; return pte; }
+static inline pte_t pte_mkyoung(pte_t pte) { (pte).pte |= _PAGE_ACCESSED; return pte; }
+static inline pte_t pte_mkwrite(pte_t pte) { (pte).pte &= ~_PAGE_WP; return pte; }
+static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
+
+static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep)
+{
+ int i = test_and_clear_bit(_PAGE_BIT_ACCESSED, ptep);
+ asm volatile("dcf %M0" :: "U"(*ptep));
+ return i;
+}
+
+static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
+{
+ unsigned long x = xchg(&ptep->pte, 0);
+ asm volatile("dcf %M0" :: "U"(*ptep));
+ return __pte(x);
+}
+
+static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
+{
+ set_bit(_PAGE_BIT_WP, ptep);
+ asm volatile("dcf %M0" :: "U"(*ptep));
+}
+
+/*
+ * Macro to mark a page protection value as "uncacheable"
+ */
+#define pgprot_noncached(prot) (__pgprot(pgprot_val(prot) | _PAGE_NOCACHE))
+
+/*
+ * Conversion functions: convert a page and protection to a page entry,
+ * and a page entry and page directory to the page they refer to.
+ */
+
+#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot))
+#define mk_pte_huge(entry) ((entry).pte_low |= _PAGE_PRESENT | _PAGE_PSE)
+
+/* This takes a physical page address that is used by the remapping functions */
+#define mk_pte_phys(physpage, pgprot) pfn_pte((physpage) >> PAGE_SHIFT, pgprot)
+
+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+{
+ pte.pte &= _PAGE_CHG_MASK;
+ pte.pte |= pgprot_val(newprot);
+ return pte;
+}
+
+/* to find an entry in a page-table-directory. */
+#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
+#define pgd_index_k(addr) pgd_index(addr)
+
+/* Find an entry in the bottom-level page table.. */
+#define __pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
+
+/*
+ * the pte page can be thought of an array like this: pte_t[PTRS_PER_PTE]
+ *
+ * this macro returns the index of the entry in the pte page which would
+ * control the given virtual address
+ */
+#define pte_index(address) \
+ (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
+#define pte_offset_kernel(dir, address) \
+ ((pte_t *) pmd_page_vaddr(*(dir)) + pte_index(address))
+
+#if defined(CONFIG_HIGHPTE)
+#define pte_offset_map(dir, address) \
+ ((pte_t *)kmap_atomic(pmd_page(*(dir))) + pte_index(address))
+#define pte_unmap(pte) kunmap_atomic(pte)
+#else
+#define pte_offset_map(dir, address) \
+ ((pte_t *)page_address(pmd_page(*(dir))) + pte_index(address))
+#define pte_unmap(pte) do { } while (0)
+#endif
+
+/*
+ * Handle swap and file entries
+ * - the PTE is encoded in the following format:
+ * bit 0: Must be 0 (!_PAGE_PRESENT)
+ * bit 1: Type: 0 for swap, 1 for file (_PAGE_FILE)
+ * bits 2-7: Swap type
+ * bits 8-31: Swap offset
+ * bits 2-31: File pgoff
+ */
+#define __swp_type(x) (((x).val >> 2) & 0x1f)
+#define __swp_offset(x) ((x).val >> 8)
+#define __swp_entry(type, offset) ((swp_entry_t) { ((type) << 2) | ((offset) << 8) })
+#define __pte_to_swp_entry(_pte) ((swp_entry_t) { (_pte).pte })
+#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
+
+static inline int pte_file(pte_t pte)
+{
+ return pte.pte & _PAGE_FILE;
+}
+
+#define PTE_FILE_MAX_BITS 29
+
+#define pte_to_pgoff(PTE) ((PTE).pte >> 2)
+#define pgoff_to_pte(off) __pte((off) << 2 | _PAGE_FILE)
+
+/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
+#define PageSkip(page) (0)
+#define kern_addr_valid(addr) (1)
+
+#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
+#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
+#define __HAVE_ARCH_PTEP_SET_WRPROTECT
+#define __HAVE_ARCH_PTE_SAME
+#include <asm-generic/pgtable.h>
+
+/*
+ * preload information about a newly instantiated PTE into the SCR0/SCR1 PGE cache
+ */
+static inline void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep)
+{
+ struct mm_struct *mm;
+ unsigned long ampr;
+
+ mm = current->mm;
+ if (mm) {
+ pgd_t *pge = pgd_offset(mm, address);
+ pud_t *pue = pud_offset(pge, address);
+ pmd_t *pme = pmd_offset(pue, address);
+
+ ampr = pme->ste[0] & 0xffffff00;
+ ampr |= xAMPRx_L | xAMPRx_SS_16Kb | xAMPRx_S | xAMPRx_C |
+ xAMPRx_V;
+ } else {
+ address = ULONG_MAX;
+ ampr = 0;
+ }
+
+ asm volatile("movgs %0,scr0\n"
+ "movgs %0,scr1\n"
+ "movgs %1,dampr4\n"
+ "movgs %1,dampr5\n"
+ :
+ : "r"(address), "r"(ampr)
+ );
+}
+
+#ifdef CONFIG_PROC_FS
+extern char *proc_pid_status_frv_cxnr(struct mm_struct *mm, char *buffer);
+#endif
+
+extern void __init pgtable_cache_init(void);
+
+#endif /* !__ASSEMBLY__ */
+#endif /* !CONFIG_MMU */
+
+#ifndef __ASSEMBLY__
+extern void __init paging_init(void);
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_PGTABLE_H */
diff --git a/arch/frv/include/asm/processor.h b/arch/frv/include/asm/processor.h
new file mode 100644
index 00000000000..a34f309e580
--- /dev/null
+++ b/arch/frv/include/asm/processor.h
@@ -0,0 +1,142 @@
+/* processor.h: FRV processor definitions
+ *
+ * Copyright (C) 2003 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_PROCESSOR_H
+#define _ASM_PROCESSOR_H
+
+#include <asm/mem-layout.h>
+
+#ifndef __ASSEMBLY__
+/*
+ * Default implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+#define current_text_addr() ({ __label__ _l; _l: &&_l;})
+
+#include <linux/compiler.h>
+#include <linux/linkage.h>
+#include <asm/sections.h>
+#include <asm/segment.h>
+#include <asm/fpu.h>
+#include <asm/registers.h>
+#include <asm/ptrace.h>
+#include <asm/current.h>
+#include <asm/cache.h>
+
+/* Forward declaration, a strange C thing */
+struct task_struct;
+
+/*
+ * CPU type and hardware bug flags. Kept separately for each CPU.
+ */
+struct cpuinfo_frv {
+#ifdef CONFIG_MMU
+ unsigned long *pgd_quick;
+ unsigned long *pte_quick;
+ unsigned long pgtable_cache_sz;
+#endif
+} __cacheline_aligned;
+
+extern struct cpuinfo_frv __nongprelbss boot_cpu_data;
+
+#define cpu_data (&boot_cpu_data)
+#define current_cpu_data boot_cpu_data
+
+/*
+ * Bus types
+ */
+#define EISA_bus 0
+
+struct thread_struct {
+ struct pt_regs *frame; /* [GR28] exception frame ptr for this thread */
+ struct task_struct *curr; /* [GR29] current pointer for this thread */
+ unsigned long sp; /* [GR1 ] kernel stack pointer */
+ unsigned long fp; /* [GR2 ] kernel frame pointer */
+ unsigned long lr; /* link register */
+ unsigned long pc; /* program counter */
+ unsigned long gr[12]; /* [GR16-GR27] */
+ unsigned long sched_lr; /* LR from schedule() */
+
+ union {
+ struct pt_regs *frame0; /* top (user) stack frame */
+ struct user_context *user; /* userspace context */
+ };
+} __attribute__((aligned(8)));
+
+extern struct pt_regs *__kernel_frame0_ptr;
+extern struct task_struct *__kernel_current_task;
+
+#endif
+
+#ifndef __ASSEMBLY__
+#define INIT_THREAD_FRAME0 \
+ ((struct pt_regs *) \
+ (sizeof(init_stack) + (unsigned long) init_stack - sizeof(struct user_context)))
+
+#define INIT_THREAD { \
+ NULL, \
+ (struct task_struct *) init_stack, \
+ 0, 0, 0, 0, \
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, \
+ 0, \
+ { INIT_THREAD_FRAME0 }, \
+}
+
+/*
+ * do necessary setup to start up a newly executed thread.
+ */
+#define start_thread(_regs, _pc, _usp) \
+do { \
+ _regs->pc = (_pc); \
+ _regs->psr &= ~PSR_S; \
+ _regs->sp = (_usp); \
+} while(0)
+
+/* Free all resources held by a thread. */
+static inline void release_thread(struct task_struct *dead_task)
+{
+}
+
+extern asmlinkage void save_user_regs(struct user_context *target);
+extern asmlinkage void *restore_user_regs(const struct user_context *target, ...);
+
+#define copy_segments(tsk, mm) do { } while (0)
+#define release_segments(mm) do { } while (0)
+#define forget_segments() do { } while (0)
+
+/*
+ * Free current thread data structures etc..
+ */
+static inline void exit_thread(void)
+{
+}
+
+/*
+ * Return saved PC of a blocked thread.
+ */
+extern unsigned long thread_saved_pc(struct task_struct *tsk);
+
+unsigned long get_wchan(struct task_struct *p);
+
+#define KSTK_EIP(tsk) ((tsk)->thread.frame0->pc)
+#define KSTK_ESP(tsk) ((tsk)->thread.frame0->sp)
+
+#define cpu_relax() barrier()
+
+/* data cache prefetch */
+#define ARCH_HAS_PREFETCH
+static inline void prefetch(const void *x)
+{
+ asm volatile("dcpl %0,gr0,#0" : : "r"(x));
+}
+
+#endif /* __ASSEMBLY__ */
+#endif /* _ASM_PROCESSOR_H */
diff --git a/arch/frv/include/asm/ptrace.h b/arch/frv/include/asm/ptrace.h
new file mode 100644
index 00000000000..034f1793419
--- /dev/null
+++ b/arch/frv/include/asm/ptrace.h
@@ -0,0 +1,41 @@
+/* ptrace.h: ptrace() relevant definitions
+ *
+ * Copyright (C) 2003 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _ASM_PTRACE_H
+#define _ASM_PTRACE_H
+
+#include <asm/irq_regs.h>
+#include <uapi/asm/ptrace.h>
+
+#define in_syscall(regs) (((regs)->tbr & TBR_TT) == TBR_TT_TRAP0)
+#ifndef __ASSEMBLY__
+
+struct task_struct;
+
+/*
+ * we dedicate GR28 to keeping a pointer to the current exception frame
+ * - gr28 is destroyed on entry to the kernel from userspace
+ */
+register struct pt_regs *__frame asm("gr28");
+
+#define user_mode(regs) (!((regs)->psr & PSR_S))
+#define instruction_pointer(regs) ((regs)->pc)
+#define user_stack_pointer(regs) ((regs)->sp)
+#define current_pt_regs() (__frame)
+
+extern unsigned long user_stack(const struct pt_regs *);
+#define profile_pc(regs) ((regs)->pc)
+
+#define task_pt_regs(task) ((task)->thread.frame0)
+
+#define arch_has_single_step() (1)
+
+#endif /* !__ASSEMBLY__ */
+#endif /* _ASM_PTRACE_H */
diff --git a/arch/frv/include/asm/scatterlist.h b/arch/frv/include/asm/scatterlist.h
new file mode 100644
index 00000000000..0e5eb301846
--- /dev/null
+++ b/arch/frv/include/asm/scatterlist.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCATTERLIST_H
+#define _ASM_SCATTERLIST_H
+
+#include <asm-generic/scatterlist.h>
+
+#endif /* !_ASM_SCATTERLIST_H */
diff --git a/arch/frv/include/asm/sections.h b/arch/frv/include/asm/sections.h
new file mode 100644
index 00000000000..17d0fb171bb
--- /dev/null
+++ b/arch/frv/include/asm/sections.h
@@ -0,0 +1,46 @@
+/* sections.h: linkage layout variables
+ *
+ * Copyright (C) 2004 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_SECTIONS_H
+#define _ASM_SECTIONS_H
+
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+#include <asm-generic/sections.h>
+
+#ifdef __KERNEL__
+
+/*
+ * we don't want to put variables in the GP-REL section if they're not used very much - that would
+ * be waste since GP-REL addressing is limited to GP16+/-2048
+ */
+#define __nongpreldata __attribute__((section(".data")))
+#define __nongprelbss __attribute__((section(".bss")))
+
+/*
+ * linker symbols
+ */
+extern const void __kernel_image_start, __kernel_image_end, __page_offset;
+
+extern unsigned long __nongprelbss memory_start;
+extern unsigned long __nongprelbss memory_end;
+extern unsigned long __nongprelbss rom_length;
+
+/* determine if we're running from ROM */
+static inline int is_in_rom(unsigned long addr)
+{
+ return 0; /* default case: not in ROM */
+}
+
+#endif
+#endif
+#endif /* _ASM_SECTIONS_H */
diff --git a/arch/frv/include/asm/segment.h b/arch/frv/include/asm/segment.h
new file mode 100644
index 00000000000..a2320a4a004
--- /dev/null
+++ b/arch/frv/include/asm/segment.h
@@ -0,0 +1,45 @@
+/* segment.h: MMU segment settings
+ *
+ * Copyright (C) 2003 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_SEGMENT_H
+#define _ASM_SEGMENT_H
+
+
+#ifndef __ASSEMBLY__
+
+typedef struct {
+ unsigned long seg;
+} mm_segment_t;
+
+#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
+
+#ifdef CONFIG_MMU
+#define USER_DS MAKE_MM_SEG(TASK_SIZE - 1)
+#define KERNEL_DS MAKE_MM_SEG(0xdfffffffUL)
+#else
+#define USER_DS MAKE_MM_SEG(memory_end)
+#define KERNEL_DS MAKE_MM_SEG(0xe0000000UL)
+#endif
+
+#define get_ds() (KERNEL_DS)
+#define get_fs() (__current_thread_info->addr_limit)
+#define segment_eq(a,b) ((a).seg == (b).seg)
+#define __kernel_ds_p() segment_eq(get_fs(), KERNEL_DS)
+#define get_addr_limit() (get_fs().seg)
+
+#define set_fs(_x) \
+do { \
+ __current_thread_info->addr_limit = (_x); \
+} while(0)
+
+
+#endif /* __ASSEMBLY__ */
+#endif /* _ASM_SEGMENT_H */
diff --git a/arch/frv/include/asm/serial-regs.h b/arch/frv/include/asm/serial-regs.h
new file mode 100644
index 00000000000..e1286bda00e
--- /dev/null
+++ b/arch/frv/include/asm/serial-regs.h
@@ -0,0 +1,44 @@
+/* serial-regs.h: serial port registers
+ *
+ * Copyright (C) 2003 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_SERIAL_REGS_H
+#define _ASM_SERIAL_REGS_H
+
+#include <linux/serial_reg.h>
+#include <asm/irc-regs.h>
+
+#define SERIAL_ICLK 33333333 /* the target serial input clock */
+#define UART0_BASE 0xfeff9c00
+#define UART1_BASE 0xfeff9c40
+
+#define __get_UART0(R) ({ __reg(UART0_BASE + (R) * 8) >> 24; })
+#define __get_UART1(R) ({ __reg(UART1_BASE + (R) * 8) >> 24; })
+#define __set_UART0(R,V) do { __reg(UART0_BASE + (R) * 8) = (V) << 24; } while(0)
+#define __set_UART1(R,V) do { __reg(UART1_BASE + (R) * 8) = (V) << 24; } while(0)
+
+#define __get_UART0_LSR() ({ __get_UART0(UART_LSR); })
+#define __get_UART1_LSR() ({ __get_UART1(UART_LSR); })
+
+#define __set_UART0_IER(V) __set_UART0(UART_IER,(V))
+#define __set_UART1_IER(V) __set_UART1(UART_IER,(V))
+
+/* serial prescaler select register */
+#define __get_UCPSR() ({ *(volatile unsigned long *)(0xfeff9c90); })
+#define __set_UCPSR(V) do { *(volatile unsigned long *)(0xfeff9c90) = (V); } while(0)
+#define UCPSR_SELECT0 0x07000000
+#define UCPSR_SELECT1 0x38000000
+
+/* serial prescaler base value register */
+#define __get_UCPVR() ({ *(volatile unsigned long *)(0xfeff9c98); mb(); })
+#define __set_UCPVR(V) do { *(volatile unsigned long *)(0xfeff9c98) = (V) << 24; mb(); } while(0)
+
+
+#endif /* _ASM_SERIAL_REGS_H */
diff --git a/arch/frv/include/asm/serial.h b/arch/frv/include/asm/serial.h
new file mode 100644
index 00000000000..dbb82599868
--- /dev/null
+++ b/arch/frv/include/asm/serial.h
@@ -0,0 +1,18 @@
+/*
+ * serial.h
+ *
+ * Copyright (C) 2003 Develer S.r.l. (http://www.develer.com/)
+ * Author: Bernardo Innocenti <bernie@codewiz.org>
+ *
+ * Based on linux/include/asm-i386/serial.h
+ */
+#include <asm/serial-regs.h>
+
+/*
+ * the base baud is derived from the clock speed and so is variable
+ */
+#define BASE_BAUD 0
+
+#define STD_COM_FLAGS ASYNC_BOOT_AUTOCONF
+
+#define SERIAL_PORT_DFNS
diff --git a/arch/frv/include/asm/setup.h b/arch/frv/include/asm/setup.h
new file mode 100644
index 00000000000..aa76f2eac09
--- /dev/null
+++ b/arch/frv/include/asm/setup.h
@@ -0,0 +1,26 @@
+/* setup.h: setup stuff
+ *
+ * Copyright (C) 2004 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _ASM_SETUP_H
+#define _ASM_SETUP_H
+
+
+#include <linux/init.h>
+#include <uapi/asm/setup.h>
+
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_MMU
+extern unsigned long __initdata num_mappedpages;
+#endif
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_SETUP_H */
diff --git a/arch/frv/include/asm/shmparam.h b/arch/frv/include/asm/shmparam.h
new file mode 100644
index 00000000000..ab711009cfa
--- /dev/null
+++ b/arch/frv/include/asm/shmparam.h
@@ -0,0 +1,7 @@
+#ifndef _ASM_SHMPARAM_H
+#define _ASM_SHMPARAM_H
+
+#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */
+
+#endif /* _ASM_SHMPARAM_H */
+
diff --git a/arch/frv/include/asm/signal.h b/arch/frv/include/asm/signal.h
new file mode 100644
index 00000000000..eca0abcb79d
--- /dev/null
+++ b/arch/frv/include/asm/signal.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SIGNAL_H
+#define _ASM_SIGNAL_H
+
+#include <uapi/asm/signal.h>
+
+#endif /* _ASM_SIGNAL_H */
diff --git a/arch/frv/include/asm/smp.h b/arch/frv/include/asm/smp.h
new file mode 100644
index 00000000000..38349ec8b61
--- /dev/null
+++ b/arch/frv/include/asm/smp.h
@@ -0,0 +1,9 @@
+#ifndef __ASM_SMP_H
+#define __ASM_SMP_H
+
+
+#ifdef CONFIG_SMP
+#error SMP not supported
+#endif
+
+#endif
diff --git a/arch/frv/include/asm/spinlock.h b/arch/frv/include/asm/spinlock.h
new file mode 100644
index 00000000000..fe385f45d1f
--- /dev/null
+++ b/arch/frv/include/asm/spinlock.h
@@ -0,0 +1,17 @@
+/* spinlock.h: spinlocks for FR-V
+ *
+ * Copyright (C) 2003 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_SPINLOCK_H
+#define _ASM_SPINLOCK_H
+
+#error no spinlocks for FR-V yet
+
+#endif /* _ASM_SPINLOCK_H */
diff --git a/arch/frv/include/asm/spr-regs.h b/arch/frv/include/asm/spr-regs.h
new file mode 100644
index 00000000000..d3883021f23
--- /dev/null
+++ b/arch/frv/include/asm/spr-regs.h
@@ -0,0 +1,416 @@
+/* spr-regs.h: special-purpose registers on the FRV
+ *
+ * Copyright (C) 2003, 2004 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_SPR_REGS_H
+#define _ASM_SPR_REGS_H
+
+/*
+ * PSR - Processor Status Register
+ */
+#define PSR_ET 0x00000001 /* enable interrupts/exceptions flag */
+#define PSR_PS 0x00000002 /* previous supervisor mode flag */
+#define PSR_S 0x00000004 /* supervisor mode flag */
+#define PSR_PIL 0x00000078 /* processor external interrupt level */
+#define PSR_PIL_0 0x00000000 /* - no interrupt in progress */
+#define PSR_PIL_13 0x00000068 /* - debugging only */
+#define PSR_PIL_14 0x00000070 /* - debugging in progress */
+#define PSR_PIL_15 0x00000078 /* - NMI in progress */
+#define PSR_EM 0x00000080 /* enable media operation */
+#define PSR_EF 0x00000100 /* enable FPU operation */
+#define PSR_BE 0x00001000 /* endianness mode */
+#define PSR_BE_LE 0x00000000 /* - little endian mode */
+#define PSR_BE_BE 0x00001000 /* - big endian mode */
+#define PSR_CM 0x00002000 /* conditional mode */
+#define PSR_NEM 0x00004000 /* non-excepting mode */
+#define PSR_ICE 0x00010000 /* in-circuit emulation mode */
+#define PSR_VERSION_SHIFT 24 /* CPU silicon ID */
+#define PSR_IMPLE_SHIFT 28 /* CPU core ID */
+
+#define PSR_VERSION(psr) (((psr) >> PSR_VERSION_SHIFT) & 0xf)
+#define PSR_IMPLE(psr) (((psr) >> PSR_IMPLE_SHIFT) & 0xf)
+
+#define PSR_IMPLE_FR401 0x2
+#define PSR_VERSION_FR401_MB93401 0x0
+#define PSR_VERSION_FR401_MB93401A 0x1
+#define PSR_VERSION_FR401_MB93403 0x2
+
+#define PSR_IMPLE_FR405 0x4
+#define PSR_VERSION_FR405_MB93405 0x0
+
+#define PSR_IMPLE_FR451 0x5
+#define PSR_VERSION_FR451_MB93451 0x0
+
+#define PSR_IMPLE_FR501 0x1
+#define PSR_VERSION_FR501_MB93501 0x1
+#define PSR_VERSION_FR501_MB93501A 0x2
+
+#define PSR_IMPLE_FR551 0x3
+#define PSR_VERSION_FR551_MB93555 0x1
+
+#define __get_PSR() ({ unsigned long x; asm volatile("movsg psr,%0" : "=r"(x)); x; })
+#define __set_PSR(V) do { asm volatile("movgs %0,psr" : : "r"(V)); } while(0)
+
+/*
+ * TBR - Trap Base Register
+ */
+#define TBR_TT 0x00000ff0
+#define TBR_TT_INSTR_MMU_MISS (0x01 << 4)
+#define TBR_TT_INSTR_ACC_ERROR (0x02 << 4)
+#define TBR_TT_INSTR_ACC_EXCEP (0x03 << 4)
+#define TBR_TT_PRIV_INSTR (0x06 << 4)
+#define TBR_TT_ILLEGAL_INSTR (0x07 << 4)
+#define TBR_TT_FP_EXCEPTION (0x0d << 4)
+#define TBR_TT_MP_EXCEPTION (0x0e << 4)
+#define TBR_TT_DATA_ACC_ERROR (0x11 << 4)
+#define TBR_TT_DATA_MMU_MISS (0x12 << 4)
+#define TBR_TT_DATA_ACC_EXCEP (0x13 << 4)
+#define TBR_TT_DATA_STR_ERROR (0x14 << 4)
+#define TBR_TT_DIVISION_EXCEP (0x17 << 4)
+#define TBR_TT_COMMIT_EXCEP (0x19 << 4)
+#define TBR_TT_INSTR_TLB_MISS (0x1a << 4)
+#define TBR_TT_DATA_TLB_MISS (0x1b << 4)
+#define TBR_TT_DATA_DAT_EXCEP (0x1d << 4)
+#define TBR_TT_DECREMENT_TIMER (0x1f << 4)
+#define TBR_TT_COMPOUND_EXCEP (0x20 << 4)
+#define TBR_TT_INTERRUPT_1 (0x21 << 4)
+#define TBR_TT_INTERRUPT_2 (0x22 << 4)
+#define TBR_TT_INTERRUPT_3 (0x23 << 4)
+#define TBR_TT_INTERRUPT_4 (0x24 << 4)
+#define TBR_TT_INTERRUPT_5 (0x25 << 4)
+#define TBR_TT_INTERRUPT_6 (0x26 << 4)
+#define TBR_TT_INTERRUPT_7 (0x27 << 4)
+#define TBR_TT_INTERRUPT_8 (0x28 << 4)
+#define TBR_TT_INTERRUPT_9 (0x29 << 4)
+#define TBR_TT_INTERRUPT_10 (0x2a << 4)
+#define TBR_TT_INTERRUPT_11 (0x2b << 4)
+#define TBR_TT_INTERRUPT_12 (0x2c << 4)
+#define TBR_TT_INTERRUPT_13 (0x2d << 4)
+#define TBR_TT_INTERRUPT_14 (0x2e << 4)
+#define TBR_TT_INTERRUPT_15 (0x2f << 4)
+#define TBR_TT_TRAP0 (0x80 << 4)
+#define TBR_TT_TRAP1 (0x81 << 4)
+#define TBR_TT_TRAP2 (0x82 << 4)
+#define TBR_TT_TRAP3 (0x83 << 4)
+#define TBR_TT_TRAP120 (0xf8 << 4)
+#define TBR_TT_TRAP121 (0xf9 << 4)
+#define TBR_TT_TRAP122 (0xfa << 4)
+#define TBR_TT_TRAP123 (0xfb << 4)
+#define TBR_TT_TRAP124 (0xfc << 4)
+#define TBR_TT_TRAP125 (0xfd << 4)
+#define TBR_TT_TRAP126 (0xfe << 4)
+#define TBR_TT_BREAK (0xff << 4)
+
+#define TBR_TT_ATOMIC_CMPXCHG32 TBR_TT_TRAP120
+#define TBR_TT_ATOMIC_XCHG32 TBR_TT_TRAP121
+#define TBR_TT_ATOMIC_XOR TBR_TT_TRAP122
+#define TBR_TT_ATOMIC_OR TBR_TT_TRAP123
+#define TBR_TT_ATOMIC_AND TBR_TT_TRAP124
+#define TBR_TT_ATOMIC_SUB TBR_TT_TRAP125
+#define TBR_TT_ATOMIC_ADD TBR_TT_TRAP126
+
+#define __get_TBR() ({ unsigned long x; asm volatile("movsg tbr,%0" : "=r"(x)); x; })
+
+/*
+ * HSR0 - Hardware Status Register 0
+ */
+#define HSR0_PDM 0x00000007 /* power down mode */
+#define HSR0_PDM_NORMAL 0x00000000 /* - normal mode */
+#define HSR0_PDM_CORE_SLEEP 0x00000001 /* - CPU core sleep mode */
+#define HSR0_PDM_BUS_SLEEP 0x00000003 /* - bus sleep mode */
+#define HSR0_PDM_PLL_RUN 0x00000005 /* - PLL run */
+#define HSR0_PDM_PLL_STOP 0x00000007 /* - PLL stop */
+#define HSR0_GRLE 0x00000040 /* GR lower register set enable */
+#define HSR0_GRHE 0x00000080 /* GR higher register set enable */
+#define HSR0_FRLE 0x00000100 /* FR lower register set enable */
+#define HSR0_FRHE 0x00000200 /* FR higher register set enable */
+#define HSR0_GRN 0x00000400 /* GR quantity */
+#define HSR0_GRN_64 0x00000000 /* - 64 GR registers */
+#define HSR0_GRN_32 0x00000400 /* - 32 GR registers */
+#define HSR0_FRN 0x00000800 /* FR quantity */
+#define HSR0_FRN_64 0x00000000 /* - 64 FR registers */
+#define HSR0_FRN_32 0x00000800 /* - 32 FR registers */
+#define HSR0_SA 0x00001000 /* start address (RAMBOOT#) */
+#define HSR0_ETMI 0x00008000 /* enable TIMERI (64-bit up timer) */
+#define HSR0_ETMD 0x00004000 /* enable TIMERD (32-bit down timer) */
+#define HSR0_PEDAT 0x00010000 /* previous DAT mode */
+#define HSR0_XEDAT 0x00020000 /* exception DAT mode */
+#define HSR0_EDAT 0x00080000 /* enable DAT mode */
+#define HSR0_RME 0x00400000 /* enable RAM mode */
+#define HSR0_EMEM 0x00800000 /* enable MMU_Miss mask */
+#define HSR0_EXMMU 0x01000000 /* enable extended MMU mode */
+#define HSR0_EDMMU 0x02000000 /* enable data MMU */
+#define HSR0_EIMMU 0x04000000 /* enable instruction MMU */
+#define HSR0_CBM 0x08000000 /* copy back mode */
+#define HSR0_CBM_WRITE_THRU 0x00000000 /* - write through */
+#define HSR0_CBM_COPY_BACK 0x08000000 /* - copy back */
+#define HSR0_NWA 0x10000000 /* no write allocate */
+#define HSR0_DCE 0x40000000 /* data cache enable */
+#define HSR0_ICE 0x80000000 /* instruction cache enable */
+
+#define __get_HSR(R) ({ unsigned long x; asm volatile("movsg hsr"#R",%0" : "=r"(x)); x; })
+#define __set_HSR(R,V) do { asm volatile("movgs %0,hsr"#R : : "r"(V)); } while(0)
+
+/*
+ * CCR - Condition Codes Register
+ */
+#define CCR_FCC0 0x0000000f /* FP/Media condition 0 (fcc0 reg) */
+#define CCR_FCC1 0x000000f0 /* FP/Media condition 1 (fcc1 reg) */
+#define CCR_FCC2 0x00000f00 /* FP/Media condition 2 (fcc2 reg) */
+#define CCR_FCC3 0x0000f000 /* FP/Media condition 3 (fcc3 reg) */
+#define CCR_ICC0 0x000f0000 /* Integer condition 0 (icc0 reg) */
+#define CCR_ICC0_C 0x00010000 /* - Carry flag */
+#define CCR_ICC0_V 0x00020000 /* - Overflow flag */
+#define CCR_ICC0_Z 0x00040000 /* - Zero flag */
+#define CCR_ICC0_N 0x00080000 /* - Negative flag */
+#define CCR_ICC1 0x00f00000 /* Integer condition 1 (icc1 reg) */
+#define CCR_ICC2 0x0f000000 /* Integer condition 2 (icc2 reg) */
+#define CCR_ICC3 0xf0000000 /* Integer condition 3 (icc3 reg) */
+
+/*
+ * CCCR - Condition Codes for Conditional Instructions Register
+ */
+#define CCCR_CC0 0x00000003 /* condition 0 (cc0 reg) */
+#define CCCR_CC0_FALSE 0x00000002 /* - condition is false */
+#define CCCR_CC0_TRUE 0x00000003 /* - condition is true */
+#define CCCR_CC1 0x0000000c /* condition 1 (cc1 reg) */
+#define CCCR_CC2 0x00000030 /* condition 2 (cc2 reg) */
+#define CCCR_CC3 0x000000c0 /* condition 3 (cc3 reg) */
+#define CCCR_CC4 0x00000300 /* condition 4 (cc4 reg) */
+#define CCCR_CC5 0x00000c00 /* condition 5 (cc5 reg) */
+#define CCCR_CC6 0x00003000 /* condition 6 (cc6 reg) */
+#define CCCR_CC7 0x0000c000 /* condition 7 (cc7 reg) */
+
+/*
+ * ISR - Integer Status Register
+ */
+#define ISR_EMAM 0x00000001 /* memory misaligned access handling */
+#define ISR_EMAM_EXCEPTION 0x00000000 /* - generate exception */
+#define ISR_EMAM_FUDGE 0x00000001 /* - mask out invalid address bits */
+#define ISR_AEXC 0x00000004 /* accrued [overflow] exception */
+#define ISR_DTT 0x00000018 /* division type trap */
+#define ISR_DTT_IGNORE 0x00000000 /* - ignore division error */
+#define ISR_DTT_DIVBYZERO 0x00000008 /* - generate exception */
+#define ISR_DTT_OVERFLOW 0x00000010 /* - record overflow */
+#define ISR_EDE 0x00000020 /* enable division exception */
+#define ISR_PLI 0x20000000 /* pre-load instruction information */
+#define ISR_QI 0x80000000 /* quad data implementation information */
+
+/*
+ * EPCR0 - Exception PC Register
+ */
+#define EPCR0_V 0x00000001 /* register content validity indicator */
+#define EPCR0_PC 0xfffffffc /* faulting instruction address */
+
+/*
+ * ESR0/14/15 - Exception Status Register
+ */
+#define ESRx_VALID 0x00000001 /* register content validity indicator */
+#define ESRx_EC 0x0000003e /* exception type */
+#define ESRx_EC_DATA_STORE 0x00000000 /* - data_store_error */
+#define ESRx_EC_INSN_ACCESS 0x00000006 /* - instruction_access_error */
+#define ESRx_EC_PRIV_INSN 0x00000008 /* - privileged_instruction */
+#define ESRx_EC_ILL_INSN 0x0000000a /* - illegal_instruction */
+#define ESRx_EC_MP_EXCEP 0x0000001c /* - mp_exception */
+#define ESRx_EC_DATA_ACCESS 0x00000020 /* - data_access_error */
+#define ESRx_EC_DIVISION 0x00000026 /* - division_exception */
+#define ESRx_EC_ITLB_MISS 0x00000034 /* - instruction_access_TLB_miss */
+#define ESRx_EC_DTLB_MISS 0x00000036 /* - data_access_TLB_miss */
+#define ESRx_EC_DATA_ACCESS_DAT 0x0000003a /* - data_access_DAT_exception */
+
+#define ESR0_IAEC 0x00000100 /* info for instruction-access-exception */
+#define ESR0_IAEC_RESV 0x00000000 /* - reserved */
+#define ESR0_IAEC_PROT_VIOL 0x00000100 /* - protection violation */
+
+#define ESR0_ATXC 0x00f00000 /* address translation exception code */
+#define ESR0_ATXC_MMU_MISS 0x00000000 /* - MMU miss exception and more (?) */
+#define ESR0_ATXC_MULTI_DAT 0x00800000 /* - multiple DAT entry hit */
+#define ESR0_ATXC_MULTI_SAT 0x00900000 /* - multiple SAT entry hit */
+#define ESR0_ATXC_AMRTLB_MISS 0x00a00000 /* - MMU/TLB miss exception */
+#define ESR0_ATXC_PRIV_EXCEP 0x00c00000 /* - privilege protection fault */
+#define ESR0_ATXC_WP_EXCEP 0x00d00000 /* - write protection fault */
+
+#define ESR0_EAV 0x00000800 /* true if EAR0 register valid */
+#define ESR15_EAV 0x00000800 /* true if EAR15 register valid */
+
+/*
+ * ESFR1 - Exception Status Valid Flag Register
+ */
+#define ESFR1_ESR0 0x00000001 /* true if ESR0 is valid */
+#define ESFR1_ESR14 0x00004000 /* true if ESR14 is valid */
+#define ESFR1_ESR15 0x00008000 /* true if ESR15 is valid */
+
+/*
+ * MSR - Media Status Register
+ */
+#define MSR0_AOVF 0x00000001 /* overflow exception accrued */
+#define MSRx_OVF 0x00000002 /* overflow exception detected */
+#define MSRx_SIE 0x0000003c /* last SIMD instruction exception detected */
+#define MSRx_SIE_NONE 0x00000000 /* - none detected */
+#define MSRx_SIE_FRkHI_ACCk 0x00000020 /* - exception at FRkHI or ACCk */
+#define MSRx_SIE_FRkLO_ACCk1 0x00000010 /* - exception at FRkLO or ACCk+1 */
+#define MSRx_SIE_FRk1HI_ACCk2 0x00000008 /* - exception at FRk+1HI or ACCk+2 */
+#define MSRx_SIE_FRk1LO_ACCk3 0x00000004 /* - exception at FRk+1LO or ACCk+3 */
+#define MSR0_MTT 0x00007000 /* type of last media trap detected */
+#define MSR0_MTT_NONE 0x00000000 /* - none detected */
+#define MSR0_MTT_OVERFLOW 0x00001000 /* - overflow detected */
+#define MSR0_HI 0x00c00000 /* hardware implementation */
+#define MSR0_HI_ROUNDING 0x00000000 /* - rounding mode */
+#define MSR0_HI_NONROUNDING 0x00c00000 /* - non-rounding mode */
+#define MSR0_EMCI 0x01000000 /* enable media custom instructions */
+#define MSR0_SRDAV 0x10000000 /* select rounding mode of MAVEH */
+#define MSR0_SRDAV_RDAV 0x00000000 /* - controlled by MSR.RDAV */
+#define MSR0_SRDAV_RD 0x10000000 /* - controlled by MSR.RD */
+#define MSR0_RDAV 0x20000000 /* rounding mode of MAVEH */
+#define MSR0_RDAV_NEAREST_MI 0x00000000 /* - round to nearest minus */
+#define MSR0_RDAV_NEAREST_PL 0x20000000 /* - round to nearest plus */
+#define MSR0_RD 0xc0000000 /* rounding mode */
+#define MSR0_RD_NEAREST 0x00000000 /* - nearest */
+#define MSR0_RD_ZERO 0x40000000 /* - zero */
+#define MSR0_RD_POS_INF 0x80000000 /* - positive infinity */
+#define MSR0_RD_NEG_INF 0xc0000000 /* - negative infinity */
+
+/*
+ * IAMPR0-7 - Instruction Address Mapping Register
+ * DAMPR0-7 - Data Address Mapping Register
+ */
+#define xAMPRx_V 0x00000001 /* register content validity indicator */
+#define DAMPRx_WP 0x00000002 /* write protect */
+#define DAMPRx_WP_RW 0x00000000 /* - read/write */
+#define DAMPRx_WP_RO 0x00000002 /* - read-only */
+#define xAMPRx_C 0x00000004 /* cached/uncached */
+#define xAMPRx_C_CACHED 0x00000000 /* - cached */
+#define xAMPRx_C_UNCACHED 0x00000004 /* - uncached */
+#define xAMPRx_S 0x00000008 /* supervisor only */
+#define xAMPRx_S_USER 0x00000000 /* - userspace can access */
+#define xAMPRx_S_KERNEL 0x00000008 /* - kernel only */
+#define xAMPRx_SS 0x000000f0 /* segment size */
+#define xAMPRx_SS_16Kb 0x00000000 /* - 16 kilobytes */
+#define xAMPRx_SS_64Kb 0x00000010 /* - 64 kilobytes */
+#define xAMPRx_SS_256Kb 0x00000020 /* - 256 kilobytes */
+#define xAMPRx_SS_1Mb 0x00000030 /* - 1 megabyte */
+#define xAMPRx_SS_2Mb 0x00000040 /* - 2 megabytes */
+#define xAMPRx_SS_4Mb 0x00000050 /* - 4 megabytes */
+#define xAMPRx_SS_8Mb 0x00000060 /* - 8 megabytes */
+#define xAMPRx_SS_16Mb 0x00000070 /* - 16 megabytes */
+#define xAMPRx_SS_32Mb 0x00000080 /* - 32 megabytes */
+#define xAMPRx_SS_64Mb 0x00000090 /* - 64 megabytes */
+#define xAMPRx_SS_128Mb 0x000000a0 /* - 128 megabytes */
+#define xAMPRx_SS_256Mb 0x000000b0 /* - 256 megabytes */
+#define xAMPRx_SS_512Mb 0x000000c0 /* - 512 megabytes */
+#define xAMPRx_RESERVED8 0x00000100 /* reserved bit */
+#define xAMPRx_NG 0x00000200 /* non-global */
+#define xAMPRx_L 0x00000400 /* locked */
+#define xAMPRx_M 0x00000800 /* modified */
+#define xAMPRx_D 0x00001000 /* DAT entry */
+#define xAMPRx_RESERVED13 0x00002000 /* reserved bit */
+#define xAMPRx_PPFN 0xfff00000 /* physical page frame number */
+
+#define xAMPRx_V_BIT 0
+#define DAMPRx_WP_BIT 1
+#define xAMPRx_C_BIT 2
+#define xAMPRx_S_BIT 3
+#define xAMPRx_RESERVED8_BIT 8
+#define xAMPRx_NG_BIT 9
+#define xAMPRx_L_BIT 10
+#define xAMPRx_M_BIT 11
+#define xAMPRx_D_BIT 12
+#define xAMPRx_RESERVED13_BIT 13
+
+#define __get_IAMPR(R) ({ unsigned long x; asm volatile("movsg iampr"#R",%0" : "=r"(x)); x; })
+#define __get_DAMPR(R) ({ unsigned long x; asm volatile("movsg dampr"#R",%0" : "=r"(x)); x; })
+
+#define __get_IAMLR(R) ({ unsigned long x; asm volatile("movsg iamlr"#R",%0" : "=r"(x)); x; })
+#define __get_DAMLR(R) ({ unsigned long x; asm volatile("movsg damlr"#R",%0" : "=r"(x)); x; })
+
+#define __set_IAMPR(R,V) do { asm volatile("movgs %0,iampr"#R : : "r"(V)); } while(0)
+#define __set_DAMPR(R,V) do { asm volatile("movgs %0,dampr"#R : : "r"(V)); } while(0)
+
+#define __set_IAMLR(R,V) do { asm volatile("movgs %0,iamlr"#R : : "r"(V)); } while(0)
+#define __set_DAMLR(R,V) do { asm volatile("movgs %0,damlr"#R : : "r"(V)); } while(0)
+
+#define save_dampr(R, _dampr) \
+do { \
+ asm volatile("movsg dampr"R",%0" : "=r"(_dampr)); \
+} while(0)
+
+#define restore_dampr(R, _dampr) \
+do { \
+ asm volatile("movgs %0,dampr"R :: "r"(_dampr)); \
+} while(0)
+
+/*
+ * AMCR - Address Mapping Control Register
+ */
+#define AMCR_IAMRN 0x000000ff /* quantity of IAMPR registers */
+#define AMCR_DAMRN 0x0000ff00 /* quantity of DAMPR registers */
+
+/*
+ * TTBR - Address Translation Table Base Register
+ */
+#define __get_TTBR() ({ unsigned long x; asm volatile("movsg ttbr,%0" : "=r"(x)); x; })
+
+/*
+ * TPXR - TLB Probe Extend Register
+ */
+#define TPXR_E 0x00000001
+#define TPXR_LMAX_SHIFT 20
+#define TPXR_LMAX_SMASK 0xf
+#define TPXR_WMAX_SHIFT 24
+#define TPXR_WMAX_SMASK 0xf
+#define TPXR_WAY_SHIFT 28
+#define TPXR_WAY_SMASK 0xf
+
+/*
+ * DCR - Debug Control Register
+ */
+#define DCR_IBCE3 0x00000001 /* break on conditional insn pointed to by IBAR3 */
+#define DCR_IBE3 0x00000002 /* break on insn pointed to by IBAR3 */
+#define DCR_IBCE1 0x00000004 /* break on conditional insn pointed to by IBAR2 */
+#define DCR_IBE1 0x00000008 /* break on insn pointed to by IBAR2 */
+#define DCR_IBCE2 0x00000010 /* break on conditional insn pointed to by IBAR1 */
+#define DCR_IBE2 0x00000020 /* break on insn pointed to by IBAR1 */
+#define DCR_IBCE0 0x00000040 /* break on conditional insn pointed to by IBAR0 */
+#define DCR_IBE0 0x00000080 /* break on insn pointed to by IBAR0 */
+
+#define DCR_DDBE1 0x00004000 /* use DBDR1x when checking DBAR1 */
+#define DCR_DWBE1 0x00008000 /* break on store to address in DBAR1/DBMR1x */
+#define DCR_DRBE1 0x00010000 /* break on load from address in DBAR1/DBMR1x */
+#define DCR_DDBE0 0x00020000 /* use DBDR0x when checking DBAR0 */
+#define DCR_DWBE0 0x00040000 /* break on store to address in DBAR0/DBMR0x */
+#define DCR_DRBE0 0x00080000 /* break on load from address in DBAR0/DBMR0x */
+
+#define DCR_EIM 0x0c000000 /* external interrupt disable */
+#define DCR_IBM 0x10000000 /* instruction break disable */
+#define DCR_SE 0x20000000 /* single step enable */
+#define DCR_EBE 0x40000000 /* exception break enable */
+
+/*
+ * BRR - Break Interrupt Request Register
+ */
+#define BRR_ST 0x00000001 /* single-step detected */
+#define BRR_SB 0x00000002 /* break instruction detected */
+#define BRR_BB 0x00000004 /* branch with hint detected */
+#define BRR_CBB 0x00000008 /* branch to LR detected */
+#define BRR_IBx 0x000000f0 /* hardware breakpoint detected */
+#define BRR_DBx 0x00000f00 /* hardware watchpoint detected */
+#define BRR_DBNEx 0x0000f000 /* ? */
+#define BRR_EBTT 0x00ff0000 /* trap type of exception break */
+#define BRR_TB 0x10000000 /* external break request detected */
+#define BRR_CB 0x20000000 /* ICE break command detected */
+#define BRR_EB 0x40000000 /* exception break detected */
+
+/*
+ * BPSR - Break PSR Save Register
+ */
+#define BPSR_BET 0x00000001 /* former PSR.ET */
+#define BPSR_BS 0x00001000 /* former PSR.S */
+
+#endif /* _ASM_SPR_REGS_H */
diff --git a/arch/frv/include/asm/string.h b/arch/frv/include/asm/string.h
new file mode 100644
index 00000000000..5ed310f64b7
--- /dev/null
+++ b/arch/frv/include/asm/string.h
@@ -0,0 +1,51 @@
+/* string.h: FRV string handling
+ *
+ * Copyright (C) 2004 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_STRING_H_
+#define _ASM_STRING_H_
+
+#ifdef __KERNEL__ /* only set these up for kernel code */
+
+#define __HAVE_ARCH_MEMSET 1
+#define __HAVE_ARCH_MEMCPY 1
+
+extern void *memset(void *, int, __kernel_size_t);
+extern void *memcpy(void *, const void *, __kernel_size_t);
+
+#else /* KERNEL */
+
+/*
+ * let user libraries deal with these,
+ * IMHO the kernel has no place defining these functions for user apps
+ */
+
+#define __HAVE_ARCH_STRCPY 1
+#define __HAVE_ARCH_STRNCPY 1
+#define __HAVE_ARCH_STRCAT 1
+#define __HAVE_ARCH_STRNCAT 1
+#define __HAVE_ARCH_STRCMP 1
+#define __HAVE_ARCH_STRNCMP 1
+#define __HAVE_ARCH_STRNICMP 1
+#define __HAVE_ARCH_STRCHR 1
+#define __HAVE_ARCH_STRRCHR 1
+#define __HAVE_ARCH_STRSTR 1
+#define __HAVE_ARCH_STRLEN 1
+#define __HAVE_ARCH_STRNLEN 1
+#define __HAVE_ARCH_MEMSET 1
+#define __HAVE_ARCH_MEMCPY 1
+#define __HAVE_ARCH_MEMMOVE 1
+#define __HAVE_ARCH_MEMSCAN 1
+#define __HAVE_ARCH_MEMCMP 1
+#define __HAVE_ARCH_MEMCHR 1
+#define __HAVE_ARCH_STRTOK 1
+
+#endif /* KERNEL */
+#endif /* _ASM_STRING_H_ */
diff --git a/arch/frv/include/asm/switch_to.h b/arch/frv/include/asm/switch_to.h
new file mode 100644
index 00000000000..2cf0f6a7fbb
--- /dev/null
+++ b/arch/frv/include/asm/switch_to.h
@@ -0,0 +1,35 @@
+/* FR-V CPU basic task switching
+ *
+ * Copyright (C) 2003 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_SWITCH_TO_H
+#define _ASM_SWITCH_TO_H
+
+#include <linux/thread_info.h>
+
+/*
+ * switch_to(prev, next) should switch from task `prev' to `next'
+ * `prev' will never be the same as `next'.
+ * The `mb' is to tell GCC not to cache `current' across this call.
+ */
+extern asmlinkage
+struct task_struct *__switch_to(struct thread_struct *prev_thread,
+ struct thread_struct *next_thread,
+ struct task_struct *prev);
+
+#define switch_to(prev, next, last) \
+do { \
+ (prev)->thread.sched_lr = \
+ (unsigned long) __builtin_return_address(0); \
+ (last) = __switch_to(&(prev)->thread, &(next)->thread, (prev)); \
+ mb(); \
+} while(0)
+
+#endif /* _ASM_SWITCH_TO_H */
diff --git a/arch/frv/include/asm/syscall.h b/arch/frv/include/asm/syscall.h
new file mode 100644
index 00000000000..70689eb29b9
--- /dev/null
+++ b/arch/frv/include/asm/syscall.h
@@ -0,0 +1,123 @@
+/* syscall parameter access functions
+ *
+ * Copyright (C) 2009 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_SYSCALL_H
+#define _ASM_SYSCALL_H
+
+#include <linux/err.h>
+#include <asm/ptrace.h>
+
+/*
+ * Get the system call number or -1
+ */
+static inline long syscall_get_nr(struct task_struct *task,
+ struct pt_regs *regs)
+{
+ return regs->syscallno;
+}
+
+/*
+ * Restore the clobbered GR8 register
+ * (1st syscall arg was overwritten with syscall return or error)
+ */
+static inline void syscall_rollback(struct task_struct *task,
+ struct pt_regs *regs)
+{
+ regs->gr8 = regs->orig_gr8;
+}
+
+/*
+ * See if the syscall return value is an error, returning it if it is and 0 if
+ * not
+ */
+static inline long syscall_get_error(struct task_struct *task,
+ struct pt_regs *regs)
+{
+ return IS_ERR_VALUE(regs->gr8) ? regs->gr8 : 0;
+}
+
+/*
+ * Get the syscall return value
+ */
+static inline long syscall_get_return_value(struct task_struct *task,
+ struct pt_regs *regs)
+{
+ return regs->gr8;
+}
+
+/*
+ * Set the syscall return value
+ */
+static inline void syscall_set_return_value(struct task_struct *task,
+ struct pt_regs *regs,
+ int error, long val)
+{
+ if (error)
+ regs->gr8 = -error;
+ else
+ regs->gr8 = val;
+}
+
+/*
+ * Retrieve the system call arguments
+ */
+static inline void syscall_get_arguments(struct task_struct *task,
+ struct pt_regs *regs,
+ unsigned int i, unsigned int n,
+ unsigned long *args)
+{
+ /*
+ * Do this simply for now. If we need to start supporting
+ * fetching arguments from arbitrary indices, this will need some
+ * extra logic. Presently there are no in-tree users that depend
+ * on this behaviour.
+ */
+ BUG_ON(i);
+
+ /* Argument pattern is: GR8, GR9, GR10, GR11, GR12, GR13 */
+ switch (n) {
+ case 6: args[5] = regs->gr13;
+ case 5: args[4] = regs->gr12;
+ case 4: args[3] = regs->gr11;
+ case 3: args[2] = regs->gr10;
+ case 2: args[1] = regs->gr9;
+ case 1: args[0] = regs->gr8;
+ break;
+ default:
+ BUG();
+ }
+}
+
+/*
+ * Alter the system call arguments
+ */
+static inline void syscall_set_arguments(struct task_struct *task,
+ struct pt_regs *regs,
+ unsigned int i, unsigned int n,
+ const unsigned long *args)
+{
+ /* Same note as above applies */
+ BUG_ON(i);
+
+ switch (n) {
+ case 6: regs->gr13 = args[5];
+ case 5: regs->gr12 = args[4];
+ case 4: regs->gr11 = args[3];
+ case 3: regs->gr10 = args[2];
+ case 2: regs->gr9 = args[1];
+ case 1: regs->gr8 = args[0];
+ break;
+ default:
+ BUG();
+ }
+}
+
+#endif /* _ASM_SYSCALL_H */
diff --git a/arch/frv/include/asm/termios.h b/arch/frv/include/asm/termios.h
new file mode 100644
index 00000000000..9f753fc0953
--- /dev/null
+++ b/arch/frv/include/asm/termios.h
@@ -0,0 +1,14 @@
+#ifndef _ASM_TERMIOS_H
+#define _ASM_TERMIOS_H
+
+#include <uapi/asm/termios.h>
+
+/* 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"
+#include <asm-generic/termios-base.h>
+#endif /* _ASM_TERMIOS_H */
diff --git a/arch/frv/include/asm/thread_info.h b/arch/frv/include/asm/thread_info.h
new file mode 100644
index 00000000000..af29e17c018
--- /dev/null
+++ b/arch/frv/include/asm/thread_info.h
@@ -0,0 +1,125 @@
+/* thread_info.h: description
+ *
+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ * Derived from include/asm-i386/thread_info.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_THREAD_INFO_H
+#define _ASM_THREAD_INFO_H
+
+#ifdef __KERNEL__
+
+#ifndef __ASSEMBLY__
+#include <asm/processor.h>
+#endif
+
+#define THREAD_SIZE 8192
+
+/*
+ * low level task data that entry.S needs immediate access to
+ * - this struct should fit entirely inside of one cache line
+ * - this struct shares the supervisor stack pages
+ * - if the contents of this structure are changed, the assembly constants must also be changed
+ */
+#ifndef __ASSEMBLY__
+
+struct thread_info {
+ struct task_struct *task; /* main task structure */
+ struct exec_domain *exec_domain; /* execution domain */
+ unsigned long flags; /* low level flags */
+ unsigned long status; /* thread-synchronous flags */
+ __u32 cpu; /* current CPU */
+ int preempt_count; /* 0 => preemptable, <0 => BUG */
+
+ mm_segment_t addr_limit; /* thread address space:
+ * 0-0xBFFFFFFF for user-thead
+ * 0-0xFFFFFFFF for kernel-thread
+ */
+ struct restart_block restart_block;
+
+ __u8 supervisor_stack[0];
+};
+
+#else /* !__ASSEMBLY__ */
+
+#include <asm/asm-offsets.h>
+
+#endif
+
+/*
+ * macros/functions for gaining access to the thread information structure
+ */
+#ifndef __ASSEMBLY__
+
+#define INIT_THREAD_INFO(tsk) \
+{ \
+ .task = &tsk, \
+ .exec_domain = &default_exec_domain, \
+ .flags = 0, \
+ .cpu = 0, \
+ .preempt_count = INIT_PREEMPT_COUNT, \
+ .addr_limit = KERNEL_DS, \
+ .restart_block = { \
+ .fn = do_no_restart_syscall, \
+ }, \
+}
+
+#define init_thread_info (init_thread_union.thread_info)
+#define init_stack (init_thread_union.stack)
+
+/* how to get the thread information struct from C */
+register struct thread_info *__current_thread_info asm("gr15");
+
+#define current_thread_info() ({ __current_thread_info; })
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * thread information flags
+ * - these are process state flags that various assembly files may need to access
+ * - pending work-to-be-done flags are in LSW
+ * - other flags in MSW
+ */
+#define TIF_SYSCALL_TRACE 0 /* syscall trace active */
+#define TIF_NOTIFY_RESUME 1 /* callback before returning to user */
+#define TIF_SIGPENDING 2 /* signal pending */
+#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
+#define TIF_SINGLESTEP 4 /* restore singlestep on return to user mode */
+#define TIF_RESTORE_SIGMASK 5 /* restore signal mask in do_signal() */
+#define TIF_MEMDIE 7 /* is terminating due to OOM killer */
+
+#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
+#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
+#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
+#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
+#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP)
+
+/* work to do on interrupt/exception return */
+#define _TIF_WORK_MASK \
+ (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_SINGLESTEP)
+
+/* work to do on any return to u-space */
+#define _TIF_ALLWORK_MASK (_TIF_WORK_MASK | _TIF_SYSCALL_TRACE)
+
+#if _TIF_ALLWORK_MASK >= 0x2000
+#error "_TIF_ALLWORK_MASK won't fit in an ANDI now (see entry.S)"
+#endif
+
+/*
+ * Thread-synchronous status.
+ *
+ * This is different from the flags in that nobody else
+ * ever touches our thread-synchronous status, so we don't
+ * have to worry about atomic accesses.
+ */
+#define TS_USEDFPM 0x0001 /* FPU/Media was used by this task this quantum (SMP) */
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_THREAD_INFO_H */
diff --git a/arch/frv/include/asm/timer-regs.h b/arch/frv/include/asm/timer-regs.h
new file mode 100644
index 00000000000..6c5a871ce5e
--- /dev/null
+++ b/arch/frv/include/asm/timer-regs.h
@@ -0,0 +1,106 @@
+/* timer-regs.h: hardware timer register definitions
+ *
+ * Copyright (C) 2003 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_TIMER_REGS_H
+#define _ASM_TIMER_REGS_H
+
+#include <asm/sections.h>
+
+extern unsigned long __nongprelbss __clkin_clock_speed_HZ;
+extern unsigned long __nongprelbss __ext_bus_clock_speed_HZ;
+extern unsigned long __nongprelbss __res_bus_clock_speed_HZ;
+extern unsigned long __nongprelbss __sdram_clock_speed_HZ;
+extern unsigned long __nongprelbss __core_bus_clock_speed_HZ;
+extern unsigned long __nongprelbss __core_clock_speed_HZ;
+extern unsigned long __nongprelbss __dsu_clock_speed_HZ;
+extern unsigned long __nongprelbss __serial_clock_speed_HZ;
+
+#define __get_CLKC() ({ *(volatile unsigned long *)(0xfeff9a00); })
+
+static inline void __set_CLKC(unsigned long v)
+{
+ int tmp;
+
+ asm volatile(" st%I0.p %2,%M0 \n"
+ " setlos %3,%1 \n"
+ " membar \n"
+ "0: \n"
+ " subicc %1,#1,%1,icc0 \n"
+ " bnc icc0,#1,0b \n"
+ : "=m"(*(volatile unsigned long *) 0xfeff9a00), "=r"(tmp)
+ : "r"(v), "i"(256)
+ : "icc0");
+}
+
+#define __get_TCTR() ({ *(volatile unsigned long *)(0xfeff9418); })
+#define __get_TPRV() ({ *(volatile unsigned long *)(0xfeff9420); })
+#define __get_TPRCKSL() ({ *(volatile unsigned long *)(0xfeff9428); })
+#define __get_TCSR(T) ({ *(volatile unsigned long *)(0xfeff9400 + 8 * (T)); })
+#define __get_TxCKSL(T) ({ *(volatile unsigned long *)(0xfeff9430 + 8 * (T)); })
+
+#define __get_TCSR_DATA(T) ({ __get_TCSR(T) >> 24; })
+
+#define __set_TCTR(V) do { *(volatile unsigned long *)(0xfeff9418) = (V); mb(); } while(0)
+#define __set_TPRV(V) do { *(volatile unsigned long *)(0xfeff9420) = (V) << 24; mb(); } while(0)
+#define __set_TPRCKSL(V) do { *(volatile unsigned long *)(0xfeff9428) = (V); mb(); } while(0)
+#define __set_TCSR(T,V) \
+do { *(volatile unsigned long *)(0xfeff9400 + 8 * (T)) = (V); mb(); } while(0)
+
+#define __set_TxCKSL(T,V) \
+do { *(volatile unsigned long *)(0xfeff9430 + 8 * (T)) = (V); mb(); } while(0)
+
+#define __set_TCSR_DATA(T,V) __set_TCSR(T, (V) << 24)
+#define __set_TxCKSL_DATA(T,V) __set_TxCKSL(T, TxCKSL_EIGHT | __TxCKSL_SELECT((V)))
+
+/* clock control register */
+#define CLKC_CMODE 0x0f000000
+#define CLKC_SLPL 0x000f0000
+#define CLKC_P0 0x00000100
+#define CLKC_CM 0x00000003
+
+#define CLKC_CMODE_s 24
+
+/* timer control register - non-readback mode */
+#define TCTR_MODE_0 0x00000000
+#define TCTR_MODE_2 0x04000000
+#define TCTR_MODE_4 0x08000000
+#define TCTR_MODE_5 0x0a000000
+#define TCTR_RL_LATCH 0x00000000
+#define TCTR_RL_RW_LOW8 0x10000000
+#define TCTR_RL_RW_HIGH8 0x20000000
+#define TCTR_RL_RW_LH8 0x30000000
+#define TCTR_SC_CTR0 0x00000000
+#define TCTR_SC_CTR1 0x40000000
+#define TCTR_SC_CTR2 0x80000000
+
+/* timer control register - readback mode */
+#define TCTR_CNT0 0x02000000
+#define TCTR_CNT1 0x04000000
+#define TCTR_CNT2 0x08000000
+#define TCTR_NSTATUS 0x10000000
+#define TCTR_NCOUNT 0x20000000
+#define TCTR_SC_READBACK 0xc0000000
+
+/* timer control status registers - non-readback mode */
+#define TCSRx_DATA 0xff000000
+
+/* timer control status registers - readback mode */
+#define TCSRx_OUTPUT 0x80000000
+#define TCSRx_NULLCOUNT 0x40000000
+#define TCSRx_RL 0x30000000
+#define TCSRx_MODE 0x07000000
+
+/* timer clock select registers */
+#define TxCKSL_SELECT 0x0f000000
+#define __TxCKSL_SELECT(X) ((X) << 24)
+#define TxCKSL_EIGHT 0xf0000000
+
+#endif /* _ASM_TIMER_REGS_H */
diff --git a/arch/frv/include/asm/timex.h b/arch/frv/include/asm/timex.h
new file mode 100644
index 00000000000..a89bddefdac
--- /dev/null
+++ b/arch/frv/include/asm/timex.h
@@ -0,0 +1,20 @@
+/* timex.h: FR-V architecture timex specifications
+ */
+#ifndef _ASM_TIMEX_H
+#define _ASM_TIMEX_H
+
+#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */
+#define CLOCK_TICK_FACTOR 20 /* Factor of both 1000000 and CLOCK_TICK_RATE */
+
+typedef unsigned long cycles_t;
+
+static inline cycles_t get_cycles(void)
+{
+ return 0;
+}
+
+#define vxtime_lock() do {} while (0)
+#define vxtime_unlock() do {} while (0)
+
+#endif
+
diff --git a/arch/frv/include/asm/tlb.h b/arch/frv/include/asm/tlb.h
new file mode 100644
index 00000000000..cd458eb6d75
--- /dev/null
+++ b/arch/frv/include/asm/tlb.h
@@ -0,0 +1,27 @@
+#ifndef _ASM_TLB_H
+#define _ASM_TLB_H
+
+#include <asm/tlbflush.h>
+
+#ifdef CONFIG_MMU
+extern void check_pgt_cache(void);
+#else
+#define check_pgt_cache() do {} while(0)
+#endif
+
+/*
+ * we don't need any special per-pte or per-vma handling...
+ */
+#define tlb_start_vma(tlb, vma) do { } while (0)
+#define tlb_end_vma(tlb, vma) do { } while (0)
+#define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0)
+
+/*
+ * .. because we flush the whole mm when it fills up
+ */
+#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
+
+#include <asm-generic/tlb.h>
+
+#endif /* _ASM_TLB_H */
+
diff --git a/arch/frv/include/asm/tlbflush.h b/arch/frv/include/asm/tlbflush.h
new file mode 100644
index 00000000000..7ac5eafc5d9
--- /dev/null
+++ b/arch/frv/include/asm/tlbflush.h
@@ -0,0 +1,73 @@
+/* tlbflush.h: TLB flushing functions
+ *
+ * Copyright (C) 2004 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_TLBFLUSH_H
+#define _ASM_TLBFLUSH_H
+
+#include <linux/mm.h>
+#include <asm/processor.h>
+
+#ifdef CONFIG_MMU
+
+#ifndef __ASSEMBLY__
+extern void asmlinkage __flush_tlb_all(void);
+extern void asmlinkage __flush_tlb_mm(unsigned long contextid);
+extern void asmlinkage __flush_tlb_page(unsigned long contextid, unsigned long start);
+extern void asmlinkage __flush_tlb_range(unsigned long contextid,
+ unsigned long start, unsigned long end);
+#endif /* !__ASSEMBLY__ */
+
+#define flush_tlb_all() \
+do { \
+ preempt_disable(); \
+ __flush_tlb_all(); \
+ preempt_enable(); \
+} while(0)
+
+#define flush_tlb_mm(mm) \
+do { \
+ preempt_disable(); \
+ __flush_tlb_mm((mm)->context.id); \
+ preempt_enable(); \
+} while(0)
+
+#define flush_tlb_range(vma,start,end) \
+do { \
+ preempt_disable(); \
+ __flush_tlb_range((vma)->vm_mm->context.id, start, end); \
+ preempt_enable(); \
+} while(0)
+
+#define flush_tlb_page(vma,addr) \
+do { \
+ preempt_disable(); \
+ __flush_tlb_page((vma)->vm_mm->context.id, addr); \
+ preempt_enable(); \
+} while(0)
+
+
+#define __flush_tlb_global() flush_tlb_all()
+#define flush_tlb() flush_tlb_all()
+#define flush_tlb_kernel_range(start, end) flush_tlb_all()
+
+#else
+
+#define flush_tlb() BUG()
+#define flush_tlb_all() BUG()
+#define flush_tlb_mm(mm) BUG()
+#define flush_tlb_page(vma,addr) BUG()
+#define flush_tlb_range(mm,start,end) BUG()
+#define flush_tlb_kernel_range(start, end) BUG()
+
+#endif
+
+
+#endif /* _ASM_TLBFLUSH_H */
diff --git a/arch/frv/include/asm/topology.h b/arch/frv/include/asm/topology.h
new file mode 100644
index 00000000000..94272435270
--- /dev/null
+++ b/arch/frv/include/asm/topology.h
@@ -0,0 +1,12 @@
+#ifndef _ASM_TOPOLOGY_H
+#define _ASM_TOPOLOGY_H
+
+#ifdef CONFIG_NUMA
+
+#error NUMA not supported yet
+
+#endif /* CONFIG_NUMA */
+
+#include <asm-generic/topology.h>
+
+#endif /* _ASM_TOPOLOGY_H */
diff --git a/arch/frv/include/asm/types.h b/arch/frv/include/asm/types.h
new file mode 100644
index 00000000000..6bc63650d83
--- /dev/null
+++ b/arch/frv/include/asm/types.h
@@ -0,0 +1,22 @@
+/* types.h: FRV types
+ *
+ * Copyright (C) 2004 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _ASM_TYPES_H
+#define _ASM_TYPES_H
+
+#include <uapi/asm/types.h>
+
+/*
+ * These aren't exported outside the kernel to avoid name space clashes
+ */
+
+#define BITS_PER_LONG 32
+
+#endif /* _ASM_TYPES_H */
diff --git a/arch/frv/include/asm/uaccess.h b/arch/frv/include/asm/uaccess.h
new file mode 100644
index 00000000000..3ac9a59d65d
--- /dev/null
+++ b/arch/frv/include/asm/uaccess.h
@@ -0,0 +1,319 @@
+/* uaccess.h: userspace accessor functions
+ *
+ * Copyright (C) 2004 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_UACCESS_H
+#define _ASM_UACCESS_H
+
+/*
+ * User space memory access functions
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/segment.h>
+#include <asm/sections.h>
+
+#define HAVE_ARCH_UNMAPPED_AREA /* we decide where to put mmaps */
+
+#define __ptr(x) ((unsigned long __force *)(x))
+
+#define VERIFY_READ 0
+#define VERIFY_WRITE 1
+
+/*
+ * check that a range of addresses falls within the current address limit
+ */
+static inline int ___range_ok(unsigned long addr, unsigned long size)
+{
+#ifdef CONFIG_MMU
+ int flag = -EFAULT, tmp;
+
+ asm volatile (
+ " addcc %3,%2,%1,icc0 \n" /* set C-flag if addr+size>4GB */
+ " subcc.p %1,%4,gr0,icc1 \n" /* jump if addr+size>limit */
+ " bc icc0,#0,0f \n"
+ " bhi icc1,#0,0f \n"
+ " setlos #0,%0 \n" /* mark okay */
+ "0: \n"
+ : "=r"(flag), "=&r"(tmp)
+ : "r"(addr), "r"(size), "r"(get_addr_limit()), "0"(flag)
+ );
+
+ return flag;
+
+#else
+
+ if (addr < memory_start ||
+ addr > memory_end ||
+ size > memory_end - memory_start ||
+ addr + size > memory_end)
+ return -EFAULT;
+
+ return 0;
+#endif
+}
+
+#define __range_ok(addr,size) ___range_ok((unsigned long) (addr), (unsigned long) (size))
+
+#define access_ok(type,addr,size) (__range_ok((void __user *)(addr), (size)) == 0)
+#define __access_ok(addr,size) (__range_ok((addr), (size)) == 0)
+
+/*
+ * 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;
+};
+
+/* Returns 0 if exception not found and fixup otherwise. */
+extern unsigned long search_exception_table(unsigned long);
+
+
+/*
+ * These are the main single-value transfer routines. They automatically
+ * use the right size if we just have the right pointer type.
+ */
+#define __put_user(x, ptr) \
+({ \
+ int __pu_err = 0; \
+ \
+ typeof(*(ptr)) __pu_val = (x); \
+ __chk_user_ptr(ptr); \
+ \
+ switch (sizeof (*(ptr))) { \
+ case 1: \
+ __put_user_asm(__pu_err, __pu_val, ptr, "b", "r"); \
+ break; \
+ case 2: \
+ __put_user_asm(__pu_err, __pu_val, ptr, "h", "r"); \
+ break; \
+ case 4: \
+ __put_user_asm(__pu_err, __pu_val, ptr, "", "r"); \
+ break; \
+ case 8: \
+ __put_user_asm(__pu_err, __pu_val, ptr, "d", "e"); \
+ break; \
+ default: \
+ __pu_err = __put_user_bad(); \
+ break; \
+ } \
+ __pu_err; \
+})
+
+#define put_user(x, ptr) \
+({ \
+ typeof(*(ptr)) __user *_p = (ptr); \
+ int _e; \
+ \
+ _e = __range_ok(_p, sizeof(*_p)); \
+ if (_e == 0) \
+ _e = __put_user((x), _p); \
+ _e; \
+})
+
+extern int __put_user_bad(void);
+
+/*
+ * Tell gcc we read from memory instead of writing: this is because
+ * we do not write to any memory gcc knows about, so there are no
+ * aliasing issues.
+ */
+
+#ifdef CONFIG_MMU
+
+#define __put_user_asm(err,x,ptr,dsize,constraint) \
+do { \
+ asm volatile("1: st"dsize"%I1 %2,%M1 \n" \
+ "2: \n" \
+ ".subsection 2 \n" \
+ "3: setlos %3,%0 \n" \
+ " bra 2b \n" \
+ ".previous \n" \
+ ".section __ex_table,\"a\" \n" \
+ " .balign 8 \n" \
+ " .long 1b,3b \n" \
+ ".previous" \
+ : "=r" (err) \
+ : "m" (*__ptr(ptr)), constraint (x), "i"(-EFAULT), "0"(err) \
+ : "memory"); \
+} while (0)
+
+#else
+
+#define __put_user_asm(err,x,ptr,bwl,con) \
+do { \
+ asm(" st"bwl"%I0 %1,%M0 \n" \
+ " membar \n" \
+ : \
+ : "m" (*__ptr(ptr)), con (x) \
+ : "memory"); \
+} while (0)
+
+#endif
+
+/*****************************************************************************/
+/*
+ *
+ */
+#define __get_user(x, ptr) \
+({ \
+ int __gu_err = 0; \
+ __chk_user_ptr(ptr); \
+ \
+ switch (sizeof(*(ptr))) { \
+ case 1: { \
+ unsigned char __gu_val; \
+ __get_user_asm(__gu_err, __gu_val, ptr, "ub", "=r"); \
+ (x) = *(__force __typeof__(*(ptr)) *) &__gu_val; \
+ break; \
+ } \
+ case 2: { \
+ unsigned short __gu_val; \
+ __get_user_asm(__gu_err, __gu_val, ptr, "uh", "=r"); \
+ (x) = *(__force __typeof__(*(ptr)) *) &__gu_val; \
+ break; \
+ } \
+ case 4: { \
+ unsigned int __gu_val; \
+ __get_user_asm(__gu_err, __gu_val, ptr, "", "=r"); \
+ (x) = *(__force __typeof__(*(ptr)) *) &__gu_val; \
+ break; \
+ } \
+ case 8: { \
+ unsigned long long __gu_val; \
+ __get_user_asm(__gu_err, __gu_val, ptr, "d", "=e"); \
+ (x) = *(__force __typeof__(*(ptr)) *) &__gu_val; \
+ break; \
+ } \
+ default: \
+ __gu_err = __get_user_bad(); \
+ break; \
+ } \
+ __gu_err; \
+})
+
+#define get_user(x, ptr) \
+({ \
+ const typeof(*(ptr)) __user *_p = (ptr);\
+ int _e; \
+ \
+ _e = __range_ok(_p, sizeof(*_p)); \
+ if (likely(_e == 0)) \
+ _e = __get_user((x), _p); \
+ else \
+ (x) = (typeof(x)) 0; \
+ _e; \
+})
+
+extern int __get_user_bad(void);
+
+#ifdef CONFIG_MMU
+
+#define __get_user_asm(err,x,ptr,dtype,constraint) \
+do { \
+ asm("1: ld"dtype"%I2 %M2,%1 \n" \
+ "2: \n" \
+ ".subsection 2 \n" \
+ "3: setlos %3,%0 \n" \
+ " setlos #0,%1 \n" \
+ " bra 2b \n" \
+ ".previous \n" \
+ ".section __ex_table,\"a\" \n" \
+ " .balign 8 \n" \
+ " .long 1b,3b \n" \
+ ".previous" \
+ : "=r" (err), constraint (x) \
+ : "m" (*__ptr(ptr)), "i"(-EFAULT), "0"(err) \
+ ); \
+} while(0)
+
+#else
+
+#define __get_user_asm(err,x,ptr,bwl,con) \
+ asm(" ld"bwl"%I1 %M1,%0 \n" \
+ " membar \n" \
+ : con(x) \
+ : "m" (*__ptr(ptr)))
+
+#endif
+
+/*****************************************************************************/
+/*
+ *
+ */
+#define ____force(x) (__force void *)(void __user *)(x)
+#ifdef CONFIG_MMU
+extern long __memset_user(void *dst, unsigned long count);
+extern long __memcpy_user(void *dst, const void *src, unsigned long count);
+
+#define clear_user(dst,count) __memset_user(____force(dst), (count))
+#define __copy_from_user_inatomic(to, from, n) __memcpy_user((to), ____force(from), (n))
+#define __copy_to_user_inatomic(to, from, n) __memcpy_user(____force(to), (from), (n))
+
+#else
+
+#define clear_user(dst,count) (memset(____force(dst), 0, (count)), 0)
+#define __copy_from_user_inatomic(to, from, n) (memcpy((to), ____force(from), (n)), 0)
+#define __copy_to_user_inatomic(to, from, n) (memcpy(____force(to), (from), (n)), 0)
+
+#endif
+
+#define __clear_user clear_user
+
+static inline unsigned long __must_check
+__copy_to_user(void __user *to, const void *from, unsigned long n)
+{
+ might_fault();
+ return __copy_to_user_inatomic(to, from, n);
+}
+
+static inline unsigned long
+__copy_from_user(void *to, const void __user *from, unsigned long n)
+{
+ might_fault();
+ return __copy_from_user_inatomic(to, from, n);
+}
+
+static inline long copy_from_user(void *to, const void __user *from, unsigned long n)
+{
+ unsigned long ret = n;
+
+ if (likely(__access_ok(from, n)))
+ ret = __copy_from_user(to, from, n);
+
+ if (unlikely(ret != 0))
+ memset(to + (n - ret), 0, ret);
+
+ return ret;
+}
+
+static inline long copy_to_user(void __user *to, const void *from, unsigned long n)
+{
+ return likely(__access_ok(to, n)) ? __copy_to_user(to, from, n) : n;
+}
+
+extern long strncpy_from_user(char *dst, const char __user *src, long count);
+extern long strnlen_user(const char __user *src, long count);
+
+#define strlen_user(str) strnlen_user(str, 32767)
+
+extern unsigned long search_exception_table(unsigned long addr);
+
+#endif /* _ASM_UACCESS_H */
diff --git a/arch/frv/include/asm/ucontext.h b/arch/frv/include/asm/ucontext.h
new file mode 100644
index 00000000000..8d8c0c94800
--- /dev/null
+++ b/arch/frv/include/asm/ucontext.h
@@ -0,0 +1,12 @@
+#ifndef _ASM_UCONTEXT_H
+#define _ASM_UCONTEXT_H
+
+struct ucontext {
+ unsigned long uc_flags;
+ struct ucontext *uc_link;
+ stack_t uc_stack;
+ struct sigcontext uc_mcontext;
+ sigset_t uc_sigmask; /* mask last for extensibility */
+};
+
+#endif
diff --git a/arch/frv/include/asm/unaligned.h b/arch/frv/include/asm/unaligned.h
new file mode 100644
index 00000000000..6c61c05b2e0
--- /dev/null
+++ b/arch/frv/include/asm/unaligned.h
@@ -0,0 +1,22 @@
+/* unaligned.h: unaligned access handler
+ *
+ * Copyright (C) 2004 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_UNALIGNED_H
+#define _ASM_UNALIGNED_H
+
+#include <linux/unaligned/le_byteshift.h>
+#include <linux/unaligned/be_struct.h>
+#include <linux/unaligned/generic.h>
+
+#define get_unaligned __get_unaligned_be
+#define put_unaligned __put_unaligned_be
+
+#endif /* _ASM_UNALIGNED_H */
diff --git a/arch/frv/include/asm/unistd.h b/arch/frv/include/asm/unistd.h
new file mode 100644
index 00000000000..17b5df8fc28
--- /dev/null
+++ b/arch/frv/include/asm/unistd.h
@@ -0,0 +1,33 @@
+#ifndef _ASM_UNISTD_H_
+#define _ASM_UNISTD_H_
+
+#include <uapi/asm/unistd.h>
+
+
+#define NR_syscalls 338
+
+/* #define __ARCH_WANT_OLD_READDIR */
+#define __ARCH_WANT_OLD_STAT
+#define __ARCH_WANT_STAT64
+#define __ARCH_WANT_SYS_ALARM
+/* #define __ARCH_WANT_SYS_GETHOSTNAME */
+#define __ARCH_WANT_SYS_IPC
+#define __ARCH_WANT_SYS_PAUSE
+/* #define __ARCH_WANT_SYS_SIGNAL */
+#define __ARCH_WANT_SYS_TIME
+#define __ARCH_WANT_SYS_UTIME
+#define __ARCH_WANT_SYS_WAITPID
+#define __ARCH_WANT_SYS_SOCKETCALL
+#define __ARCH_WANT_SYS_FADVISE64
+#define __ARCH_WANT_SYS_GETPGRP
+#define __ARCH_WANT_SYS_LLSEEK
+#define __ARCH_WANT_SYS_NICE
+/* #define __ARCH_WANT_SYS_OLD_GETRLIMIT */
+#define __ARCH_WANT_SYS_OLDUMOUNT
+/* #define __ARCH_WANT_SYS_SIGPENDING */
+#define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_FORK
+#define __ARCH_WANT_SYS_VFORK
+#define __ARCH_WANT_SYS_CLONE
+
+#endif /* _ASM_UNISTD_H_ */
diff --git a/arch/frv/include/asm/user.h b/arch/frv/include/asm/user.h
new file mode 100644
index 00000000000..82fa8fab64a
--- /dev/null
+++ b/arch/frv/include/asm/user.h
@@ -0,0 +1,80 @@
+/* user.h: FR-V core file format stuff
+ *
+ * Copyright (C) 2003 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _ASM_USER_H
+#define _ASM_USER_H
+
+#include <asm/page.h>
+#include <asm/registers.h>
+
+/* 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.
+ */
+
+/* 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 user_context regs;
+
+ /* The rest of this junk is to help gdb figure out what goes where */
+ unsigned long u_tsize; /* Text segment size (pages). */
+ unsigned long u_dsize; /* Data segment size (pages). */
+ unsigned long 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. */
+
+ unsigned long magic; /* To uniquely identify a core file */
+ char u_comm[32]; /* User command that was responsible */
+};
+
+#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)
+
+#endif
diff --git a/arch/frv/include/asm/vga.h b/arch/frv/include/asm/vga.h
new file mode 100644
index 00000000000..a702c800a22
--- /dev/null
+++ b/arch/frv/include/asm/vga.h
@@ -0,0 +1,17 @@
+/* vga.h: VGA register stuff
+ *
+ * Copyright (C) 2006 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_VGA_H
+#define _ASM_VGA_H
+
+
+
+#endif /* _ASM_VGA_H */
diff --git a/arch/frv/include/asm/virtconvert.h b/arch/frv/include/asm/virtconvert.h
new file mode 100644
index 00000000000..b26d70ab911
--- /dev/null
+++ b/arch/frv/include/asm/virtconvert.h
@@ -0,0 +1,41 @@
+/* virtconvert.h: virtual/physical/page address conversion
+ *
+ * Copyright (C) 2004 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _ASM_VIRTCONVERT_H
+#define _ASM_VIRTCONVERT_H
+
+/*
+ * Macros used for converting between virtual and physical mappings.
+ */
+
+#ifdef __KERNEL__
+
+#include <asm/setup.h>
+
+#ifdef CONFIG_MMU
+
+#define phys_to_virt(vaddr) ((void *) ((unsigned long)(vaddr) + PAGE_OFFSET))
+#define virt_to_phys(vaddr) ((unsigned long) (vaddr) - PAGE_OFFSET)
+
+#else
+
+#define phys_to_virt(vaddr) ((void *) (vaddr))
+#define virt_to_phys(vaddr) ((unsigned long) (vaddr))
+
+#endif
+
+#define virt_to_bus virt_to_phys
+#define bus_to_virt phys_to_virt
+
+#define __page_address(page) (PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT))
+#define page_to_phys(page) virt_to_phys((void *)__page_address(page))
+
+#endif
+#endif
diff --git a/arch/frv/include/asm/xor.h b/arch/frv/include/asm/xor.h
new file mode 100644
index 00000000000..c82eb12a5b1
--- /dev/null
+++ b/arch/frv/include/asm/xor.h
@@ -0,0 +1 @@
+#include <asm-generic/xor.h>
diff --git a/arch/frv/include/uapi/asm/Kbuild b/arch/frv/include/uapi/asm/Kbuild
new file mode 100644
index 00000000000..42a2b33461c
--- /dev/null
+++ b/arch/frv/include/uapi/asm/Kbuild
@@ -0,0 +1,35 @@
+# UAPI Header export list
+include include/uapi/asm-generic/Kbuild.asm
+
+header-y += auxvec.h
+header-y += bitsperlong.h
+header-y += byteorder.h
+header-y += errno.h
+header-y += fcntl.h
+header-y += ioctl.h
+header-y += ioctls.h
+header-y += ipcbuf.h
+header-y += kvm_para.h
+header-y += mman.h
+header-y += msgbuf.h
+header-y += param.h
+header-y += poll.h
+header-y += posix_types.h
+header-y += ptrace.h
+header-y += registers.h
+header-y += resource.h
+header-y += sembuf.h
+header-y += setup.h
+header-y += shmbuf.h
+header-y += sigcontext.h
+header-y += siginfo.h
+header-y += signal.h
+header-y += socket.h
+header-y += sockios.h
+header-y += stat.h
+header-y += statfs.h
+header-y += swab.h
+header-y += termbits.h
+header-y += termios.h
+header-y += types.h
+header-y += unistd.h
diff --git a/arch/frv/include/uapi/asm/auxvec.h b/arch/frv/include/uapi/asm/auxvec.h
new file mode 100644
index 00000000000..07710778fa1
--- /dev/null
+++ b/arch/frv/include/uapi/asm/auxvec.h
@@ -0,0 +1,4 @@
+#ifndef __FRV_AUXVEC_H
+#define __FRV_AUXVEC_H
+
+#endif
diff --git a/arch/frv/include/uapi/asm/bitsperlong.h b/arch/frv/include/uapi/asm/bitsperlong.h
new file mode 100644
index 00000000000..6dc0bb0c13b
--- /dev/null
+++ b/arch/frv/include/uapi/asm/bitsperlong.h
@@ -0,0 +1 @@
+#include <asm-generic/bitsperlong.h>
diff --git a/arch/frv/include/uapi/asm/byteorder.h b/arch/frv/include/uapi/asm/byteorder.h
new file mode 100644
index 00000000000..f29b7593e08
--- /dev/null
+++ b/arch/frv/include/uapi/asm/byteorder.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_BYTEORDER_H
+#define _ASM_BYTEORDER_H
+
+#include <linux/byteorder/big_endian.h>
+
+#endif /* _ASM_BYTEORDER_H */
diff --git a/arch/frv/include/uapi/asm/errno.h b/arch/frv/include/uapi/asm/errno.h
new file mode 100644
index 00000000000..d010795ceef
--- /dev/null
+++ b/arch/frv/include/uapi/asm/errno.h
@@ -0,0 +1,7 @@
+#ifndef _ASM_ERRNO_H
+#define _ASM_ERRNO_H
+
+#include <asm-generic/errno.h>
+
+#endif /* _ASM_ERRNO_H */
+
diff --git a/arch/frv/include/uapi/asm/fcntl.h b/arch/frv/include/uapi/asm/fcntl.h
new file mode 100644
index 00000000000..46ab12db573
--- /dev/null
+++ b/arch/frv/include/uapi/asm/fcntl.h
@@ -0,0 +1 @@
+#include <asm-generic/fcntl.h>
diff --git a/arch/frv/include/uapi/asm/ioctl.h b/arch/frv/include/uapi/asm/ioctl.h
new file mode 100644
index 00000000000..b279fe06dfe
--- /dev/null
+++ b/arch/frv/include/uapi/asm/ioctl.h
@@ -0,0 +1 @@
+#include <asm-generic/ioctl.h>
diff --git a/arch/frv/include/uapi/asm/ioctls.h b/arch/frv/include/uapi/asm/ioctls.h
new file mode 100644
index 00000000000..2f9fb436ec3
--- /dev/null
+++ b/arch/frv/include/uapi/asm/ioctls.h
@@ -0,0 +1,10 @@
+#ifndef __ASM_IOCTLS_H__
+#define __ASM_IOCTLS_H__
+
+#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */
+#define FIOQSIZE 0x545E
+
+#include <asm-generic/ioctls.h>
+
+#endif /* __ASM_IOCTLS_H__ */
+
diff --git a/arch/frv/include/uapi/asm/ipcbuf.h b/arch/frv/include/uapi/asm/ipcbuf.h
new file mode 100644
index 00000000000..84c7e51cb6d
--- /dev/null
+++ b/arch/frv/include/uapi/asm/ipcbuf.h
@@ -0,0 +1 @@
+#include <asm-generic/ipcbuf.h>
diff --git a/arch/frv/include/uapi/asm/kvm_para.h b/arch/frv/include/uapi/asm/kvm_para.h
new file mode 100644
index 00000000000..14fab8f0b95
--- /dev/null
+++ b/arch/frv/include/uapi/asm/kvm_para.h
@@ -0,0 +1 @@
+#include <asm-generic/kvm_para.h>
diff --git a/arch/frv/include/uapi/asm/mman.h b/arch/frv/include/uapi/asm/mman.h
new file mode 100644
index 00000000000..8eebf89f5ab
--- /dev/null
+++ b/arch/frv/include/uapi/asm/mman.h
@@ -0,0 +1 @@
+#include <asm-generic/mman.h>
diff --git a/arch/frv/include/uapi/asm/msgbuf.h b/arch/frv/include/uapi/asm/msgbuf.h
new file mode 100644
index 00000000000..97ceb55a06f
--- /dev/null
+++ b/arch/frv/include/uapi/asm/msgbuf.h
@@ -0,0 +1,32 @@
+#ifndef _ASM_MSGBUF_H
+#define _ASM_MSGBUF_H
+
+/*
+ * The msqid64_ds structure for FR-V 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 /* _ASM_MSGBUF_H */
+
diff --git a/arch/frv/include/uapi/asm/param.h b/arch/frv/include/uapi/asm/param.h
new file mode 100644
index 00000000000..a52dca9a956
--- /dev/null
+++ b/arch/frv/include/uapi/asm/param.h
@@ -0,0 +1,8 @@
+#ifndef _ASM_PARAM_H
+#define _ASM_PARAM_H
+
+#define EXEC_PAGESIZE 16384
+
+#include <asm-generic/param.h>
+
+#endif /* _ASM_PARAM_H */
diff --git a/arch/frv/include/uapi/asm/poll.h b/arch/frv/include/uapi/asm/poll.h
new file mode 100644
index 00000000000..0d01479ccc5
--- /dev/null
+++ b/arch/frv/include/uapi/asm/poll.h
@@ -0,0 +1,12 @@
+#ifndef _ASM_POLL_H
+#define _ASM_POLL_H
+
+#define POLLWRNORM POLLOUT
+#define POLLWRBAND 256
+
+#include <asm-generic/poll.h>
+
+#undef POLLREMOVE
+
+#endif
+
diff --git a/arch/frv/include/uapi/asm/posix_types.h b/arch/frv/include/uapi/asm/posix_types.h
new file mode 100644
index 00000000000..fe512af74a5
--- /dev/null
+++ b/arch/frv/include/uapi/asm/posix_types.h
@@ -0,0 +1,26 @@
+#ifndef _ASM_POSIX_TYPES_H
+#define _ASM_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 short __kernel_mode_t;
+#define __kernel_mode_t __kernel_mode_t
+
+typedef unsigned short __kernel_ipc_pid_t;
+#define __kernel_ipc_pid_t __kernel_ipc_pid_t
+
+typedef unsigned short __kernel_uid_t;
+typedef unsigned short __kernel_gid_t;
+#define __kernel_uid_t __kernel_uid_t
+
+typedef unsigned short __kernel_old_dev_t;
+#define __kernel_old_dev_t __kernel_old_dev_t
+
+#include <asm-generic/posix_types.h>
+
+#endif
+
diff --git a/arch/frv/include/uapi/asm/ptrace.h b/arch/frv/include/uapi/asm/ptrace.h
new file mode 100644
index 00000000000..3887e493468
--- /dev/null
+++ b/arch/frv/include/uapi/asm/ptrace.h
@@ -0,0 +1,60 @@
+/* ptrace.h: ptrace() relevant definitions
+ *
+ * Copyright (C) 2003 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _UAPI_ASM_PTRACE_H
+#define _UAPI_ASM_PTRACE_H
+
+#include <asm/registers.h>
+
+
+#define PT_PSR 0
+#define PT_ISR 1
+#define PT_CCR 2
+#define PT_CCCR 3
+#define PT_LR 4
+#define PT_LCR 5
+#define PT_PC 6
+
+#define PT__STATUS 7 /* exception status */
+#define PT_SYSCALLNO 8 /* syscall number or -1 */
+#define PT_ORIG_GR8 9 /* saved GR8 for signal handling */
+#define PT_GNER0 10
+#define PT_GNER1 11
+#define PT_IACC0H 12
+#define PT_IACC0L 13
+
+#define PT_GR(j) ( 14 + (j)) /* GRj for 0<=j<=63 */
+#define PT_FR(j) ( 78 + (j)) /* FRj for 0<=j<=63 */
+#define PT_FNER(j) (142 + (j)) /* FNERj for 0<=j<=1 */
+#define PT_MSR(j) (144 + (j)) /* MSRj for 0<=j<=2 */
+#define PT_ACC(j) (146 + (j)) /* ACCj for 0<=j<=7 */
+#define PT_ACCG(jklm) (154 + (jklm)) /* ACCGjklm for 0<=jklm<=1 (reads four regs per slot) */
+#define PT_FSR(j) (156 + (j)) /* FSRj for 0<=j<=0 */
+#define PT__GPEND 78
+#define PT__END 157
+
+#define PT_TBR PT_GR(0)
+#define PT_SP PT_GR(1)
+#define PT_FP PT_GR(2)
+#define PT_PREV_FRAME PT_GR(28) /* previous exception frame pointer (old gr28 value) */
+#define PT_CURR_TASK PT_GR(29) /* current task */
+
+
+/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
+#define PTRACE_GETREGS 12
+#define PTRACE_SETREGS 13
+#define PTRACE_GETFPREGS 14
+#define PTRACE_SETFPREGS 15
+#define PTRACE_GETFDPIC 31 /* get the ELF fdpic loadmap address */
+
+#define PTRACE_GETFDPIC_EXEC 0 /* [addr] request the executable loadmap */
+#define PTRACE_GETFDPIC_INTERP 1 /* [addr] request the interpreter loadmap */
+
+#endif /* _UAPI_ASM_PTRACE_H */
diff --git a/arch/frv/include/uapi/asm/registers.h b/arch/frv/include/uapi/asm/registers.h
new file mode 100644
index 00000000000..9666119fcf6
--- /dev/null
+++ b/arch/frv/include/uapi/asm/registers.h
@@ -0,0 +1,232 @@
+/* registers.h: register frame declarations
+ *
+ * Copyright (C) 2003 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+/*
+ * notes:
+ *
+ * (1) that the members of all these structures are carefully aligned to permit
+ * usage of STD/STDF instructions
+ *
+ * (2) if you change these structures, you must change the code in
+ * arch/frvnommu/kernel/{break.S,entry.S,switch_to.S,gdb-stub.c}
+ *
+ *
+ * the kernel stack space block looks like this:
+ *
+ * +0x2000 +----------------------
+ * | union {
+ * | struct frv_frame0 {
+ * | struct user_context {
+ * | struct user_int_regs
+ * | struct user_fpmedia_regs
+ * | }
+ * | struct frv_debug_regs
+ * | }
+ * | struct pt_regs [user exception]
+ * | }
+ * +---------------------- <-- __kernel_frame0_ptr (maybe GR28)
+ * |
+ * | kernel stack
+ * |
+ * |......................
+ * | struct pt_regs [kernel exception]
+ * |...................... <-- __kernel_frame0_ptr (maybe GR28)
+ * |
+ * | kernel stack
+ * |
+ * |...................... <-- stack pointer (GR1)
+ * |
+ * | unused stack space
+ * |
+ * +----------------------
+ * | struct thread_info
+ * +0x0000 +---------------------- <-- __current_thread_info (GR15);
+ *
+ * note that GR28 points to the current exception frame
+ */
+
+#ifndef _ASM_REGISTERS_H
+#define _ASM_REGISTERS_H
+
+#ifndef __ASSEMBLY__
+#define __OFFSET(X,N) ((X)+(N)*4)
+#define __OFFSETC(X,N) xxxxxxxxxxxxxxxxxxxxxxxx
+#else
+#define __OFFSET(X,N) ((X)+(N)*4)
+#define __OFFSETC(X,N) ((X)+(N))
+#endif
+
+/*****************************************************************************/
+/*
+ * Exception/Interrupt frame
+ * - held on kernel stack
+ * - 8-byte aligned on stack (old SP is saved in frame)
+ * - GR0 is fixed 0, so we don't save it
+ */
+#ifndef __ASSEMBLY__
+
+struct pt_regs {
+ unsigned long psr; /* Processor Status Register */
+ unsigned long isr; /* Integer Status Register */
+ unsigned long ccr; /* Condition Code Register */
+ unsigned long cccr; /* Condition Code for Conditional Insns Register */
+ unsigned long lr; /* Link Register */
+ unsigned long lcr; /* Loop Count Register */
+ unsigned long pc; /* Program Counter Register */
+ unsigned long __status; /* exception status */
+ unsigned long syscallno; /* syscall number or -1 */
+ unsigned long orig_gr8; /* original syscall arg #1 */
+ unsigned long gner0;
+ unsigned long gner1;
+ unsigned long long iacc0;
+ unsigned long tbr; /* GR0 is fixed zero, so we use this for TBR */
+ unsigned long sp; /* GR1: USP/KSP */
+ unsigned long fp; /* GR2: FP */
+ unsigned long gr3;
+ unsigned long gr4;
+ unsigned long gr5;
+ unsigned long gr6;
+ unsigned long gr7; /* syscall number */
+ unsigned long gr8; /* 1st syscall param; syscall return */
+ unsigned long gr9; /* 2nd syscall param */
+ unsigned long gr10; /* 3rd syscall param */
+ unsigned long gr11; /* 4th syscall param */
+ unsigned long gr12; /* 5th syscall param */
+ unsigned long gr13; /* 6th syscall param */
+ unsigned long gr14;
+ unsigned long gr15;
+ unsigned long gr16; /* GP pointer */
+ unsigned long gr17; /* small data */
+ unsigned long gr18; /* PIC/PID */
+ unsigned long gr19;
+ unsigned long gr20;
+ unsigned long gr21;
+ unsigned long gr22;
+ unsigned long gr23;
+ unsigned long gr24;
+ unsigned long gr25;
+ unsigned long gr26;
+ unsigned long gr27;
+ struct pt_regs *next_frame; /* GR28 - next exception frame */
+ unsigned long gr29; /* GR29 - OS reserved */
+ unsigned long gr30; /* GR30 - OS reserved */
+ unsigned long gr31; /* GR31 - OS reserved */
+} __attribute__((aligned(8)));
+
+#endif
+
+#define REG__STATUS_STEP 0x00000001 /* - reenable single stepping on return */
+#define REG__STATUS_STEPPED 0x00000002 /* - single step caused exception */
+#define REG__STATUS_BROKE 0x00000004 /* - BREAK insn caused exception */
+#define REG__STATUS_SYSC_ENTRY 0x40000000 /* - T on syscall entry (ptrace.c only) */
+#define REG__STATUS_SYSC_EXIT 0x80000000 /* - T on syscall exit (ptrace.c only) */
+
+#define REG_GR(R) __OFFSET(REG_GR0, (R))
+
+#define REG_SP REG_GR(1)
+#define REG_FP REG_GR(2)
+#define REG_PREV_FRAME REG_GR(28) /* previous exception frame pointer (old gr28 value) */
+#define REG_CURR_TASK REG_GR(29) /* current task */
+
+/*****************************************************************************/
+/*
+ * debugging registers
+ */
+#ifndef __ASSEMBLY__
+
+struct frv_debug_regs
+{
+ unsigned long dcr;
+ unsigned long ibar[4] __attribute__((aligned(8)));
+ unsigned long dbar[4] __attribute__((aligned(8)));
+ unsigned long dbdr[4][4] __attribute__((aligned(8)));
+ unsigned long dbmr[4][4] __attribute__((aligned(8)));
+} __attribute__((aligned(8)));
+
+#endif
+
+/*****************************************************************************/
+/*
+ * userspace registers
+ */
+#ifndef __ASSEMBLY__
+
+struct user_int_regs
+{
+ /* integer registers
+ * - up to gr[31] mirror pt_regs
+ * - total size must be multiple of 8 bytes
+ */
+ unsigned long psr; /* Processor Status Register */
+ unsigned long isr; /* Integer Status Register */
+ unsigned long ccr; /* Condition Code Register */
+ unsigned long cccr; /* Condition Code for Conditional Insns Register */
+ unsigned long lr; /* Link Register */
+ unsigned long lcr; /* Loop Count Register */
+ unsigned long pc; /* Program Counter Register */
+ unsigned long __status; /* exception status */
+ unsigned long syscallno; /* syscall number or -1 */
+ unsigned long orig_gr8; /* original syscall arg #1 */
+ unsigned long gner[2];
+ unsigned long long iacc[1];
+
+ union {
+ unsigned long tbr;
+ unsigned long gr[64];
+ };
+};
+
+struct user_fpmedia_regs
+{
+ /* FP/Media registers */
+ unsigned long fr[64];
+ unsigned long fner[2];
+ unsigned long msr[2];
+ unsigned long acc[8];
+ unsigned char accg[8];
+ unsigned long fsr[1];
+};
+
+struct user_context
+{
+ struct user_int_regs i;
+ struct user_fpmedia_regs f;
+
+ /* we provide a context extension so that we can save the regs for CPUs that
+ * implement many more of Fujitsu's lavish register spec
+ */
+ void *extension;
+} __attribute__((aligned(8)));
+
+struct frv_frame0 {
+ union {
+ struct pt_regs regs;
+ struct user_context uc;
+ };
+
+ struct frv_debug_regs debug;
+
+} __attribute__((aligned(32)));
+
+#endif
+
+#define __INT_GR(R) __OFFSET(__INT_GR0, (R))
+
+#define __FPMEDIA_FR(R) __OFFSET(__FPMEDIA_FR0, (R))
+#define __FPMEDIA_FNER(R) __OFFSET(__FPMEDIA_FNER0, (R))
+#define __FPMEDIA_MSR(R) __OFFSET(__FPMEDIA_MSR0, (R))
+#define __FPMEDIA_ACC(R) __OFFSET(__FPMEDIA_ACC0, (R))
+#define __FPMEDIA_ACCG(R) __OFFSETC(__FPMEDIA_ACCG0, (R))
+#define __FPMEDIA_FSR(R) __OFFSET(__FPMEDIA_FSR0, (R))
+
+#define __THREAD_GR(R) __OFFSET(__THREAD_GR16, (R) - 16)
+
+#endif /* _ASM_REGISTERS_H */
diff --git a/arch/frv/include/uapi/asm/resource.h b/arch/frv/include/uapi/asm/resource.h
new file mode 100644
index 00000000000..5fc60548fd0
--- /dev/null
+++ b/arch/frv/include/uapi/asm/resource.h
@@ -0,0 +1,7 @@
+#ifndef _ASM_RESOURCE_H
+#define _ASM_RESOURCE_H
+
+#include <asm-generic/resource.h>
+
+#endif /* _ASM_RESOURCE_H */
+
diff --git a/arch/frv/include/uapi/asm/sembuf.h b/arch/frv/include/uapi/asm/sembuf.h
new file mode 100644
index 00000000000..164b12786d6
--- /dev/null
+++ b/arch/frv/include/uapi/asm/sembuf.h
@@ -0,0 +1,26 @@
+#ifndef _ASM_SEMBUF_H
+#define _ASM_SEMBUF_H
+
+/*
+ * The semid64_ds structure for FR-V 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 /* _ASM_SEMBUF_H */
+
diff --git a/arch/frv/include/uapi/asm/setup.h b/arch/frv/include/uapi/asm/setup.h
new file mode 100644
index 00000000000..fbf3fc96aae
--- /dev/null
+++ b/arch/frv/include/uapi/asm/setup.h
@@ -0,0 +1,18 @@
+/* setup.h: setup stuff
+ *
+ * Copyright (C) 2004 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _UAPI_ASM_SETUP_H
+#define _UAPI_ASM_SETUP_H
+
+#define COMMAND_LINE_SIZE 512
+
+
+#endif /* _UAPI_ASM_SETUP_H */
diff --git a/arch/frv/include/uapi/asm/shmbuf.h b/arch/frv/include/uapi/asm/shmbuf.h
new file mode 100644
index 00000000000..4c6e711a477
--- /dev/null
+++ b/arch/frv/include/uapi/asm/shmbuf.h
@@ -0,0 +1,43 @@
+#ifndef _ASM_SHMBUF_H
+#define _ASM_SHMBUF_H
+
+/*
+ * The shmid64_ds structure for FR-V 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 /* _ASM_SHMBUF_H */
+
diff --git a/arch/frv/include/uapi/asm/sigcontext.h b/arch/frv/include/uapi/asm/sigcontext.h
new file mode 100644
index 00000000000..3b263f3cc96
--- /dev/null
+++ b/arch/frv/include/uapi/asm/sigcontext.h
@@ -0,0 +1,26 @@
+/* sigcontext.h: FRV signal context
+ *
+ * Copyright (C) 2003 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _ASM_SIGCONTEXT_H
+#define _ASM_SIGCONTEXT_H
+
+#include <asm/registers.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 {
+ struct user_context sc_context;
+ unsigned long sc_oldmask; /* old sigmask */
+} __attribute__((aligned(8)));
+
+#endif
diff --git a/arch/frv/include/uapi/asm/siginfo.h b/arch/frv/include/uapi/asm/siginfo.h
new file mode 100644
index 00000000000..d3fd1ca4565
--- /dev/null
+++ b/arch/frv/include/uapi/asm/siginfo.h
@@ -0,0 +1,12 @@
+#ifndef _ASM_SIGINFO_H
+#define _ASM_SIGINFO_H
+
+#include <linux/types.h>
+#include <asm-generic/siginfo.h>
+
+#define FPE_MDAOVF (__SI_FAULT|9) /* media overflow */
+#undef NSIGFPE
+#define NSIGFPE 9
+
+#endif
+
diff --git a/arch/frv/include/uapi/asm/signal.h b/arch/frv/include/uapi/asm/signal.h
new file mode 100644
index 00000000000..bf3b162f9be
--- /dev/null
+++ b/arch/frv/include/uapi/asm/signal.h
@@ -0,0 +1,36 @@
+#ifndef _UAPI_ASM_SIGNAL_H
+#define _UAPI_ASM_SIGNAL_H
+
+#include <linux/types.h>
+
+#ifndef __KERNEL__
+/* Here we must cater to libcs that poke about in kernel headers. */
+
+#define NSIG 32
+typedef unsigned long sigset_t;
+
+#endif /* !__KERNEL__ */
+
+#define SA_RESTORER 0x04000000 /* to get struct sigaction correct */
+
+#include <asm-generic/signal.h>
+
+#ifndef __KERNEL__
+/* 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__ */
+
+#endif /* _UAPI_ASM_SIGNAL_H */
diff --git a/arch/frv/include/uapi/asm/socket.h b/arch/frv/include/uapi/asm/socket.h
new file mode 100644
index 00000000000..ca2c6e6f31c
--- /dev/null
+++ b/arch/frv/include/uapi/asm/socket.h
@@ -0,0 +1,84 @@
+#ifndef _ASM_SOCKET_H
+#define _ASM_SOCKET_H
+
+#include <asm/sockios.h>
+
+/* 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
+#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_GET_FILTER SO_ATTACH_FILTER
+
+#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
+
+#define SO_WIFI_STATUS 41
+#define SCM_WIFI_STATUS SO_WIFI_STATUS
+#define SO_PEEK_OFF 42
+
+/* Instruct lower device to use last 4-bytes of skb data as FCS */
+#define SO_NOFCS 43
+
+#define SO_LOCK_FILTER 44
+
+#define SO_SELECT_ERR_QUEUE 45
+
+#define SO_BUSY_POLL 46
+
+#define SO_MAX_PACING_RATE 47
+
+#define SO_BPF_EXTENSIONS 48
+
+#endif /* _ASM_SOCKET_H */
+
diff --git a/arch/frv/include/uapi/asm/sockios.h b/arch/frv/include/uapi/asm/sockios.h
new file mode 100644
index 00000000000..5dbdd13e6de
--- /dev/null
+++ b/arch/frv/include/uapi/asm/sockios.h
@@ -0,0 +1,14 @@
+#ifndef _ASM_SOCKIOS__
+#define _ASM_SOCKIOS__
+
+/* 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 /* _ASM_SOCKIOS__ */
+
diff --git a/arch/frv/include/uapi/asm/stat.h b/arch/frv/include/uapi/asm/stat.h
new file mode 100644
index 00000000000..ce56de9b37b
--- /dev/null
+++ b/arch/frv/include/uapi/asm/stat.h
@@ -0,0 +1,100 @@
+#ifndef _ASM_STAT_H
+#define _ASM_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;
+};
+
+/* This matches struct stat in uClibc/glibc. */
+struct stat {
+ unsigned char __pad1[6];
+ unsigned short st_dev;
+
+ unsigned long __pad2;
+ unsigned long st_ino;
+
+ unsigned short __pad3;
+ unsigned short st_mode;
+ unsigned short __pad4;
+ unsigned short st_nlink;
+
+ unsigned short __pad5;
+ unsigned short st_uid;
+ unsigned short __pad6;
+ unsigned short st_gid;
+
+ unsigned char __pad7[6];
+ unsigned short st_rdev;
+
+ unsigned long __pad8;
+ unsigned long st_size;
+
+ unsigned long __pad9; /* align 64-bit st_blocks to 2-word */
+ unsigned long st_blksize;
+
+ unsigned long __pad10; /* future possible st_blocks high bits */
+ unsigned long st_blocks; /* Number 512-byte blocks allocated. */
+
+ unsigned long __unused1;
+ unsigned long st_atime;
+
+ unsigned long __unused2;
+ unsigned long st_mtime;
+
+ unsigned long __unused3;
+ unsigned long st_ctime;
+
+ unsigned long long __unused4;
+};
+
+/* This matches struct stat64 in uClibc/glibc. The layout is exactly
+ the same as that of struct stat above, with 64-bit types taking up
+ space that was formerly used by padding. stat syscalls are still
+ different from stat64, though, in that the former tests for
+ overflow. */
+struct stat64 {
+ unsigned char __pad1[6];
+ unsigned short st_dev;
+
+ unsigned long long st_ino;
+
+ unsigned int st_mode;
+ unsigned int st_nlink;
+
+ unsigned long st_uid;
+ unsigned long st_gid;
+
+ unsigned char __pad2[6];
+ unsigned short st_rdev;
+
+ long long st_size;
+
+ unsigned long __pad3; /* align 64-bit st_blocks to 2-word */
+ unsigned long st_blksize;
+
+ unsigned long __pad4; /* future possible st_blocks high bits */
+ unsigned long st_blocks; /* Number 512-byte blocks allocated. */
+
+ unsigned long st_atime_nsec;
+ unsigned long st_atime;
+
+ unsigned int st_mtime_nsec;
+ unsigned long st_mtime;
+
+ unsigned long st_ctime_nsec;
+ unsigned long st_ctime;
+
+ unsigned long long __unused4;
+};
+
+#endif /* _ASM_STAT_H */
diff --git a/arch/frv/include/uapi/asm/statfs.h b/arch/frv/include/uapi/asm/statfs.h
new file mode 100644
index 00000000000..741f586045b
--- /dev/null
+++ b/arch/frv/include/uapi/asm/statfs.h
@@ -0,0 +1,7 @@
+#ifndef _ASM_STATFS_H
+#define _ASM_STATFS_H
+
+#include <asm-generic/statfs.h>
+
+#endif /* _ASM_STATFS_H */
+
diff --git a/arch/frv/include/uapi/asm/swab.h b/arch/frv/include/uapi/asm/swab.h
new file mode 100644
index 00000000000..f305834b479
--- /dev/null
+++ b/arch/frv/include/uapi/asm/swab.h
@@ -0,0 +1,10 @@
+#ifndef _ASM_SWAB_H
+#define _ASM_SWAB_H
+
+#include <linux/types.h>
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__)
+# define __SWAB_64_THRU_32__
+#endif
+
+#endif /* _ASM_SWAB_H */
diff --git a/arch/frv/include/uapi/asm/termbits.h b/arch/frv/include/uapi/asm/termbits.h
new file mode 100644
index 00000000000..7722e19cc34
--- /dev/null
+++ b/arch/frv/include/uapi/asm/termbits.h
@@ -0,0 +1,203 @@
+#ifndef _ASM_TERMBITS_H__
+#define _ASM_TERMBITS_H__
+
+#include <linux/posix_types.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 CTVB 004000000000 /* VisioBraille Terminal flow control */
+#define CMSPAR 010000000000 /* mark or space (stick) parity */
+#define CRTSCTS 020000000000 /* flow control */
+
+#define IBSHIFT 16 /* Shift from CBAUD to CIBAUD */
+
+/* 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_TERMBITS_H__ */
+
diff --git a/arch/frv/include/uapi/asm/termios.h b/arch/frv/include/uapi/asm/termios.h
new file mode 100644
index 00000000000..edcc08a2238
--- /dev/null
+++ b/arch/frv/include/uapi/asm/termios.h
@@ -0,0 +1,46 @@
+#ifndef _UAPI_ASM_TERMIOS_H
+#define _UAPI_ASM_TERMIOS_H
+
+#include <asm/termbits.h>
+#include <asm/ioctls.h>
+
+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 */
+};
+
+
+/* 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
+
+#define TIOCM_MODEM_BITS TIOCM_OUT2 /* IRDA support */
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+
+
+#endif /* _UAPI_ASM_TERMIOS_H */
diff --git a/arch/frv/include/uapi/asm/types.h b/arch/frv/include/uapi/asm/types.h
new file mode 100644
index 00000000000..cf23149943f
--- /dev/null
+++ b/arch/frv/include/uapi/asm/types.h
@@ -0,0 +1,11 @@
+/* types.h: FRV types
+ *
+ * Copyright (C) 2004 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <asm-generic/int-ll64.h>
diff --git a/arch/frv/include/uapi/asm/unistd.h b/arch/frv/include/uapi/asm/unistd.h
new file mode 100644
index 00000000000..9e2612ff1c9
--- /dev/null
+++ b/arch/frv/include/uapi/asm/unistd.h
@@ -0,0 +1,348 @@
+#ifndef _UAPI_ASM_UNISTD_H_
+#define _UAPI_ASM_UNISTD_H_
+
+/*
+ * This file contains the system call numbers.
+ */
+
+#define __NR_restart_syscall 0
+#define __NR_exit 1
+#define __NR_fork 2
+#define __NR_read 3
+#define __NR_write 4
+#define __NR_open 5
+#define __NR_close 6
+#define __NR_waitpid 7
+#define __NR_creat 8
+#define __NR_link 9
+#define __NR_unlink 10
+#define __NR_execve 11
+#define __NR_chdir 12
+#define __NR_time 13
+#define __NR_mknod 14
+#define __NR_chmod 15
+#define __NR_lchown 16
+#define __NR_break 17
+#define __NR_oldstat 18
+#define __NR_lseek 19
+#define __NR_getpid 20
+#define __NR_mount 21
+#define __NR_umount 22
+#define __NR_setuid 23
+#define __NR_getuid 24
+#define __NR_stime 25
+#define __NR_ptrace 26
+#define __NR_alarm 27
+#define __NR_oldfstat 28
+#define __NR_pause 29
+#define __NR_utime 30
+#define __NR_stty 31
+#define __NR_gtty 32
+#define __NR_access 33
+#define __NR_nice 34
+#define __NR_ftime 35
+#define __NR_sync 36
+#define __NR_kill 37
+#define __NR_rename 38
+#define __NR_mkdir 39
+#define __NR_rmdir 40
+#define __NR_dup 41
+#define __NR_pipe 42
+#define __NR_times 43
+#define __NR_prof 44
+#define __NR_brk 45
+#define __NR_setgid 46
+#define __NR_getgid 47
+#define __NR_signal 48
+#define __NR_geteuid 49
+#define __NR_getegid 50
+#define __NR_acct 51
+#define __NR_umount2 52
+#define __NR_lock 53
+#define __NR_ioctl 54
+#define __NR_fcntl 55
+#define __NR_mpx 56
+#define __NR_setpgid 57
+#define __NR_ulimit 58
+// #define __NR_oldolduname /* 59 */ obsolete
+#define __NR_umask 60
+#define __NR_chroot 61
+#define __NR_ustat 62
+#define __NR_dup2 63
+#define __NR_getppid 64
+#define __NR_getpgrp 65
+#define __NR_setsid 66
+#define __NR_sigaction 67
+#define __NR_sgetmask 68
+#define __NR_ssetmask 69
+#define __NR_setreuid 70
+#define __NR_setregid 71
+#define __NR_sigsuspend 72
+#define __NR_sigpending 73
+#define __NR_sethostname 74
+#define __NR_setrlimit 75
+#define __NR_getrlimit 76 /* Back compatible 2Gig limited rlimit */
+#define __NR_getrusage 77
+#define __NR_gettimeofday 78
+#define __NR_settimeofday 79
+#define __NR_getgroups 80
+#define __NR_setgroups 81
+#define __NR_select 82
+#define __NR_symlink 83
+#define __NR_oldlstat 84
+#define __NR_readlink 85
+#define __NR_uselib 86
+#define __NR_swapon 87
+#define __NR_reboot 88
+#define __NR_readdir 89
+// #define __NR_mmap 90 /* obsolete - not implemented */
+#define __NR_munmap 91
+#define __NR_truncate 92
+#define __NR_ftruncate 93
+#define __NR_fchmod 94
+#define __NR_fchown 95
+#define __NR_getpriority 96
+#define __NR_setpriority 97
+// #define __NR_profil /* 98 */ obsolete
+#define __NR_statfs 99
+#define __NR_fstatfs 100
+// #define __NR_ioperm /* 101 */ not supported
+#define __NR_socketcall 102
+#define __NR_syslog 103
+#define __NR_setitimer 104
+#define __NR_getitimer 105
+#define __NR_stat 106
+#define __NR_lstat 107
+#define __NR_fstat 108
+// #define __NR_olduname /* 109 */ obsolete
+// #define __NR_iopl /* 110 */ not supported
+#define __NR_vhangup 111
+// #define __NR_idle /* 112 */ Obsolete
+// #define __NR_vm86old /* 113 */ not supported
+#define __NR_wait4 114
+#define __NR_swapoff 115
+#define __NR_sysinfo 116
+#define __NR_ipc 117
+#define __NR_fsync 118
+#define __NR_sigreturn 119
+#define __NR_clone 120
+#define __NR_setdomainname 121
+#define __NR_uname 122
+// #define __NR_modify_ldt /* 123 */ not supported
+#define __NR_cacheflush 123
+#define __NR_adjtimex 124
+#define __NR_mprotect 125
+#define __NR_sigprocmask 126
+#define __NR_create_module 127
+#define __NR_init_module 128
+#define __NR_delete_module 129
+#define __NR_get_kernel_syms 130
+#define __NR_quotactl 131
+#define __NR_getpgid 132
+#define __NR_fchdir 133
+#define __NR_bdflush 134
+#define __NR_sysfs 135
+#define __NR_personality 136
+#define __NR_afs_syscall 137 /* Syscall for Andrew File System */
+#define __NR_setfsuid 138
+#define __NR_setfsgid 139
+#define __NR__llseek 140
+#define __NR_getdents 141
+#define __NR__newselect 142
+#define __NR_flock 143
+#define __NR_msync 144
+#define __NR_readv 145
+#define __NR_writev 146
+#define __NR_getsid 147
+#define __NR_fdatasync 148
+#define __NR__sysctl 149
+#define __NR_mlock 150
+#define __NR_munlock 151
+#define __NR_mlockall 152
+#define __NR_munlockall 153
+#define __NR_sched_setparam 154
+#define __NR_sched_getparam 155
+#define __NR_sched_setscheduler 156
+#define __NR_sched_getscheduler 157
+#define __NR_sched_yield 158
+#define __NR_sched_get_priority_max 159
+#define __NR_sched_get_priority_min 160
+#define __NR_sched_rr_get_interval 161
+#define __NR_nanosleep 162
+#define __NR_mremap 163
+#define __NR_setresuid 164
+#define __NR_getresuid 165
+// #define __NR_vm86 /* 166 */ not supported
+#define __NR_query_module 167
+#define __NR_poll 168
+#define __NR_nfsservctl 169
+#define __NR_setresgid 170
+#define __NR_getresgid 171
+#define __NR_prctl 172
+#define __NR_rt_sigreturn 173
+#define __NR_rt_sigaction 174
+#define __NR_rt_sigprocmask 175
+#define __NR_rt_sigpending 176
+#define __NR_rt_sigtimedwait 177
+#define __NR_rt_sigqueueinfo 178
+#define __NR_rt_sigsuspend 179
+#define __NR_pread64 180
+#define __NR_pwrite64 181
+#define __NR_chown 182
+#define __NR_getcwd 183
+#define __NR_capget 184
+#define __NR_capset 185
+#define __NR_sigaltstack 186
+#define __NR_sendfile 187
+#define __NR_getpmsg 188 /* some people actually want streams */
+#define __NR_putpmsg 189 /* some people actually want streams */
+#define __NR_vfork 190
+#define __NR_ugetrlimit 191 /* SuS compliant getrlimit */
+#define __NR_mmap2 192
+#define __NR_truncate64 193
+#define __NR_ftruncate64 194
+#define __NR_stat64 195
+#define __NR_lstat64 196
+#define __NR_fstat64 197
+#define __NR_lchown32 198
+#define __NR_getuid32 199
+#define __NR_getgid32 200
+#define __NR_geteuid32 201
+#define __NR_getegid32 202
+#define __NR_setreuid32 203
+#define __NR_setregid32 204
+#define __NR_getgroups32 205
+#define __NR_setgroups32 206
+#define __NR_fchown32 207
+#define __NR_setresuid32 208
+#define __NR_getresuid32 209
+#define __NR_setresgid32 210
+#define __NR_getresgid32 211
+#define __NR_chown32 212
+#define __NR_setuid32 213
+#define __NR_setgid32 214
+#define __NR_setfsuid32 215
+#define __NR_setfsgid32 216
+#define __NR_pivot_root 217
+#define __NR_mincore 218
+#define __NR_madvise 219
+
+#define __NR_getdents64 220
+#define __NR_fcntl64 221
+#define __NR_security 223 /* syscall for security modules */
+#define __NR_gettid 224
+#define __NR_readahead 225
+#define __NR_setxattr 226
+#define __NR_lsetxattr 227
+#define __NR_fsetxattr 228
+#define __NR_getxattr 229
+#define __NR_lgetxattr 230
+#define __NR_fgetxattr 231
+#define __NR_listxattr 232
+#define __NR_llistxattr 233
+#define __NR_flistxattr 234
+#define __NR_removexattr 235
+#define __NR_lremovexattr 236
+#define __NR_fremovexattr 237
+#define __NR_tkill 238
+#define __NR_sendfile64 239
+#define __NR_futex 240
+#define __NR_sched_setaffinity 241
+#define __NR_sched_getaffinity 242
+#define __NR_set_thread_area 243
+#define __NR_get_thread_area 244
+#define __NR_io_setup 245
+#define __NR_io_destroy 246
+#define __NR_io_getevents 247
+#define __NR_io_submit 248
+#define __NR_io_cancel 249
+#define __NR_fadvise64 250
+
+#define __NR_exit_group 252
+#define __NR_lookup_dcookie 253
+#define __NR_epoll_create 254
+#define __NR_epoll_ctl 255
+#define __NR_epoll_wait 256
+#define __NR_remap_file_pages 257
+#define __NR_set_tid_address 258
+#define __NR_timer_create 259
+#define __NR_timer_settime (__NR_timer_create+1)
+#define __NR_timer_gettime (__NR_timer_create+2)
+#define __NR_timer_getoverrun (__NR_timer_create+3)
+#define __NR_timer_delete (__NR_timer_create+4)
+#define __NR_clock_settime (__NR_timer_create+5)
+#define __NR_clock_gettime (__NR_timer_create+6)
+#define __NR_clock_getres (__NR_timer_create+7)
+#define __NR_clock_nanosleep (__NR_timer_create+8)
+#define __NR_statfs64 268
+#define __NR_fstatfs64 269
+#define __NR_tgkill 270
+#define __NR_utimes 271
+#define __NR_fadvise64_64 272
+#define __NR_vserver 273
+#define __NR_mbind 274
+#define __NR_get_mempolicy 275
+#define __NR_set_mempolicy 276
+#define __NR_mq_open 277
+#define __NR_mq_unlink (__NR_mq_open+1)
+#define __NR_mq_timedsend (__NR_mq_open+2)
+#define __NR_mq_timedreceive (__NR_mq_open+3)
+#define __NR_mq_notify (__NR_mq_open+4)
+#define __NR_mq_getsetattr (__NR_mq_open+5)
+#define __NR_kexec_load 283
+#define __NR_waitid 284
+/* #define __NR_sys_setaltroot 285 */
+#define __NR_add_key 286
+#define __NR_request_key 287
+#define __NR_keyctl 288
+#define __NR_ioprio_set 289
+#define __NR_ioprio_get 290
+#define __NR_inotify_init 291
+#define __NR_inotify_add_watch 292
+#define __NR_inotify_rm_watch 293
+#define __NR_migrate_pages 294
+#define __NR_openat 295
+#define __NR_mkdirat 296
+#define __NR_mknodat 297
+#define __NR_fchownat 298
+#define __NR_futimesat 299
+#define __NR_fstatat64 300
+#define __NR_unlinkat 301
+#define __NR_renameat 302
+#define __NR_linkat 303
+#define __NR_symlinkat 304
+#define __NR_readlinkat 305
+#define __NR_fchmodat 306
+#define __NR_faccessat 307
+#define __NR_pselect6 308
+#define __NR_ppoll 309
+#define __NR_unshare 310
+#define __NR_set_robust_list 311
+#define __NR_get_robust_list 312
+#define __NR_splice 313
+#define __NR_sync_file_range 314
+#define __NR_tee 315
+#define __NR_vmsplice 316
+#define __NR_move_pages 317
+#define __NR_getcpu 318
+#define __NR_epoll_pwait 319
+#define __NR_utimensat 320
+#define __NR_signalfd 321
+#define __NR_timerfd_create 322
+#define __NR_eventfd 323
+#define __NR_fallocate 324
+#define __NR_timerfd_settime 325
+#define __NR_timerfd_gettime 326
+#define __NR_signalfd4 327
+#define __NR_eventfd2 328
+#define __NR_epoll_create1 329
+#define __NR_dup3 330
+#define __NR_pipe2 331
+#define __NR_inotify_init1 332
+#define __NR_preadv 333
+#define __NR_pwritev 334
+#define __NR_rt_tgsigqueueinfo 335
+#define __NR_perf_event_open 336
+#define __NR_setns 337
+
+#endif /* _UAPI_ASM_UNISTD_H_ */
diff --git a/arch/frv/kernel/Makefile b/arch/frv/kernel/Makefile
index 5a827b349b5..3cbb3294b9f 100644
--- a/arch/frv/kernel/Makefile
+++ b/arch/frv/kernel/Makefile
@@ -5,20 +5,19 @@
heads-y := head-uc-fr401.o head-uc-fr451.o head-uc-fr555.o
heads-$(CONFIG_MMU) := head-mmu-fr451.o
-extra-y:= head.o init_task.o vmlinux.lds
+extra-y:= head.o vmlinux.lds
-obj-y := $(heads-y) entry.o entry-table.o break.o switch_to.o kernel_thread.o \
+obj-y := $(heads-y) entry.o entry-table.o break.o switch_to.o \
process.o traps.o ptrace.o signal.o dma.o \
- sys_frv.o time.o semaphore.o setup.o frv_ksyms.o \
- debug-stub.o irq.o irq-routing.o sleep.o uaccess.o
+ sys_frv.o time.o setup.o frv_ksyms.o \
+ debug-stub.o irq.o sleep.o uaccess.o
obj-$(CONFIG_GDBSTUB) += gdb-stub.o gdb-io.o
obj-$(CONFIG_MB93091_VDK) += irq-mb93091.o
-obj-$(CONFIG_MB93093_PDK) += irq-mb93093.o
-obj-$(CONFIG_FUJITSU_MB93493) += irq-mb93493.o
obj-$(CONFIG_PM) += pm.o cmode.o
obj-$(CONFIG_MB93093_PDK) += pm-mb93093.o
+obj-$(CONFIG_FUJITSU_MB93493) += irq-mb93493.o
obj-$(CONFIG_SYSCTL) += sysctl.o
obj-$(CONFIG_FUTEX) += futex.o
obj-$(CONFIG_MODULES) += module.o
diff --git a/arch/frv/kernel/asm-offsets.c b/arch/frv/kernel/asm-offsets.c
index 9e263112a6e..9de96843a27 100644
--- a/arch/frv/kernel/asm-offsets.c
+++ b/arch/frv/kernel/asm-offsets.c
@@ -1 +1,108 @@
-/* Dummy asm-offsets.c file. Required by kbuild and ready to be used - hint! */
+/*
+ * Generate definitions needed by assembly language modules.
+ * This code generates raw asm output which is post-processed
+ * to extract and format the required data.
+ */
+
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/personality.h>
+#include <linux/kbuild.h>
+#include <asm/registers.h>
+#include <asm/ucontext.h>
+#include <asm/processor.h>
+#include <asm/thread_info.h>
+#include <asm/gdb-stub.h>
+
+#define DEF_PTREG(sym, reg) \
+ asm volatile("\n->" #sym " %0 offsetof(struct pt_regs, " #reg ")" \
+ : : "i" (offsetof(struct pt_regs, reg)))
+
+#define DEF_IREG(sym, reg) \
+ asm volatile("\n->" #sym " %0 offsetof(struct user_context, " #reg ")" \
+ : : "i" (offsetof(struct user_context, reg)))
+
+#define DEF_FREG(sym, reg) \
+ asm volatile("\n->" #sym " %0 offsetof(struct user_context, " #reg ")" \
+ : : "i" (offsetof(struct user_context, reg)))
+
+#define DEF_0REG(sym, reg) \
+ asm volatile("\n->" #sym " %0 offsetof(struct frv_frame0, " #reg ")" \
+ : : "i" (offsetof(struct frv_frame0, reg)))
+
+void foo(void)
+{
+ /* offsets into the thread_info structure */
+ OFFSET(TI_TASK, thread_info, task);
+ OFFSET(TI_EXEC_DOMAIN, thread_info, exec_domain);
+ OFFSET(TI_FLAGS, thread_info, flags);
+ OFFSET(TI_STATUS, thread_info, status);
+ OFFSET(TI_CPU, thread_info, cpu);
+ OFFSET(TI_PREEMPT_COUNT, thread_info, preempt_count);
+ OFFSET(TI_ADDR_LIMIT, thread_info, addr_limit);
+ OFFSET(TI_RESTART_BLOCK, thread_info, restart_block);
+ BLANK();
+
+ /* offsets into register file storage */
+ DEF_PTREG(REG_PSR, psr);
+ DEF_PTREG(REG_ISR, isr);
+ DEF_PTREG(REG_CCR, ccr);
+ DEF_PTREG(REG_CCCR, cccr);
+ DEF_PTREG(REG_LR, lr);
+ DEF_PTREG(REG_LCR, lcr);
+ DEF_PTREG(REG_PC, pc);
+ DEF_PTREG(REG__STATUS, __status);
+ DEF_PTREG(REG_SYSCALLNO, syscallno);
+ DEF_PTREG(REG_ORIG_GR8, orig_gr8);
+ DEF_PTREG(REG_GNER0, gner0);
+ DEF_PTREG(REG_GNER1, gner1);
+ DEF_PTREG(REG_IACC0, iacc0);
+ DEF_PTREG(REG_TBR, tbr);
+ DEF_PTREG(REG_GR0, tbr);
+ DEFINE(REG__END, sizeof(struct pt_regs));
+ BLANK();
+
+ DEF_0REG(REG_DCR, debug.dcr);
+ DEF_0REG(REG_IBAR0, debug.ibar[0]);
+ DEF_0REG(REG_DBAR0, debug.dbar[0]);
+ DEF_0REG(REG_DBDR00, debug.dbdr[0][0]);
+ DEF_0REG(REG_DBMR00, debug.dbmr[0][0]);
+ BLANK();
+
+ DEF_IREG(__INT_GR0, i.gr[0]);
+ DEF_FREG(__USER_FPMEDIA, f);
+ DEF_FREG(__FPMEDIA_FR0, f.fr[0]);
+ DEF_FREG(__FPMEDIA_FNER0, f.fner[0]);
+ DEF_FREG(__FPMEDIA_MSR0, f.msr[0]);
+ DEF_FREG(__FPMEDIA_ACC0, f.acc[0]);
+ DEF_FREG(__FPMEDIA_ACCG0, f.accg[0]);
+ DEF_FREG(__FPMEDIA_FSR0, f.fsr[0]);
+ BLANK();
+
+ DEFINE(NR_PT_REGS, sizeof(struct pt_regs) / 4);
+ DEFINE(NR_USER_INT_REGS, sizeof(struct user_int_regs) / 4);
+ DEFINE(NR_USER_FPMEDIA_REGS, sizeof(struct user_fpmedia_regs) / 4);
+ DEFINE(NR_USER_CONTEXT, sizeof(struct user_context) / 4);
+ DEFINE(FRV_FRAME0_SIZE, sizeof(struct frv_frame0));
+ BLANK();
+
+ /* offsets into thread_struct */
+ OFFSET(__THREAD_FRAME, thread_struct, frame);
+ OFFSET(__THREAD_CURR, thread_struct, curr);
+ OFFSET(__THREAD_SP, thread_struct, sp);
+ OFFSET(__THREAD_FP, thread_struct, fp);
+ OFFSET(__THREAD_LR, thread_struct, lr);
+ OFFSET(__THREAD_PC, thread_struct, pc);
+ OFFSET(__THREAD_GR16, thread_struct, gr[0]);
+ OFFSET(__THREAD_SCHED_LR, thread_struct, sched_lr);
+ OFFSET(__THREAD_FRAME0, thread_struct, frame0);
+ OFFSET(__THREAD_USER, thread_struct, user);
+ BLANK();
+
+ /* offsets into frv_debug_status */
+ OFFSET(DEBUG_BPSR, frv_debug_status, bpsr);
+ OFFSET(DEBUG_DCR, frv_debug_status, dcr);
+ OFFSET(DEBUG_BRR, frv_debug_status, brr);
+ OFFSET(DEBUG_NMAR, frv_debug_status, nmar);
+ BLANK();
+}
diff --git a/arch/frv/kernel/break.S b/arch/frv/kernel/break.S
index 33233dc23e2..cbb6958a314 100644
--- a/arch/frv/kernel/break.S
+++ b/arch/frv/kernel/break.S
@@ -9,12 +9,11 @@
* 2 of the License, or (at your option) any later version.
*/
-#include <linux/sys.h>
-#include <linux/config.h>
#include <linux/linkage.h>
#include <asm/setup.h>
#include <asm/segment.h>
#include <asm/ptrace.h>
+#include <asm/thread_info.h>
#include <asm/spr-regs.h>
#include <asm/errno.h>
@@ -22,15 +21,13 @@
#
# the break handler has its own stack
#
- .section .bss.stack
+ .section .bss..stack
.globl __break_user_context
- .balign 8192
+ .balign THREAD_SIZE
__break_stack:
- .space (8192 - (USER_CONTEXT_SIZE + REG__DEBUG_XTRA)) & ~7
-__break_stack_tos:
- .space REG__DEBUG_XTRA
-__break_user_context:
- .space USER_CONTEXT_SIZE
+ .space THREAD_SIZE - FRV_FRAME0_SIZE
+__break_frame_0:
+ .space FRV_FRAME0_SIZE
#
# miscellaneous variables
@@ -66,7 +63,7 @@ __break_trace_through_exceptions:
# entry point for Break Exceptions/Interrupts
#
###############################################################################
- .text
+ .section .text..break
.balign 4
.globl __entry_break
__entry_break:
@@ -75,8 +72,8 @@ __entry_break:
#endif
LEDS 0x1001,gr31
- sethi.p %hi(__break_user_context),gr31
- setlo %lo(__break_user_context),gr31
+ sethi.p %hi(__break_frame_0),gr31
+ setlo %lo(__break_frame_0),gr31
stdi gr2,@(gr31,#REG_GR(2))
movsg ccr,gr3
@@ -200,12 +197,20 @@ __break_step:
movsg bpcsr,gr2
sethi.p %hi(__entry_kernel_external_interrupt),gr3
setlo %lo(__entry_kernel_external_interrupt),gr3
- subcc gr2,gr3,gr0,icc0
+ subcc.p gr2,gr3,gr0,icc0
+ sethi %hi(__entry_uspace_external_interrupt),gr3
+ setlo.p %lo(__entry_uspace_external_interrupt),gr3
beq icc0,#2,__break_step_kernel_external_interrupt
- sethi.p %hi(__entry_uspace_external_interrupt),gr3
- setlo %lo(__entry_uspace_external_interrupt),gr3
- subcc gr2,gr3,gr0,icc0
+ subcc.p gr2,gr3,gr0,icc0
+ sethi %hi(__entry_kernel_external_interrupt_virtually_disabled),gr3
+ setlo.p %lo(__entry_kernel_external_interrupt_virtually_disabled),gr3
beq icc0,#2,__break_step_uspace_external_interrupt
+ subcc.p gr2,gr3,gr0,icc0
+ sethi %hi(__entry_kernel_external_interrupt_virtual_reenable),gr3
+ setlo.p %lo(__entry_kernel_external_interrupt_virtual_reenable),gr3
+ beq icc0,#2,__break_step_kernel_external_interrupt_virtually_disabled
+ subcc gr2,gr3,gr0,icc0
+ beq icc0,#2,__break_step_kernel_external_interrupt_virtual_reenable
LEDS 0x2007,gr2
@@ -254,6 +259,9 @@ __break_step_kernel_softprog_interrupt:
# step through an external interrupt from kernel mode
.globl __break_step_kernel_external_interrupt
__break_step_kernel_external_interrupt:
+ # deal with virtual interrupt disablement
+ beq icc2,#0,__break_step_kernel_external_interrupt_virtually_disabled
+
sethi.p %hi(__entry_kernel_external_interrupt_reentry),gr3
setlo %lo(__entry_kernel_external_interrupt_reentry),gr3
@@ -294,6 +302,64 @@ __break_return_as_kernel_prologue:
#endif
rett #1
+# we single-stepped into an interrupt handler whilst interrupts were merely virtually disabled
+# need to really disable interrupts, set flag, fix up and return
+__break_step_kernel_external_interrupt_virtually_disabled:
+ movsg psr,gr2
+ andi gr2,#~PSR_PIL,gr2
+ ori gr2,#PSR_PIL_14,gr2 /* debugging interrupts only */
+ movgs gr2,psr
+
+ ldi @(gr31,#REG_CCR),gr3
+ movgs gr3,ccr
+ subcc.p gr0,gr0,gr0,icc2 /* leave Z set, clear C */
+
+ # exceptions must've been enabled and we must've been in supervisor mode
+ setlos BPSR_BET|BPSR_BS,gr3
+ movgs gr3,bpsr
+
+ # return to where the interrupt happened
+ movsg pcsr,gr2
+ movgs gr2,bpcsr
+
+ lddi.p @(gr31,#REG_GR(2)),gr2
+
+ xor gr31,gr31,gr31
+ movgs gr0,brr
+#ifdef CONFIG_MMU
+ movsg scr3,gr31
+#endif
+ rett #1
+
+# we stepped through into the virtual interrupt reenablement trap
+#
+# we also want to single step anyway, but after fixing up so that we get an event on the
+# instruction after the broken-into exception returns
+ .globl __break_step_kernel_external_interrupt_virtual_reenable
+__break_step_kernel_external_interrupt_virtual_reenable:
+ movsg psr,gr2
+ andi gr2,#~PSR_PIL,gr2
+ movgs gr2,psr
+
+ ldi @(gr31,#REG_CCR),gr3
+ movgs gr3,ccr
+ subicc gr0,#1,gr0,icc2 /* clear Z, set C */
+
+ # save the adjusted ICC2
+ movsg ccr,gr3
+ sti gr3,@(gr31,#REG_CCR)
+
+ # exceptions must've been enabled and we must've been in supervisor mode
+ setlos BPSR_BET|BPSR_BS,gr3
+ movgs gr3,bpsr
+
+ # return to where the trap happened
+ movsg pcsr,gr2
+ movgs gr2,bpcsr
+
+ # and then process the single step
+ bra __break_continue
+
# step through an internal exception from uspace mode
.globl __break_step_uspace_softprog_interrupt
__break_step_uspace_softprog_interrupt:
@@ -517,8 +583,8 @@ __break_continue:
# set up the kernel stack pointer
sti sp,@(gr31,#REG_SP)
- sethi.p %hi(__break_stack_tos),sp
- setlo %lo(__break_stack_tos),sp
+ sethi.p %hi(__break_frame_0),sp
+ setlo %lo(__break_frame_0),sp
# finish building the exception frame
stdi gr4 ,@(gr31,#REG_GR(4))
@@ -583,9 +649,12 @@ __break_continue:
movsg nmar,gr5
movsg dcr,gr6
- stdi gr4 ,@(gr31,#REG_BRR)
- sti gr19,@(gr31,#REG_BPSR)
- sti.p gr6 ,@(gr31,#REG_DCR)
+ sethi.p %hi(__debug_status),gr7
+ setlo %lo(__debug_status),gr7
+
+ stdi gr4 ,@(gr7,#DEBUG_BRR)
+ sti gr19,@(gr7,#DEBUG_BPSR)
+ sti.p gr6 ,@(gr7,#DEBUG_DCR)
# trap exceptions during break handling and disable h/w breakpoints/watchpoints
sethi %hi(DCR_EBE),gr5
@@ -630,7 +699,10 @@ __break_continue:
lddi @(gr31,#REG_PSR) ,gr22
ldi @(gr31,#REG_PC) ,gr21
ldi @(gr31,#REG_TBR) ,gr20
- ldi.p @(gr31,#REG_DCR) ,gr6
+
+ sethi.p %hi(__debug_status),gr6
+ setlo %lo(__debug_status),gr6
+ ldi.p @(gr6,#DEBUG_DCR) ,gr6
andi gr22,#PSR_S,gr19 /* rebuild BPSR */
andi.p gr22,#PSR_ET,gr5
diff --git a/arch/frv/kernel/cmode.S b/arch/frv/kernel/cmode.S
index 6591e6a37ae..53deeb5d7e8 100644
--- a/arch/frv/kernel/cmode.S
+++ b/arch/frv/kernel/cmode.S
@@ -1,7 +1,7 @@
/* cmode.S: clock mode management
*
* Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
- * Written by David Woodhouse (dwmw2@redhat.com)
+ * Written by David Woodhouse (dwmw2@infradead.org)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -11,7 +11,6 @@
*/
#include <linux/sys.h>
-#include <linux/config.h>
#include <linux/linkage.h>
#include <asm/setup.h>
#include <asm/segment.h>
diff --git a/arch/frv/kernel/debug-stub.c b/arch/frv/kernel/debug-stub.c
index 4761cc4b4a9..a0228f717ef 100644
--- a/arch/frv/kernel/debug-stub.c
+++ b/arch/frv/kernel/debug-stub.c
@@ -15,8 +15,8 @@
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/serial_reg.h>
+#include <linux/start_kernel.h>
-#include <asm/system.h>
#include <asm/serial-regs.h>
#include <asm/timer-regs.h>
#include <asm/irc-regs.h>
@@ -39,10 +39,9 @@ do { \
gdbstub_do_rx(); \
} while(!FLOWCTL_QUERY(LINE))
-static void __init debug_stub_init(void);
+struct frv_debug_status __debug_status;
-extern asmlinkage void __break_hijack_kernel_event(void);
-extern asmlinkage void __break_hijack_kernel_event_breaks_here(void);
+static void __init debug_stub_init(void);
/*****************************************************************************/
/*
@@ -67,7 +66,7 @@ asmlinkage void debug_stub(void)
__set_HSR(0, hsr0 & ~HSR0_ETMD);
/* disable single stepping */
- __debug_regs->dcr &= ~DCR_SE;
+ __debug_status.dcr &= ~DCR_SE;
/* kernel mode can propose an exception be handled in debug mode by jumping to a special
* location */
@@ -76,8 +75,8 @@ asmlinkage void debug_stub(void)
* the top kernel context */
*__debug_frame = *__frame;
__frame = __debug_frame->next_frame;
- __debug_regs->brr = (__debug_frame->tbr & TBR_TT) << 12;
- __debug_regs->brr |= BRR_EB;
+ __debug_status.brr = (__debug_frame->tbr & TBR_TT) << 12;
+ __debug_status.brr |= BRR_EB;
}
if (__debug_frame->pc == (unsigned long) __debug_bug_trap + 4) {
@@ -124,7 +123,7 @@ static void __init debug_stub_init(void)
__debug_frame->pc = (unsigned long) start_kernel;
/* enable the debug events we want to trap */
- __debug_regs->dcr = DCR_EBE;
+ __debug_status.dcr = DCR_EBE;
#ifdef CONFIG_GDBSTUB
gdbstub_init();
diff --git a/arch/frv/kernel/dma.c b/arch/frv/kernel/dma.c
index f5de6cf7df4..156184e17e5 100644
--- a/arch/frv/kernel/dma.c
+++ b/arch/frv/kernel/dma.c
@@ -121,15 +121,14 @@ unsigned long frv_dma_inprogress;
/*
* DMA irq handler - determine channel involved, grab status and call real handler
*/
-static irqreturn_t dma_irq_handler(int irq, void *_channel, struct pt_regs *regs)
+static irqreturn_t dma_irq_handler(int irq, void *_channel)
{
struct frv_dma_channel *channel = _channel;
frv_clear_dma_inprogress(channel - frv_dma_channels);
return channel->handler(channel - frv_dma_channels,
__get_DMAC(channel->ioaddr, CSTR),
- channel->data,
- regs);
+ channel->data);
} /* end dma_irq_handler() */
diff --git a/arch/frv/kernel/entry-table.S b/arch/frv/kernel/entry-table.S
index 9b9243e2103..06c5ae191e5 100644
--- a/arch/frv/kernel/entry-table.S
+++ b/arch/frv/kernel/entry-table.S
@@ -11,7 +11,6 @@
*/
#include <linux/sys.h>
-#include <linux/config.h>
#include <linux/linkage.h>
#include <asm/spr-regs.h>
@@ -87,7 +86,7 @@ __break_usertrap_fixup_table:
.globl __break_kerneltrap_fixup_table
__break_kerneltrap_fixup_table:
- # handler declaration for a sofware or program interrupt
+ # handler declaration for a software or program interrupt
.macro VECTOR_SOFTPROG tbr_tt, vec
.section .trap.user
.org \tbr_tt
@@ -116,6 +115,8 @@ __break_kerneltrap_fixup_table:
.long __break_step_uspace_external_interrupt
.section .trap.kernel
.org \tbr_tt
+ # deal with virtual interrupt disablement
+ beq icc2,#0,__entry_kernel_external_interrupt_virtually_disabled
bra __entry_kernel_external_interrupt
.section .trap.fixup.kernel
.org \tbr_tt >> 2
@@ -144,7 +145,7 @@ __break_kerneltrap_fixup_table:
.long \vec
.endm
- # handler declaration for an MMU only sofware or program interrupt
+ # handler declaration for an MMU only software or program interrupt
.macro VECTOR_SP_MMU tbr_tt, vec
#ifdef CONFIG_MMU
VECTOR_SOFTPROG \tbr_tt, \vec
@@ -259,25 +260,52 @@ __trap_fixup_kernel_data_tlb_miss:
.org TBR_TT_TRAP0
.rept 127
bra __entry_uspace_softprog_interrupt
- bra __break_step_uspace_softprog_interrupt
- .long 0,0
+ .long 0,0,0
.endr
.org TBR_TT_BREAK
bra __entry_break
.long 0,0,0
+ .section .trap.fixup.user
+ .org TBR_TT_TRAP0 >> 2
+ .rept 127
+ .long __break_step_uspace_softprog_interrupt
+ .endr
+ .org TBR_TT_BREAK >> 2
+ .long 0
+
# miscellaneous kernel mode entry points
.section .trap.kernel
.org TBR_TT_TRAP0
- .rept 127
bra __entry_kernel_softprog_interrupt
- bra __break_step_kernel_softprog_interrupt
- .long 0,0
+ .org TBR_TT_TRAP1
+ bra __entry_kernel_softprog_interrupt
+
+ # trap #2 in kernel - reenable interrupts
+ .org TBR_TT_TRAP2
+ bra __entry_kernel_external_interrupt_virtual_reenable
+
+ # miscellaneous kernel traps
+ .org TBR_TT_TRAP3
+ .rept 124
+ bra __entry_kernel_softprog_interrupt
+ .long 0,0,0
.endr
.org TBR_TT_BREAK
bra __entry_break
.long 0,0,0
+ .section .trap.fixup.kernel
+ .org TBR_TT_TRAP0 >> 2
+ .long __break_step_kernel_softprog_interrupt
+ .long __break_step_kernel_softprog_interrupt
+ .long __break_step_kernel_external_interrupt_virtual_reenable
+ .rept 124
+ .long __break_step_kernel_softprog_interrupt
+ .endr
+ .org TBR_TT_BREAK >> 2
+ .long 0
+
# miscellaneous debug mode entry points
.section .trap.break
.org TBR_TT_BREAK
@@ -288,8 +316,14 @@ __trap_fixup_kernel_data_tlb_miss:
.section .trap.vector
.org TBR_TT_TRAP0 >> 2
.long system_call
- .rept 126
+ .rept 119
.long __entry_unsupported_trap
.endr
+
+ # userspace atomic op emulation, traps 120-126
+ .rept 7
+ .long __entry_atomic_op
+ .endr
+
.org TBR_TT_BREAK >> 2
.long __entry_debug_exception
diff --git a/arch/frv/kernel/entry.S b/arch/frv/kernel/entry.S
index 5f6548388b7..dfcd263c051 100644
--- a/arch/frv/kernel/entry.S
+++ b/arch/frv/kernel/entry.S
@@ -27,8 +27,6 @@
*
*/
-#include <linux/sys.h>
-#include <linux/config.h>
#include <linux/linkage.h>
#include <asm/thread_info.h>
#include <asm/setup.h>
@@ -40,7 +38,7 @@
#define nr_syscalls ((syscall_table_size)/4)
- .text
+ .section .text..entry
.balign 4
.macro LEDS val
@@ -141,7 +139,10 @@ __entry_uspace_external_interrupt_reentry:
movsg gner0,gr4
movsg gner1,gr5
- stdi gr4,@(gr28,#REG_GNER0)
+ stdi.p gr4,@(gr28,#REG_GNER0)
+
+ # interrupts start off fully disabled in the interrupt handler
+ subcc gr0,gr0,gr0,icc2 /* set Z and clear C */
# set up kernel global registers
sethi.p %hi(__kernel_current_task),gr5
@@ -193,9 +194,8 @@ __entry_uspace_external_interrupt_reentry:
.type __entry_kernel_external_interrupt,@function
__entry_kernel_external_interrupt:
LEDS 0x6210
-
- sub sp,gr15,gr31
- LEDS32
+// sub sp,gr15,gr31
+// LEDS32
# set up the stack pointer
or.p sp,gr0,gr30
@@ -231,7 +231,10 @@ __entry_kernel_external_interrupt_reentry:
stdi gr24,@(gr28,#REG_GR(24))
stdi gr26,@(gr28,#REG_GR(26))
sti gr29,@(gr28,#REG_GR(29))
- stdi gr30,@(gr28,#REG_GR(30))
+ stdi.p gr30,@(gr28,#REG_GR(30))
+
+ # note virtual interrupts will be fully enabled upon return
+ subicc gr0,#1,gr0,icc2 /* clear Z, set C */
movsg tbr ,gr20
movsg psr ,gr22
@@ -250,7 +253,7 @@ __entry_kernel_external_interrupt_reentry:
andi.p gr5,#~PSR_ET,gr5
# set CCCR.CC3 to Undefined to abort atomic-modify completion inside the kernel
- # - for an explanation of how it works, see: Documentation/fujitsu/frv/atomic-ops.txt
+ # - for an explanation of how it works, see: Documentation/frv/atomic-ops.txt
andi gr25,#~0xc0,gr25
sti gr20,@(gr28,#REG_TBR)
@@ -267,7 +270,10 @@ __entry_kernel_external_interrupt_reentry:
movsg gner0,gr4
movsg gner1,gr5
- stdi gr4,@(gr28,#REG_GNER0)
+ stdi.p gr4,@(gr28,#REG_GNER0)
+
+ # interrupts start off fully disabled in the interrupt handler
+ subcc gr0,gr0,gr0,icc2 /* set Z and clear C */
# set the return address
sethi.p %hi(__entry_return_from_kernel_interrupt),gr4
@@ -291,6 +297,45 @@ __entry_kernel_external_interrupt_reentry:
.size __entry_kernel_external_interrupt,.-__entry_kernel_external_interrupt
+###############################################################################
+#
+# deal with interrupts that were actually virtually disabled
+# - we need to really disable them, flag the fact and return immediately
+# - if you change this, you must alter break.S also
+#
+###############################################################################
+ .balign L1_CACHE_BYTES
+ .globl __entry_kernel_external_interrupt_virtually_disabled
+ .type __entry_kernel_external_interrupt_virtually_disabled,@function
+__entry_kernel_external_interrupt_virtually_disabled:
+ movsg psr,gr30
+ andi gr30,#~PSR_PIL,gr30
+ ori gr30,#PSR_PIL_14,gr30 ; debugging interrupts only
+ movgs gr30,psr
+ subcc gr0,gr0,gr0,icc2 ; leave Z set, clear C
+ rett #0
+
+ .size __entry_kernel_external_interrupt_virtually_disabled,.-__entry_kernel_external_interrupt_virtually_disabled
+
+###############################################################################
+#
+# deal with re-enablement of interrupts that were pending when virtually re-enabled
+# - set ICC2.C, re-enable the real interrupts and return
+# - we can clear ICC2.Z because we shouldn't be here if it's not 0 [due to TIHI]
+# - if you change this, you must alter break.S also
+#
+###############################################################################
+ .balign L1_CACHE_BYTES
+ .globl __entry_kernel_external_interrupt_virtual_reenable
+ .type __entry_kernel_external_interrupt_virtual_reenable,@function
+__entry_kernel_external_interrupt_virtual_reenable:
+ movsg psr,gr30
+ andi gr30,#~PSR_PIL,gr30 ; re-enable interrupts
+ movgs gr30,psr
+ subicc gr0,#1,gr0,icc2 ; clear Z, set C
+ rett #0
+
+ .size __entry_kernel_external_interrupt_virtual_reenable,.-__entry_kernel_external_interrupt_virtual_reenable
###############################################################################
#
@@ -335,6 +380,7 @@ __entry_uspace_softprog_interrupt_reentry:
sethi.p %hi(__entry_return_from_user_exception),gr23
setlo %lo(__entry_return_from_user_exception),gr23
+
bra __entry_common
.size __entry_uspace_softprog_interrupt,.-__entry_uspace_softprog_interrupt
@@ -399,7 +445,7 @@ __entry_kernel_softprog_interrupt_reentry:
sti gr22,@(sp,#REG_SP)
# set CCCR.CC3 to Undefined to abort atomic-modify completion inside the kernel
- # - for an explanation of how it works, see: Documentation/fujitsu/frv/atomic-ops.txt
+ # - for an explanation of how it works, see: Documentation/frv/atomic-ops.txt
movsg cccr,gr20
andi gr20,#~0xc0,gr20
movgs gr20,cccr
@@ -495,7 +541,10 @@ __entry_common:
movsg gner0,gr4
movsg gner1,gr5
- stdi gr4,@(gr28,#REG_GNER0)
+ stdi.p gr4,@(gr28,#REG_GNER0)
+
+ # set up virtual interrupt disablement
+ subicc gr0,#1,gr0,icc2 /* clear Z flag, set C flag */
# set up kernel global registers
sethi.p %hi(__kernel_current_task),gr5
@@ -607,6 +656,26 @@ __entry_debug_exception:
###############################################################################
#
+# handle atomic operation emulation for userspace
+#
+###############################################################################
+ .globl __entry_atomic_op
+__entry_atomic_op:
+ LEDS 0x6012
+ sethi.p %hi(atomic_operation),gr5
+ setlo %lo(atomic_operation),gr5
+ movsg esfr1,gr8
+ movsg epcr0,gr9
+ movsg esr0,gr10
+
+ # now that we've accessed the exception regs, we can enable exceptions
+ movsg psr,gr4
+ ori gr4,#PSR_ET,gr4
+ movgs gr4,psr
+ jmpl @(gr5,gr0) ; call atomic_operation(esfr1,epcr0,esr0)
+
+###############################################################################
+#
# handle media exception
#
###############################################################################
@@ -794,6 +863,14 @@ ret_from_fork:
setlos.p #0,gr8
bra __syscall_exit
+ .globl ret_from_kernel_thread
+ret_from_kernel_thread:
+ lddi.p @(gr28,#REG_GR(8)),gr20
+ call schedule_tail
+ calll.p @(gr21,gr0)
+ or gr20,gr20,gr8
+ bra __syscall_exit
+
###################################################################################################
#
# Return to user mode is not as complex as all this looks,
@@ -817,7 +894,6 @@ system_call:
bnc icc0,#0,__syscall_badsys
ldi @(gr15,#TI_FLAGS),gr4
- ori gr4,#_TIF_SYSCALL_TRACE,gr4
andicc gr4,#_TIF_SYSCALL_TRACE,gr0,icc0
bne icc0,#0,__syscall_trace_entry
@@ -837,18 +913,19 @@ __syscall_call:
__syscall_exit:
LEDS 0x6300
- sti gr8,@(gr28,#REG_GR(8)) ; save return value
+ # keep current PSR in GR23
+ movsg psr,gr23
- # rebuild saved psr - execve will change it for init/main.c
ldi @(gr28,#REG_PSR),gr22
+
+ sti.p gr8,@(gr28,#REG_GR(8)) ; save return value
+
+ # rebuild saved psr - execve will change it for init/main.c
srli gr22,#1,gr5
andi.p gr22,#~PSR_PS,gr22
andi gr5,#PSR_PS,gr5
or gr5,gr22,gr22
- ori gr22,#PSR_S,gr22
-
- # keep current PSR in GR23
- movsg psr,gr23
+ ori.p gr22,#PSR_S,gr22
# make sure we don't miss an interrupt setting need_resched or sigpending between
# sampling and the RETT
@@ -856,9 +933,7 @@ __syscall_exit:
movgs gr23,psr
ldi @(gr15,#TI_FLAGS),gr4
- sethi.p %hi(_TIF_ALLWORK_MASK),gr5
- setlo %lo(_TIF_ALLWORK_MASK),gr5
- andcc gr4,gr5,gr0,icc0
+ andicc gr4,#_TIF_ALLWORK_MASK,gr0,icc0
bne icc0,#0,__syscall_exit_work
# restore all registers and return
@@ -1000,27 +1075,10 @@ __entry_return_from_kernel_interrupt:
subicc gr5,#0,gr0,icc0
beq icc0,#0,__entry_return_direct
-__entry_preempt_need_resched:
- ldi @(gr15,#TI_FLAGS),gr4
- andicc gr4,#_TIF_NEED_RESCHED,gr0,icc0
- beq icc0,#1,__entry_return_direct
-
- setlos #PREEMPT_ACTIVE,gr5
- sti gr5,@(gr15,#TI_FLAGS)
-
- andi gr23,#~PSR_PIL,gr23
- movgs gr23,psr
-
- call schedule
- sti gr0,@(gr15,#TI_PRE_COUNT)
-
- movsg psr,gr23
- ori gr23,#PSR_PIL_14,gr23
- movgs gr23,psr
- bra __entry_preempt_need_resched
-#else
- bra __entry_return_direct
+ subcc gr0,gr0,gr0,icc2 /* set Z and clear C */
+ call preempt_schedule_irq
#endif
+ bra __entry_return_direct
###############################################################################
@@ -1043,9 +1101,7 @@ __entry_resume_userspace:
__entry_return_from_user_interrupt:
LEDS 0x6402
ldi @(gr15,#TI_FLAGS),gr4
- sethi.p %hi(_TIF_WORK_MASK),gr5
- setlo %lo(_TIF_WORK_MASK),gr5
- andcc gr4,gr5,gr0,icc0
+ andicc gr4,#_TIF_WORK_MASK,gr0,icc0
beq icc0,#1,__entry_return_direct
__entry_work_pending:
@@ -1065,9 +1121,7 @@ __entry_work_resched:
LEDS 0x6401
ldi @(gr15,#TI_FLAGS),gr4
- sethi.p %hi(_TIF_WORK_MASK),gr5
- setlo %lo(_TIF_WORK_MASK),gr5
- andcc gr4,gr5,gr0,icc0
+ andicc gr4,#_TIF_WORK_MASK,gr0,icc0
beq icc0,#1,__entry_return_direct
andicc gr4,#_TIF_NEED_RESCHED,gr0,icc0
bne icc0,#1,__entry_work_resched
@@ -1081,11 +1135,10 @@ __entry_work_notifysig:
# perform syscall entry tracing
__syscall_trace_entry:
LEDS 0x6320
- setlos.p #0,gr8
- call do_syscall_trace
+ call syscall_trace_entry
- ldi @(gr28,#REG_SYSCALLNO),gr7
- lddi @(gr28,#REG_GR(8)) ,gr8
+ lddi.p @(gr28,#REG_GR(8)) ,gr8
+ ori gr8,#0,gr7 ; syscall_trace_entry() returned new syscallno
lddi @(gr28,#REG_GR(10)),gr10
lddi.p @(gr28,#REG_GR(12)),gr12
@@ -1096,15 +1149,16 @@ __syscall_trace_entry:
# perform syscall exit tracing
__syscall_exit_work:
LEDS 0x6340
- andicc gr4,#_TIF_SYSCALL_TRACE,gr0,icc0
+ andicc gr22,#PSR_PS,gr0,icc1 ; don't handle on return to kernel mode
+ andicc.p gr4,#_TIF_SYSCALL_TRACE,gr0,icc0
+ bne icc1,#0,__entry_return_direct
beq icc0,#1,__entry_work_pending
movsg psr,gr23
- andi gr23,#~PSR_PIL,gr23 ; could let do_syscall_trace() call schedule()
+ andi gr23,#~PSR_PIL,gr23 ; could let syscall_trace_exit() call schedule()
movgs gr23,psr
- setlos.p #1,gr8
- call do_syscall_trace
+ call syscall_trace_exit
bra __entry_resume_userspace
__syscall_badsys:
@@ -1119,12 +1173,6 @@ __syscall_badsys:
# syscall vector table
#
###############################################################################
-#ifdef CONFIG_MMU
-#define __MMU(X) X
-#else
-#define __MMU(X) sys_ni_syscall
-#endif
-
.section .rodata
ALIGN
.globl sys_call_table
@@ -1254,7 +1302,7 @@ sys_call_table:
.long sys_newuname
.long sys_ni_syscall /* old "cacheflush" */
.long sys_adjtimex
- .long __MMU(sys_mprotect) /* 125 */
+ .long sys_mprotect /* 125 */
.long sys_sigprocmask
.long sys_ni_syscall /* old "create_module" */
.long sys_init_module
@@ -1273,16 +1321,16 @@ sys_call_table:
.long sys_getdents
.long sys_select
.long sys_flock
- .long __MMU(sys_msync)
+ .long sys_msync
.long sys_readv /* 145 */
.long sys_writev
.long sys_getsid
.long sys_fdatasync
.long sys_sysctl
- .long __MMU(sys_mlock) /* 150 */
- .long __MMU(sys_munlock)
- .long __MMU(sys_mlockall)
- .long __MMU(sys_munlockall)
+ .long sys_mlock /* 150 */
+ .long sys_munlock
+ .long sys_mlockall
+ .long sys_munlockall
.long sys_sched_setparam
.long sys_sched_getparam /* 155 */
.long sys_sched_setscheduler
@@ -1292,13 +1340,13 @@ sys_call_table:
.long sys_sched_get_priority_min /* 160 */
.long sys_sched_rr_get_interval
.long sys_nanosleep
- .long __MMU(sys_mremap)
+ .long sys_mremap
.long sys_setresuid16
.long sys_getresuid16 /* 165 */
.long sys_ni_syscall /* for vm86 */
.long sys_ni_syscall /* Old sys_query_module */
.long sys_poll
- .long sys_nfsservctl
+ .long sys_ni_syscall /* Old nfsservctl */
.long sys_setresgid16 /* 170 */
.long sys_getresgid16
.long sys_prctl
@@ -1347,8 +1395,8 @@ sys_call_table:
.long sys_setfsuid /* 215 */
.long sys_setfsgid
.long sys_pivot_root
- .long __MMU(sys_mincore)
- .long __MMU(sys_madvise)
+ .long sys_mincore
+ .long sys_madvise
.long sys_getdents64 /* 220 */
.long sys_fcntl64
.long sys_ni_syscall /* reserved for TUX */
@@ -1386,7 +1434,7 @@ sys_call_table:
.long sys_epoll_create
.long sys_epoll_ctl /* 255 */
.long sys_epoll_wait
- .long __MMU(sys_remap_file_pages)
+ .long sys_remap_file_pages
.long sys_set_tid_address
.long sys_timer_create
.long sys_timer_settime /* 260 */
@@ -1418,11 +1466,54 @@ sys_call_table:
.long sys_add_key
.long sys_request_key
.long sys_keyctl
- .long sys_ni_syscall // sys_vperfctr_open
- .long sys_ni_syscall // sys_vperfctr_control /* 290 */
- .long sys_ni_syscall // sys_vperfctr_unlink
- .long sys_ni_syscall // sys_vperfctr_iresume
- .long sys_ni_syscall // sys_vperfctr_read
-
+ .long sys_ioprio_set
+ .long sys_ioprio_get /* 290 */
+ .long sys_inotify_init
+ .long sys_inotify_add_watch
+ .long sys_inotify_rm_watch
+ .long sys_migrate_pages
+ .long sys_openat /* 295 */
+ .long sys_mkdirat
+ .long sys_mknodat
+ .long sys_fchownat
+ .long sys_futimesat
+ .long sys_fstatat64 /* 300 */
+ .long sys_unlinkat
+ .long sys_renameat
+ .long sys_linkat
+ .long sys_symlinkat
+ .long sys_readlinkat /* 305 */
+ .long sys_fchmodat
+ .long sys_faccessat
+ .long sys_pselect6
+ .long sys_ppoll
+ .long sys_unshare /* 310 */
+ .long sys_set_robust_list
+ .long sys_get_robust_list
+ .long sys_splice
+ .long sys_sync_file_range
+ .long sys_tee /* 315 */
+ .long sys_vmsplice
+ .long sys_move_pages
+ .long sys_getcpu
+ .long sys_epoll_pwait
+ .long sys_utimensat /* 320 */
+ .long sys_signalfd
+ .long sys_timerfd_create
+ .long sys_eventfd
+ .long sys_fallocate
+ .long sys_timerfd_settime /* 325 */
+ .long sys_timerfd_gettime
+ .long sys_signalfd4
+ .long sys_eventfd2
+ .long sys_epoll_create1
+ .long sys_dup3 /* 330 */
+ .long sys_pipe2
+ .long sys_inotify_init1
+ .long sys_preadv
+ .long sys_pwritev
+ .long sys_rt_tgsigqueueinfo /* 335 */
+ .long sys_perf_event_open
+ .long sys_setns
syscall_table_size = (. - sys_call_table)
diff --git a/arch/frv/kernel/frv_ksyms.c b/arch/frv/kernel/frv_ksyms.c
index 0f1c6cbc4f5..86c516d96dc 100644
--- a/arch/frv/kernel/frv_ksyms.c
+++ b/arch/frv/kernel/frv_ksyms.c
@@ -7,13 +7,11 @@
#include <linux/elfcore.h>
#include <linux/in6.h>
#include <linux/interrupt.h>
-#include <linux/config.h>
#include <asm/setup.h>
#include <asm/pgalloc.h>
#include <asm/irq.h>
#include <asm/io.h>
-#include <asm/semaphore.h>
#include <asm/checksum.h>
#include <asm/hardirq.h>
#include <asm/cacheflush.h>
@@ -26,26 +24,13 @@ extern long __memset_user(void *dst, const void *src, size_t count);
EXPORT_SYMBOL(__ioremap);
EXPORT_SYMBOL(iounmap);
-EXPORT_SYMBOL(strnlen);
-EXPORT_SYMBOL(strrchr);
-EXPORT_SYMBOL(strstr);
-EXPORT_SYMBOL(strchr);
-EXPORT_SYMBOL(strcat);
-EXPORT_SYMBOL(strlen);
-EXPORT_SYMBOL(strcmp);
-EXPORT_SYMBOL(strncmp);
-EXPORT_SYMBOL(strncpy);
-
EXPORT_SYMBOL(ip_fast_csum);
#if 0
EXPORT_SYMBOL(local_irq_count);
EXPORT_SYMBOL(local_bh_count);
#endif
-EXPORT_SYMBOL(kernel_thread);
-EXPORT_SYMBOL(enable_irq);
-EXPORT_SYMBOL(disable_irq);
EXPORT_SYMBOL(__res_bus_clock_speed_HZ);
EXPORT_SYMBOL(__page_offset);
EXPORT_SYMBOL(__memcpy_user);
@@ -62,24 +47,16 @@ EXPORT_SYMBOL(memory_end);
EXPORT_SYMBOL(__debug_bug_trap);
-/* Networking helper routines. */
-EXPORT_SYMBOL(csum_partial_copy);
-
/* The following are special because they're not called
explicitly (the C compiler generates them). Fortunately,
their interface isn't gonna change any time soon now, so
it's OK to leave it out of version control. */
EXPORT_SYMBOL(memcpy);
EXPORT_SYMBOL(memset);
-EXPORT_SYMBOL(memcmp);
-EXPORT_SYMBOL(memscan);
-EXPORT_SYMBOL(memmove);
EXPORT_SYMBOL(__outsl_ns);
EXPORT_SYMBOL(__insl_ns);
-EXPORT_SYMBOL(get_wchan);
-
#ifdef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS
EXPORT_SYMBOL(atomic_test_and_ANDNOT_mask);
EXPORT_SYMBOL(atomic_test_and_OR_mask);
@@ -89,6 +66,10 @@ EXPORT_SYMBOL(atomic_sub_return);
EXPORT_SYMBOL(__xchg_32);
EXPORT_SYMBOL(__cmpxchg_32);
#endif
+EXPORT_SYMBOL(atomic64_add_return);
+EXPORT_SYMBOL(atomic64_sub_return);
+EXPORT_SYMBOL(__xchg_64);
+EXPORT_SYMBOL(__cmpxchg_64);
EXPORT_SYMBOL(__debug_bug_printk);
EXPORT_SYMBOL(__delay_loops_MHz);
diff --git a/arch/frv/kernel/futex.c b/arch/frv/kernel/futex.c
index eae874a970c..d155ca9e509 100644
--- a/arch/frv/kernel/futex.c
+++ b/arch/frv/kernel/futex.c
@@ -10,15 +10,15 @@
*/
#include <linux/futex.h>
+#include <linux/uaccess.h>
#include <asm/futex.h>
#include <asm/errno.h>
-#include <asm/uaccess.h>
/*
* the various futex operations; MMU fault checking is ignored under no-MMU
* conditions
*/
-static inline int atomic_futex_op_xchg_set(int oparg, int __user *uaddr, int *_oldval)
+static inline int atomic_futex_op_xchg_set(int oparg, u32 __user *uaddr, int *_oldval)
{
int oldval, ret;
@@ -50,7 +50,7 @@ static inline int atomic_futex_op_xchg_set(int oparg, int __user *uaddr, int *_o
return ret;
}
-static inline int atomic_futex_op_xchg_add(int oparg, int __user *uaddr, int *_oldval)
+static inline int atomic_futex_op_xchg_add(int oparg, u32 __user *uaddr, int *_oldval)
{
int oldval, ret;
@@ -83,7 +83,7 @@ static inline int atomic_futex_op_xchg_add(int oparg, int __user *uaddr, int *_o
return ret;
}
-static inline int atomic_futex_op_xchg_or(int oparg, int __user *uaddr, int *_oldval)
+static inline int atomic_futex_op_xchg_or(int oparg, u32 __user *uaddr, int *_oldval)
{
int oldval, ret;
@@ -116,7 +116,7 @@ static inline int atomic_futex_op_xchg_or(int oparg, int __user *uaddr, int *_ol
return ret;
}
-static inline int atomic_futex_op_xchg_and(int oparg, int __user *uaddr, int *_oldval)
+static inline int atomic_futex_op_xchg_and(int oparg, u32 __user *uaddr, int *_oldval)
{
int oldval, ret;
@@ -149,7 +149,7 @@ static inline int atomic_futex_op_xchg_and(int oparg, int __user *uaddr, int *_o
return ret;
}
-static inline int atomic_futex_op_xchg_xor(int oparg, int __user *uaddr, int *_oldval)
+static inline int atomic_futex_op_xchg_xor(int oparg, u32 __user *uaddr, int *_oldval)
{
int oldval, ret;
@@ -186,7 +186,7 @@ static inline int atomic_futex_op_xchg_xor(int oparg, int __user *uaddr, int *_o
/*
* do the futex operations
*/
-int futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
+int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
{
int op = (encoded_op >> 28) & 7;
int cmp = (encoded_op >> 24) & 15;
@@ -197,10 +197,10 @@ int futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
oparg = 1 << oparg;
- if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
+ if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
return -EFAULT;
- inc_preempt_count();
+ pagefault_disable();
switch (op) {
case FUTEX_OP_SET:
@@ -223,7 +223,7 @@ int futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
break;
}
- dec_preempt_count();
+ pagefault_enable();
if (!ret) {
switch (cmp) {
diff --git a/arch/frv/kernel/gdb-io.c b/arch/frv/kernel/gdb-io.c
index c997bccb922..0707d35079b 100644
--- a/arch/frv/kernel/gdb-io.c
+++ b/arch/frv/kernel/gdb-io.c
@@ -19,7 +19,6 @@
#include <linux/serial_reg.h>
#include <asm/pgtable.h>
-#include <asm/system.h>
#include <asm/irc-regs.h>
#include <asm/timer-regs.h>
#include <asm/gdb-stub.h>
@@ -171,11 +170,11 @@ int gdbstub_rx_char(unsigned char *_ch, int nonblock)
return -EINTR;
}
else if (st & (UART_LSR_FE|UART_LSR_OE|UART_LSR_PE)) {
- gdbstub_proto("### GDB Rx Error (st=%02x) ###\n",st);
+ gdbstub_io("### GDB Rx Error (st=%02x) ###\n",st);
return -EIO;
}
else {
- gdbstub_proto("### GDB Rx %02x (st=%02x) ###\n",ch,st);
+ gdbstub_io("### GDB Rx %02x (st=%02x) ###\n",ch,st);
*_ch = ch & 0x7f;
return 0;
}
diff --git a/arch/frv/kernel/gdb-stub.c b/arch/frv/kernel/gdb-stub.c
index 8f860d9c494..bbe78b0bffe 100644
--- a/arch/frv/kernel/gdb-stub.c
+++ b/arch/frv/kernel/gdb-stub.c
@@ -87,7 +87,7 @@
* Example:
* $ cd ~/linux
* $ make menuconfig <go to "Kernel Hacking" and turn on remote debugging>
- * $ make dep; make vmlinux
+ * $ make vmlinux
*
* Step 3:
* Download the kernel to the remote target and start
@@ -124,8 +124,8 @@
#include <linux/slab.h>
#include <linux/nmi.h>
+#include <asm/asm-offsets.h>
#include <asm/pgtable.h>
-#include <asm/system.h>
#include <asm/gdb-stub.h>
#define LEDS(x) do { /* *(u32*)0xe1200004 = ~(x); mb(); */ } while(0)
@@ -136,7 +136,6 @@ extern void debug_to_serial(const char *p, int n);
extern void gdbstub_console_write(struct console *co, const char *p, unsigned n);
extern volatile uint32_t __break_error_detect[3]; /* ESFR1, ESR15, EAR15 */
-extern struct user_context __break_user_context;
struct __debug_amr {
unsigned long L, P;
@@ -182,8 +181,6 @@ extern volatile u32 __attribute__((section(".bss"))) gdbstub_trace_through_excep
static char input_buffer[BUFMAX];
static char output_buffer[BUFMAX];
-static const char hexchars[] = "0123456789abcdef";
-
static const char *regnames[] = {
"PSR ", "ISR ", "CCR ", "CCCR",
"LR ", "LCR ", "PC ", "_stt",
@@ -383,8 +380,8 @@ static int gdbstub_send_packet(char *buffer)
}
gdbstub_tx_char('#');
- gdbstub_tx_char(hexchars[checksum >> 4]);
- gdbstub_tx_char(hexchars[checksum & 0xf]);
+ gdbstub_tx_char(hex_asc_hi(checksum));
+ gdbstub_tx_char(hex_asc_lo(checksum));
} while (gdbstub_rx_char(&ch,0),
#ifdef GDBSTUB_DEBUG_PROTOCOL
@@ -647,17 +644,11 @@ void debug_to_serial(const char *p, int n)
}
#endif
-#ifdef CONFIG_GDBSTUB_CONSOLE
-
-static kdev_t gdbstub_console_dev(struct console *con)
-{
- return MKDEV(1,3); /* /dev/null */
-}
+#ifdef CONFIG_GDB_CONSOLE
static struct console gdbstub_console = {
.name = "gdb",
.write = gdbstub_console_write, /* in break.S */
- .device = gdbstub_console_dev,
.flags = CON_PRINTBUFFER,
.index = -1,
};
@@ -680,8 +671,7 @@ static unsigned char *mem2hex(const void *_mem, char *buf, int count, int may_fa
if ((uint32_t)mem&1 && count>=1) {
if (!gdbstub_read_byte(mem,ch))
return NULL;
- *buf++ = hexchars[ch[0] >> 4];
- *buf++ = hexchars[ch[0] & 0xf];
+ buf = hex_byte_pack(buf, ch[0]);
mem++;
count--;
}
@@ -689,10 +679,8 @@ static unsigned char *mem2hex(const void *_mem, char *buf, int count, int may_fa
if ((uint32_t)mem&3 && count>=2) {
if (!gdbstub_read_word(mem,(uint16_t *)ch))
return NULL;
- *buf++ = hexchars[ch[0] >> 4];
- *buf++ = hexchars[ch[0] & 0xf];
- *buf++ = hexchars[ch[1] >> 4];
- *buf++ = hexchars[ch[1] & 0xf];
+ buf = hex_byte_pack(buf, ch[0]);
+ buf = hex_byte_pack(buf, ch[1]);
mem += 2;
count -= 2;
}
@@ -700,14 +688,10 @@ static unsigned char *mem2hex(const void *_mem, char *buf, int count, int may_fa
while (count>=4) {
if (!gdbstub_read_dword(mem,(uint32_t *)ch))
return NULL;
- *buf++ = hexchars[ch[0] >> 4];
- *buf++ = hexchars[ch[0] & 0xf];
- *buf++ = hexchars[ch[1] >> 4];
- *buf++ = hexchars[ch[1] & 0xf];
- *buf++ = hexchars[ch[2] >> 4];
- *buf++ = hexchars[ch[2] & 0xf];
- *buf++ = hexchars[ch[3] >> 4];
- *buf++ = hexchars[ch[3] & 0xf];
+ buf = hex_byte_pack(buf, ch[0]);
+ buf = hex_byte_pack(buf, ch[1]);
+ buf = hex_byte_pack(buf, ch[2]);
+ buf = hex_byte_pack(buf, ch[3]);
mem += 4;
count -= 4;
}
@@ -715,10 +699,8 @@ static unsigned char *mem2hex(const void *_mem, char *buf, int count, int may_fa
if (count>=2) {
if (!gdbstub_read_word(mem,(uint16_t *)ch))
return NULL;
- *buf++ = hexchars[ch[0] >> 4];
- *buf++ = hexchars[ch[0] & 0xf];
- *buf++ = hexchars[ch[1] >> 4];
- *buf++ = hexchars[ch[1] & 0xf];
+ buf = hex_byte_pack(buf, ch[0]);
+ buf = hex_byte_pack(buf, ch[1]);
mem += 2;
count -= 2;
}
@@ -726,8 +708,7 @@ static unsigned char *mem2hex(const void *_mem, char *buf, int count, int may_fa
if (count>=1) {
if (!gdbstub_read_byte(mem,ch))
return NULL;
- *buf++ = hexchars[ch[0] >> 4];
- *buf++ = hexchars[ch[0] & 0xf];
+ buf = hex_byte_pack(buf, ch[0]);
}
*buf = 0;
@@ -926,6 +907,7 @@ static int gdbstub_set_breakpoint(unsigned long type, unsigned long addr, unsign
if (!(__debug_regs->dcr & DCR_IBE0)) {
//gdbstub_printk("set h/w break 0: %08lx\n", addr);
__debug_regs->dcr |= DCR_IBE0;
+ __debug_regs->ibar[0] = addr;
asm volatile("movgs %0,ibar0" : : "r"(addr));
return 0;
}
@@ -933,6 +915,7 @@ static int gdbstub_set_breakpoint(unsigned long type, unsigned long addr, unsign
if (!(__debug_regs->dcr & DCR_IBE1)) {
//gdbstub_printk("set h/w break 1: %08lx\n", addr);
__debug_regs->dcr |= DCR_IBE1;
+ __debug_regs->ibar[1] = addr;
asm volatile("movgs %0,ibar1" : : "r"(addr));
return 0;
}
@@ -940,6 +923,7 @@ static int gdbstub_set_breakpoint(unsigned long type, unsigned long addr, unsign
if (!(__debug_regs->dcr & DCR_IBE2)) {
//gdbstub_printk("set h/w break 2: %08lx\n", addr);
__debug_regs->dcr |= DCR_IBE2;
+ __debug_regs->ibar[2] = addr;
asm volatile("movgs %0,ibar2" : : "r"(addr));
return 0;
}
@@ -947,6 +931,7 @@ static int gdbstub_set_breakpoint(unsigned long type, unsigned long addr, unsign
if (!(__debug_regs->dcr & DCR_IBE3)) {
//gdbstub_printk("set h/w break 3: %08lx\n", addr);
__debug_regs->dcr |= DCR_IBE3;
+ __debug_regs->ibar[3] = addr;
asm volatile("movgs %0,ibar3" : : "r"(addr));
return 0;
}
@@ -971,7 +956,14 @@ static int gdbstub_set_breakpoint(unsigned long type, unsigned long addr, unsign
if (!(__debug_regs->dcr & (DCR_DRBE0|DCR_DWBE0))) {
//gdbstub_printk("set h/w watchpoint 0 type %ld: %08lx\n", type, addr);
tmp = type==2 ? DCR_DWBE0 : type==3 ? DCR_DRBE0 : DCR_DRBE0|DCR_DWBE0;
+
__debug_regs->dcr |= tmp;
+ __debug_regs->dbar[0] = addr;
+ __debug_regs->dbmr[0][0] = dbmr.mask0;
+ __debug_regs->dbmr[0][1] = dbmr.mask1;
+ __debug_regs->dbdr[0][0] = 0;
+ __debug_regs->dbdr[0][1] = 0;
+
asm volatile(" movgs %0,dbar0 \n"
" movgs %1,dbmr00 \n"
" movgs %2,dbmr01 \n"
@@ -984,7 +976,14 @@ static int gdbstub_set_breakpoint(unsigned long type, unsigned long addr, unsign
if (!(__debug_regs->dcr & (DCR_DRBE1|DCR_DWBE1))) {
//gdbstub_printk("set h/w watchpoint 1 type %ld: %08lx\n", type, addr);
tmp = type==2 ? DCR_DWBE1 : type==3 ? DCR_DRBE1 : DCR_DRBE1|DCR_DWBE1;
+
__debug_regs->dcr |= tmp;
+ __debug_regs->dbar[1] = addr;
+ __debug_regs->dbmr[1][0] = dbmr.mask0;
+ __debug_regs->dbmr[1][1] = dbmr.mask1;
+ __debug_regs->dbdr[1][0] = 0;
+ __debug_regs->dbdr[1][1] = 0;
+
asm volatile(" movgs %0,dbar1 \n"
" movgs %1,dbmr10 \n"
" movgs %2,dbmr11 \n"
@@ -1047,6 +1046,7 @@ int gdbstub_clear_breakpoint(unsigned long type, unsigned long addr, unsigned lo
if (__debug_regs->dcr & DCR_IBE0 && __get_ibar(0) == addr) {
//gdbstub_printk("clear h/w break 0: %08lx\n", addr);
__debug_regs->dcr &= ~DCR_IBE0;
+ __debug_regs->ibar[0] = 0;
asm volatile("movgs gr0,ibar0");
return 0;
}
@@ -1054,6 +1054,7 @@ int gdbstub_clear_breakpoint(unsigned long type, unsigned long addr, unsigned lo
if (__debug_regs->dcr & DCR_IBE1 && __get_ibar(1) == addr) {
//gdbstub_printk("clear h/w break 1: %08lx\n", addr);
__debug_regs->dcr &= ~DCR_IBE1;
+ __debug_regs->ibar[1] = 0;
asm volatile("movgs gr0,ibar1");
return 0;
}
@@ -1061,6 +1062,7 @@ int gdbstub_clear_breakpoint(unsigned long type, unsigned long addr, unsigned lo
if (__debug_regs->dcr & DCR_IBE2 && __get_ibar(2) == addr) {
//gdbstub_printk("clear h/w break 2: %08lx\n", addr);
__debug_regs->dcr &= ~DCR_IBE2;
+ __debug_regs->ibar[2] = 0;
asm volatile("movgs gr0,ibar2");
return 0;
}
@@ -1068,6 +1070,7 @@ int gdbstub_clear_breakpoint(unsigned long type, unsigned long addr, unsigned lo
if (__debug_regs->dcr & DCR_IBE3 && __get_ibar(3) == addr) {
//gdbstub_printk("clear h/w break 3: %08lx\n", addr);
__debug_regs->dcr &= ~DCR_IBE3;
+ __debug_regs->ibar[3] = 0;
asm volatile("movgs gr0,ibar3");
return 0;
}
@@ -1104,6 +1107,12 @@ int gdbstub_clear_breakpoint(unsigned long type, unsigned long addr, unsigned lo
//gdbstub_printk("clear h/w watchpoint 0 type %ld: %08lx\n", type, addr);
__debug_regs->dcr &= ~(DCR_DRBE0|DCR_DWBE0);
+ __debug_regs->dbar[0] = 0;
+ __debug_regs->dbmr[0][0] = 0;
+ __debug_regs->dbmr[0][1] = 0;
+ __debug_regs->dbdr[0][0] = 0;
+ __debug_regs->dbdr[0][1] = 0;
+
asm volatile(" movgs gr0,dbar0 \n"
" movgs gr0,dbmr00 \n"
" movgs gr0,dbmr01 \n"
@@ -1123,6 +1132,12 @@ int gdbstub_clear_breakpoint(unsigned long type, unsigned long addr, unsigned lo
//gdbstub_printk("clear h/w watchpoint 1 type %ld: %08lx\n", type, addr);
__debug_regs->dcr &= ~(DCR_DRBE1|DCR_DWBE1);
+ __debug_regs->dbar[1] = 0;
+ __debug_regs->dbmr[1][0] = 0;
+ __debug_regs->dbmr[1][1] = 0;
+ __debug_regs->dbdr[1][0] = 0;
+ __debug_regs->dbdr[1][1] = 0;
+
asm volatile(" movgs gr0,dbar1 \n"
" movgs gr0,dbmr10 \n"
" movgs gr0,dbmr11 \n"
@@ -1161,9 +1176,9 @@ static void gdbstub_check_breakpoint(void)
/*
*
*/
-static void __attribute__((unused)) gdbstub_show_regs(void)
+static void __maybe_unused gdbstub_show_regs(void)
{
- uint32_t *reg;
+ unsigned long *reg;
int loop;
gdbstub_printk("\n");
@@ -1172,11 +1187,11 @@ static void __attribute__((unused)) gdbstub_show_regs(void)
__debug_frame,
__debug_frame->psr & PSR_S ? "kernel" : "user");
- reg = (uint32_t *) __debug_frame;
- for (loop = 0; loop < REG__END; loop++) {
- printk("%s %08x", regnames[loop + 0], reg[loop + 0]);
+ reg = (unsigned long *) __debug_frame;
+ for (loop = 0; loop < NR_PT_REGS; loop++) {
+ printk("%s %08lx", regnames[loop + 0], reg[loop + 0]);
- if (loop == REG__END - 1 || loop % 5 == 4)
+ if (loop == NR_PT_REGS - 1 || loop % 5 == 4)
printk("\n");
else
printk(" | ");
@@ -1189,15 +1204,10 @@ static void __attribute__((unused)) gdbstub_show_regs(void)
/*
* dump debugging regs
*/
-static void __attribute__((unused)) gdbstub_dump_debugregs(void)
+static void __maybe_unused gdbstub_dump_debugregs(void)
{
- unsigned long x;
-
- x = __debug_regs->dcr;
- gdbstub_printk("DCR %08lx ", x);
-
- x = __debug_regs->brr;
- gdbstub_printk("BRR %08lx\n", x);
+ gdbstub_printk("DCR %08lx ", __debug_status.dcr);
+ gdbstub_printk("BRR %08lx\n", __debug_status.brr);
gdbstub_printk("IBAR0 %08lx ", __get_ibar(0));
gdbstub_printk("IBAR1 %08lx ", __get_ibar(1));
@@ -1333,6 +1343,44 @@ void gdbstub_get_mmu_state(void)
} /* end gdbstub_get_mmu_state() */
+/*
+ * handle general query commands of the form 'qXXXXX'
+ */
+static void gdbstub_handle_query(void)
+{
+ if (strcmp(input_buffer, "qAttached") == 0) {
+ /* return current thread ID */
+ sprintf(output_buffer, "1");
+ return;
+ }
+
+ if (strcmp(input_buffer, "qC") == 0) {
+ /* return current thread ID */
+ sprintf(output_buffer, "QC 0");
+ return;
+ }
+
+ if (strcmp(input_buffer, "qOffsets") == 0) {
+ /* return relocation offset of text and data segments */
+ sprintf(output_buffer, "Text=0;Data=0;Bss=0");
+ return;
+ }
+
+ if (strcmp(input_buffer, "qSymbol::") == 0) {
+ sprintf(output_buffer, "OK");
+ return;
+ }
+
+ if (strcmp(input_buffer, "qSupported") == 0) {
+ /* query of supported features */
+ sprintf(output_buffer, "PacketSize=%u;ReverseContinue-;ReverseStep-",
+ sizeof(input_buffer));
+ return;
+ }
+
+ gdbstub_strcpy(output_buffer,"E01");
+}
+
/*****************************************************************************/
/*
* handle event interception and GDB remote protocol processing
@@ -1360,7 +1408,7 @@ void gdbstub(int sigval)
#endif
}
- save_user_regs(&__break_user_context);
+ save_user_regs(&__debug_frame0->uc);
#if 0
gdbstub_printk("--> gdbstub() %08x %p %08x %08x\n",
@@ -1389,8 +1437,8 @@ void gdbstub(int sigval)
__debug_frame->psr &= ~PSR_S;
if (__debug_frame->psr & PSR_PS)
__debug_frame->psr |= PSR_S;
- __debug_regs->brr = (__debug_frame->tbr & TBR_TT) << 12;
- __debug_regs->brr |= BRR_EB;
+ __debug_status.brr = (__debug_frame->tbr & TBR_TT) << 12;
+ __debug_status.brr |= BRR_EB;
sigval = SIGINT;
}
@@ -1404,15 +1452,15 @@ void gdbstub(int sigval)
__debug_frame->psr &= ~PSR_S;
if (__debug_frame->psr & PSR_PS)
__debug_frame->psr |= PSR_S;
- __debug_regs->brr = (__debug_frame->tbr & TBR_TT) << 12;
- __debug_regs->brr |= BRR_EB;
- sigval = SIGXCPU;;
+ __debug_status.brr = (__debug_frame->tbr & TBR_TT) << 12;
+ __debug_status.brr |= BRR_EB;
+ sigval = SIGXCPU;
}
LEDS(0x5002);
/* after a BREAK insn, the PC lands on the far side of it */
- if (__debug_regs->brr & BRR_SB)
+ if (__debug_status.brr & BRR_SB)
gdbstub_check_breakpoint();
LEDS(0x5003);
@@ -1431,7 +1479,7 @@ void gdbstub(int sigval)
}
if (!sigval)
- sigval = gdbstub_compute_signal(__debug_regs->brr);
+ sigval = gdbstub_compute_signal(__debug_status.brr);
LEDS(0x5004);
@@ -1441,29 +1489,29 @@ void gdbstub(int sigval)
if (sigval != SIGINT && sigval != SIGTRAP && sigval != SIGILL) {
static const char title[] = "Break ";
static const char crlf[] = "\r\n";
- unsigned long brr = __debug_regs->brr;
+ unsigned long brr = __debug_status.brr;
char hx;
ptr = output_buffer;
*ptr++ = 'O';
ptr = mem2hex(title, ptr, sizeof(title) - 1,0);
- hx = hexchars[(brr & 0xf0000000) >> 28];
- *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf];
- hx = hexchars[(brr & 0x0f000000) >> 24];
- *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf];
- hx = hexchars[(brr & 0x00f00000) >> 20];
- *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf];
- hx = hexchars[(brr & 0x000f0000) >> 16];
- *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf];
- hx = hexchars[(brr & 0x0000f000) >> 12];
- *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf];
- hx = hexchars[(brr & 0x00000f00) >> 8];
- *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf];
- hx = hexchars[(brr & 0x000000f0) >> 4];
- *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf];
- hx = hexchars[(brr & 0x0000000f)];
- *ptr++ = hexchars[hx >> 4]; *ptr++ = hexchars[hx & 0xf];
+ hx = hex_asc_hi(brr >> 24);
+ ptr = hex_byte_pack(ptr, hx);
+ hx = hex_asc_lo(brr >> 24);
+ ptr = hex_byte_pack(ptr, hx);
+ hx = hex_asc_hi(brr >> 16);
+ ptr = hex_byte_pack(ptr, hx);
+ hx = hex_asc_lo(brr >> 16);
+ ptr = hex_byte_pack(ptr, hx);
+ hx = hex_asc_hi(brr >> 8);
+ ptr = hex_byte_pack(ptr, hx);
+ hx = hex_asc_lo(brr >> 8);
+ ptr = hex_byte_pack(ptr, hx);
+ hx = hex_asc_hi(brr);
+ ptr = hex_byte_pack(ptr, hx);
+ hx = hex_asc_lo(brr);
+ ptr = hex_byte_pack(ptr, hx);
ptr = mem2hex(crlf, ptr, sizeof(crlf) - 1, 0);
*ptr = 0;
@@ -1477,12 +1525,10 @@ void gdbstub(int sigval)
/* Send trap type (converted to signal) */
*ptr++ = 'T';
- *ptr++ = hexchars[sigval >> 4];
- *ptr++ = hexchars[sigval & 0xf];
+ ptr = hex_byte_pack(ptr, sigval);
/* Send Error PC */
- *ptr++ = hexchars[GDB_REG_PC >> 4];
- *ptr++ = hexchars[GDB_REG_PC & 0xf];
+ ptr = hex_byte_pack(ptr, GDB_REG_PC);
*ptr++ = ':';
ptr = mem2hex(&__debug_frame->pc, ptr, 4, 0);
*ptr++ = ';';
@@ -1490,8 +1536,7 @@ void gdbstub(int sigval)
/*
* Send frame pointer
*/
- *ptr++ = hexchars[GDB_REG_FP >> 4];
- *ptr++ = hexchars[GDB_REG_FP & 0xf];
+ ptr = hex_byte_pack(ptr, GDB_REG_FP);
*ptr++ = ':';
ptr = mem2hex(&__debug_frame->fp, ptr, 4, 0);
*ptr++ = ';';
@@ -1499,8 +1544,7 @@ void gdbstub(int sigval)
/*
* Send stack pointer
*/
- *ptr++ = hexchars[GDB_REG_SP >> 4];
- *ptr++ = hexchars[GDB_REG_SP & 0xf];
+ ptr = hex_byte_pack(ptr, GDB_REG_SP);
*ptr++ = ':';
ptr = mem2hex(&__debug_frame->sp, ptr, 4, 0);
*ptr++ = ';';
@@ -1525,8 +1569,8 @@ void gdbstub(int sigval)
/* request repeat of last signal number */
case '?':
output_buffer[0] = 'S';
- output_buffer[1] = hexchars[sigval >> 4];
- output_buffer[2] = hexchars[sigval & 0xf];
+ output_buffer[1] = hex_asc_hi(sigval);
+ output_buffer[2] = hex_asc_lo(sigval);
output_buffer[3] = 0;
break;
@@ -1565,28 +1609,24 @@ void gdbstub(int sigval)
ptr = mem2hex(&zero, ptr, 4, 0);
for (loop = 1; loop <= 27; loop++)
- ptr = mem2hex((unsigned long *)__debug_frame + REG_GR(loop),
- ptr, 4, 0);
+ ptr = mem2hex(&__debug_user_context->i.gr[loop], ptr, 4, 0);
temp = (unsigned long) __frame;
ptr = mem2hex(&temp, ptr, 4, 0);
- ptr = mem2hex((unsigned long *)__debug_frame + REG_GR(29), ptr, 4, 0);
- ptr = mem2hex((unsigned long *)__debug_frame + REG_GR(30), ptr, 4, 0);
+ ptr = mem2hex(&__debug_user_context->i.gr[29], ptr, 4, 0);
+ ptr = mem2hex(&__debug_user_context->i.gr[30], ptr, 4, 0);
#ifdef CONFIG_MMU
- ptr = mem2hex((unsigned long *)__debug_frame + REG_GR(31), ptr, 4, 0);
+ ptr = mem2hex(&__debug_user_context->i.gr[31], ptr, 4, 0);
#else
temp = (unsigned long) __debug_frame;
ptr = mem2hex(&temp, ptr, 4, 0);
#endif
for (loop = 32; loop <= 63; loop++)
- ptr = mem2hex((unsigned long *)__debug_frame + REG_GR(loop),
- ptr, 4, 0);
+ ptr = mem2hex(&__debug_user_context->i.gr[loop], ptr, 4, 0);
/* deal with FR0-FR63 */
for (loop = 0; loop <= 63; loop++)
- ptr = mem2hex((unsigned long *)&__break_user_context +
- __FPMEDIA_FR(loop),
- ptr, 4, 0);
+ ptr = mem2hex(&__debug_user_context->f.fr[loop], ptr, 4, 0);
/* deal with special registers */
ptr = mem2hex(&__debug_frame->pc, ptr, 4, 0);
@@ -1597,7 +1637,7 @@ void gdbstub(int sigval)
ptr = mem2hex(&zero, ptr, 4, 0);
ptr = mem2hex(&zero, ptr, 4, 0);
ptr = mem2hex(&__debug_frame->tbr, ptr, 4, 0);
- ptr = mem2hex(&__debug_regs->brr , ptr, 4, 0);
+ ptr = mem2hex(&__debug_status.brr , ptr, 4, 0);
asm volatile("movsg dbar0,%0" : "=r"(dbar));
ptr = mem2hex(&dbar, ptr, 4, 0);
@@ -1622,21 +1662,21 @@ void gdbstub(int sigval)
ptr = mem2hex(&__debug_frame->iacc0, ptr, 8, 0);
- ptr = mem2hex(&__break_user_context.f.fsr[0], ptr, 4, 0);
+ ptr = mem2hex(&__debug_user_context->f.fsr[0], ptr, 4, 0);
for (loop = 0; loop <= 7; loop++)
- ptr = mem2hex(&__break_user_context.f.acc[loop], ptr, 4, 0);
+ ptr = mem2hex(&__debug_user_context->f.acc[loop], ptr, 4, 0);
- ptr = mem2hex(&__break_user_context.f.accg, ptr, 8, 0);
+ ptr = mem2hex(&__debug_user_context->f.accg, ptr, 8, 0);
for (loop = 0; loop <= 1; loop++)
- ptr = mem2hex(&__break_user_context.f.msr[loop], ptr, 4, 0);
+ ptr = mem2hex(&__debug_user_context->f.msr[loop], ptr, 4, 0);
ptr = mem2hex(&__debug_frame->gner0, ptr, 4, 0);
ptr = mem2hex(&__debug_frame->gner1, ptr, 4, 0);
- ptr = mem2hex(&__break_user_context.f.fner[0], ptr, 4, 0);
- ptr = mem2hex(&__break_user_context.f.fner[1], ptr, 4, 0);
+ ptr = mem2hex(&__debug_user_context->f.fner[0], ptr, 4, 0);
+ ptr = mem2hex(&__debug_user_context->f.fner[1], ptr, 4, 0);
break;
@@ -1648,8 +1688,7 @@ void gdbstub(int sigval)
ptr = hex2mem(ptr, &temp, 4);
for (loop = 1; loop <= 27; loop++)
- ptr = hex2mem(ptr, (unsigned long *)__debug_frame + REG_GR(loop),
- 4);
+ ptr = hex2mem(ptr, &__debug_user_context->i.gr[loop], 4);
ptr = hex2mem(ptr, &temp, 4);
__frame = (struct pt_regs *) temp;
@@ -1662,14 +1701,11 @@ void gdbstub(int sigval)
#endif
for (loop = 32; loop <= 63; loop++)
- ptr = hex2mem(ptr, (unsigned long *)__debug_frame + REG_GR(loop),
- 4);
+ ptr = hex2mem(ptr, &__debug_user_context->i.gr[loop], 4);
/* deal with FR0-FR63 */
for (loop = 0; loop <= 63; loop++)
- ptr = mem2hex((unsigned long *)&__break_user_context +
- __FPMEDIA_FR(loop),
- ptr, 4, 0);
+ ptr = mem2hex(&__debug_user_context->f.fr[loop], ptr, 4, 0);
/* deal with special registers */
ptr = hex2mem(ptr, &__debug_frame->pc, 4);
@@ -1694,21 +1730,21 @@ void gdbstub(int sigval)
ptr = hex2mem(ptr, &__debug_frame->iacc0, 8);
- ptr = hex2mem(ptr, &__break_user_context.f.fsr[0], 4);
+ ptr = hex2mem(ptr, &__debug_user_context->f.fsr[0], 4);
for (loop = 0; loop <= 7; loop++)
- ptr = hex2mem(ptr, &__break_user_context.f.acc[loop], 4);
+ ptr = hex2mem(ptr, &__debug_user_context->f.acc[loop], 4);
- ptr = hex2mem(ptr, &__break_user_context.f.accg, 8);
+ ptr = hex2mem(ptr, &__debug_user_context->f.accg, 8);
for (loop = 0; loop <= 1; loop++)
- ptr = hex2mem(ptr, &__break_user_context.f.msr[loop], 4);
+ ptr = hex2mem(ptr, &__debug_user_context->f.msr[loop], 4);
ptr = hex2mem(ptr, &__debug_frame->gner0, 4);
ptr = hex2mem(ptr, &__debug_frame->gner1, 4);
- ptr = hex2mem(ptr, &__break_user_context.f.fner[0], 4);
- ptr = hex2mem(ptr, &__break_user_context.f.fner[1], 4);
+ ptr = hex2mem(ptr, &__debug_user_context->f.fner[0], 4);
+ ptr = hex2mem(ptr, &__debug_user_context->f.fner[1], 4);
gdbstub_strcpy(output_buffer,"OK");
break;
@@ -1752,6 +1788,12 @@ void gdbstub(int sigval)
flush_cache = 1;
break;
+ /* pNN: Read value of reg N and return it */
+ case 'p':
+ /* return no value, indicating that we don't support
+ * this command and that gdb should use 'g' instead */
+ break;
+
/* PNN,=RRRRRRRR: Write value R to reg N return OK */
case 'P':
ptr = &input_buffer[1];
@@ -1769,52 +1811,52 @@ void gdbstub(int sigval)
case GDB_REG_GR(0):
break;
case GDB_REG_GR(1) ... GDB_REG_GR(63):
- __break_user_context.i.gr[addr - GDB_REG_GR(0)] = temp;
+ __debug_user_context->i.gr[addr - GDB_REG_GR(0)] = temp;
break;
case GDB_REG_FR(0) ... GDB_REG_FR(63):
- __break_user_context.f.fr[addr - GDB_REG_FR(0)] = temp;
+ __debug_user_context->f.fr[addr - GDB_REG_FR(0)] = temp;
break;
case GDB_REG_PC:
- __break_user_context.i.pc = temp;
+ __debug_user_context->i.pc = temp;
break;
case GDB_REG_PSR:
- __break_user_context.i.psr = temp;
+ __debug_user_context->i.psr = temp;
break;
case GDB_REG_CCR:
- __break_user_context.i.ccr = temp;
+ __debug_user_context->i.ccr = temp;
break;
case GDB_REG_CCCR:
- __break_user_context.i.cccr = temp;
+ __debug_user_context->i.cccr = temp;
break;
case GDB_REG_BRR:
- __debug_regs->brr = temp;
+ __debug_status.brr = temp;
break;
case GDB_REG_LR:
- __break_user_context.i.lr = temp;
+ __debug_user_context->i.lr = temp;
break;
case GDB_REG_LCR:
- __break_user_context.i.lcr = temp;
+ __debug_user_context->i.lcr = temp;
break;
case GDB_REG_FSR0:
- __break_user_context.f.fsr[0] = temp;
+ __debug_user_context->f.fsr[0] = temp;
break;
case GDB_REG_ACC(0) ... GDB_REG_ACC(7):
- __break_user_context.f.acc[addr - GDB_REG_ACC(0)] = temp;
+ __debug_user_context->f.acc[addr - GDB_REG_ACC(0)] = temp;
break;
case GDB_REG_ACCG(0):
- *(uint32_t *) &__break_user_context.f.accg[0] = temp;
+ *(uint32_t *) &__debug_user_context->f.accg[0] = temp;
break;
case GDB_REG_ACCG(4):
- *(uint32_t *) &__break_user_context.f.accg[4] = temp;
+ *(uint32_t *) &__debug_user_context->f.accg[4] = temp;
break;
case GDB_REG_MSR(0) ... GDB_REG_MSR(1):
- __break_user_context.f.msr[addr - GDB_REG_MSR(0)] = temp;
+ __debug_user_context->f.msr[addr - GDB_REG_MSR(0)] = temp;
break;
case GDB_REG_GNER(0) ... GDB_REG_GNER(1):
- __break_user_context.i.gner[addr - GDB_REG_GNER(0)] = temp;
+ __debug_user_context->i.gner[addr - GDB_REG_GNER(0)] = temp;
break;
case GDB_REG_FNER(0) ... GDB_REG_FNER(1):
- __break_user_context.f.fner[addr - GDB_REG_FNER(0)] = temp;
+ __debug_user_context->f.fner[addr - GDB_REG_FNER(0)] = temp;
break;
default:
temp2 = 0;
@@ -1841,6 +1883,10 @@ void gdbstub(int sigval)
case 'k' :
goto done; /* just continue */
+ /* detach */
+ case 'D':
+ gdbstub_strcpy(output_buffer, "OK");
+ break;
/* reset the whole machine (FIXME: system dependent) */
case 'r':
@@ -1850,8 +1896,17 @@ void gdbstub(int sigval)
/* step to next instruction */
case 's':
__debug_regs->dcr |= DCR_SE;
+ __debug_status.dcr |= DCR_SE;
goto done;
+ /* extended command */
+ case 'v':
+ if (strcmp(input_buffer, "vCont?") == 0) {
+ output_buffer[0] = 0;
+ break;
+ }
+ goto unsupported_cmd;
+
/* set baud rate (bBB) */
case 'b':
ptr = &input_buffer[1];
@@ -1923,8 +1978,19 @@ void gdbstub(int sigval)
gdbstub_strcpy(output_buffer,"OK");
break;
+ /* Thread-setting packet */
+ case 'H':
+ gdbstub_strcpy(output_buffer, "OK");
+ break;
+
+ case 'q':
+ gdbstub_handle_query();
+ break;
+
default:
+ unsupported_cmd:
gdbstub_proto("### GDB Unsupported Cmd '%s'\n",input_buffer);
+ gdbstub_strcpy(output_buffer,"E01");
break;
}
@@ -1934,7 +2000,7 @@ void gdbstub(int sigval)
}
done:
- restore_user_regs(&__break_user_context);
+ restore_user_regs(&__debug_frame0->uc);
//gdbstub_dump_debugregs();
//gdbstub_printk("<-- gdbstub() %08x\n", __debug_frame->pc);
@@ -1966,7 +2032,6 @@ void __init gdbstub_init(void)
#endif
gdbstub_printk("%s", gdbstub_banner);
- gdbstub_printk("DCR: %x\n", __debug_regs->dcr);
gdbstub_io_init();
@@ -2000,7 +2065,7 @@ void __init gdbstub_init(void)
ptr = mem2hex(gdbstub_banner, ptr, sizeof(gdbstub_banner) - 1, 0);
gdbstub_send_packet(output_buffer);
#endif
-#if defined(CONFIG_GDBSTUB_CONSOLE) && defined(CONFIG_GDBSTUB_IMMEDIATE)
+#if defined(CONFIG_GDB_CONSOLE) && defined(CONFIG_GDBSTUB_IMMEDIATE)
register_console(&gdbstub_console);
#endif
@@ -2010,7 +2075,7 @@ void __init gdbstub_init(void)
/*
* register the console at a more appropriate time
*/
-#if defined (CONFIG_GDBSTUB_CONSOLE) && !defined(CONFIG_GDBSTUB_IMMEDIATE)
+#if defined (CONFIG_GDB_CONSOLE) && !defined(CONFIG_GDBSTUB_IMMEDIATE)
static int __init gdbstub_postinit(void)
{
printk("registering console\n");
@@ -2044,8 +2109,8 @@ void gdbstub_exit(int status)
}
gdbstub_tx_char('#');
- gdbstub_tx_char(hexchars[checksum >> 4]);
- gdbstub_tx_char(hexchars[checksum & 0xf]);
+ gdbstub_tx_char(hex_asc_hi(checksum));
+ gdbstub_tx_char(hex_asc_lo(checksum));
/* make sure the output is flushed, or else RedBoot might clobber it */
gdbstub_tx_char('-');
@@ -2058,25 +2123,25 @@ void gdbstub_exit(int status)
* GDB wants to call malloc() and free() to allocate memory for calling kernel
* functions directly from its command line
*/
-static void *malloc(size_t size) __attribute__((unused));
+static void *malloc(size_t size) __maybe_unused;
static void *malloc(size_t size)
{
return kmalloc(size, GFP_ATOMIC);
}
-static void free(void *p) __attribute__((unused));
+static void free(void *p) __maybe_unused;
static void free(void *p)
{
kfree(p);
}
-static uint32_t ___get_HSR0(void) __attribute__((unused));
+static uint32_t ___get_HSR0(void) __maybe_unused;
static uint32_t ___get_HSR0(void)
{
return __get_HSR(0);
}
-static uint32_t ___set_HSR0(uint32_t x) __attribute__((unused));
+static uint32_t ___set_HSR0(uint32_t x) __maybe_unused;
static uint32_t ___set_HSR0(uint32_t x)
{
__set_HSR(0, x);
diff --git a/arch/frv/kernel/head-mmu-fr451.S b/arch/frv/kernel/head-mmu-fr451.S
index a143c2f66ee..98f87d586e5 100644
--- a/arch/frv/kernel/head-mmu-fr451.S
+++ b/arch/frv/kernel/head-mmu-fr451.S
@@ -9,7 +9,7 @@
* 2 of the License, or (at your option) any later version.
*/
-#include <linux/config.h>
+#include <linux/init.h>
#include <linux/threads.h>
#include <linux/linkage.h>
#include <asm/ptrace.h>
@@ -32,7 +32,7 @@
#define __400_LCR 0xfe000100
#define __400_LSBR 0xfe000c00
- .section .text.init,"ax"
+ __INIT
.balign 4
###############################################################################
diff --git a/arch/frv/kernel/head-uc-fr401.S b/arch/frv/kernel/head-uc-fr401.S
index 4ccf8414ae4..438643cfa38 100644
--- a/arch/frv/kernel/head-uc-fr401.S
+++ b/arch/frv/kernel/head-uc-fr401.S
@@ -9,7 +9,7 @@
* 2 of the License, or (at your option) any later version.
*/
-#include <linux/config.h>
+#include <linux/init.h>
#include <linux/threads.h>
#include <linux/linkage.h>
#include <asm/ptrace.h>
@@ -31,7 +31,7 @@
#define __400_LCR 0xfe000100
#define __400_LSBR 0xfe000c00
- .section .text.init,"ax"
+ __INIT
.balign 4
###############################################################################
diff --git a/arch/frv/kernel/head-uc-fr451.S b/arch/frv/kernel/head-uc-fr451.S
index 31cb54a6f08..b2a76c4a178 100644
--- a/arch/frv/kernel/head-uc-fr451.S
+++ b/arch/frv/kernel/head-uc-fr451.S
@@ -9,7 +9,7 @@
* 2 of the License, or (at your option) any later version.
*/
-#include <linux/config.h>
+#include <linux/init.h>
#include <linux/threads.h>
#include <linux/linkage.h>
#include <asm/ptrace.h>
@@ -31,7 +31,7 @@
#define __400_LCR 0xfe000100
#define __400_LSBR 0xfe000c00
- .section .text.init,"ax"
+ __INIT
.balign 4
###############################################################################
diff --git a/arch/frv/kernel/head-uc-fr555.S b/arch/frv/kernel/head-uc-fr555.S
index d088db2699b..5497aaf34f7 100644
--- a/arch/frv/kernel/head-uc-fr555.S
+++ b/arch/frv/kernel/head-uc-fr555.S
@@ -9,7 +9,7 @@
* 2 of the License, or (at your option) any later version.
*/
-#include <linux/config.h>
+#include <linux/init.h>
#include <linux/threads.h>
#include <linux/linkage.h>
#include <asm/ptrace.h>
@@ -30,7 +30,7 @@
#define __551_LCR 0xfeff1100
#define __551_LSBR 0xfeff1c00
- .section .text.init,"ax"
+ __INIT
.balign 4
###############################################################################
diff --git a/arch/frv/kernel/head.S b/arch/frv/kernel/head.S
index c73b4fe9f6c..a7d0bea9c03 100644
--- a/arch/frv/kernel/head.S
+++ b/arch/frv/kernel/head.S
@@ -9,9 +9,10 @@
* 2 of the License, or (at your option) any later version.
*/
-#include <linux/config.h>
+#include <linux/init.h>
#include <linux/threads.h>
#include <linux/linkage.h>
+#include <asm/thread_info.h>
#include <asm/ptrace.h>
#include <asm/page.h>
#include <asm/spr-regs.h>
@@ -27,7 +28,7 @@
# command line string
#
###############################################################################
- .section .text.head,"ax"
+ __HEAD
.balign 4
.globl _boot, __head_reference
@@ -478,11 +479,6 @@ __head_mmu_enabled:
LEDS 0x000c
- # initialise the processor and the peripherals
- #call SYMBOL_NAME(processor_init)
- #call SYMBOL_NAME(unit_init)
- #LEDS 0x0aff
-
sethi.p #0xe5e5,gr3
setlo #0xe5e5,gr3
or.p gr3,gr0,gr4
@@ -513,6 +509,9 @@ __head_mmu_enabled:
movgs gr0,ccr
movgs gr0,cccr
+ # initialise the virtual interrupt handling
+ subcc gr0,gr0,gr0,icc2 /* set Z, clear C */
+
#ifdef CONFIG_MMU
movgs gr3,scr2
movgs gr3,scr3
@@ -538,7 +537,7 @@ __head_end:
.size _boot, .-_boot
# provide a point for GDB to place a break
- .section .text.start,"ax"
+ .section .text..start,"ax"
.globl _start
.balign 4
_start:
diff --git a/arch/frv/kernel/head.inc b/arch/frv/kernel/head.inc
index d424cd2eb21..bff66628b99 100644
--- a/arch/frv/kernel/head.inc
+++ b/arch/frv/kernel/head.inc
@@ -46,5 +46,5 @@
#ifdef CONFIG_MMU
__sdram_base = 0x00000000 /* base address to which SDRAM relocated */
#else
-__sdram_base = 0xc0000000 /* base address to which SDRAM relocated */
+__sdram_base = __page_offset /* base address to which SDRAM relocated */
#endif
diff --git a/arch/frv/kernel/init_task.c b/arch/frv/kernel/init_task.c
deleted file mode 100644
index 22993932b3f..00000000000
--- a/arch/frv/kernel/init_task.c
+++ /dev/null
@@ -1,39 +0,0 @@
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/init_task.h>
-#include <linux/fs.h>
-#include <linux/mqueue.h>
-
-#include <asm/uaccess.h>
-#include <asm/pgtable.h>
-
-
-static struct fs_struct init_fs = INIT_FS;
-static struct files_struct init_files = INIT_FILES;
-static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
-static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
-struct mm_struct init_mm = INIT_MM(init_mm);
-
-EXPORT_SYMBOL(init_mm);
-
-/*
- * Initial thread structure.
- *
- * We need to make sure that this is THREAD_SIZE aligned due to the
- * way process stacks are handled. This is done by having a special
- * "init_task" linker map entry..
- */
-union thread_union init_thread_union
- __attribute__((__section__(".data.init_task"))) =
- { INIT_THREAD_INFO(init_task) };
-
-/*
- * Initial task structure.
- *
- * All other task structs will be allocated on slabs in fork.c
- */
-struct task_struct init_task = INIT_TASK(init_task);
-
-EXPORT_SYMBOL(init_task);
diff --git a/arch/frv/kernel/irq-mb93091.c b/arch/frv/kernel/irq-mb93091.c
index 9778e0ff7c1..2cc327a1ca4 100644
--- a/arch/frv/kernel/irq-mb93091.c
+++ b/arch/frv/kernel/irq-mb93091.c
@@ -9,7 +9,6 @@
* 2 of the License, or (at your option) any later version.
*/
-#include <linux/config.h>
#include <linux/ptrace.h>
#include <linux/errno.h>
#include <linux/signal.h>
@@ -18,14 +17,12 @@
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/irq.h>
+#include <linux/bitops.h>
#include <asm/io.h>
-#include <asm/system.h>
-#include <asm/bitops.h>
#include <asm/delay.h>
#include <asm/irq.h>
#include <asm/irc-regs.h>
-#include <asm/irq-routing.h>
#define __reg16(ADDR) (*(volatile unsigned short *)(ADDR))
@@ -34,83 +31,127 @@
#define __get_IFR() ({ __reg16(0xffc0000c); })
#define __clr_IFR(M) do { __reg16(0xffc0000c) = ~(M); wmb(); } while(0)
-static void frv_fpga_doirq(struct irq_source *source);
-static void frv_fpga_control(struct irq_group *group, int irq, int on);
-/*****************************************************************************/
/*
- * FPGA IRQ multiplexor
+ * on-motherboard FPGA PIC operations
*/
-static struct irq_source frv_fpga[4] = {
-#define __FPGA(X, M) \
- [X] = { \
- .muxname = "fpga."#X, \
- .irqmask = M, \
- .doirq = frv_fpga_doirq, \
- }
+static void frv_fpga_mask(struct irq_data *d)
+{
+ uint16_t imr = __get_IMR();
- __FPGA(0, 0x0028),
- __FPGA(1, 0x0050),
- __FPGA(2, 0x1c00),
- __FPGA(3, 0x6386),
-};
+ imr |= 1 << (d->irq - IRQ_BASE_FPGA);
-static struct irq_group frv_fpga_irqs = {
- .first_irq = IRQ_BASE_FPGA,
- .control = frv_fpga_control,
- .sources = {
- [ 1] = &frv_fpga[3],
- [ 2] = &frv_fpga[3],
- [ 3] = &frv_fpga[0],
- [ 4] = &frv_fpga[1],
- [ 5] = &frv_fpga[0],
- [ 6] = &frv_fpga[1],
- [ 7] = &frv_fpga[3],
- [ 8] = &frv_fpga[3],
- [ 9] = &frv_fpga[3],
- [10] = &frv_fpga[2],
- [11] = &frv_fpga[2],
- [12] = &frv_fpga[2],
- [13] = &frv_fpga[3],
- [14] = &frv_fpga[3],
- },
-};
+ __set_IMR(imr);
+}
+static void frv_fpga_ack(struct irq_data *d)
+{
+ __clr_IFR(1 << (d->irq - IRQ_BASE_FPGA));
+}
-static void frv_fpga_control(struct irq_group *group, int index, int on)
+static void frv_fpga_mask_ack(struct irq_data *d)
{
uint16_t imr = __get_IMR();
- if (on)
- imr &= ~(1 << index);
- else
- imr |= 1 << index;
+ imr |= 1 << (d->irq - IRQ_BASE_FPGA);
+ __set_IMR(imr);
+
+ __clr_IFR(1 << (d->irq - IRQ_BASE_FPGA));
+}
+
+static void frv_fpga_unmask(struct irq_data *d)
+{
+ uint16_t imr = __get_IMR();
+
+ imr &= ~(1 << (d->irq - IRQ_BASE_FPGA));
__set_IMR(imr);
}
-static void frv_fpga_doirq(struct irq_source *source)
+static struct irq_chip frv_fpga_pic = {
+ .name = "mb93091",
+ .irq_ack = frv_fpga_ack,
+ .irq_mask = frv_fpga_mask,
+ .irq_mask_ack = frv_fpga_mask_ack,
+ .irq_unmask = frv_fpga_unmask,
+};
+
+/*
+ * FPGA PIC interrupt handler
+ */
+static irqreturn_t fpga_interrupt(int irq, void *_mask)
{
- uint16_t mask, imr;
+ uint16_t imr, mask = (unsigned long) _mask;
imr = __get_IMR();
- mask = source->irqmask & ~imr & __get_IFR();
- if (mask) {
- __set_IMR(imr | mask);
- __clr_IFR(mask);
- distribute_irqs(&frv_fpga_irqs, mask);
- __set_IMR(imr);
+ mask = mask & ~imr & __get_IFR();
+
+ /* poll all the triggered IRQs */
+ while (mask) {
+ int irq;
+
+ asm("scan %1,gr0,%0" : "=r"(irq) : "r"(mask));
+ irq = 31 - irq;
+ mask &= ~(1 << irq);
+
+ generic_handle_irq(IRQ_BASE_FPGA + irq);
}
+
+ return IRQ_HANDLED;
}
+/*
+ * define an interrupt action for each FPGA PIC output
+ * - use dev_id to indicate the FPGA PIC input to output mappings
+ */
+static struct irqaction fpga_irq[4] = {
+ [0] = {
+ .handler = fpga_interrupt,
+ .flags = IRQF_DISABLED | IRQF_SHARED,
+ .name = "fpga.0",
+ .dev_id = (void *) 0x0028UL,
+ },
+ [1] = {
+ .handler = fpga_interrupt,
+ .flags = IRQF_DISABLED | IRQF_SHARED,
+ .name = "fpga.1",
+ .dev_id = (void *) 0x0050UL,
+ },
+ [2] = {
+ .handler = fpga_interrupt,
+ .flags = IRQF_DISABLED | IRQF_SHARED,
+ .name = "fpga.2",
+ .dev_id = (void *) 0x1c00UL,
+ },
+ [3] = {
+ .handler = fpga_interrupt,
+ .flags = IRQF_DISABLED | IRQF_SHARED,
+ .name = "fpga.3",
+ .dev_id = (void *) 0x6386UL,
+ }
+};
+
+/*
+ * initialise the motherboard FPGA's PIC
+ */
void __init fpga_init(void)
{
+ int irq;
+
+ /* all PIC inputs are all set to be low-level driven, apart from the
+ * NMI button (15) which is fixed at falling-edge
+ */
__set_IMR(0x7ffe);
__clr_IFR(0x0000);
- frv_irq_route_external(&frv_fpga[0], IRQ_CPU_EXTERNAL0);
- frv_irq_route_external(&frv_fpga[1], IRQ_CPU_EXTERNAL1);
- frv_irq_route_external(&frv_fpga[2], IRQ_CPU_EXTERNAL2);
- frv_irq_route_external(&frv_fpga[3], IRQ_CPU_EXTERNAL3);
- frv_irq_set_group(&frv_fpga_irqs);
+ for (irq = IRQ_BASE_FPGA + 1; irq <= IRQ_BASE_FPGA + 14; irq++)
+ irq_set_chip_and_handler(irq, &frv_fpga_pic, handle_level_irq);
+
+ irq_set_chip_and_handler(IRQ_FPGA_NMI, &frv_fpga_pic, handle_edge_irq);
+
+ /* the FPGA drives the first four external IRQ inputs on the CPU PIC */
+ setup_irq(IRQ_CPU_EXTERNAL0, &fpga_irq[0]);
+ setup_irq(IRQ_CPU_EXTERNAL1, &fpga_irq[1]);
+ setup_irq(IRQ_CPU_EXTERNAL2, &fpga_irq[2]);
+ setup_irq(IRQ_CPU_EXTERNAL3, &fpga_irq[3]);
}
diff --git a/arch/frv/kernel/irq-mb93093.c b/arch/frv/kernel/irq-mb93093.c
index 21ca2b29824..95e4eb4f1f3 100644
--- a/arch/frv/kernel/irq-mb93093.c
+++ b/arch/frv/kernel/irq-mb93093.c
@@ -1,6 +1,6 @@
/* irq-mb93093.c: MB93093 FPGA interrupt handling
*
- * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
@@ -9,7 +9,6 @@
* 2 of the License, or (at your option) any later version.
*/
-#include <linux/config.h>
#include <linux/ptrace.h>
#include <linux/errno.h>
#include <linux/signal.h>
@@ -18,14 +17,12 @@
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/irq.h>
+#include <linux/bitops.h>
#include <asm/io.h>
-#include <asm/system.h>
-#include <asm/bitops.h>
#include <asm/delay.h>
#include <asm/irq.h>
#include <asm/irc-regs.h>
-#include <asm/irq-routing.h>
#define __reg16(ADDR) (*(volatile unsigned short *)(__region_CS2 + (ADDR)))
@@ -34,66 +31,100 @@
#define __get_IFR() ({ __reg16(0x02); })
#define __clr_IFR(M) do { __reg16(0x02) = ~(M); wmb(); } while(0)
-static void frv_fpga_doirq(struct irq_source *source);
-static void frv_fpga_control(struct irq_group *group, int irq, int on);
-
-/*****************************************************************************/
/*
- * FPGA IRQ multiplexor
+ * off-CPU FPGA PIC operations
*/
-static struct irq_source frv_fpga[4] = {
-#define __FPGA(X, M) \
- [X] = { \
- .muxname = "fpga."#X, \
- .irqmask = M, \
- .doirq = frv_fpga_doirq, \
- }
+static void frv_fpga_mask(struct irq_data *d)
+{
+ uint16_t imr = __get_IMR();
- __FPGA(0, 0x0700),
-};
+ imr |= 1 << (d->irq - IRQ_BASE_FPGA);
+ __set_IMR(imr);
+}
-static struct irq_group frv_fpga_irqs = {
- .first_irq = IRQ_BASE_FPGA,
- .control = frv_fpga_control,
- .sources = {
- [ 8] = &frv_fpga[0],
- [ 9] = &frv_fpga[0],
- [10] = &frv_fpga[0],
- },
-};
+static void frv_fpga_ack(struct irq_data *d)
+{
+ __clr_IFR(1 << (d->irq - IRQ_BASE_FPGA));
+}
+
+static void frv_fpga_mask_ack(struct irq_data *d)
+{
+ uint16_t imr = __get_IMR();
+ imr |= 1 << (d->irq - IRQ_BASE_FPGA);
+ __set_IMR(imr);
+
+ __clr_IFR(1 << (d->irq - IRQ_BASE_FPGA));
+}
-static void frv_fpga_control(struct irq_group *group, int index, int on)
+static void frv_fpga_unmask(struct irq_data *d)
{
uint16_t imr = __get_IMR();
- if (on)
- imr &= ~(1 << index);
- else
- imr |= 1 << index;
+ imr &= ~(1 << (d->irq - IRQ_BASE_FPGA));
__set_IMR(imr);
}
-static void frv_fpga_doirq(struct irq_source *source)
+static struct irq_chip frv_fpga_pic = {
+ .name = "mb93093",
+ .irq_ack = frv_fpga_ack,
+ .irq_mask = frv_fpga_mask,
+ .irq_mask_ack = frv_fpga_mask_ack,
+ .irq_unmask = frv_fpga_unmask,
+};
+
+/*
+ * FPGA PIC interrupt handler
+ */
+static irqreturn_t fpga_interrupt(int irq, void *_mask)
{
- uint16_t mask, imr;
+ uint16_t imr, mask = (unsigned long) _mask;
imr = __get_IMR();
- mask = source->irqmask & ~imr & __get_IFR();
- if (mask) {
- __set_IMR(imr | mask);
- __clr_IFR(mask);
- distribute_irqs(&frv_fpga_irqs, mask);
- __set_IMR(imr);
+ mask = mask & ~imr & __get_IFR();
+
+ /* poll all the triggered IRQs */
+ while (mask) {
+ int irq;
+
+ asm("scan %1,gr0,%0" : "=r"(irq) : "r"(mask));
+ irq = 31 - irq;
+ mask &= ~(1 << irq);
+
+ generic_handle_irq(IRQ_BASE_FPGA + irq);
}
+
+ return IRQ_HANDLED;
}
+/*
+ * define an interrupt action for each FPGA PIC output
+ * - use dev_id to indicate the FPGA PIC input to output mappings
+ */
+static struct irqaction fpga_irq[1] = {
+ [0] = {
+ .handler = fpga_interrupt,
+ .flags = IRQF_DISABLED,
+ .name = "fpga.0",
+ .dev_id = (void *) 0x0700UL,
+ }
+};
+
+/*
+ * initialise the motherboard FPGA's PIC
+ */
void __init fpga_init(void)
{
+ int irq;
+
+ /* all PIC inputs are all set to be edge triggered */
__set_IMR(0x0700);
__clr_IFR(0x0000);
- frv_irq_route_external(&frv_fpga[0], IRQ_CPU_EXTERNAL2);
- frv_irq_set_group(&frv_fpga_irqs);
+ for (irq = IRQ_BASE_FPGA + 8; irq <= IRQ_BASE_FPGA + 10; irq++)
+ irq_set_chip_and_handler(irq, &frv_fpga_pic, handle_edge_irq);
+
+ /* the FPGA drives external IRQ input #2 on the CPU PIC */
+ setup_irq(IRQ_CPU_EXTERNAL2, &fpga_irq[0]);
}
diff --git a/arch/frv/kernel/irq-mb93493.c b/arch/frv/kernel/irq-mb93493.c
index c003ae5e2b3..ba648da0932 100644
--- a/arch/frv/kernel/irq-mb93493.c
+++ b/arch/frv/kernel/irq-mb93493.c
@@ -1,6 +1,6 @@
/* irq-mb93493.c: MB93493 companion chip interrupt handler
*
- * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
@@ -9,7 +9,6 @@
* 2 of the License, or (at your option) any later version.
*/
-#include <linux/config.h>
#include <linux/ptrace.h>
#include <linux/errno.h>
#include <linux/signal.h>
@@ -18,91 +17,131 @@
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/irq.h>
+#include <linux/bitops.h>
#include <asm/io.h>
-#include <asm/system.h>
-#include <asm/bitops.h>
#include <asm/delay.h>
#include <asm/irq.h>
#include <asm/irc-regs.h>
-#include <asm/irq-routing.h>
#include <asm/mb93493-irqs.h>
+#include <asm/mb93493-regs.h>
-static void frv_mb93493_doirq(struct irq_source *source);
+#define IRQ_ROUTE_ONE(X) (X##_ROUTE << (X - IRQ_BASE_MB93493))
+
+#define IRQ_ROUTING \
+ (IRQ_ROUTE_ONE(IRQ_MB93493_VDC) | \
+ IRQ_ROUTE_ONE(IRQ_MB93493_VCC) | \
+ IRQ_ROUTE_ONE(IRQ_MB93493_AUDIO_OUT) | \
+ IRQ_ROUTE_ONE(IRQ_MB93493_I2C_0) | \
+ IRQ_ROUTE_ONE(IRQ_MB93493_I2C_1) | \
+ IRQ_ROUTE_ONE(IRQ_MB93493_USB) | \
+ IRQ_ROUTE_ONE(IRQ_MB93493_LOCAL_BUS) | \
+ IRQ_ROUTE_ONE(IRQ_MB93493_PCMCIA) | \
+ IRQ_ROUTE_ONE(IRQ_MB93493_GPIO) | \
+ IRQ_ROUTE_ONE(IRQ_MB93493_AUDIO_IN))
-/*****************************************************************************/
/*
- * MB93493 companion chip IRQ multiplexor
+ * daughter board PIC operations
+ * - there is no way to ACK interrupts in the MB93493 chip
*/
-static struct irq_source frv_mb93493[2] = {
- [0] = {
- .muxname = "mb93493.0",
- .muxdata = __region_CS3 + 0x3d0,
- .doirq = frv_mb93493_doirq,
- .irqmask = 0x0000,
- },
- [1] = {
- .muxname = "mb93493.1",
- .muxdata = __region_CS3 + 0x3d4,
- .doirq = frv_mb93493_doirq,
- .irqmask = 0x0000,
- },
-};
-
-static void frv_mb93493_control(struct irq_group *group, int index, int on)
+static void frv_mb93493_mask(struct irq_data *d)
{
- struct irq_source *source;
uint32_t iqsr;
+ volatile void *piqsr;
- if ((frv_mb93493[0].irqmask & (1 << index)))
- source = &frv_mb93493[0];
+ if (IRQ_ROUTING & (1 << (d->irq - IRQ_BASE_MB93493)))
+ piqsr = __addr_MB93493_IQSR(1);
else
- source = &frv_mb93493[1];
+ piqsr = __addr_MB93493_IQSR(0);
+
+ iqsr = readl(piqsr);
+ iqsr &= ~(1 << (d->irq - IRQ_BASE_MB93493 + 16));
+ writel(iqsr, piqsr);
+}
- iqsr = readl(source->muxdata);
- if (on)
- iqsr |= 1 << (index + 16);
+static void frv_mb93493_ack(struct irq_data *d)
+{
+}
+
+static void frv_mb93493_unmask(struct irq_data *d)
+{
+ uint32_t iqsr;
+ volatile void *piqsr;
+
+ if (IRQ_ROUTING & (1 << (d->irq - IRQ_BASE_MB93493)))
+ piqsr = __addr_MB93493_IQSR(1);
else
- iqsr &= ~(1 << (index + 16));
+ piqsr = __addr_MB93493_IQSR(0);
- writel(iqsr, source->muxdata);
+ iqsr = readl(piqsr);
+ iqsr |= 1 << (d->irq - IRQ_BASE_MB93493 + 16);
+ writel(iqsr, piqsr);
}
-static struct irq_group frv_mb93493_irqs = {
- .first_irq = IRQ_BASE_MB93493,
- .control = frv_mb93493_control,
+static struct irq_chip frv_mb93493_pic = {
+ .name = "mb93093",
+ .irq_ack = frv_mb93493_ack,
+ .irq_mask = frv_mb93493_mask,
+ .irq_mask_ack = frv_mb93493_mask,
+ .irq_unmask = frv_mb93493_unmask,
};
-static void frv_mb93493_doirq(struct irq_source *source)
+/*
+ * MB93493 PIC interrupt handler
+ */
+static irqreturn_t mb93493_interrupt(int irq, void *_piqsr)
{
- uint32_t mask = readl(source->muxdata);
- mask = mask & (mask >> 16) & 0xffff;
+ volatile void *piqsr = _piqsr;
+ uint32_t iqsr;
- if (mask)
- distribute_irqs(&frv_mb93493_irqs, mask);
-}
+ iqsr = readl(piqsr);
+ iqsr = iqsr & (iqsr >> 16) & 0xffff;
-static void __init mb93493_irq_route(int irq, int source)
-{
- frv_mb93493[source].irqmask |= 1 << (irq - IRQ_BASE_MB93493);
- frv_mb93493_irqs.sources[irq - IRQ_BASE_MB93493] = &frv_mb93493[source];
+ /* poll all the triggered IRQs */
+ while (iqsr) {
+ int irq;
+
+ asm("scan %1,gr0,%0" : "=r"(irq) : "r"(iqsr));
+ irq = 31 - irq;
+ iqsr &= ~(1 << irq);
+
+ generic_handle_irq(IRQ_BASE_MB93493 + irq);
+ }
+
+ return IRQ_HANDLED;
}
-void __init route_mb93493_irqs(void)
+/*
+ * define an interrupt action for each MB93493 PIC output
+ * - use dev_id to indicate the MB93493 PIC input to output mappings
+ */
+static struct irqaction mb93493_irq[2] = {
+ [0] = {
+ .handler = mb93493_interrupt,
+ .flags = IRQF_DISABLED | IRQF_SHARED,
+ .name = "mb93493.0",
+ .dev_id = (void *) __addr_MB93493_IQSR(0),
+ },
+ [1] = {
+ .handler = mb93493_interrupt,
+ .flags = IRQF_DISABLED | IRQF_SHARED,
+ .name = "mb93493.1",
+ .dev_id = (void *) __addr_MB93493_IQSR(1),
+ }
+};
+
+/*
+ * initialise the motherboard MB93493's PIC
+ */
+void __init mb93493_init(void)
{
- frv_irq_route_external(&frv_mb93493[0], IRQ_CPU_MB93493_0);
- frv_irq_route_external(&frv_mb93493[1], IRQ_CPU_MB93493_1);
-
- frv_irq_set_group(&frv_mb93493_irqs);
-
- mb93493_irq_route(IRQ_MB93493_VDC, IRQ_MB93493_VDC_ROUTE);
- mb93493_irq_route(IRQ_MB93493_VCC, IRQ_MB93493_VCC_ROUTE);
- mb93493_irq_route(IRQ_MB93493_AUDIO_IN, IRQ_MB93493_AUDIO_IN_ROUTE);
- mb93493_irq_route(IRQ_MB93493_I2C_0, IRQ_MB93493_I2C_0_ROUTE);
- mb93493_irq_route(IRQ_MB93493_I2C_1, IRQ_MB93493_I2C_1_ROUTE);
- mb93493_irq_route(IRQ_MB93493_USB, IRQ_MB93493_USB_ROUTE);
- mb93493_irq_route(IRQ_MB93493_LOCAL_BUS, IRQ_MB93493_LOCAL_BUS_ROUTE);
- mb93493_irq_route(IRQ_MB93493_PCMCIA, IRQ_MB93493_PCMCIA_ROUTE);
- mb93493_irq_route(IRQ_MB93493_GPIO, IRQ_MB93493_GPIO_ROUTE);
- mb93493_irq_route(IRQ_MB93493_AUDIO_OUT, IRQ_MB93493_AUDIO_OUT_ROUTE);
+ int irq;
+
+ for (irq = IRQ_BASE_MB93493 + 0; irq <= IRQ_BASE_MB93493 + 10; irq++)
+ irq_set_chip_and_handler(irq, &frv_mb93493_pic,
+ handle_edge_irq);
+
+ /* the MB93493 drives external IRQ inputs on the CPU PIC */
+ setup_irq(IRQ_CPU_MB93493_0, &mb93493_irq[0]);
+ setup_irq(IRQ_CPU_MB93493_1, &mb93493_irq[1]);
}
diff --git a/arch/frv/kernel/irq-routing.c b/arch/frv/kernel/irq-routing.c
deleted file mode 100644
index d4776d1f4e8..00000000000
--- a/arch/frv/kernel/irq-routing.c
+++ /dev/null
@@ -1,291 +0,0 @@
-/* irq-routing.c: IRQ routing
- *
- * Copyright (C) 2004 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 License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include <linux/sched.h>
-#include <linux/random.h>
-#include <linux/init.h>
-#include <linux/serial_reg.h>
-#include <asm/io.h>
-#include <asm/irq-routing.h>
-#include <asm/irc-regs.h>
-#include <asm/serial-regs.h>
-#include <asm/dma.h>
-
-struct irq_level frv_irq_levels[16] = {
- [0 ... 15] = {
- .lock = SPIN_LOCK_UNLOCKED,
- }
-};
-
-struct irq_group *irq_groups[NR_IRQ_GROUPS];
-
-extern struct irq_group frv_cpu_irqs;
-
-void __init frv_irq_route(struct irq_source *source, int irqlevel)
-{
- source->level = &frv_irq_levels[irqlevel];
- source->next = frv_irq_levels[irqlevel].sources;
- frv_irq_levels[irqlevel].sources = source;
-}
-
-void __init frv_irq_route_external(struct irq_source *source, int irq)
-{
- int irqlevel = 0;
-
- switch (irq) {
- case IRQ_CPU_EXTERNAL0: irqlevel = IRQ_XIRQ0_LEVEL; break;
- case IRQ_CPU_EXTERNAL1: irqlevel = IRQ_XIRQ1_LEVEL; break;
- case IRQ_CPU_EXTERNAL2: irqlevel = IRQ_XIRQ2_LEVEL; break;
- case IRQ_CPU_EXTERNAL3: irqlevel = IRQ_XIRQ3_LEVEL; break;
- case IRQ_CPU_EXTERNAL4: irqlevel = IRQ_XIRQ4_LEVEL; break;
- case IRQ_CPU_EXTERNAL5: irqlevel = IRQ_XIRQ5_LEVEL; break;
- case IRQ_CPU_EXTERNAL6: irqlevel = IRQ_XIRQ6_LEVEL; break;
- case IRQ_CPU_EXTERNAL7: irqlevel = IRQ_XIRQ7_LEVEL; break;
- default: BUG();
- }
-
- source->level = &frv_irq_levels[irqlevel];
- source->next = frv_irq_levels[irqlevel].sources;
- frv_irq_levels[irqlevel].sources = source;
-}
-
-void __init frv_irq_set_group(struct irq_group *group)
-{
- irq_groups[group->first_irq >> NR_IRQ_LOG2_ACTIONS_PER_GROUP] = group;
-}
-
-void distribute_irqs(struct irq_group *group, unsigned long irqmask)
-{
- struct irqaction *action;
- int irq;
-
- while (irqmask) {
- asm("scan %1,gr0,%0" : "=r"(irq) : "r"(irqmask));
- if (irq < 0 || irq > 31)
- asm volatile("break");
- irq = 31 - irq;
-
- irqmask &= ~(1 << irq);
- action = group->actions[irq];
-
- irq += group->first_irq;
-
- if (action) {
- int status = 0;
-
-// if (!(action->flags & SA_INTERRUPT))
-// local_irq_enable();
-
- do {
- status |= action->flags;
- action->handler(irq, action->dev_id, __frame);
- action = action->next;
- } while (action);
-
- if (status & SA_SAMPLE_RANDOM)
- add_interrupt_randomness(irq);
- local_irq_disable();
- }
- }
-}
-
-/*****************************************************************************/
-/*
- * CPU UART interrupts
- */
-static void frv_cpuuart_doirq(struct irq_source *source)
-{
-// uint8_t iir = readb(source->muxdata + UART_IIR * 8);
-// if ((iir & 0x0f) != UART_IIR_NO_INT)
- distribute_irqs(&frv_cpu_irqs, source->irqmask);
-}
-
-struct irq_source frv_cpuuart[2] = {
-#define __CPUUART(X, A) \
- [X] = { \
- .muxname = "uart", \
- .muxdata = (volatile void __iomem *) A, \
- .irqmask = 1 << IRQ_CPU_UART##X, \
- .doirq = frv_cpuuart_doirq, \
- }
-
- __CPUUART(0, UART0_BASE),
- __CPUUART(1, UART1_BASE),
-};
-
-/*****************************************************************************/
-/*
- * CPU DMA interrupts
- */
-static void frv_cpudma_doirq(struct irq_source *source)
-{
- uint32_t cstr = readl(source->muxdata + DMAC_CSTRx);
- if (cstr & DMAC_CSTRx_INT)
- distribute_irqs(&frv_cpu_irqs, source->irqmask);
-}
-
-struct irq_source frv_cpudma[8] = {
-#define __CPUDMA(X, A) \
- [X] = { \
- .muxname = "dma", \
- .muxdata = (volatile void __iomem *) A, \
- .irqmask = 1 << IRQ_CPU_DMA##X, \
- .doirq = frv_cpudma_doirq, \
- }
-
- __CPUDMA(0, 0xfe000900),
- __CPUDMA(1, 0xfe000980),
- __CPUDMA(2, 0xfe000a00),
- __CPUDMA(3, 0xfe000a80),
- __CPUDMA(4, 0xfe001000),
- __CPUDMA(5, 0xfe001080),
- __CPUDMA(6, 0xfe001100),
- __CPUDMA(7, 0xfe001180),
-};
-
-/*****************************************************************************/
-/*
- * CPU timer interrupts - can't tell whether they've generated an interrupt or not
- */
-static void frv_cputimer_doirq(struct irq_source *source)
-{
- distribute_irqs(&frv_cpu_irqs, source->irqmask);
-}
-
-struct irq_source frv_cputimer[3] = {
-#define __CPUTIMER(X) \
- [X] = { \
- .muxname = "timer", \
- .muxdata = 0, \
- .irqmask = 1 << IRQ_CPU_TIMER##X, \
- .doirq = frv_cputimer_doirq, \
- }
-
- __CPUTIMER(0),
- __CPUTIMER(1),
- __CPUTIMER(2),
-};
-
-/*****************************************************************************/
-/*
- * external CPU interrupts - can't tell directly whether they've generated an interrupt or not
- */
-static void frv_cpuexternal_doirq(struct irq_source *source)
-{
- distribute_irqs(&frv_cpu_irqs, source->irqmask);
-}
-
-struct irq_source frv_cpuexternal[8] = {
-#define __CPUEXTERNAL(X) \
- [X] = { \
- .muxname = "ext", \
- .muxdata = 0, \
- .irqmask = 1 << IRQ_CPU_EXTERNAL##X, \
- .doirq = frv_cpuexternal_doirq, \
- }
-
- __CPUEXTERNAL(0),
- __CPUEXTERNAL(1),
- __CPUEXTERNAL(2),
- __CPUEXTERNAL(3),
- __CPUEXTERNAL(4),
- __CPUEXTERNAL(5),
- __CPUEXTERNAL(6),
- __CPUEXTERNAL(7),
-};
-
-#define set_IRR(N,A,B,C,D) __set_IRR(N, (A << 28) | (B << 24) | (C << 20) | (D << 16))
-
-struct irq_group frv_cpu_irqs = {
- .sources = {
- [IRQ_CPU_UART0] = &frv_cpuuart[0],
- [IRQ_CPU_UART1] = &frv_cpuuart[1],
- [IRQ_CPU_TIMER0] = &frv_cputimer[0],
- [IRQ_CPU_TIMER1] = &frv_cputimer[1],
- [IRQ_CPU_TIMER2] = &frv_cputimer[2],
- [IRQ_CPU_DMA0] = &frv_cpudma[0],
- [IRQ_CPU_DMA1] = &frv_cpudma[1],
- [IRQ_CPU_DMA2] = &frv_cpudma[2],
- [IRQ_CPU_DMA3] = &frv_cpudma[3],
- [IRQ_CPU_DMA4] = &frv_cpudma[4],
- [IRQ_CPU_DMA5] = &frv_cpudma[5],
- [IRQ_CPU_DMA6] = &frv_cpudma[6],
- [IRQ_CPU_DMA7] = &frv_cpudma[7],
- [IRQ_CPU_EXTERNAL0] = &frv_cpuexternal[0],
- [IRQ_CPU_EXTERNAL1] = &frv_cpuexternal[1],
- [IRQ_CPU_EXTERNAL2] = &frv_cpuexternal[2],
- [IRQ_CPU_EXTERNAL3] = &frv_cpuexternal[3],
- [IRQ_CPU_EXTERNAL4] = &frv_cpuexternal[4],
- [IRQ_CPU_EXTERNAL5] = &frv_cpuexternal[5],
- [IRQ_CPU_EXTERNAL6] = &frv_cpuexternal[6],
- [IRQ_CPU_EXTERNAL7] = &frv_cpuexternal[7],
- },
-};
-
-/*****************************************************************************/
-/*
- * route the CPU's interrupt sources
- */
-void __init route_cpu_irqs(void)
-{
- frv_irq_set_group(&frv_cpu_irqs);
-
- __set_IITMR(0, 0x003f0000); /* DMA0-3, TIMER0-2 IRQ detect levels */
- __set_IITMR(1, 0x20000000); /* ERR0-1, UART0-1, DMA4-7 IRQ detect levels */
-
- /* route UART and error interrupts */
- frv_irq_route(&frv_cpuuart[0], IRQ_UART0_LEVEL);
- frv_irq_route(&frv_cpuuart[1], IRQ_UART1_LEVEL);
-
- set_IRR(6, IRQ_GDBSTUB_LEVEL, IRQ_GDBSTUB_LEVEL, IRQ_UART1_LEVEL, IRQ_UART0_LEVEL);
-
- /* route DMA channel interrupts */
- frv_irq_route(&frv_cpudma[0], IRQ_DMA0_LEVEL);
- frv_irq_route(&frv_cpudma[1], IRQ_DMA1_LEVEL);
- frv_irq_route(&frv_cpudma[2], IRQ_DMA2_LEVEL);
- frv_irq_route(&frv_cpudma[3], IRQ_DMA3_LEVEL);
- frv_irq_route(&frv_cpudma[4], IRQ_DMA4_LEVEL);
- frv_irq_route(&frv_cpudma[5], IRQ_DMA5_LEVEL);
- frv_irq_route(&frv_cpudma[6], IRQ_DMA6_LEVEL);
- frv_irq_route(&frv_cpudma[7], IRQ_DMA7_LEVEL);
-
- set_IRR(4, IRQ_DMA3_LEVEL, IRQ_DMA2_LEVEL, IRQ_DMA1_LEVEL, IRQ_DMA0_LEVEL);
- set_IRR(7, IRQ_DMA7_LEVEL, IRQ_DMA6_LEVEL, IRQ_DMA5_LEVEL, IRQ_DMA4_LEVEL);
-
- /* route timer interrupts */
- frv_irq_route(&frv_cputimer[0], IRQ_TIMER0_LEVEL);
- frv_irq_route(&frv_cputimer[1], IRQ_TIMER1_LEVEL);
- frv_irq_route(&frv_cputimer[2], IRQ_TIMER2_LEVEL);
-
- set_IRR(5, 0, IRQ_TIMER2_LEVEL, IRQ_TIMER1_LEVEL, IRQ_TIMER0_LEVEL);
-
- /* route external interrupts */
- frv_irq_route(&frv_cpuexternal[0], IRQ_XIRQ0_LEVEL);
- frv_irq_route(&frv_cpuexternal[1], IRQ_XIRQ1_LEVEL);
- frv_irq_route(&frv_cpuexternal[2], IRQ_XIRQ2_LEVEL);
- frv_irq_route(&frv_cpuexternal[3], IRQ_XIRQ3_LEVEL);
- frv_irq_route(&frv_cpuexternal[4], IRQ_XIRQ4_LEVEL);
- frv_irq_route(&frv_cpuexternal[5], IRQ_XIRQ5_LEVEL);
- frv_irq_route(&frv_cpuexternal[6], IRQ_XIRQ6_LEVEL);
- frv_irq_route(&frv_cpuexternal[7], IRQ_XIRQ7_LEVEL);
-
- set_IRR(2, IRQ_XIRQ7_LEVEL, IRQ_XIRQ6_LEVEL, IRQ_XIRQ5_LEVEL, IRQ_XIRQ4_LEVEL);
- set_IRR(3, IRQ_XIRQ3_LEVEL, IRQ_XIRQ2_LEVEL, IRQ_XIRQ1_LEVEL, IRQ_XIRQ0_LEVEL);
-
-#if defined(CONFIG_MB93091_VDK)
- __set_TM1(0x55550000); /* XIRQ7-0 all active low */
-#elif defined(CONFIG_MB93093_PDK)
- __set_TM1(0x15550000); /* XIRQ7 active high, 6-0 all active low */
-#else
-#error dont know external IRQ trigger levels for this setup
-#endif
-
-} /* end route_cpu_irqs() */
diff --git a/arch/frv/kernel/irq.c b/arch/frv/kernel/irq.c
index 59580c59c62..2239346fa3d 100644
--- a/arch/frv/kernel/irq.c
+++ b/arch/frv/kernel/irq.c
@@ -1,6 +1,6 @@
/* irq.c: FRV IRQ handling
*
- * Copyright (C) 2003, 2004 Red Hat, Inc. All Rights Reserved.
+ * Copyright (C) 2003, 2004, 2006 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
@@ -9,14 +9,6 @@
* 2 of the License, or (at your option) any later version.
*/
-/*
- * (mostly architecture independent, will move to kernel/irq.c in 2.5.)
- *
- * IRQs are in fact implemented a bit like signal handlers for the kernel.
- * Naturally it's not a 1:1 relation, but there are similarities.
- */
-
-#include <linux/config.h>
#include <linux/ptrace.h>
#include <linux/errno.h>
#include <linux/signal.h>
@@ -24,758 +16,144 @@
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/timex.h>
-#include <linux/slab.h>
#include <linux/random.h>
-#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/kernel_stat.h>
#include <linux/irq.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/module.h>
+#include <linux/bitops.h>
-#include <asm/atomic.h>
+#include <linux/atomic.h>
#include <asm/io.h>
#include <asm/smp.h>
-#include <asm/system.h>
-#include <asm/bitops.h>
#include <asm/uaccess.h>
#include <asm/pgalloc.h>
#include <asm/delay.h>
#include <asm/irq.h>
#include <asm/irc-regs.h>
-#include <asm/irq-routing.h>
#include <asm/gdb-stub.h>
-extern void __init fpga_init(void);
-extern void __init route_mb93493_irqs(void);
-
-static void register_irq_proc (unsigned int irq);
+#define set_IRR(N,A,B,C,D) __set_IRR(N, (A << 28) | (B << 24) | (C << 20) | (D << 16))
-/*
- * Special irq handlers.
- */
+extern void __init fpga_init(void);
+#ifdef CONFIG_FUJITSU_MB93493
+extern void __init mb93493_init(void);
+#endif
-irqreturn_t no_action(int cpl, void *dev_id, struct pt_regs *regs) { return IRQ_HANDLED; }
+#define __reg16(ADDR) (*(volatile unsigned short *)(ADDR))
atomic_t irq_err_count;
-/*
- * Generic, controller-independent functions:
- */
-int show_interrupts(struct seq_file *p, void *v)
+int arch_show_interrupts(struct seq_file *p, int prec)
{
- struct irqaction *action;
- struct irq_group *group;
- unsigned long flags;
- int level, grp, ix, i, j;
-
- i = *(loff_t *) v;
-
- switch (i) {
- case 0:
- seq_printf(p, " ");
- for (j = 0; j < NR_CPUS; j++)
- if (cpu_online(j))
- seq_printf(p, "CPU%d ",j);
-
- seq_putc(p, '\n');
- break;
-
- case 1 ... NR_IRQ_GROUPS * NR_IRQ_ACTIONS_PER_GROUP:
- local_irq_save(flags);
-
- grp = (i - 1) / NR_IRQ_ACTIONS_PER_GROUP;
- group = irq_groups[grp];
- if (!group)
- goto skip;
-
- ix = (i - 1) % NR_IRQ_ACTIONS_PER_GROUP;
- action = group->actions[ix];
- if (!action)
- goto skip;
-
- seq_printf(p, "%3d: ", i - 1);
-
-#ifndef CONFIG_SMP
- seq_printf(p, "%10u ", kstat_irqs(i));
-#else
- for (j = 0; j < NR_CPUS; j++)
- if (cpu_online(j))
- seq_printf(p, "%10u ", kstat_cpu(j).irqs[i - 1]);
-#endif
-
- level = group->sources[ix]->level - frv_irq_levels;
-
- seq_printf(p, " %12s@%x", group->sources[ix]->muxname, level);
- seq_printf(p, " %s", action->name);
-
- for (action = action->next; action; action = action->next)
- seq_printf(p, ", %s", action->name);
-
- seq_putc(p, '\n');
-skip:
- local_irq_restore(flags);
- break;
-
- case NR_IRQ_GROUPS * NR_IRQ_ACTIONS_PER_GROUP + 1:
- seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
- break;
-
- default:
- break;
- }
-
+ seq_printf(p, "%*s: ", prec, "ERR");
+ seq_printf(p, "%10u\n", atomic_read(&irq_err_count));
return 0;
}
-
/*
- * Generic enable/disable code: this just calls
- * down into the PIC-specific version for the actual
- * hardware disable after having gotten the irq
- * controller lock.
- */
-
-/**
- * disable_irq_nosync - disable an irq without waiting
- * @irq: Interrupt to disable
- *
- * Disable the selected interrupt line. Disables and Enables are
- * nested.
- * Unlike disable_irq(), this function does not ensure existing
- * instances of the IRQ handler have completed before returning.
- *
- * This function may be called from IRQ context.
+ * on-CPU PIC operations
*/
-
-void disable_irq_nosync(unsigned int irq)
+static void frv_cpupic_ack(struct irq_data *d)
{
- struct irq_source *source;
- struct irq_group *group;
- struct irq_level *level;
- unsigned long flags;
- int idx = irq & (NR_IRQ_ACTIONS_PER_GROUP - 1);
-
- group = irq_groups[irq >> NR_IRQ_LOG2_ACTIONS_PER_GROUP];
- if (!group)
- BUG();
-
- source = group->sources[idx];
- if (!source)
- BUG();
-
- level = source->level;
-
- spin_lock_irqsave(&level->lock, flags);
-
- if (group->control) {
- if (!group->disable_cnt[idx]++)
- group->control(group, idx, 0);
- } else if (!level->disable_count++) {
- __set_MASK(level - frv_irq_levels);
- }
-
- spin_unlock_irqrestore(&level->lock, flags);
+ __clr_RC(d->irq);
+ __clr_IRL();
}
-EXPORT_SYMBOL(disable_irq_nosync);
-
-/**
- * disable_irq - disable an irq and wait for completion
- * @irq: Interrupt to disable
- *
- * Disable the selected interrupt line. Enables and Disables are
- * nested.
- * This function waits for any pending IRQ handlers for this interrupt
- * to complete before returning. If you use this function while
- * holding a resource the IRQ handler may need you will deadlock.
- *
- * This function may be called - with care - from IRQ context.
- */
-
-void disable_irq(unsigned int irq)
+static void frv_cpupic_mask(struct irq_data *d)
{
- disable_irq_nosync(irq);
-
-#ifdef CONFIG_SMP
- if (!local_irq_count(smp_processor_id())) {
- do {
- barrier();
- } while (irq_desc[irq].status & IRQ_INPROGRESS);
- }
-#endif
+ __set_MASK(d->irq);
}
-EXPORT_SYMBOL(disable_irq);
-
-/**
- * enable_irq - enable handling of an irq
- * @irq: Interrupt to enable
- *
- * Undoes the effect of one call to disable_irq(). If this
- * matches the last disable, processing of interrupts on this
- * IRQ line is re-enabled.
- *
- * This function may be called from IRQ context.
- */
-
-void enable_irq(unsigned int irq)
+static void frv_cpupic_mask_ack(struct irq_data *d)
{
- struct irq_source *source;
- struct irq_group *group;
- struct irq_level *level;
- unsigned long flags;
- int idx = irq & (NR_IRQ_ACTIONS_PER_GROUP - 1);
- int count;
-
- group = irq_groups[irq >> NR_IRQ_LOG2_ACTIONS_PER_GROUP];
- if (!group)
- BUG();
-
- source = group->sources[idx];
- if (!source)
- BUG();
-
- level = source->level;
-
- spin_lock_irqsave(&level->lock, flags);
-
- if (group->control)
- count = group->disable_cnt[idx];
- else
- count = level->disable_count;
-
- switch (count) {
- case 1:
- if (group->control) {
- if (group->actions[idx])
- group->control(group, idx, 1);
- } else {
- if (level->usage)
- __clr_MASK(level - frv_irq_levels);
- }
- /* fall-through */
-
- default:
- count--;
- break;
-
- case 0:
- printk("enable_irq(%u) unbalanced from %p\n", irq, __builtin_return_address(0));
- }
-
- if (group->control)
- group->disable_cnt[idx] = count;
- else
- level->disable_count = count;
+ __set_MASK(d->irq);
+ __clr_RC(d->irq);
+ __clr_IRL();
+}
- spin_unlock_irqrestore(&level->lock, flags);
+static void frv_cpupic_unmask(struct irq_data *d)
+{
+ __clr_MASK(d->irq);
}
-EXPORT_SYMBOL(enable_irq);
+static struct irq_chip frv_cpu_pic = {
+ .name = "cpu",
+ .irq_ack = frv_cpupic_ack,
+ .irq_mask = frv_cpupic_mask,
+ .irq_mask_ack = frv_cpupic_mask_ack,
+ .irq_unmask = frv_cpupic_unmask,
+};
-/*****************************************************************************/
/*
- * handles all normal device IRQ's
+ * handles all normal device IRQs
* - registers are referred to by the __frame variable (GR28)
* - IRQ distribution is complicated in this arch because of the many PICs, the
* way they work and the way they cascade
*/
asmlinkage void do_IRQ(void)
{
- struct irq_source *source;
- int level, cpu;
-
- level = (__frame->tbr >> 4) & 0xf;
- cpu = smp_processor_id();
-
-#if 0
- {
- static u32 irqcount;
- *(volatile u32 *) 0xe1200004 = ~((irqcount++ << 8) | level);
- *(volatile u16 *) 0xffc00100 = (u16) ~0x9999;
- mb();
- }
-#endif
-
- if ((unsigned long) __frame - (unsigned long) (current + 1) < 512)
- BUG();
-
- __set_MASK(level);
- __clr_RC(level);
- __clr_IRL();
-
- kstat_this_cpu.irqs[level]++;
-
irq_enter();
-
- for (source = frv_irq_levels[level].sources; source; source = source->next)
- source->doirq(source);
-
+ generic_handle_irq(__get_IRL());
irq_exit();
+}
- __clr_MASK(level);
-
- /* only process softirqs if we didn't interrupt another interrupt handler */
- if ((__frame->psr & PSR_PIL) == PSR_PIL_0)
- if (local_softirq_pending())
- do_softirq();
-
-#ifdef CONFIG_PREEMPT
- local_irq_disable();
- while (--current->preempt_count == 0) {
- if (!(__frame->psr & PSR_S) ||
- current->need_resched == 0 ||
- in_interrupt())
- break;
- current->preempt_count++;
- local_irq_enable();
- preempt_schedule();
- local_irq_disable();
- }
-#endif
-
-#if 0
- {
- *(volatile u16 *) 0xffc00100 = (u16) ~0x6666;
- mb();
- }
-#endif
-
-} /* end do_IRQ() */
-
-/*****************************************************************************/
/*
* handles all NMIs when not co-opted by the debugger
* - registers are referred to by the __frame variable (GR28)
*/
asmlinkage void do_NMI(void)
{
-} /* end do_NMI() */
-
-/*****************************************************************************/
-/**
- * request_irq - allocate an interrupt line
- * @irq: Interrupt line to allocate
- * @handler: Function to be called when the IRQ occurs
- * @irqflags: Interrupt type flags
- * @devname: An ascii name for the claiming device
- * @dev_id: A cookie passed back to the handler function
- *
- * This call allocates interrupt resources and enables the
- * interrupt line and IRQ handling. From the point this
- * call is made your handler function may be invoked. Since
- * your handler function must clear any interrupt the board
- * raises, you must take care both to initialise your hardware
- * and to set up the interrupt handler in the right order.
- *
- * Dev_id must be globally unique. Normally the address of the
- * device data structure is used as the cookie. Since the handler
- * receives this value it makes sense to use it.
- *
- * If your interrupt is shared you must pass a non NULL dev_id
- * as this is required when freeing the interrupt.
- *
- * Flags:
- *
- * SA_SHIRQ Interrupt is shared
- *
- * SA_INTERRUPT Disable local interrupts while processing
- *
- * SA_SAMPLE_RANDOM The interrupt can be used for entropy
- *
- */
-
-int request_irq(unsigned int irq,
- irqreturn_t (*handler)(int, void *, struct pt_regs *),
- unsigned long irqflags,
- const char * devname,
- void *dev_id)
-{
- int retval;
- struct irqaction *action;
-
-#if 1
- /*
- * Sanity-check: shared interrupts should REALLY pass in
- * a real dev-ID, otherwise we'll have trouble later trying
- * to figure out which interrupt is which (messes up the
- * interrupt freeing logic etc).
- */
- if (irqflags & SA_SHIRQ) {
- if (!dev_id)
- printk("Bad boy: %s (at 0x%x) called us without a dev_id!\n",
- devname, (&irq)[-1]);
- }
-#endif
-
- if ((irq >> NR_IRQ_LOG2_ACTIONS_PER_GROUP) >= NR_IRQ_GROUPS)
- return -EINVAL;
- if (!handler)
- return -EINVAL;
-
- action = (struct irqaction *) kmalloc(sizeof(struct irqaction), GFP_KERNEL);
- if (!action)
- return -ENOMEM;
-
- action->handler = handler;
- action->flags = irqflags;
- action->mask = CPU_MASK_NONE;
- action->name = devname;
- action->next = NULL;
- action->dev_id = dev_id;
-
- retval = setup_irq(irq, action);
- if (retval)
- kfree(action);
- return retval;
}
-EXPORT_SYMBOL(request_irq);
-
-/**
- * free_irq - free an interrupt
- * @irq: Interrupt line to free
- * @dev_id: Device identity to free
- *
- * Remove an interrupt handler. The handler is removed and if the
- * interrupt line is no longer in use by any driver it is disabled.
- * On a shared IRQ the caller must ensure the interrupt is disabled
- * on the card it drives before calling this function. The function
- * does not return until any executing interrupts for this IRQ
- * have completed.
- *
- * This function may be called from interrupt context.
- *
- * Bugs: Attempting to free an irq in a handler for the same irq hangs
- * the machine.
- */
-
-void free_irq(unsigned int irq, void *dev_id)
-{
- struct irq_source *source;
- struct irq_group *group;
- struct irq_level *level;
- struct irqaction **p, **pp;
- unsigned long flags;
-
- if ((irq >> NR_IRQ_LOG2_ACTIONS_PER_GROUP) >= NR_IRQ_GROUPS)
- return;
-
- group = irq_groups[irq >> NR_IRQ_LOG2_ACTIONS_PER_GROUP];
- if (!group)
- BUG();
-
- source = group->sources[irq & (NR_IRQ_ACTIONS_PER_GROUP - 1)];
- if (!source)
- BUG();
-
- level = source->level;
- p = &group->actions[irq & (NR_IRQ_ACTIONS_PER_GROUP - 1)];
-
- spin_lock_irqsave(&level->lock, flags);
-
- for (pp = p; *pp; pp = &(*pp)->next) {
- struct irqaction *action = *pp;
-
- if (action->dev_id != dev_id)
- continue;
-
- /* found it - remove from the list of entries */
- *pp = action->next;
-
- level->usage--;
-
- if (p == pp && group->control)
- group->control(group, irq & (NR_IRQ_ACTIONS_PER_GROUP - 1), 0);
-
- if (level->usage == 0)
- __set_MASK(level - frv_irq_levels);
-
- spin_unlock_irqrestore(&level->lock,flags);
-
-#ifdef CONFIG_SMP
- /* Wait to make sure it's not being used on another CPU */
- while (desc->status & IRQ_INPROGRESS)
- barrier();
-#endif
- kfree(action);
- return;
- }
-}
-
-EXPORT_SYMBOL(free_irq);
-
/*
- * IRQ autodetection code..
- *
- * This depends on the fact that any interrupt that comes in on to an
- * unassigned IRQ will cause GxICR_DETECT to be set
- */
-
-static DECLARE_MUTEX(probe_sem);
-
-/**
- * probe_irq_on - begin an interrupt autodetect
- *
- * Commence probing for an interrupt. The interrupts are scanned
- * and a mask of potential interrupt lines is returned.
- *
- */
-
-unsigned long probe_irq_on(void)
-{
- down(&probe_sem);
- return 0;
-}
-
-EXPORT_SYMBOL(probe_irq_on);
-
-/*
- * Return a mask of triggered interrupts (this
- * can handle only legacy ISA interrupts).
- */
-
-/**
- * probe_irq_mask - scan a bitmap of interrupt lines
- * @val: mask of interrupts to consider
- *
- * Scan the ISA bus interrupt lines and return a bitmap of
- * active interrupts. The interrupt probe logic state is then
- * returned to its previous value.
- *
- * Note: we need to scan all the irq's even though we will
- * only return ISA irq numbers - just so that we reset them
- * all to a known state.
- */
-unsigned int probe_irq_mask(unsigned long xmask)
-{
- up(&probe_sem);
- return 0;
-}
-
-EXPORT_SYMBOL(probe_irq_mask);
-
-/*
- * Return the one interrupt that triggered (this can
- * handle any interrupt source).
- */
-
-/**
- * probe_irq_off - end an interrupt autodetect
- * @xmask: mask of potential interrupts (unused)
- *
- * Scans the unused interrupt lines and returns the line which
- * appears to have triggered the interrupt. If no interrupt was
- * found then zero is returned. If more than one interrupt is
- * found then minus the first candidate is returned to indicate
- * their is doubt.
- *
- * The interrupt probe logic state is returned to its previous
- * value.
- *
- * BUGS: When used in a module (which arguably shouldnt happen)
- * nothing prevents two IRQ probe callers from overlapping. The
- * results of this are non-optimal.
+ * initialise the interrupt system
*/
-
-int probe_irq_off(unsigned long xmask)
-{
- up(&probe_sem);
- return -1;
-}
-
-EXPORT_SYMBOL(probe_irq_off);
-
-/* this was setup_x86_irq but it seems pretty generic */
-int setup_irq(unsigned int irq, struct irqaction *new)
-{
- struct irq_source *source;
- struct irq_group *group;
- struct irq_level *level;
- struct irqaction **p, **pp;
- unsigned long flags;
-
- group = irq_groups[irq >> NR_IRQ_LOG2_ACTIONS_PER_GROUP];
- if (!group)
- BUG();
-
- source = group->sources[irq & (NR_IRQ_ACTIONS_PER_GROUP - 1)];
- if (!source)
- BUG();
-
- level = source->level;
-
- p = &group->actions[irq & (NR_IRQ_ACTIONS_PER_GROUP - 1)];
-
- /*
- * Some drivers like serial.c use request_irq() heavily,
- * so we have to be careful not to interfere with a
- * running system.
- */
- if (new->flags & SA_SAMPLE_RANDOM) {
- /*
- * This function might sleep, we want to call it first,
- * outside of the atomic block.
- * Yes, this might clear the entropy pool if the wrong
- * driver is attempted to be loaded, without actually
- * installing a new handler, but is this really a problem,
- * only the sysadmin is able to do this.
- */
- rand_initialize_irq(irq);
- }
-
- /* must juggle the interrupt processing stuff with interrupts disabled */
- spin_lock_irqsave(&level->lock, flags);
-
- /* can't share interrupts unless all parties agree to */
- if (level->usage != 0 && !(level->flags & new->flags & SA_SHIRQ)) {
- spin_unlock_irqrestore(&level->lock,flags);
- return -EBUSY;
- }
-
- /* add new interrupt at end of irq queue */
- pp = p;
- while (*pp)
- pp = &(*pp)->next;
-
- *pp = new;
-
- level->usage++;
- level->flags = new->flags;
-
- /* turn the interrupts on */
- if (level->usage == 1)
- __clr_MASK(level - frv_irq_levels);
-
- if (p == pp && group->control)
- group->control(group, irq & (NR_IRQ_ACTIONS_PER_GROUP - 1), 1);
-
- spin_unlock_irqrestore(&level->lock, flags);
- register_irq_proc(irq);
- return 0;
-}
-
-static struct proc_dir_entry * root_irq_dir;
-static struct proc_dir_entry * irq_dir [NR_IRQS];
-
-#define HEX_DIGITS 8
-
-static unsigned int parse_hex_value (const char *buffer,
- unsigned long count, unsigned long *ret)
-{
- unsigned char hexnum [HEX_DIGITS];
- unsigned long value;
- int i;
-
- if (!count)
- return -EINVAL;
- if (count > HEX_DIGITS)
- count = HEX_DIGITS;
- if (copy_from_user(hexnum, buffer, count))
- return -EFAULT;
-
- /*
- * Parse the first 8 characters as a hex string, any non-hex char
- * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same.
- */
- value = 0;
-
- for (i = 0; i < count; i++) {
- unsigned int c = hexnum[i];
-
- switch (c) {
- case '0' ... '9': c -= '0'; break;
- case 'a' ... 'f': c -= 'a'-10; break;
- case 'A' ... 'F': c -= 'A'-10; break;
- default:
- goto out;
- }
- value = (value << 4) | c;
- }
-out:
- *ret = value;
- return 0;
-}
-
-
-static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
- int count, int *eof, void *data)
-{
- unsigned long *mask = (unsigned long *) data;
- if (count < HEX_DIGITS+1)
- return -EINVAL;
- return sprintf (page, "%08lx\n", *mask);
-}
-
-static int prof_cpu_mask_write_proc (struct file *file, const char *buffer,
- unsigned long count, void *data)
-{
- unsigned long *mask = (unsigned long *) data, full_count = count, err;
- unsigned long new_value;
-
- show_state();
- err = parse_hex_value(buffer, count, &new_value);
- if (err)
- return err;
-
- *mask = new_value;
- return full_count;
-}
-
-#define MAX_NAMELEN 10
-
-static void register_irq_proc (unsigned int irq)
-{
- char name [MAX_NAMELEN];
-
- if (!root_irq_dir || irq_dir[irq])
- return;
-
- memset(name, 0, MAX_NAMELEN);
- sprintf(name, "%d", irq);
-
- /* create /proc/irq/1234 */
- irq_dir[irq] = proc_mkdir(name, root_irq_dir);
-}
-
-unsigned long prof_cpu_mask = -1;
-
-void init_irq_proc (void)
+void __init init_IRQ(void)
{
- struct proc_dir_entry *entry;
- int i;
-
- /* create /proc/irq */
- root_irq_dir = proc_mkdir("irq", 0);
+ int level;
- /* create /proc/irq/prof_cpu_mask */
- entry = create_proc_entry("prof_cpu_mask", 0600, root_irq_dir);
- if (!entry)
- return;
+ for (level = 1; level <= 14; level++)
+ irq_set_chip_and_handler(level, &frv_cpu_pic,
+ handle_level_irq);
- entry->nlink = 1;
- entry->data = (void *)&prof_cpu_mask;
- entry->read_proc = prof_cpu_mask_read_proc;
- entry->write_proc = prof_cpu_mask_write_proc;
+ irq_set_handler(IRQ_CPU_TIMER0, handle_edge_irq);
- /*
- * Create entries for all existing IRQs.
+ /* set the trigger levels for internal interrupt sources
+ * - timers all falling-edge
+ * - ERR0 is rising-edge
+ * - all others are high-level
*/
- for (i = 0; i < NR_IRQS; i++)
- register_irq_proc(i);
-}
+ __set_IITMR(0, 0x003f0000); /* DMA0-3, TIMER0-2 */
+ __set_IITMR(1, 0x20000000); /* ERR0-1, UART0-1, DMA4-7 */
+
+ /* route internal interrupts */
+ set_IRR(4, IRQ_DMA3_LEVEL, IRQ_DMA2_LEVEL, IRQ_DMA1_LEVEL,
+ IRQ_DMA0_LEVEL);
+ set_IRR(5, 0, IRQ_TIMER2_LEVEL, IRQ_TIMER1_LEVEL, IRQ_TIMER0_LEVEL);
+ set_IRR(6, IRQ_GDBSTUB_LEVEL, IRQ_GDBSTUB_LEVEL,
+ IRQ_UART1_LEVEL, IRQ_UART0_LEVEL);
+ set_IRR(7, IRQ_DMA7_LEVEL, IRQ_DMA6_LEVEL, IRQ_DMA5_LEVEL,
+ IRQ_DMA4_LEVEL);
+
+ /* route external interrupts */
+ set_IRR(2, IRQ_XIRQ7_LEVEL, IRQ_XIRQ6_LEVEL, IRQ_XIRQ5_LEVEL,
+ IRQ_XIRQ4_LEVEL);
+ set_IRR(3, IRQ_XIRQ3_LEVEL, IRQ_XIRQ2_LEVEL, IRQ_XIRQ1_LEVEL,
+ IRQ_XIRQ0_LEVEL);
+
+#if defined(CONFIG_MB93091_VDK)
+ __set_TM1(0x55550000); /* XIRQ7-0 all active low */
+#elif defined(CONFIG_MB93093_PDK)
+ __set_TM1(0x15550000); /* XIRQ7 active high, 6-0 all active low */
+#else
+#error dont know external IRQ trigger levels for this setup
+#endif
-/*****************************************************************************/
-/*
- * initialise the interrupt system
- */
-void __init init_IRQ(void)
-{
- route_cpu_irqs();
fpga_init();
#ifdef CONFIG_FUJITSU_MB93493
- route_mb93493_irqs();
+ mb93493_init();
#endif
-} /* end init_IRQ() */
+}
diff --git a/arch/frv/kernel/kernel_thread.S b/arch/frv/kernel/kernel_thread.S
deleted file mode 100644
index 4531c830d20..00000000000
--- a/arch/frv/kernel/kernel_thread.S
+++ /dev/null
@@ -1,77 +0,0 @@
-/* kernel_thread.S: kernel thread creation
- *
- * Copyright (C) 2003 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 License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include <linux/linkage.h>
-#include <asm/unistd.h>
-
-#define CLONE_VM 0x00000100 /* set if VM shared between processes */
-#define KERN_ERR "<3>"
-
- .section .rodata
-kernel_thread_emsg:
- .asciz KERN_ERR "failed to create kernel thread: error=%d\n"
-
- .text
- .balign 4
-
-###############################################################################
-#
-# Create a kernel thread
-#
-# int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
-#
-###############################################################################
- .globl kernel_thread
- .type kernel_thread,@function
-kernel_thread:
- or.p gr8,gr0,gr4
- or gr9,gr0,gr5
-
- # start by forking the current process, but with shared VM
- setlos.p #__NR_clone,gr7 ; syscall number
- ori gr10,#CLONE_VM,gr8 ; first syscall arg [clone_flags]
- sethi.p #0xe4e4,gr9 ; second syscall arg [newsp]
- setlo #0xe4e4,gr9
- setlos.p #0,gr10 ; third syscall arg [parent_tidptr]
- setlos #0,gr11 ; fourth syscall arg [child_tidptr]
- tira gr0,#0
- setlos.p #4095,gr7
- andcc gr8,gr8,gr0,icc0
- addcc.p gr8,gr7,gr0,icc1
- bnelr icc0,#2
- bc icc1,#0,kernel_thread_error
-
- # now invoke the work function
- or gr5,gr0,gr8
- calll @(gr4,gr0)
-
- # and finally exit the thread
- setlos #__NR_exit,gr7 ; syscall number
- tira gr0,#0
-
-kernel_thread_error:
- subi sp,#8,sp
- movsg lr,gr4
- sti gr8,@(sp,#0)
- sti.p gr4,@(sp,#4)
-
- or gr8,gr0,gr9
- sethi.p %hi(kernel_thread_emsg),gr8
- setlo %lo(kernel_thread_emsg),gr8
-
- call printk
-
- ldi @(sp,#4),gr4
- ldi @(sp,#0),gr8
- subi sp,#8,sp
- jmpl @(gr4,gr0)
-
- .size kernel_thread,.-kernel_thread
diff --git a/arch/frv/kernel/local.h b/arch/frv/kernel/local.h
index e9471761d78..76606d13b1a 100644
--- a/arch/frv/kernel/local.h
+++ b/arch/frv/kernel/local.h
@@ -51,6 +51,9 @@ extern void (*__power_switch_wake_cleanup)(void);
/* time.c */
extern void time_divisor_init(void);
+/* cmode.S */
+extern asmlinkage void frv_change_cmode(int);
+
#endif /* __ASSEMBLY__ */
#endif /* _FRV_LOCAL_H */
diff --git a/arch/frv/kernel/local64.h b/arch/frv/kernel/local64.h
new file mode 100644
index 00000000000..36c93b5cc23
--- /dev/null
+++ b/arch/frv/kernel/local64.h
@@ -0,0 +1 @@
+#include <asm-generic/local64.h>
diff --git a/arch/frv/kernel/module.c b/arch/frv/kernel/module.c
index 850d168f69f..9d9835f1fe2 100644
--- a/arch/frv/kernel/module.c
+++ b/arch/frv/kernel/module.c
@@ -22,59 +22,6 @@
#define DEBUGP(fmt...)
#endif
-void *module_alloc(unsigned long size)
-{
- if (size == 0)
- return NULL;
-
- return vmalloc_exec(size);
-}
-
-
-/* Free memory returned from module_alloc */
-void module_free(struct module *mod, void *module_region)
-{
- vfree(module_region);
- /* FIXME: If module_region == mod->init_region, trim exception
- table entries. */
-}
-
-/* We don't need anything special. */
-int module_frob_arch_sections(Elf_Ehdr *hdr,
- Elf_Shdr *sechdrs,
- char *secstrings,
- struct module *mod)
-{
- return 0;
-}
-
-int apply_relocate(Elf32_Shdr *sechdrs,
- const char *strtab,
- unsigned int symindex,
- unsigned int relsec,
- struct module *me)
-{
- printk(KERN_ERR "module %s: ADD RELOCATION unsupported\n", me->name);
- return -ENOEXEC;
-}
-
-int apply_relocate_add(Elf32_Shdr *sechdrs,
- const char *strtab,
- unsigned int symindex,
- unsigned int relsec,
- struct module *me)
-{
- printk(KERN_ERR "module %s: ADD RELOCATION unsupported\n", me->name);
- return -ENOEXEC;
-}
-
-int module_finalize(const Elf_Ehdr *hdr,
- const Elf_Shdr *sechdrs,
- struct module *me)
-{
- return 0;
-}
-
-void module_arch_cleanup(struct module *mod)
-{
-}
+/* TODO: At least one of apply_relocate or apply_relocate_add must be
+ * implemented in order to get working module support.
+ */
diff --git a/arch/frv/kernel/pm-mb93093.c b/arch/frv/kernel/pm-mb93093.c
index 34d01d7dcc3..eaa7b582ef5 100644
--- a/arch/frv/kernel/pm-mb93093.c
+++ b/arch/frv/kernel/pm-mb93093.c
@@ -10,7 +10,6 @@
*
*/
-#include <linux/config.h>
#include <linux/init.h>
#include <linux/pm.h>
#include <linux/sched.h>
diff --git a/arch/frv/kernel/pm.c b/arch/frv/kernel/pm.c
index f0b8fff3e73..ac767d94a88 100644
--- a/arch/frv/kernel/pm.c
+++ b/arch/frv/kernel/pm.c
@@ -11,11 +11,9 @@
*
*/
-#include <linux/config.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/pm.h>
-#include <linux/pm_legacy.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/sysctl.h>
@@ -27,11 +25,6 @@
#include "local.h"
-void (*pm_power_off)(void);
-EXPORT_SYMBOL(pm_power_off);
-
-extern void frv_change_cmode(int);
-
/*
* Debug macros
*/
@@ -131,13 +124,12 @@ unsigned long sleep_phys_sp(void *sp)
* Use a temporary sysctl number. Horrid, but will be cleaned up in 2.6
* when all the PM interfaces exist nicely.
*/
-#define CTL_PM 9899
#define CTL_PM_SUSPEND 1
#define CTL_PM_CMODE 2
#define CTL_PM_P0 4
#define CTL_PM_CM 5
-static int user_atoi(char *ubuf, size_t len)
+static int user_atoi(char __user *ubuf, size_t len)
{
char buf[16];
unsigned long ret;
@@ -158,29 +150,25 @@ static int user_atoi(char *ubuf, size_t len)
/*
* Send us to sleep.
*/
-static int sysctl_pm_do_suspend(ctl_table *ctl, int write, struct file *filp,
- void *buffer, size_t *lenp, loff_t *fpos)
+static int sysctl_pm_do_suspend(struct ctl_table *ctl, int write,
+ void __user *buffer, size_t *lenp, loff_t *fpos)
{
- int retval, mode;
+ int mode;
if (*lenp <= 0)
return -EIO;
mode = user_atoi(buffer, *lenp);
- if ((mode != 1) && (mode != 5))
- return -EINVAL;
+ switch (mode) {
+ case 1:
+ return pm_do_suspend();
- retval = pm_send_all(PM_SUSPEND, (void *)3);
+ case 5:
+ return pm_do_bus_sleep();
- if (retval == 0) {
- if (mode == 5)
- retval = pm_do_bus_sleep();
- else
- retval = pm_do_suspend();
- pm_send_all(PM_RESUME, (void *)0);
+ default:
+ return -EINVAL;
}
-
- return retval;
}
static int try_set_cmode(int new_cmode)
@@ -190,9 +178,6 @@ static int try_set_cmode(int new_cmode)
if (!(clock_cmodes_permitted & (1<<new_cmode)))
return -EINVAL;
- /* tell all the drivers we're suspending */
- pm_send_all(PM_SUSPEND, (void *)3);
-
/* now change cmode */
local_irq_disable();
frv_dma_pause_all();
@@ -208,56 +193,23 @@ static int try_set_cmode(int new_cmode)
frv_dma_resume_all();
local_irq_enable();
- /* tell all the drivers we're resuming */
- pm_send_all(PM_RESUME, (void *)0);
return 0;
}
-static int cmode_procctl(ctl_table *ctl, int write, struct file *filp,
- void *buffer, size_t *lenp, loff_t *fpos)
+static int cmode_procctl(struct ctl_table *ctl, int write,
+ void __user *buffer, size_t *lenp, loff_t *fpos)
{
int new_cmode;
if (!write)
- return proc_dointvec(ctl, write, filp, buffer, lenp, fpos);
+ return proc_dointvec(ctl, write, buffer, lenp, fpos);
new_cmode = user_atoi(buffer, *lenp);
return try_set_cmode(new_cmode)?:*lenp;
}
-static int cmode_sysctl(ctl_table *table, int *name, int nlen,
- void *oldval, size_t *oldlenp,
- void *newval, size_t newlen, void **context)
-{
- if (oldval && oldlenp) {
- size_t oldlen;
-
- if (get_user(oldlen, oldlenp))
- return -EFAULT;
-
- if (oldlen != sizeof(int))
- return -EINVAL;
-
- if (put_user(clock_cmode_current, (unsigned int *)oldval) ||
- put_user(sizeof(int), oldlenp))
- return -EFAULT;
- }
- if (newval && newlen) {
- int new_cmode;
-
- if (newlen != sizeof(int))
- return -EINVAL;
-
- if (get_user(new_cmode, (int *)newval))
- return -EFAULT;
-
- return try_set_cmode(new_cmode)?:1;
- }
- return 1;
-}
-
static int try_set_p0(int new_p0)
{
unsigned long flags, clkc;
@@ -317,108 +269,73 @@ static int try_set_cm(int new_cm)
return 0;
}
-static int p0_procctl(ctl_table *ctl, int write, struct file *filp,
- void *buffer, size_t *lenp, loff_t *fpos)
+static int p0_procctl(struct ctl_table *ctl, int write,
+ void __user *buffer, size_t *lenp, loff_t *fpos)
{
int new_p0;
if (!write)
- return proc_dointvec(ctl, write, filp, buffer, lenp, fpos);
+ return proc_dointvec(ctl, write, buffer, lenp, fpos);
new_p0 = user_atoi(buffer, *lenp);
return try_set_p0(new_p0)?:*lenp;
}
-static int p0_sysctl(ctl_table *table, int *name, int nlen,
- void *oldval, size_t *oldlenp,
- void *newval, size_t newlen, void **context)
-{
- if (oldval && oldlenp) {
- size_t oldlen;
-
- if (get_user(oldlen, oldlenp))
- return -EFAULT;
-
- if (oldlen != sizeof(int))
- return -EINVAL;
-
- if (put_user(clock_p0_current, (unsigned int *)oldval) ||
- put_user(sizeof(int), oldlenp))
- return -EFAULT;
- }
- if (newval && newlen) {
- int new_p0;
-
- if (newlen != sizeof(int))
- return -EINVAL;
-
- if (get_user(new_p0, (int *)newval))
- return -EFAULT;
-
- return try_set_p0(new_p0)?:1;
- }
- return 1;
-}
-
-static int cm_procctl(ctl_table *ctl, int write, struct file *filp,
- void *buffer, size_t *lenp, loff_t *fpos)
+static int cm_procctl(struct ctl_table *ctl, int write,
+ void __user *buffer, size_t *lenp, loff_t *fpos)
{
int new_cm;
if (!write)
- return proc_dointvec(ctl, write, filp, buffer, lenp, fpos);
+ return proc_dointvec(ctl, write, buffer, lenp, fpos);
new_cm = user_atoi(buffer, *lenp);
return try_set_cm(new_cm)?:*lenp;
}
-static int cm_sysctl(ctl_table *table, int *name, int nlen,
- void *oldval, size_t *oldlenp,
- void *newval, size_t newlen, void **context)
-{
- if (oldval && oldlenp) {
- size_t oldlen;
-
- if (get_user(oldlen, oldlenp))
- return -EFAULT;
-
- if (oldlen != sizeof(int))
- return -EINVAL;
-
- if (put_user(clock_cm_current, (unsigned int *)oldval) ||
- put_user(sizeof(int), oldlenp))
- return -EFAULT;
- }
- if (newval && newlen) {
- int new_cm;
-
- if (newlen != sizeof(int))
- return -EINVAL;
-
- if (get_user(new_cm, (int *)newval))
- return -EFAULT;
-
- return try_set_cm(new_cm)?:1;
- }
- return 1;
-}
-
-
static struct ctl_table pm_table[] =
{
- {CTL_PM_SUSPEND, "suspend", NULL, 0, 0200, NULL, &sysctl_pm_do_suspend},
- {CTL_PM_CMODE, "cmode", &clock_cmode_current, sizeof(int), 0644, NULL, &cmode_procctl, &cmode_sysctl, NULL},
- {CTL_PM_P0, "p0", &clock_p0_current, sizeof(int), 0644, NULL, &p0_procctl, &p0_sysctl, NULL},
- {CTL_PM_CM, "cm", &clock_cm_current, sizeof(int), 0644, NULL, &cm_procctl, &cm_sysctl, NULL},
- {0}
+ {
+ .procname = "suspend",
+ .data = NULL,
+ .maxlen = 0,
+ .mode = 0200,
+ .proc_handler = sysctl_pm_do_suspend,
+ },
+ {
+ .procname = "cmode",
+ .data = &clock_cmode_current,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = cmode_procctl,
+ },
+ {
+ .procname = "p0",
+ .data = &clock_p0_current,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = p0_procctl,
+ },
+ {
+ .procname = "cm",
+ .data = &clock_cm_current,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = cm_procctl,
+ },
+ { }
};
static struct ctl_table pm_dir_table[] =
{
- {CTL_PM, "pm", NULL, 0, 0555, pm_table},
- {0}
+ {
+ .procname = "pm",
+ .mode = 0555,
+ .child = pm_table,
+ },
+ { }
};
/*
@@ -426,7 +343,7 @@ static struct ctl_table pm_dir_table[] =
*/
static int __init pm_init(void)
{
- register_sysctl_table(pm_dir_table, 1);
+ register_sysctl_table(pm_dir_table);
return 0;
}
diff --git a/arch/frv/kernel/process.c b/arch/frv/kernel/process.c
index 0fff8a61ef2..5d40aeb7712 100644
--- a/arch/frv/kernel/process.c
+++ b/arch/frv/kernel/process.c
@@ -10,13 +10,12 @@
* 2 of the License, or (at your option) any later version.
*/
-#include <linux/config.h>
+#include <linux/module.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
@@ -25,33 +24,26 @@
#include <linux/elf.h>
#include <linux/reboot.h>
#include <linux/interrupt.h>
+#include <linux/pagemap.h>
+#include <linux/rcupdate.h>
+#include <asm/asm-offsets.h>
#include <asm/uaccess.h>
-#include <asm/system.h>
#include <asm/setup.h>
#include <asm/pgtable.h>
+#include <asm/tlb.h>
#include <asm/gdb-stub.h>
#include <asm/mb-regs.h>
#include "local.h"
asmlinkage void ret_from_fork(void);
+asmlinkage void ret_from_kernel_thread(void);
#include <asm/pgalloc.h>
-struct task_struct *alloc_task_struct(void)
-{
- struct task_struct *p = kmalloc(THREAD_SIZE, GFP_KERNEL);
- if (p)
- atomic_set((atomic_t *)(p+1), 1);
- return p;
-}
-
-void free_task_struct(struct task_struct *p)
-{
- if (atomic_dec_and_test((atomic_t *)(p+1)))
- kfree(p);
-}
+void (*pm_power_off)(void);
+EXPORT_SYMBOL(pm_power_off);
static void core_sleep_idle(void)
{
@@ -67,31 +59,12 @@ static void core_sleep_idle(void)
mb();
}
-void (*idle)(void) = core_sleep_idle;
-
-/*
- * The idle thread. There's no useful work to be
- * done, so just try to conserve power and have a
- * low exit latency (ie sit in a loop waiting for
- * somebody to say that they'd like to reschedule)
- */
-void cpu_idle(void)
+void arch_cpu_idle(void)
{
- int cpu = smp_processor_id();
-
- /* endless idle loop with no priority at all */
- while (1) {
- while (!need_resched()) {
- irq_stat[cpu].idle_timestamp = jiffies;
-
- if (!frv_dma_inprogress && idle)
- idle();
- }
-
- preempt_enable_no_resched();
- schedule();
- preempt_disable();
- }
+ if (!frv_dma_inprogress)
+ core_sleep_idle();
+ else
+ local_irq_enable();
}
void machine_restart(char * __unused)
@@ -139,10 +112,7 @@ void machine_power_off(void)
void flush_thread(void)
{
-#if 0 //ndef NO_FPU
- unsigned long zero = 0;
-#endif
- set_fs(USER_DS);
+ /* nothing */
}
inline unsigned long user_stack(const struct pt_regs *regs)
@@ -152,87 +122,40 @@ inline unsigned long user_stack(const struct pt_regs *regs)
return user_mode(regs) ? regs->sp : 0;
}
-asmlinkage int sys_fork(void)
-{
-#ifndef CONFIG_MMU
- /* fork almost works, enough to trick you into looking elsewhere:-( */
- return -EINVAL;
-#else
- return do_fork(SIGCHLD, user_stack(__frame), __frame, 0, NULL, NULL);
-#endif
-}
-
-asmlinkage int sys_vfork(void)
-{
- return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, user_stack(__frame), __frame, 0,
- NULL, NULL);
-}
-
-/*****************************************************************************/
-/*
- * clone a process
- * - tlsptr is retrieved by copy_thread()
- */
-asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
- int __user *parent_tidptr, int __user *child_tidptr,
- int __user *tlsptr)
-{
- if (!newsp)
- newsp = user_stack(__frame);
- return do_fork(clone_flags, newsp, __frame, 0, parent_tidptr, child_tidptr);
-} /* end sys_clone() */
-
-/*****************************************************************************/
-/*
- * This gets called before we allocate a new thread and copy
- * the current task into it.
- */
-void prepare_to_copy(struct task_struct *tsk)
-{
- //unlazy_fpu(tsk);
-} /* end prepare_to_copy() */
-
-/*****************************************************************************/
/*
* set up the kernel stack and exception frames for a new process
*/
-int copy_thread(int nr, unsigned long clone_flags,
- unsigned long usp, unsigned long topstk,
- struct task_struct *p, struct pt_regs *regs)
+int copy_thread(unsigned long clone_flags,
+ unsigned long usp, unsigned long arg,
+ struct task_struct *p)
{
- struct pt_regs *childregs0, *childregs, *regs0;
+ struct pt_regs *childregs;
- regs0 = __kernel_frame0_ptr;
- childregs0 = (struct pt_regs *)
- (task_stack_page(p) + THREAD_SIZE - USER_CONTEXT_SIZE);
- childregs = childregs0;
+ childregs = (struct pt_regs *)
+ (task_stack_page(p) + THREAD_SIZE - FRV_FRAME0_SIZE);
/* set up the userspace frame (the only place that the USP is stored) */
- *childregs0 = *regs0;
-
- childregs0->gr8 = 0;
- childregs0->sp = usp;
- childregs0->next_frame = NULL;
-
- /* set up the return kernel frame if called from kernel_thread() */
- if (regs != regs0) {
- childregs--;
- *childregs = *regs;
- childregs->sp = (unsigned long) childregs0;
- childregs->next_frame = childregs0;
- childregs->gr15 = (unsigned long) task_thread_info(p);
- childregs->gr29 = (unsigned long) p;
- }
-
- p->set_child_tid = p->clear_child_tid = NULL;
+ *childregs = *current_pt_regs();
p->thread.frame = childregs;
p->thread.curr = p;
p->thread.sp = (unsigned long) childregs;
p->thread.fp = 0;
p->thread.lr = 0;
- p->thread.pc = (unsigned long) ret_from_fork;
- p->thread.frame0 = childregs0;
+ p->thread.frame0 = childregs;
+
+ if (unlikely(p->flags & PF_KTHREAD)) {
+ childregs->gr9 = usp; /* function */
+ childregs->gr8 = arg;
+ p->thread.pc = (unsigned long) ret_from_kernel_thread;
+ save_user_regs(p->thread.user);
+ return 0;
+ }
+ if (usp)
+ childregs->sp = usp;
+ childregs->next_frame = NULL;
+
+ p->thread.pc = (unsigned long) ret_from_fork;
/* the new TLS pointer is passed in as arg #5 to sys_clone() */
if (clone_flags & CLONE_SETTLS)
@@ -243,26 +166,6 @@ int copy_thread(int nr, unsigned long clone_flags,
return 0;
} /* end copy_thread() */
-/*
- * sys_execve() executes a new program.
- */
-asmlinkage int sys_execve(char *name, char **argv, char **envp)
-{
- int error;
- char * filename;
-
- lock_kernel();
- filename = getname(name);
- error = PTR_ERR(filename);
- if (IS_ERR(filename))
- goto out;
- error = do_execve(filename, argv, envp, __frame);
- putname(filename);
- out:
- unlock_kernel();
- return error;
-}
-
unsigned long get_wchan(struct task_struct *p)
{
struct pt_regs *regs0;
@@ -368,3 +271,11 @@ int elf_check_arch(const struct elf32_hdr *hdr)
return 1;
}
+
+int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpregs)
+{
+ memcpy(fpregs,
+ &current->thread.user->f,
+ sizeof(current->thread.user->f));
+ return 1;
+}
diff --git a/arch/frv/kernel/ptrace.c b/arch/frv/kernel/ptrace.c
index f953484e7d5..3987ff88dab 100644
--- a/arch/frv/kernel/ptrace.c
+++ b/arch/frv/kernel/ptrace.c
@@ -14,18 +14,18 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/user.h>
-#include <linux/config.h>
#include <linux/security.h>
#include <linux/signal.h>
+#include <linux/regset.h>
+#include <linux/elf.h>
+#include <linux/tracehook.h>
#include <asm/uaccess.h>
#include <asm/page.h>
#include <asm/pgtable.h>
-#include <asm/system.h>
#include <asm/processor.h>
#include <asm/unistd.h>
@@ -35,6 +35,169 @@
*/
/*
+ * retrieve the contents of FRV userspace general registers
+ */
+static int genregs_get(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ void *kbuf, void __user *ubuf)
+{
+ const struct user_int_regs *iregs = &target->thread.user->i;
+ int ret;
+
+ ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ iregs, 0, sizeof(*iregs));
+ if (ret < 0)
+ return ret;
+
+ return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
+ sizeof(*iregs), -1);
+}
+
+/*
+ * update the contents of the FRV userspace general registers
+ */
+static int genregs_set(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ const void *kbuf, const void __user *ubuf)
+{
+ struct user_int_regs *iregs = &target->thread.user->i;
+ unsigned int offs_gr0, offs_gr1;
+ int ret;
+
+ /* not allowed to set PSR or __status */
+ if (pos < offsetof(struct user_int_regs, psr) + sizeof(long) &&
+ pos + count > offsetof(struct user_int_regs, psr))
+ return -EIO;
+
+ if (pos < offsetof(struct user_int_regs, __status) + sizeof(long) &&
+ pos + count > offsetof(struct user_int_regs, __status))
+ return -EIO;
+
+ /* set the control regs */
+ offs_gr0 = offsetof(struct user_int_regs, gr[0]);
+ offs_gr1 = offsetof(struct user_int_regs, gr[1]);
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ iregs, 0, offs_gr0);
+ if (ret < 0)
+ return ret;
+
+ /* skip GR0/TBR */
+ ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
+ offs_gr0, offs_gr1);
+ if (ret < 0)
+ return ret;
+
+ /* set the general regs */
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &iregs->gr[1], offs_gr1, sizeof(*iregs));
+ if (ret < 0)
+ return ret;
+
+ return user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
+ sizeof(*iregs), -1);
+}
+
+/*
+ * retrieve the contents of FRV userspace FP/Media registers
+ */
+static int fpmregs_get(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ void *kbuf, void __user *ubuf)
+{
+ const struct user_fpmedia_regs *fpregs = &target->thread.user->f;
+ int ret;
+
+ ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ fpregs, 0, sizeof(*fpregs));
+ if (ret < 0)
+ return ret;
+
+ return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
+ sizeof(*fpregs), -1);
+}
+
+/*
+ * update the contents of the FRV userspace FP/Media registers
+ */
+static int fpmregs_set(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ const void *kbuf, const void __user *ubuf)
+{
+ struct user_fpmedia_regs *fpregs = &target->thread.user->f;
+ int ret;
+
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ fpregs, 0, sizeof(*fpregs));
+ if (ret < 0)
+ return ret;
+
+ return user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
+ sizeof(*fpregs), -1);
+}
+
+/*
+ * determine if the FP/Media registers have actually been used
+ */
+static int fpmregs_active(struct task_struct *target,
+ const struct user_regset *regset)
+{
+ return tsk_used_math(target) ? regset->n : 0;
+}
+
+/*
+ * Define the register sets available on the FRV under Linux
+ */
+enum frv_regset {
+ REGSET_GENERAL,
+ REGSET_FPMEDIA,
+};
+
+static const struct user_regset frv_regsets[] = {
+ /*
+ * General register format is:
+ * PSR, ISR, CCR, CCCR, LR, LCR, PC, (STATUS), SYSCALLNO, ORIG_G8
+ * GNER0-1, IACC0, TBR, GR1-63
+ */
+ [REGSET_GENERAL] = {
+ .core_note_type = NT_PRSTATUS,
+ .n = ELF_NGREG,
+ .size = sizeof(long),
+ .align = sizeof(long),
+ .get = genregs_get,
+ .set = genregs_set,
+ },
+ /*
+ * FPU/Media register format is:
+ * FR0-63, FNER0-1, MSR0-1, ACC0-7, ACCG0-8, FSR
+ */
+ [REGSET_FPMEDIA] = {
+ .core_note_type = NT_PRFPREG,
+ .n = sizeof(struct user_fpmedia_regs) / sizeof(long),
+ .size = sizeof(long),
+ .align = sizeof(long),
+ .get = fpmregs_get,
+ .set = fpmregs_set,
+ .active = fpmregs_active,
+ },
+};
+
+static const struct user_regset_view user_frv_native_view = {
+ .name = "frv",
+ .e_machine = EM_FRV,
+ .regsets = frv_regsets,
+ .n = ARRAY_SIZE(frv_regsets),
+};
+
+const struct user_regset_view *task_user_regset_view(struct task_struct *task)
+{
+ return &user_frv_native_view;
+}
+
+/*
* Get contents of register REGNO in task TASK.
*/
static inline long get_reg(struct task_struct *task, int regno)
@@ -71,75 +234,45 @@ static inline int put_reg(struct task_struct *task, int regno,
}
/*
- * check that an address falls within the bounds of the target process's memory mappings
- */
-static inline int is_user_addr_valid(struct task_struct *child,
- unsigned long start, unsigned long len)
-{
-#ifdef CONFIG_MMU
- if (start >= PAGE_OFFSET || len > PAGE_OFFSET - start)
- return -EIO;
- return 0;
-#else
- struct vm_list_struct *vml;
-
- for (vml = child->mm->context.vmlist; vml; vml = vml->next)
- if (start >= vml->vma->vm_start && start + len <= vml->vma->vm_end)
- return 0;
-
- return -EIO;
-#endif
-}
-
-/*
* Called by kernel/ptrace.c when detaching..
*
* Control h/w single stepping
*/
-void ptrace_disable(struct task_struct *child)
+void user_enable_single_step(struct task_struct *child)
+{
+ child->thread.frame0->__status |= REG__STATUS_STEP;
+}
+
+void user_disable_single_step(struct task_struct *child)
{
child->thread.frame0->__status &= ~REG__STATUS_STEP;
}
-void ptrace_enable(struct task_struct *child)
+void ptrace_disable(struct task_struct *child)
{
- child->thread.frame0->__status |= REG__STATUS_STEP;
+ user_disable_single_step(child);
}
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
{
unsigned long tmp;
int ret;
+ int regno = addr >> 2;
+ unsigned long __user *datap = (unsigned long __user *) data;
switch (request) {
- /* when I and D space are separate, these will need to be fixed. */
- case PTRACE_PEEKTEXT: /* read word at location addr. */
- case PTRACE_PEEKDATA: {
- int copied;
-
- ret = -EIO;
- if (is_user_addr_valid(child, addr, sizeof(tmp)) < 0)
- break;
-
- copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
- if (copied != sizeof(tmp))
- break;
-
- ret = put_user(tmp,(unsigned long *) data);
- break;
- }
-
/* read the word at location addr in the USER area. */
case PTRACE_PEEKUSR: {
tmp = 0;
ret = -EIO;
- if ((addr & 3) || addr < 0)
+ if (addr & 3)
break;
ret = 0;
- switch (addr >> 2) {
+ switch (regno) {
case 0 ... PT__END - 1:
- tmp = get_reg(child, addr >> 2);
+ tmp = get_reg(child, regno);
break;
case PT__END + 0:
@@ -168,557 +301,77 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
}
if (ret == 0)
- ret = put_user(tmp, (unsigned long *) data);
+ ret = put_user(tmp, datap);
break;
}
- /* when I and D space are separate, this will have to be fixed. */
- case PTRACE_POKETEXT: /* write the word at location addr. */
- case PTRACE_POKEDATA:
- ret = -EIO;
- if (is_user_addr_valid(child, addr, sizeof(tmp)) < 0)
- break;
- if (access_process_vm(child, addr, &data, sizeof(data), 1) != sizeof(data))
- break;
- ret = 0;
- break;
-
case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
ret = -EIO;
- if ((addr & 3) || addr < 0)
- break;
-
- ret = 0;
- switch (addr >> 2) {
- case 0 ... PT__END-1:
- ret = put_reg(child, addr >> 2, data);
- break;
-
- default:
- ret = -EIO;
- break;
- }
- break;
-
- case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
- case PTRACE_CONT: /* restart after signal. */
- ret = -EIO;
- if (!valid_signal(data))
- break;
- if (request == PTRACE_SYSCALL)
- set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- else
- clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- child->exit_code = data;
- ptrace_disable(child);
- wake_up_process(child);
- ret = 0;
- break;
-
- /* make the child exit. Best I can do is send it a sigkill.
- * perhaps it should be put in the status that it wants to
- * exit.
- */
- case PTRACE_KILL:
- ret = 0;
- if (child->exit_state == EXIT_ZOMBIE) /* already dead */
+ if (addr & 3)
break;
- child->exit_code = SIGKILL;
- clear_tsk_thread_flag(child, TIF_SINGLESTEP);
- ptrace_disable(child);
- wake_up_process(child);
- break;
- case PTRACE_SINGLESTEP: /* set the trap flag. */
- ret = -EIO;
- if (!valid_signal(data))
+ switch (regno) {
+ case 0 ... PT__END - 1:
+ ret = put_reg(child, regno, data);
break;
- clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- ptrace_enable(child);
- child->exit_code = data;
- wake_up_process(child);
- ret = 0;
- break;
-
- case PTRACE_DETACH: /* detach a process that was attached. */
- ret = ptrace_detach(child, data);
- break;
-
- case PTRACE_GETREGS: { /* Get all integer regs from the child. */
- int i;
- for (i = 0; i < PT__GPEND; i++) {
- tmp = get_reg(child, i);
- if (put_user(tmp, (unsigned long *) data)) {
- ret = -EFAULT;
- break;
- }
- data += sizeof(long);
- }
- ret = 0;
- break;
- }
-
- case PTRACE_SETREGS: { /* Set all integer regs in the child. */
- int i;
- for (i = 0; i < PT__GPEND; i++) {
- if (get_user(tmp, (unsigned long *) data)) {
- ret = -EFAULT;
- break;
- }
- put_reg(child, i, tmp);
- data += sizeof(long);
}
- ret = 0;
- break;
- }
-
- case PTRACE_GETFPREGS: { /* Get the child FP/Media state. */
- ret = 0;
- if (copy_to_user((void *) data,
- &child->thread.user->f,
- sizeof(child->thread.user->f)))
- ret = -EFAULT;
- break;
- }
-
- case PTRACE_SETFPREGS: { /* Set the child FP/Media state. */
- ret = 0;
- if (copy_from_user(&child->thread.user->f,
- (void *) data,
- sizeof(child->thread.user->f)))
- ret = -EFAULT;
break;
- }
-
- case PTRACE_GETFDPIC:
- tmp = 0;
- switch (addr) {
- case PTRACE_GETFDPIC_EXEC:
- tmp = child->mm->context.exec_fdpic_loadmap;
- break;
- case PTRACE_GETFDPIC_INTERP:
- tmp = child->mm->context.interp_fdpic_loadmap;
- break;
- default:
- break;
- }
- ret = 0;
- if (put_user(tmp, (unsigned long *) data)) {
- ret = -EFAULT;
- break;
- }
- break;
+ case PTRACE_GETREGS: /* Get all integer regs from the child. */
+ return copy_regset_to_user(child, &user_frv_native_view,
+ REGSET_GENERAL,
+ 0, sizeof(child->thread.user->i),
+ datap);
+
+ case PTRACE_SETREGS: /* Set all integer regs in the child. */
+ return copy_regset_from_user(child, &user_frv_native_view,
+ REGSET_GENERAL,
+ 0, sizeof(child->thread.user->i),
+ datap);
+
+ case PTRACE_GETFPREGS: /* Get the child FP/Media state. */
+ return copy_regset_to_user(child, &user_frv_native_view,
+ REGSET_FPMEDIA,
+ 0, sizeof(child->thread.user->f),
+ datap);
+
+ case PTRACE_SETFPREGS: /* Set the child FP/Media state. */
+ return copy_regset_from_user(child, &user_frv_native_view,
+ REGSET_FPMEDIA,
+ 0, sizeof(child->thread.user->f),
+ datap);
default:
- ret = -EIO;
+ ret = ptrace_request(child, request, addr, data);
break;
}
return ret;
}
-int __nongprelbss kstrace;
-
-static const struct {
- const char *name;
- unsigned argmask;
-} __syscall_name_table[NR_syscalls] = {
- [0] = { "restart_syscall" },
- [1] = { "exit", 0x000001 },
- [2] = { "fork", 0xffffff },
- [3] = { "read", 0x000141 },
- [4] = { "write", 0x000141 },
- [5] = { "open", 0x000235 },
- [6] = { "close", 0x000001 },
- [7] = { "waitpid", 0x000141 },
- [8] = { "creat", 0x000025 },
- [9] = { "link", 0x000055 },
- [10] = { "unlink", 0x000005 },
- [11] = { "execve", 0x000445 },
- [12] = { "chdir", 0x000005 },
- [13] = { "time", 0x000004 },
- [14] = { "mknod", 0x000325 },
- [15] = { "chmod", 0x000025 },
- [16] = { "lchown", 0x000025 },
- [17] = { "break" },
- [18] = { "oldstat", 0x000045 },
- [19] = { "lseek", 0x000131 },
- [20] = { "getpid", 0xffffff },
- [21] = { "mount", 0x043555 },
- [22] = { "umount", 0x000005 },
- [23] = { "setuid", 0x000001 },
- [24] = { "getuid", 0xffffff },
- [25] = { "stime", 0x000004 },
- [26] = { "ptrace", 0x004413 },
- [27] = { "alarm", 0x000001 },
- [28] = { "oldfstat", 0x000041 },
- [29] = { "pause", 0xffffff },
- [30] = { "utime", 0x000045 },
- [31] = { "stty" },
- [32] = { "gtty" },
- [33] = { "access", 0x000025 },
- [34] = { "nice", 0x000001 },
- [35] = { "ftime" },
- [36] = { "sync", 0xffffff },
- [37] = { "kill", 0x000011 },
- [38] = { "rename", 0x000055 },
- [39] = { "mkdir", 0x000025 },
- [40] = { "rmdir", 0x000005 },
- [41] = { "dup", 0x000001 },
- [42] = { "pipe", 0x000004 },
- [43] = { "times", 0x000004 },
- [44] = { "prof" },
- [45] = { "brk", 0x000004 },
- [46] = { "setgid", 0x000001 },
- [47] = { "getgid", 0xffffff },
- [48] = { "signal", 0x000041 },
- [49] = { "geteuid", 0xffffff },
- [50] = { "getegid", 0xffffff },
- [51] = { "acct", 0x000005 },
- [52] = { "umount2", 0x000035 },
- [53] = { "lock" },
- [54] = { "ioctl", 0x000331 },
- [55] = { "fcntl", 0x000331 },
- [56] = { "mpx" },
- [57] = { "setpgid", 0x000011 },
- [58] = { "ulimit" },
- [60] = { "umask", 0x000002 },
- [61] = { "chroot", 0x000005 },
- [62] = { "ustat", 0x000043 },
- [63] = { "dup2", 0x000011 },
- [64] = { "getppid", 0xffffff },
- [65] = { "getpgrp", 0xffffff },
- [66] = { "setsid", 0xffffff },
- [67] = { "sigaction" },
- [68] = { "sgetmask" },
- [69] = { "ssetmask" },
- [70] = { "setreuid" },
- [71] = { "setregid" },
- [72] = { "sigsuspend" },
- [73] = { "sigpending" },
- [74] = { "sethostname" },
- [75] = { "setrlimit" },
- [76] = { "getrlimit" },
- [77] = { "getrusage" },
- [78] = { "gettimeofday" },
- [79] = { "settimeofday" },
- [80] = { "getgroups" },
- [81] = { "setgroups" },
- [82] = { "select" },
- [83] = { "symlink" },
- [84] = { "oldlstat" },
- [85] = { "readlink" },
- [86] = { "uselib" },
- [87] = { "swapon" },
- [88] = { "reboot" },
- [89] = { "readdir" },
- [91] = { "munmap", 0x000034 },
- [92] = { "truncate" },
- [93] = { "ftruncate" },
- [94] = { "fchmod" },
- [95] = { "fchown" },
- [96] = { "getpriority" },
- [97] = { "setpriority" },
- [99] = { "statfs" },
- [100] = { "fstatfs" },
- [102] = { "socketcall" },
- [103] = { "syslog" },
- [104] = { "setitimer" },
- [105] = { "getitimer" },
- [106] = { "stat" },
- [107] = { "lstat" },
- [108] = { "fstat" },
- [111] = { "vhangup" },
- [114] = { "wait4" },
- [115] = { "swapoff" },
- [116] = { "sysinfo" },
- [117] = { "ipc" },
- [118] = { "fsync" },
- [119] = { "sigreturn" },
- [120] = { "clone" },
- [121] = { "setdomainname" },
- [122] = { "uname" },
- [123] = { "modify_ldt" },
- [123] = { "cacheflush" },
- [124] = { "adjtimex" },
- [125] = { "mprotect" },
- [126] = { "sigprocmask" },
- [127] = { "create_module" },
- [128] = { "init_module" },
- [129] = { "delete_module" },
- [130] = { "get_kernel_syms" },
- [131] = { "quotactl" },
- [132] = { "getpgid" },
- [133] = { "fchdir" },
- [134] = { "bdflush" },
- [135] = { "sysfs" },
- [136] = { "personality" },
- [137] = { "afs_syscall" },
- [138] = { "setfsuid" },
- [139] = { "setfsgid" },
- [140] = { "_llseek", 0x014331 },
- [141] = { "getdents" },
- [142] = { "_newselect", 0x000141 },
- [143] = { "flock" },
- [144] = { "msync" },
- [145] = { "readv" },
- [146] = { "writev" },
- [147] = { "getsid", 0x000001 },
- [148] = { "fdatasync", 0x000001 },
- [149] = { "_sysctl", 0x000004 },
- [150] = { "mlock" },
- [151] = { "munlock" },
- [152] = { "mlockall" },
- [153] = { "munlockall" },
- [154] = { "sched_setparam" },
- [155] = { "sched_getparam" },
- [156] = { "sched_setscheduler" },
- [157] = { "sched_getscheduler" },
- [158] = { "sched_yield" },
- [159] = { "sched_get_priority_max" },
- [160] = { "sched_get_priority_min" },
- [161] = { "sched_rr_get_interval" },
- [162] = { "nanosleep", 0x000044 },
- [163] = { "mremap" },
- [164] = { "setresuid" },
- [165] = { "getresuid" },
- [166] = { "vm86" },
- [167] = { "query_module" },
- [168] = { "poll" },
- [169] = { "nfsservctl" },
- [170] = { "setresgid" },
- [171] = { "getresgid" },
- [172] = { "prctl", 0x333331 },
- [173] = { "rt_sigreturn", 0xffffff },
- [174] = { "rt_sigaction", 0x001441 },
- [175] = { "rt_sigprocmask", 0x001441 },
- [176] = { "rt_sigpending", 0x000014 },
- [177] = { "rt_sigtimedwait", 0x001444 },
- [178] = { "rt_sigqueueinfo", 0x000411 },
- [179] = { "rt_sigsuspend", 0x000014 },
- [180] = { "pread", 0x003341 },
- [181] = { "pwrite", 0x003341 },
- [182] = { "chown", 0x000115 },
- [183] = { "getcwd" },
- [184] = { "capget" },
- [185] = { "capset" },
- [186] = { "sigaltstack" },
- [187] = { "sendfile" },
- [188] = { "getpmsg" },
- [189] = { "putpmsg" },
- [190] = { "vfork", 0xffffff },
- [191] = { "ugetrlimit" },
- [192] = { "mmap2", 0x313314 },
- [193] = { "truncate64" },
- [194] = { "ftruncate64" },
- [195] = { "stat64", 0x000045 },
- [196] = { "lstat64", 0x000045 },
- [197] = { "fstat64", 0x000041 },
- [198] = { "lchown32" },
- [199] = { "getuid32", 0xffffff },
- [200] = { "getgid32", 0xffffff },
- [201] = { "geteuid32", 0xffffff },
- [202] = { "getegid32", 0xffffff },
- [203] = { "setreuid32" },
- [204] = { "setregid32" },
- [205] = { "getgroups32" },
- [206] = { "setgroups32" },
- [207] = { "fchown32" },
- [208] = { "setresuid32" },
- [209] = { "getresuid32" },
- [210] = { "setresgid32" },
- [211] = { "getresgid32" },
- [212] = { "chown32" },
- [213] = { "setuid32" },
- [214] = { "setgid32" },
- [215] = { "setfsuid32" },
- [216] = { "setfsgid32" },
- [217] = { "pivot_root" },
- [218] = { "mincore" },
- [219] = { "madvise" },
- [220] = { "getdents64" },
- [221] = { "fcntl64" },
- [223] = { "security" },
- [224] = { "gettid" },
- [225] = { "readahead" },
- [226] = { "setxattr" },
- [227] = { "lsetxattr" },
- [228] = { "fsetxattr" },
- [229] = { "getxattr" },
- [230] = { "lgetxattr" },
- [231] = { "fgetxattr" },
- [232] = { "listxattr" },
- [233] = { "llistxattr" },
- [234] = { "flistxattr" },
- [235] = { "removexattr" },
- [236] = { "lremovexattr" },
- [237] = { "fremovexattr" },
- [238] = { "tkill" },
- [239] = { "sendfile64" },
- [240] = { "futex" },
- [241] = { "sched_setaffinity" },
- [242] = { "sched_getaffinity" },
- [243] = { "set_thread_area" },
- [244] = { "get_thread_area" },
- [245] = { "io_setup" },
- [246] = { "io_destroy" },
- [247] = { "io_getevents" },
- [248] = { "io_submit" },
- [249] = { "io_cancel" },
- [250] = { "fadvise64" },
- [252] = { "exit_group", 0x000001 },
- [253] = { "lookup_dcookie" },
- [254] = { "epoll_create" },
- [255] = { "epoll_ctl" },
- [256] = { "epoll_wait" },
- [257] = { "remap_file_pages" },
- [258] = { "set_tid_address" },
- [259] = { "timer_create" },
- [260] = { "timer_settime" },
- [261] = { "timer_gettime" },
- [262] = { "timer_getoverrun" },
- [263] = { "timer_delete" },
- [264] = { "clock_settime" },
- [265] = { "clock_gettime" },
- [266] = { "clock_getres" },
- [267] = { "clock_nanosleep" },
- [268] = { "statfs64" },
- [269] = { "fstatfs64" },
- [270] = { "tgkill" },
- [271] = { "utimes" },
- [272] = { "fadvise64_64" },
- [273] = { "vserver" },
- [274] = { "mbind" },
- [275] = { "get_mempolicy" },
- [276] = { "set_mempolicy" },
- [277] = { "mq_open" },
- [278] = { "mq_unlink" },
- [279] = { "mq_timedsend" },
- [280] = { "mq_timedreceive" },
- [281] = { "mq_notify" },
- [282] = { "mq_getsetattr" },
- [283] = { "sys_kexec_load" },
-};
-
-asmlinkage void do_syscall_trace(int leaving)
+/*
+ * handle tracing of system call entry
+ * - return the revised system call number or ULONG_MAX to cause ENOSYS
+ */
+asmlinkage unsigned long syscall_trace_entry(void)
{
-#if 0
- unsigned long *argp;
- const char *name;
- unsigned argmask;
- char buffer[16];
-
- if (!kstrace)
- return;
-
- if (!current->mm)
- return;
-
- if (__frame->gr7 == __NR_close)
- return;
-
-#if 0
- if (__frame->gr7 != __NR_mmap2 &&
- __frame->gr7 != __NR_vfork &&
- __frame->gr7 != __NR_execve &&
- __frame->gr7 != __NR_exit)
- return;
-#endif
-
- argmask = 0;
- name = NULL;
- if (__frame->gr7 < NR_syscalls) {
- name = __syscall_name_table[__frame->gr7].name;
- argmask = __syscall_name_table[__frame->gr7].argmask;
- }
- if (!name) {
- sprintf(buffer, "sys_%lx", __frame->gr7);
- name = buffer;
- }
-
- if (!leaving) {
- if (!argmask) {
- printk(KERN_CRIT "[%d] %s(%lx,%lx,%lx,%lx,%lx,%lx)\n",
- current->pid,
- name,
- __frame->gr8,
- __frame->gr9,
- __frame->gr10,
- __frame->gr11,
- __frame->gr12,
- __frame->gr13);
- }
- else if (argmask == 0xffffff) {
- printk(KERN_CRIT "[%d] %s()\n",
- current->pid,
- name);
- }
- else {
- printk(KERN_CRIT "[%d] %s(",
- current->pid,
- name);
-
- argp = &__frame->gr8;
-
- do {
- switch (argmask & 0xf) {
- case 1:
- printk("%ld", (long) *argp);
- break;
- case 2:
- printk("%lo", *argp);
- break;
- case 3:
- printk("%lx", *argp);
- break;
- case 4:
- printk("%p", (void *) *argp);
- break;
- case 5:
- printk("\"%s\"", (char *) *argp);
- break;
- }
-
- argp++;
- argmask >>= 4;
- if (argmask)
- printk(",");
-
- } while (argmask);
-
- printk(")\n");
- }
- }
- else {
- if ((int)__frame->gr8 > -4096 && (int)__frame->gr8 < 4096)
- printk(KERN_CRIT "[%d] %s() = %ld\n", current->pid, name, __frame->gr8);
- else
- printk(KERN_CRIT "[%d] %s() = %lx\n", current->pid, name, __frame->gr8);
+ __frame->__status |= REG__STATUS_SYSC_ENTRY;
+ if (tracehook_report_syscall_entry(__frame)) {
+ /* tracing decided this syscall should not happen, so
+ * We'll return a bogus call number to get an ENOSYS
+ * error, but leave the original number in
+ * __frame->syscallno
+ */
+ return ULONG_MAX;
}
- return;
-#endif
- if (!test_thread_flag(TIF_SYSCALL_TRACE))
- return;
-
- if (!(current->ptrace & PT_PTRACED))
- return;
-
- /* we need to indicate entry or exit to strace */
- if (leaving)
- __frame->__status |= REG__STATUS_SYSC_EXIT;
- else
- __frame->__status |= REG__STATUS_SYSC_ENTRY;
-
- ptrace_notify(SIGTRAP);
+ return __frame->syscallno;
+}
- /*
- * this isn't the same as continuing with a signal, but it will do
- * for normal use. strace only continues with a signal if the
- * stopping signal is not SIGTRAP. -brl
- */
- if (current->exit_code) {
- send_sig(current->exit_code, current, 1);
- current->exit_code = 0;
- }
+/*
+ * handle tracing of system call exit
+ */
+asmlinkage void syscall_trace_exit(void)
+{
+ __frame->__status |= REG__STATUS_SYSC_EXIT;
+ tracehook_report_syscall_exit(__frame, 0);
}
diff --git a/arch/frv/kernel/semaphore.c b/arch/frv/kernel/semaphore.c
deleted file mode 100644
index 7971d680ae2..00000000000
--- a/arch/frv/kernel/semaphore.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/* semaphore.c: FR-V semaphores
- *
- * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- * - Derived from lib/rwsem-spinlock.c
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include <linux/config.h>
-#include <linux/sched.h>
-#include <linux/module.h>
-#include <asm/semaphore.h>
-
-struct sem_waiter {
- struct list_head list;
- struct task_struct *task;
-};
-
-#if SEMAPHORE_DEBUG
-void semtrace(struct semaphore *sem, const char *str)
-{
- if (sem->debug)
- printk("[%d] %s({%d,%d})\n",
- current->pid,
- str,
- sem->counter,
- list_empty(&sem->wait_list) ? 0 : 1);
-}
-#else
-#define semtrace(SEM,STR) do { } while(0)
-#endif
-
-/*
- * wait for a token to be granted from a semaphore
- * - entered with lock held and interrupts disabled
- */
-void __down(struct semaphore *sem, unsigned long flags)
-{
- struct task_struct *tsk = current;
- struct sem_waiter waiter;
-
- semtrace(sem, "Entering __down");
-
- /* set up my own style of waitqueue */
- waiter.task = tsk;
- get_task_struct(tsk);
-
- list_add_tail(&waiter.list, &sem->wait_list);
-
- /* we don't need to touch the semaphore struct anymore */
- spin_unlock_irqrestore(&sem->wait_lock, flags);
-
- /* wait to be given the semaphore */
- set_task_state(tsk, TASK_UNINTERRUPTIBLE);
-
- for (;;) {
- if (list_empty(&waiter.list))
- break;
- schedule();
- set_task_state(tsk, TASK_UNINTERRUPTIBLE);
- }
-
- tsk->state = TASK_RUNNING;
- semtrace(sem, "Leaving __down");
-}
-
-EXPORT_SYMBOL(__down);
-
-/*
- * interruptibly wait for a token to be granted from a semaphore
- * - entered with lock held and interrupts disabled
- */
-int __down_interruptible(struct semaphore *sem, unsigned long flags)
-{
- struct task_struct *tsk = current;
- struct sem_waiter waiter;
- int ret;
-
- semtrace(sem,"Entering __down_interruptible");
-
- /* set up my own style of waitqueue */
- waiter.task = tsk;
- get_task_struct(tsk);
-
- list_add_tail(&waiter.list, &sem->wait_list);
-
- /* we don't need to touch the semaphore struct anymore */
- set_task_state(tsk, TASK_INTERRUPTIBLE);
-
- spin_unlock_irqrestore(&sem->wait_lock, flags);
-
- /* wait to be given the semaphore */
- ret = 0;
- for (;;) {
- if (list_empty(&waiter.list))
- break;
- if (unlikely(signal_pending(current)))
- goto interrupted;
- schedule();
- set_task_state(tsk, TASK_INTERRUPTIBLE);
- }
-
- out:
- tsk->state = TASK_RUNNING;
- semtrace(sem, "Leaving __down_interruptible");
- return ret;
-
- interrupted:
- spin_lock_irqsave(&sem->wait_lock, flags);
-
- if (!list_empty(&waiter.list)) {
- list_del(&waiter.list);
- ret = -EINTR;
- }
-
- spin_unlock_irqrestore(&sem->wait_lock, flags);
- if (ret == -EINTR)
- put_task_struct(current);
- goto out;
-}
-
-EXPORT_SYMBOL(__down_interruptible);
-
-/*
- * release a single token back to a semaphore
- * - entered with lock held and interrupts disabled
- */
-void __up(struct semaphore *sem)
-{
- struct task_struct *tsk;
- struct sem_waiter *waiter;
-
- semtrace(sem,"Entering __up");
-
- /* grant the token to the process at the front of the queue */
- waiter = list_entry(sem->wait_list.next, struct sem_waiter, list);
-
- /* We must be careful not to touch 'waiter' after we set ->task = NULL.
- * It is an allocated on the waiter's stack and may become invalid at
- * any time after that point (due to a wakeup from another source).
- */
- list_del_init(&waiter->list);
- tsk = waiter->task;
- mb();
- waiter->task = NULL;
- wake_up_process(tsk);
- put_task_struct(tsk);
-
- semtrace(sem,"Leaving __up");
-}
-
-EXPORT_SYMBOL(__up);
diff --git a/arch/frv/kernel/setup.c b/arch/frv/kernel/setup.c
index 5908deae960..9f3a7a62d78 100644
--- a/arch/frv/kernel/setup.c
+++ b/arch/frv/kernel/setup.c
@@ -10,8 +10,7 @@
* 2 of the License, or (at your option) any later version.
*/
-#include <linux/config.h>
-#include <linux/version.h>
+#include <generated/utsrelease.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/delay.h>
@@ -30,9 +29,9 @@
#include <linux/serial.h>
#include <linux/serial_core.h>
#include <linux/serial_reg.h>
+#include <linux/serial_8250.h>
#include <asm/setup.h>
-#include <asm/serial.h>
#include <asm/irq.h>
#include <asm/sections.h>
#include <asm/pgalloc.h>
@@ -44,11 +43,9 @@
#include <asm/mb-regs.h>
#include <asm/mb93493-regs.h>
#include <asm/gdb-stub.h>
-#include <asm/irq-routing.h>
#include <asm/io.h>
#ifdef CONFIG_BLK_DEV_INITRD
-#include <linux/blk.h>
#include <asm/pgtable.h>
#endif
@@ -63,10 +60,6 @@ static void __init setup_linux_memory(void);
static void __init setup_uclinux_memory(void);
#endif
-#ifdef CONFIG_CONSOLE
-extern struct consw *conswitchp;
-#endif
-
#ifdef CONFIG_MB93090_MB00
static char __initdata mb93090_banner[] = "FJ/RH FR-V Linux";
static char __initdata mb93090_version[] = UTS_RELEASE;
@@ -113,15 +106,17 @@ unsigned long __initdata num_mappedpages;
struct cpuinfo_frv __nongprelbss boot_cpu_data;
-char command_line[COMMAND_LINE_SIZE];
+char __initdata command_line[COMMAND_LINE_SIZE];
char __initdata redboot_command_line[COMMAND_LINE_SIZE];
#ifdef CONFIG_PM
#define __pminit
#define __pminitdata
+#define __pminitconst
#else
#define __pminit __init
#define __pminitdata __initdata
+#define __pminitconst __initconst
#endif
struct clock_cmode {
@@ -191,10 +186,10 @@ static struct clock_cmode __pminitdata clock_cmodes_fr555[16] = {
[6] = { _x1, _x1_5, _x1_5, _x4_5, _x0_375 },
};
-static const struct clock_cmode __pminitdata *clock_cmodes;
+static const struct clock_cmode __pminitconst *clock_cmodes;
static int __pminitdata clock_doubled;
-static struct uart_port __initdata __frv_uart0 = {
+static struct uart_port __pminitdata __frv_uart0 = {
.uartclk = 0,
.membase = (char *) UART0_BASE,
.irq = IRQ_CPU_UART0,
@@ -203,7 +198,7 @@ static struct uart_port __initdata __frv_uart0 = {
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
};
-static struct uart_port __initdata __frv_uart1 = {
+static struct uart_port __pminitdata __frv_uart1 = {
.uartclk = 0,
.membase = (char *) UART1_BASE,
.irq = IRQ_CPU_UART1,
@@ -714,7 +709,7 @@ static void __init reserve_dma_coherent(void)
/*
* calibrate the delay loop
*/
-void __init calibrate_delay(void)
+void calibrate_delay(void)
{
loops_per_jiffy = __delay_loops_MHz * (1000000 / HZ);
@@ -740,7 +735,7 @@ static void __init parse_cmdline_early(char *cmdline)
/* "mem=XXX[kKmM]" sets SDRAM size to <mem>, overriding the value we worked
* out from the SDRAM controller mask register
*/
- if (!memcmp(cmdline, "mem=", 4)) {
+ if (!strncmp(cmdline, "mem=", 4)) {
unsigned long long mem_size;
mem_size = memparse(cmdline + 4, &cmdline);
@@ -765,7 +760,7 @@ void __init setup_arch(char **cmdline_p)
printk("uClinux FR-V port done by Red Hat Inc <dhowells@redhat.com>\n");
#endif
- memcpy(saved_command_line, redboot_command_line, COMMAND_LINE_SIZE);
+ memcpy(boot_command_line, redboot_command_line, COMMAND_LINE_SIZE);
determine_cpu();
determine_clocks(1);
@@ -798,15 +793,8 @@ void __init setup_arch(char **cmdline_p)
#endif
#endif
-#if defined(CONFIG_CHR_DEV_FLASH) || defined(CONFIG_BLK_DEV_FLASH)
- /* we need to initialize the Flashrom device here since we might
- * do things with flash early on in the boot
- */
- flash_probe();
-#endif
-
/* deal with the command line - RedBoot may have passed one to the kernel */
- memcpy(command_line, saved_command_line, sizeof(command_line));
+ memcpy(command_line, boot_command_line, sizeof(command_line));
*cmdline_p = &command_line[0];
parse_cmdline_early(command_line);
@@ -814,11 +802,11 @@ void __init setup_arch(char **cmdline_p)
* - by now the stack is part of the init task */
printk("Memory %08lx-%08lx\n", memory_start, memory_end);
- if (memory_start == memory_end) BUG();
+ BUG_ON(memory_start == memory_end);
- init_mm.start_code = (unsigned long) &_stext;
- init_mm.end_code = (unsigned long) &_etext;
- init_mm.end_data = (unsigned long) &_edata;
+ init_mm.start_code = (unsigned long) _stext;
+ init_mm.end_code = (unsigned long) _etext;
+ init_mm.end_data = (unsigned long) _edata;
#if 0 /* DAVIDM - don't set brk just incase someone decides to use it */
init_mm.brk = (unsigned long) &_end;
#else
@@ -826,10 +814,8 @@ void __init setup_arch(char **cmdline_p)
#endif
#ifdef DEBUG
- printk("KERNEL -> TEXT=0x%06x-0x%06x DATA=0x%06x-0x%06x BSS=0x%06x-0x%06x\n",
- (int) &_stext, (int) &_etext,
- (int) &_sdata, (int) &_edata,
- (int) &_sbss, (int) &_ebss);
+ printk("KERNEL -> TEXT=0x%p-0x%p DATA=0x%p-0x%p BSS=0x%p-0x%p\n",
+ _stext, _etext, _sdata, _edata, __bss_start, __bss_stop);
#endif
#ifdef CONFIG_VT
@@ -840,11 +826,6 @@ void __init setup_arch(char **cmdline_p)
#endif
#endif
-#ifdef CONFIG_BLK_DEV_BLKMEM
- ROOT_DEV = MKDEV(BLKMEM_MAJOR,0);
-#endif
- /*rom_length = (unsigned long)&_flashend - (unsigned long)&_romvec;*/
-
#ifdef CONFIG_MMU
setup_linux_memory();
#else
@@ -871,7 +852,7 @@ void __init setup_arch(char **cmdline_p)
/*
*
*/
-static int __devinit setup_arch_serial(void)
+static int setup_arch_serial(void)
{
/* register those serial ports that are available */
#ifndef CONFIG_GDBSTUB_UART0
@@ -895,6 +876,7 @@ late_initcall(setup_arch_serial);
static void __init setup_linux_memory(void)
{
unsigned long bootmap_size, low_top_pfn, kstart, kend, high_mem;
+ unsigned long physpages;
kstart = (unsigned long) &__kernel_image_start - PAGE_OFFSET;
kend = (unsigned long) &__kernel_image_end - PAGE_OFFSET;
@@ -912,19 +894,19 @@ static void __init setup_linux_memory(void)
);
/* pass the memory that the kernel can immediately use over to the bootmem allocator */
- max_mapnr = num_physpages = (memory_end - memory_start) >> PAGE_SHIFT;
+ max_mapnr = physpages = (memory_end - memory_start) >> PAGE_SHIFT;
low_top_pfn = (KERNEL_LOWMEM_END - KERNEL_LOWMEM_START) >> PAGE_SHIFT;
high_mem = 0;
- if (num_physpages > low_top_pfn) {
+ if (physpages > low_top_pfn) {
#ifdef CONFIG_HIGHMEM
- high_mem = num_physpages - low_top_pfn;
+ high_mem = physpages - low_top_pfn;
#else
- max_mapnr = num_physpages = low_top_pfn;
+ max_mapnr = physpages = low_top_pfn;
#endif
}
else {
- low_top_pfn = num_physpages;
+ low_top_pfn = physpages;
}
min_low_pfn = memory_start >> PAGE_SHIFT;
@@ -943,14 +925,16 @@ static void __init setup_linux_memory(void)
#endif
/* take back the memory occupied by the kernel image and the bootmem alloc map */
- reserve_bootmem(kstart, kend - kstart + bootmap_size);
+ reserve_bootmem(kstart, kend - kstart + bootmap_size,
+ BOOTMEM_DEFAULT);
/* reserve the memory occupied by the initial ramdisk */
#ifdef CONFIG_BLK_DEV_INITRD
if (LOADER_TYPE && INITRD_START) {
if (INITRD_START + INITRD_SIZE <= (low_top_pfn << PAGE_SHIFT)) {
- reserve_bootmem(INITRD_START, INITRD_SIZE);
- initrd_start = INITRD_START ? INITRD_START + PAGE_OFFSET : 0;
+ reserve_bootmem(INITRD_START, INITRD_SIZE,
+ BOOTMEM_DEFAULT);
+ initrd_start = INITRD_START + PAGE_OFFSET;
initrd_end = initrd_start + INITRD_SIZE;
}
else {
@@ -996,7 +980,7 @@ static void __init setup_uclinux_memory(void)
free_bootmem(memory_start, memory_end - memory_start);
high_memory = (void *) (memory_end & PAGE_MASK);
- max_mapnr = num_physpages = ((unsigned long) high_memory - PAGE_OFFSET) >> PAGE_SHIFT;
+ max_mapnr = ((unsigned long) high_memory - PAGE_OFFSET) >> PAGE_SHIFT;
min_low_pfn = memory_start >> PAGE_SHIFT;
max_low_pfn = memory_end >> PAGE_SHIFT;
@@ -1004,9 +988,10 @@ static void __init setup_uclinux_memory(void)
/* now take back the bits the core kernel is occupying */
#ifndef CONFIG_PROTECT_KERNEL
- reserve_bootmem(kend, bootmap_size);
+ reserve_bootmem(kend, bootmap_size, BOOTMEM_DEFAULT);
reserve_bootmem((unsigned long) &__kernel_image_start,
- kend - (unsigned long) &__kernel_image_start);
+ kend - (unsigned long) &__kernel_image_start,
+ BOOTMEM_DEFAULT);
#else
dampr = __get_DAMPR(0);
@@ -1014,14 +999,15 @@ static void __init setup_uclinux_memory(void)
dampr = (dampr >> 4) + 17;
dampr = 1 << dampr;
- reserve_bootmem(__get_DAMPR(0) & xAMPRx_PPFN, dampr);
+ reserve_bootmem(__get_DAMPR(0) & xAMPRx_PPFN, dampr, BOOTMEM_DEFAULT);
#endif
/* reserve some memory to do uncached DMA through if requested */
#ifdef CONFIG_RESERVE_DMA_COHERENT
if (dma_coherent_mem_start)
reserve_bootmem(dma_coherent_mem_start,
- dma_coherent_mem_end - dma_coherent_mem_start);
+ dma_coherent_mem_end - dma_coherent_mem_start,
+ BOOTMEM_DEFAULT);
#endif
} /* end setup_uclinux_memory() */
@@ -1127,7 +1113,7 @@ static void c_stop(struct seq_file *m, void *v)
{
}
-struct seq_operations cpuinfo_op = {
+const struct seq_operations cpuinfo_op = {
.start = c_start,
.next = c_next,
.stop = c_stop,
diff --git a/arch/frv/kernel/signal.c b/arch/frv/kernel/signal.c
index 679c1d5cc95..d822700d4f1 100644
--- a/arch/frv/kernel/signal.c
+++ b/arch/frv/kernel/signal.c
@@ -13,7 +13,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
@@ -21,84 +20,25 @@
#include <linux/ptrace.h>
#include <linux/unistd.h>
#include <linux/personality.h>
-#include <linux/suspend.h>
+#include <linux/tracehook.h>
#include <asm/ucontext.h>
#include <asm/uaccess.h>
#include <asm/cacheflush.h>
#define DEBUG_SIG 0
-#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
-
struct fdpic_func_descriptor {
unsigned long text;
unsigned long GOT;
};
/*
- * Atomically swap in the new signal mask, and wait for a signal.
- */
-asmlinkage int sys_sigsuspend(int history0, int history1, old_sigset_t mask)
-{
- mask &= _BLOCKABLE;
- spin_lock_irq(&current->sighand->siglock);
- current->saved_sigmask = current->blocked;
- siginitset(&current->blocked, mask);
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
-
- current->state = TASK_INTERRUPTIBLE;
- schedule();
- set_thread_flag(TIF_RESTORE_SIGMASK);
- return -ERESTARTNOHAND;
-}
-
-asmlinkage int sys_sigaction(int sig,
- const struct old_sigaction __user *act,
- struct old_sigaction __user *oact)
-{
- struct k_sigaction new_ka, old_ka;
- int ret;
-
- if (act) {
- old_sigset_t mask;
- if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
- __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
- __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
- return -EFAULT;
- __get_user(new_ka.sa.sa_flags, &act->sa_flags);
- __get_user(mask, &act->sa_mask);
- siginitset(&new_ka.sa.sa_mask, mask);
- }
-
- ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
-
- if (!ret && oact) {
- if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
- __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
- __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
- return -EFAULT;
- __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
- __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
- }
-
- return ret;
-}
-
-asmlinkage
-int sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss)
-{
- return do_sigaltstack(uss, uoss, __frame->sp);
-}
-
-
-/*
* Do a signal return; undo the signal stack.
*/
struct sigframe
{
- void (*pretcode)(void);
+ __sigrestore_t pretcode;
int sig;
struct sigcontext sc;
unsigned long extramask[_NSIG_WORDS-1];
@@ -107,10 +47,10 @@ struct sigframe
struct rt_sigframe
{
- void (*pretcode)(void);
+ __sigrestore_t pretcode;
int sig;
- struct siginfo *pinfo;
- void *puc;
+ struct siginfo __user *pinfo;
+ void __user *puc;
struct siginfo info;
struct ucontext uc;
uint32_t retcode[2];
@@ -121,6 +61,9 @@ static int restore_sigcontext(struct sigcontext __user *sc, int *_gr8)
struct user_context *user = current->thread.user;
unsigned long tbr, psr;
+ /* Always make any pending restarted system calls return -EINTR */
+ current_thread_info()->restart_block.fn = do_no_restart_syscall;
+
tbr = user->i.tbr;
psr = user->i.psr;
if (copy_from_user(user, &sc->sc_context, sizeof(sc->sc_context)))
@@ -154,11 +97,7 @@ asmlinkage int sys_sigreturn(void)
__copy_from_user(&set.sig[1], &frame->extramask, sizeof(frame->extramask)))
goto badframe;
- sigdelsetmask(&set, ~_BLOCKABLE);
- spin_lock_irq(&current->sighand->siglock);
- current->blocked = set;
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
+ set_current_blocked(&set);
if (restore_sigcontext(&frame->sc, &gr8))
goto badframe;
@@ -180,16 +119,12 @@ asmlinkage int sys_rt_sigreturn(void)
if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
goto badframe;
- sigdelsetmask(&set, ~_BLOCKABLE);
- spin_lock_irq(&current->sighand->siglock);
- current->blocked = set;
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
+ set_current_blocked(&set);
if (restore_sigcontext(&frame->uc.uc_mcontext, &gr8))
goto badframe;
- if (do_sigaltstack(&frame->uc.uc_stack, NULL, __frame->sp) == -EFAULT)
+ if (restore_altstack(&frame->uc.uc_stack))
goto badframe;
return gr8;
@@ -233,7 +168,7 @@ static inline void __user *get_sigframe(struct k_sigaction *ka,
/* This is the X/Open sanctioned signal stack switching. */
if (ka->sa.sa_flags & SA_ONSTACK) {
- if (! on_sig_stack(sp))
+ if (! sas_ss_flags(sp))
sp = current->sas_ss_sp + current->sas_ss_size;
}
@@ -250,6 +185,8 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
struct sigframe __user *frame;
int rsig;
+ set_fs(USER_DS);
+
frame = get_sigframe(ka, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
@@ -284,7 +221,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
* setlos #__NR_sigreturn,gr7
* tira gr0,0
*/
- if (__put_user((void (*)(void))frame->retcode, &frame->pretcode) ||
+ if (__put_user((__sigrestore_t)frame->retcode, &frame->pretcode) ||
__put_user(0x8efc0000|__NR_sigreturn, &frame->retcode[0]) ||
__put_user(0xc0700000, &frame->retcode[1]))
goto give_sigsegv;
@@ -293,26 +230,23 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
(unsigned long) (frame->retcode + 2));
}
- /* set up registers for signal handler */
- __frame->sp = (unsigned long) frame;
- __frame->lr = (unsigned long) &frame->retcode;
- __frame->gr8 = sig;
-
- if (get_personality & FDPIC_FUNCPTRS) {
+ /* Set up registers for the signal handler */
+ if (current->personality & FDPIC_FUNCPTRS) {
struct fdpic_func_descriptor __user *funcptr =
- (struct fdpic_func_descriptor *) ka->sa.sa_handler;
- __get_user(__frame->pc, &funcptr->text);
- __get_user(__frame->gr15, &funcptr->GOT);
+ (struct fdpic_func_descriptor __user *) ka->sa.sa_handler;
+ struct fdpic_func_descriptor desc;
+ if (copy_from_user(&desc, funcptr, sizeof(desc)))
+ goto give_sigsegv;
+ __frame->pc = desc.text;
+ __frame->gr15 = desc.GOT;
} else {
__frame->pc = (unsigned long) ka->sa.sa_handler;
__frame->gr15 = 0;
}
- set_fs(USER_DS);
-
- /* the tracer may want to single-step inside the handler */
- if (test_thread_flag(TIF_SINGLESTEP))
- ptrace_notify(SIGTRAP);
+ __frame->sp = (unsigned long) frame;
+ __frame->lr = (unsigned long) &frame->retcode;
+ __frame->gr8 = sig;
#if DEBUG_SIG
printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
@@ -323,7 +257,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
return 0;
give_sigsegv:
- force_sig(SIGSEGV, current);
+ force_sigsegv(sig, current);
return -EFAULT;
} /* end setup_frame() */
@@ -338,6 +272,8 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
struct rt_sigframe __user *frame;
int rsig;
+ set_fs(USER_DS);
+
frame = get_sigframe(ka, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
@@ -359,10 +295,8 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
/* Create the ucontext. */
if (__put_user(0, &frame->uc.uc_flags) ||
- __put_user(0, &frame->uc.uc_link) ||
- __put_user((void*)current->sas_ss_sp, &frame->uc.uc_stack.ss_sp) ||
- __put_user(sas_ss_flags(__frame->sp), &frame->uc.uc_stack.ss_flags) ||
- __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size))
+ __put_user(NULL, &frame->uc.uc_link) ||
+ __save_altstack(&frame->uc.uc_stack, __frame->sp))
goto give_sigsegv;
if (setup_sigcontext(&frame->uc.uc_mcontext, set->sig[0]))
@@ -382,7 +316,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
* setlos #__NR_sigreturn,gr7
* tira gr0,0
*/
- if (__put_user((void (*)(void))frame->retcode, &frame->pretcode) ||
+ if (__put_user((__sigrestore_t)frame->retcode, &frame->pretcode) ||
__put_user(0x8efc0000|__NR_rt_sigreturn, &frame->retcode[0]) ||
__put_user(0xc0700000, &frame->retcode[1]))
goto give_sigsegv;
@@ -392,26 +326,23 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
}
/* Set up registers for signal handler */
- __frame->sp = (unsigned long) frame;
- __frame->lr = (unsigned long) &frame->retcode;
- __frame->gr8 = sig;
- __frame->gr9 = (unsigned long) &frame->info;
-
- if (get_personality & FDPIC_FUNCPTRS) {
- struct fdpic_func_descriptor *funcptr =
+ if (current->personality & FDPIC_FUNCPTRS) {
+ struct fdpic_func_descriptor __user *funcptr =
(struct fdpic_func_descriptor __user *) ka->sa.sa_handler;
- __get_user(__frame->pc, &funcptr->text);
- __get_user(__frame->gr15, &funcptr->GOT);
+ struct fdpic_func_descriptor desc;
+ if (copy_from_user(&desc, funcptr, sizeof(desc)))
+ goto give_sigsegv;
+ __frame->pc = desc.text;
+ __frame->gr15 = desc.GOT;
} else {
__frame->pc = (unsigned long) ka->sa.sa_handler;
__frame->gr15 = 0;
}
- set_fs(USER_DS);
-
- /* the tracer may want to single-step inside the handler */
- if (test_thread_flag(TIF_SINGLESTEP))
- ptrace_notify(SIGTRAP);
+ __frame->sp = (unsigned long) frame;
+ __frame->lr = (unsigned long) &frame->retcode;
+ __frame->gr8 = sig;
+ __frame->gr9 = (unsigned long) &frame->info;
#if DEBUG_SIG
printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
@@ -422,7 +353,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
return 0;
give_sigsegv:
- force_sig(SIGSEGV, current);
+ force_sigsegv(sig, current);
return -EFAULT;
} /* end setup_rt_frame() */
@@ -431,13 +362,14 @@ give_sigsegv:
/*
* OK, we're invoking a handler
*/
-static int handle_signal(unsigned long sig, siginfo_t *info,
- struct k_sigaction *ka, sigset_t *oldset)
+static void handle_signal(unsigned long sig, siginfo_t *info,
+ struct k_sigaction *ka)
{
+ sigset_t *oldset = sigmask_to_save();
int ret;
/* Are we from a system call? */
- if (in_syscall(__frame)) {
+ if (__frame->syscallno != -1) {
/* If so, check system call restarting.. */
switch (__frame->gr8) {
case -ERESTART_RESTARTBLOCK:
@@ -456,6 +388,7 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
__frame->gr8 = __frame->orig_gr8;
__frame->pc -= 4;
}
+ __frame->syscallno = -1;
}
/* Set up the stack frame */
@@ -464,18 +397,11 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
else
ret = setup_frame(sig, ka, oldset);
- if (ret == 0) {
- spin_lock_irq(&current->sighand->siglock);
- sigorsets(&current->blocked, &current->blocked,
- &ka->sa.sa_mask);
- if (!(ka->sa.sa_flags & SA_NODEFER))
- sigaddset(&current->blocked, sig);
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
- }
-
- return ret;
+ if (ret)
+ return;
+ signal_delivered(sig, info, ka, __frame,
+ test_thread_flag(TIF_SINGLESTEP));
} /* end handle_signal() */
/*****************************************************************************/
@@ -488,43 +414,16 @@ static void do_signal(void)
{
struct k_sigaction ka;
siginfo_t info;
- sigset_t *oldset;
int signr;
- /*
- * We want the common case to go fast, which
- * is why we may in certain cases get here from
- * kernel mode. Just return without doing anything
- * if so.
- */
- if (!user_mode(__frame))
- return;
-
- if (try_to_freeze())
- goto no_signal;
-
- if (test_thread_flag(TIF_RESTORE_SIGMASK))
- oldset = &current->saved_sigmask;
- else
- oldset = &current->blocked;
-
signr = get_signal_to_deliver(&info, &ka, __frame, NULL);
if (signr > 0) {
- if (handle_signal(signr, &info, &ka, oldset) == 0) {
- /* a signal was successfully delivered; the saved
- * sigmask will have been stored in the signal frame,
- * and will be restored by sigreturn, so we can simply
- * clear the TIF_RESTORE_SIGMASK flag */
- if (test_thread_flag(TIF_RESTORE_SIGMASK))
- clear_thread_flag(TIF_RESTORE_SIGMASK);
- }
-
+ handle_signal(signr, &info, &ka);
return;
}
-no_signal:
/* Did we come from a system call? */
- if (__frame->syscallno >= 0) {
+ if (__frame->syscallno != -1) {
/* Restart the system call - no handlers present */
switch (__frame->gr8) {
case -ERESTARTNOHAND:
@@ -535,19 +434,16 @@ no_signal:
break;
case -ERESTART_RESTARTBLOCK:
- __frame->gr8 = __NR_restart_syscall;
+ __frame->gr7 = __NR_restart_syscall;
__frame->pc -= 4;
break;
}
+ __frame->syscallno = -1;
}
/* if there's no signal to deliver, we just put the saved sigmask
* back */
- if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
- clear_thread_flag(TIF_RESTORE_SIGMASK);
- sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
- }
-
+ restore_saved_sigmask();
} /* end do_signal() */
/*****************************************************************************/
@@ -562,7 +458,13 @@ asmlinkage void do_notify_resume(__u32 thread_info_flags)
clear_thread_flag(TIF_SINGLESTEP);
/* deal with pending signal delivery */
- if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
+ if (thread_info_flags & _TIF_SIGPENDING)
do_signal();
+ /* deal with notification on about to resume userspace execution */
+ if (thread_info_flags & _TIF_NOTIFY_RESUME) {
+ clear_thread_flag(TIF_NOTIFY_RESUME);
+ tracehook_notify_resume(__frame);
+ }
+
} /* end do_notify_resume() */
diff --git a/arch/frv/kernel/sleep.S b/arch/frv/kernel/sleep.S
index e6079b8cac6..f67bf73cd2c 100644
--- a/arch/frv/kernel/sleep.S
+++ b/arch/frv/kernel/sleep.S
@@ -1,7 +1,7 @@
/* sleep.S: power saving mode entry
*
* Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
- * Written by David Woodhouse (dwmw2@redhat.com)
+ * Written by David Woodhouse (dwmw2@infradead.org)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -11,7 +11,6 @@
*/
#include <linux/sys.h>
-#include <linux/config.h>
#include <linux/linkage.h>
#include <asm/setup.h>
#include <asm/segment.h>
diff --git a/arch/frv/kernel/switch_to.S b/arch/frv/kernel/switch_to.S
index 1703dc20174..b06668670fc 100644
--- a/arch/frv/kernel/switch_to.S
+++ b/arch/frv/kernel/switch_to.S
@@ -11,7 +11,7 @@
# 2 of the License, or (at your option) any later version.
#
###############################################################################
-#include <linux/config.h>
+
#include <linux/linkage.h>
#include <asm/thread_info.h>
#include <asm/processor.h>
@@ -31,7 +31,7 @@
# address of frame 0 (userspace) on current kernel stack
.globl __kernel_frame0_ptr
__kernel_frame0_ptr:
- .long init_thread_union + THREAD_SIZE - USER_CONTEXT_SIZE
+ .long init_thread_union + THREAD_SIZE - FRV_FRAME0_SIZE
# address of current task
.globl __kernel_current_task
@@ -102,13 +102,6 @@ __switch_to:
movgs gr14,lr
bar
- srli gr15,#28,gr5
- subicc gr5,#0xc,gr0,icc0
- beq icc0,#0,111f
- break
- nop
-111:
-
# jump to __switch_back or ret_from_fork as appropriate
# - move prev to GR8
movgs gr4,psr
diff --git a/arch/frv/kernel/sys_frv.c b/arch/frv/kernel/sys_frv.c
index 931aa6d895e..9c4980825bb 100644
--- a/arch/frv/kernel/sys_frv.c
+++ b/arch/frv/kernel/sys_frv.c
@@ -13,202 +13,32 @@
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/mm.h>
+#include <linux/fs.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/sem.h>
#include <linux/msg.h>
#include <linux/shm.h>
#include <linux/stat.h>
#include <linux/mman.h>
#include <linux/file.h>
-#include <linux/utsname.h>
#include <linux/syscalls.h>
+#include <linux/ipc.h>
#include <asm/setup.h>
#include <asm/uaccess.h>
-#include <asm/ipc.h>
-
-/*
- * sys_pipe() is the normal C calling standard for creating
- * a pipe. It's not the way unix traditionally does this, though.
- */
-asmlinkage long sys_pipe(unsigned long * fildes)
-{
- int fd[2];
- int error;
-
- error = do_pipe(fd);
- if (!error) {
- if (copy_to_user(fildes, fd, 2*sizeof(int)))
- error = -EFAULT;
- }
- return error;
-}
asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags,
unsigned long fd, unsigned long pgoff)
{
- int error = -EBADF;
- struct file * file = NULL;
-
- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
- if (!(flags & MAP_ANONYMOUS)) {
- file = fget(fd);
- if (!file)
- goto out;
- }
-
/* As with sparc32, make sure the shift for mmap2 is constant
(12), no matter what PAGE_SIZE we have.... */
/* But unlike sparc32, don't just silently break if we're
trying to map something we can't */
- if (pgoff & ((1<<(PAGE_SHIFT-12))-1))
+ if (pgoff & ((1 << (PAGE_SHIFT - 12)) - 1))
return -EINVAL;
- pgoff >>= (PAGE_SHIFT - 12);
-
- down_write(&current->mm->mmap_sem);
- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
- up_write(&current->mm->mmap_sem);
-
- if (file)
- fput(file);
-out:
- return error;
-}
-
-#if 0 /* DAVIDM - do we want this */
-struct mmap_arg_struct64 {
- __u32 addr;
- __u32 len;
- __u32 prot;
- __u32 flags;
- __u64 offset; /* 64 bits */
- __u32 fd;
-};
-
-asmlinkage long sys_mmap64(struct mmap_arg_struct64 *arg)
-{
- int error = -EFAULT;
- struct file * file = NULL;
- struct mmap_arg_struct64 a;
- unsigned long pgoff;
-
- if (copy_from_user(&a, arg, sizeof(a)))
- return -EFAULT;
-
- if ((long)a.offset & ~PAGE_MASK)
- return -EINVAL;
-
- pgoff = a.offset >> PAGE_SHIFT;
- if ((a.offset >> PAGE_SHIFT) != pgoff)
- return -EINVAL;
-
- if (!(a.flags & MAP_ANONYMOUS)) {
- error = -EBADF;
- file = fget(a.fd);
- if (!file)
- goto out;
- }
- a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-
- down_write(&current->mm->mmap_sem);
- error = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, pgoff);
- up_write(&current->mm->mmap_sem);
- if (file)
- fput(file);
-out:
- return error;
-}
-#endif
-
-/*
- * sys_ipc() is the de-multiplexer for the SysV IPC calls..
- *
- * This is really horribly ugly.
- */
-asmlinkage long sys_ipc(unsigned long call,
- unsigned long first,
- unsigned long second,
- unsigned long third,
- void __user *ptr,
- unsigned long fifth)
-{
- int version, ret;
-
- version = call >> 16; /* hack for backward compatibility */
- call &= 0xffff;
-
- switch (call) {
- case SEMOP:
- return sys_semtimedop(first, (struct sembuf __user *)ptr, second, NULL);
- case SEMTIMEDOP:
- return sys_semtimedop(first, (struct sembuf __user *)ptr, second,
- (const struct timespec __user *)fifth);
-
- case SEMGET:
- return sys_semget (first, second, third);
- case SEMCTL: {
- union semun fourth;
- if (!ptr)
- return -EINVAL;
- if (get_user(fourth.__pad, (void * __user *) ptr))
- return -EFAULT;
- return sys_semctl (first, second, third, fourth);
- }
-
- case MSGSND:
- return sys_msgsnd (first, (struct msgbuf __user *) ptr,
- second, third);
- case MSGRCV:
- switch (version) {
- case 0: {
- struct ipc_kludge tmp;
- if (!ptr)
- return -EINVAL;
-
- if (copy_from_user(&tmp,
- (struct ipc_kludge __user *) ptr,
- sizeof (tmp)))
- return -EFAULT;
- return sys_msgrcv (first, tmp.msgp, second,
- tmp.msgtyp, third);
- }
- default:
- return sys_msgrcv (first,
- (struct msgbuf __user *) ptr,
- second, fifth, third);
- }
- case MSGGET:
- return sys_msgget ((key_t) first, second);
- case MSGCTL:
- return sys_msgctl (first, second, (struct msqid_ds __user *) ptr);
-
- case SHMAT:
- switch (version) {
- default: {
- ulong raddr;
- ret = do_shmat (first, (char __user *) ptr, second, &raddr);
- if (ret)
- return ret;
- return put_user (raddr, (ulong __user *) third);
- }
- case 1: /* iBCS2 emulator entry point */
- if (!segment_eq(get_fs(), get_ds()))
- return -EINVAL;
- /* The "(ulong *) third" is valid _only_ because of the kernel segment thing */
- return do_shmat (first, (char __user *) ptr, second, (ulong *) third);
- }
- case SHMDT:
- return sys_shmdt ((char __user *)ptr);
- case SHMGET:
- return sys_shmget (first, second, third);
- case SHMCTL:
- return sys_shmctl (first, second,
- (struct shmid_ds __user *) ptr);
- default:
- return -ENOSYS;
- }
+ return sys_mmap_pgoff(addr, len, prot, flags, fd,
+ pgoff >> (PAGE_SHIFT - 12));
}
diff --git a/arch/frv/kernel/sysctl.c b/arch/frv/kernel/sysctl.c
index 408b0f382b4..f4dfae2c75a 100644
--- a/arch/frv/kernel/sysctl.c
+++ b/arch/frv/kernel/sysctl.c
@@ -9,8 +9,6 @@
* 2 of the License, or (at your option) any later version.
*/
-#include <linux/config.h>
-#include <linux/slab.h>
#include <linux/sysctl.h>
#include <linux/proc_fs.h>
#include <linux/init.h>
@@ -48,8 +46,9 @@ static void frv_change_dcache_mode(unsigned long newmode)
/*
* handle requests to dynamically switch the write caching mode delivered by /proc
*/
-static int procctl_frv_cachemode(ctl_table *table, int write, struct file *filp,
- void *buffer, size_t *lenp, loff_t *ppos)
+static int procctl_frv_cachemode(struct ctl_table *table, int write,
+ void __user *buffer, size_t *lenp,
+ loff_t *ppos)
{
unsigned long hsr0;
char buff[8];
@@ -86,7 +85,7 @@ static int procctl_frv_cachemode(ctl_table *table, int write, struct file *filp,
}
/* read the state */
- if (filp->f_pos > 0) {
+ if (*ppos > 0) {
*lenp = 0;
return 0;
}
@@ -112,7 +111,7 @@ static int procctl_frv_cachemode(ctl_table *table, int write, struct file *filp,
return -EFAULT;
*lenp = len;
- filp->f_pos = len;
+ *ppos = len;
return 0;
} /* end procctl_frv_cachemode() */
@@ -122,8 +121,9 @@ static int procctl_frv_cachemode(ctl_table *table, int write, struct file *filp,
* permit the mm_struct the nominated process is using have its MMU context ID pinned
*/
#ifdef CONFIG_MMU
-static int procctl_frv_pin_cxnr(ctl_table *table, int write, struct file *filp,
- void *buffer, size_t *lenp, loff_t *ppos)
+static int procctl_frv_pin_cxnr(struct ctl_table *table, int write,
+ void __user *buffer, size_t *lenp,
+ loff_t *ppos)
{
pid_t pid;
char buff[16], *p;
@@ -152,7 +152,7 @@ static int procctl_frv_pin_cxnr(ctl_table *table, int write, struct file *filp,
}
/* read the currently pinned CXN */
- if (filp->f_pos > 0) {
+ if (*ppos > 0) {
*lenp = 0;
return 0;
}
@@ -165,7 +165,7 @@ static int procctl_frv_pin_cxnr(ctl_table *table, int write, struct file *filp,
return -EFAULT;
*lenp = len;
- filp->f_pos = len;
+ *ppos = len;
return 0;
} /* end procctl_frv_pin_cxnr() */
@@ -176,22 +176,37 @@ static int procctl_frv_pin_cxnr(ctl_table *table, int write, struct file *filp,
*/
static struct ctl_table frv_table[] =
{
- { 1, "cache-mode", NULL, 0, 0644, NULL, &procctl_frv_cachemode },
+ {
+ .procname = "cache-mode",
+ .data = NULL,
+ .maxlen = 0,
+ .mode = 0644,
+ .proc_handler = procctl_frv_cachemode,
+ },
#ifdef CONFIG_MMU
- { 2, "pin-cxnr", NULL, 0, 0644, NULL, &procctl_frv_pin_cxnr },
+ {
+ .procname = "pin-cxnr",
+ .data = NULL,
+ .maxlen = 0,
+ .mode = 0644,
+ .proc_handler = procctl_frv_pin_cxnr
+ },
#endif
- { 0 }
+ {}
};
/*
* Use a temporary sysctl number. Horrid, but will be cleaned up in 2.6
* when all the PM interfaces exist nicely.
*/
-#define CTL_FRV 9898
static struct ctl_table frv_dir_table[] =
{
- {CTL_FRV, "frv", NULL, 0, 0555, frv_table},
- {0}
+ {
+ .procname = "frv",
+ .mode = 0555,
+ .child = frv_table
+ },
+ {}
};
/*
@@ -199,7 +214,7 @@ static struct ctl_table frv_dir_table[] =
*/
static int __init frv_sysctl_init(void)
{
- register_sysctl_table(frv_dir_table, 1);
+ register_sysctl_table(frv_dir_table);
return 0;
}
diff --git a/arch/frv/kernel/time.c b/arch/frv/kernel/time.c
index 24cf85f89e4..b457de496b7 100644
--- a/arch/frv/kernel/time.c
+++ b/arch/frv/kernel/time.c
@@ -10,7 +10,6 @@
* 2 of the License, or (at your option) any later version.
*/
-#include <linux/config.h> /* CONFIG_HEARTBEAT */
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/sched.h>
@@ -26,14 +25,11 @@
#include <asm/timer-regs.h>
#include <asm/mb-regs.h>
#include <asm/mb86943a.h>
-#include <asm/irq-routing.h>
#include <linux/timex.h>
#define TICK_SIZE (tick_nsec / 1000)
-extern unsigned long wall_jiffies;
-
unsigned long __nongprelbss __clkin_clock_speed_HZ;
unsigned long __nongprelbss __ext_bus_clock_speed_HZ;
unsigned long __nongprelbss __res_bus_clock_speed_HZ;
@@ -44,54 +40,23 @@ unsigned long __nongprelbss __dsu_clock_speed_HZ;
unsigned long __nongprelbss __serial_clock_speed_HZ;
unsigned long __delay_loops_MHz;
-static irqreturn_t timer_interrupt(int irq, void *dummy, struct pt_regs *regs);
+static irqreturn_t timer_interrupt(int irq, void *dummy);
static struct irqaction timer_irq = {
- timer_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "timer", NULL, NULL
+ .handler = timer_interrupt,
+ .flags = IRQF_DISABLED,
+ .name = "timer",
};
-static inline int set_rtc_mmss(unsigned long nowtime)
-{
- return -1;
-}
-
/*
* timer_interrupt() needs to keep up the real-time clock,
- * as well as call the "do_timer()" routine every clocktick
+ * as well as call the "xtime_update()" routine every clocktick
*/
-static irqreturn_t timer_interrupt(int irq, void *dummy, struct pt_regs * regs)
+static irqreturn_t timer_interrupt(int irq, void *dummy)
{
- /* last time the cmos clock got updated */
- static long last_rtc_update = 0;
-
- /*
- * Here we are in the timer irq handler. We just have irqs locally
- * disabled but we don't know if the timer_bh is running on the other
- * CPU. We need to avoid to SMP race with it. NOTE: we don' t need
- * the irq version of write_lock because as just said we have irq
- * locally disabled. -arca
- */
- write_seqlock(&xtime_lock);
-
- do_timer(regs);
- update_process_times(user_mode(regs));
- profile_tick(CPU_PROFILING, regs);
-
- /*
- * If we have an externally synchronized Linux clock, then update
- * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
- * called as close as possible to 500 ms before the new second starts.
- */
- if (ntp_synced() &&
- xtime.tv_sec > last_rtc_update + 660 &&
- (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 &&
- (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2
- ) {
- if (set_rtc_mmss(xtime.tv_sec) == 0)
- last_rtc_update = xtime.tv_sec;
- else
- last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
- }
+ profile_tick(CPU_PROFILING);
+
+ xtime_update(1);
#ifdef CONFIG_HEARTBEAT
static unsigned short n;
@@ -99,7 +64,8 @@ static irqreturn_t timer_interrupt(int irq, void *dummy, struct pt_regs * regs)
__set_LEDS(n);
#endif /* CONFIG_HEARTBEAT */
- write_sequnlock(&xtime_lock);
+ update_process_times(user_mode(get_irq_regs()));
+
return IRQ_HANDLED;
}
@@ -119,7 +85,8 @@ void time_divisor_init(void)
__set_TCSR_DATA(0, base >> 8);
}
-void time_init(void)
+
+void read_persistent_clock(struct timespec *ts)
{
unsigned int year, mon, day, hour, min, sec;
@@ -127,7 +94,7 @@ void time_init(void)
/* FIX by dqg : Set to zero for platforms that don't have tod */
/* without this time is undefined and can overflow time_t, causing */
- /* very stange errors */
+ /* very strange errors */
year = 1980;
mon = day = 1;
hour = min = sec = 0;
@@ -135,9 +102,12 @@ void time_init(void)
if ((year += 1900) < 1970)
year += 100;
- xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
- xtime.tv_nsec = 0;
+ ts->tv_sec = mktime(year, mon, day, hour, min, sec);
+ ts->tv_nsec = 0;
+}
+void time_init(void)
+{
/* install scheduling interrupt handler */
setup_irq(IRQ_CPU_TIMER0, &timer_irq);
@@ -145,85 +115,6 @@ void time_init(void)
}
/*
- * This version of gettimeofday has near microsecond resolution.
- */
-void do_gettimeofday(struct timeval *tv)
-{
- unsigned long seq;
- unsigned long usec, sec;
- unsigned long max_ntp_tick;
-
- do {
- unsigned long lost;
-
- seq = read_seqbegin(&xtime_lock);
-
- usec = 0;
- lost = jiffies - wall_jiffies;
-
- /*
- * If time_adjust is negative then NTP is slowing the clock
- * so make sure not to go into next possible interval.
- * Better to lose some accuracy than have time go backwards..
- */
- if (unlikely(time_adjust < 0)) {
- max_ntp_tick = (USEC_PER_SEC / HZ) - tickadj;
- usec = min(usec, max_ntp_tick);
-
- if (lost)
- usec += lost * max_ntp_tick;
- }
- else if (unlikely(lost))
- usec += lost * (USEC_PER_SEC / HZ);
-
- sec = xtime.tv_sec;
- usec += (xtime.tv_nsec / 1000);
- } while (read_seqretry(&xtime_lock, seq));
-
- while (usec >= 1000000) {
- usec -= 1000000;
- sec++;
- }
-
- tv->tv_sec = sec;
- tv->tv_usec = usec;
-}
-
-EXPORT_SYMBOL(do_gettimeofday);
-
-int do_settimeofday(struct timespec *tv)
-{
- time_t wtm_sec, sec = tv->tv_sec;
- long wtm_nsec, nsec = tv->tv_nsec;
-
- if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
- return -EINVAL;
-
- write_seqlock_irq(&xtime_lock);
- /*
- * This is revolting. We need to set "xtime" correctly. However, the
- * value in this location is the value at the most recent update of
- * wall time. Discover what correction gettimeofday() would have
- * made, and then undo it!
- */
- nsec -= 0 * NSEC_PER_USEC;
- nsec -= (jiffies - wall_jiffies) * TICK_NSEC;
-
- wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
- wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
-
- set_normalized_timespec(&xtime, sec, nsec);
- set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
-
- ntp_clear();
- write_sequnlock_irq(&xtime_lock);
- clock_was_set();
- return 0;
-}
-
-EXPORT_SYMBOL(do_settimeofday);
-
-/*
* Scheduler clock - returns current time in nanosec units.
*/
unsigned long long sched_clock(void)
diff --git a/arch/frv/kernel/traps.c b/arch/frv/kernel/traps.c
index 9eb84b2e6ab..a6d105d61b2 100644
--- a/arch/frv/kernel/traps.c
+++ b/arch/frv/kernel/traps.c
@@ -9,7 +9,6 @@
* 2 of the License, or (at your option) any later version.
*/
-#include <linux/config.h>
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/kernel.h>
@@ -21,9 +20,9 @@
#include <linux/init.h>
#include <linux/module.h>
+#include <asm/asm-offsets.h>
#include <asm/setup.h>
#include <asm/fpu.h>
-#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/siginfo.h>
@@ -49,7 +48,7 @@ asmlinkage void insn_access_error(unsigned long esfr1, unsigned long epcr0, unsi
info.si_signo = SIGSEGV;
info.si_code = SEGV_ACCERR;
info.si_errno = 0;
- info.si_addr = (void *) ((epcr0 & EPCR0_V) ? (epcr0 & EPCR0_PC) : __frame->pc);
+ info.si_addr = (void __user *) ((epcr0 & EPCR0_V) ? (epcr0 & EPCR0_PC) : __frame->pc);
force_sig_info(info.si_signo, &info, current);
} /* end insn_access_error() */
@@ -73,7 +72,7 @@ asmlinkage void illegal_instruction(unsigned long esfr1, unsigned long epcr0, un
epcr0, esr0, esfr1);
info.si_errno = 0;
- info.si_addr = (void *) ((epcr0 & EPCR0_PC) ? (epcr0 & EPCR0_PC) : __frame->pc);
+ info.si_addr = (void __user *) ((epcr0 & EPCR0_V) ? (epcr0 & EPCR0_PC) : __frame->pc);
switch (__frame->tbr & TBR_TT) {
case TBR_TT_ILLEGAL_INSTR:
@@ -102,6 +101,234 @@ asmlinkage void illegal_instruction(unsigned long esfr1, unsigned long epcr0, un
/*****************************************************************************/
/*
+ * handle atomic operations with errors
+ * - arguments in gr8, gr9, gr10
+ * - original memory value placed in gr5
+ * - replacement memory value placed in gr9
+ */
+asmlinkage void atomic_operation(unsigned long esfr1, unsigned long epcr0,
+ unsigned long esr0)
+{
+ static DEFINE_SPINLOCK(atomic_op_lock);
+ unsigned long x, y, z;
+ unsigned long __user *p;
+ mm_segment_t oldfs;
+ siginfo_t info;
+ int ret;
+
+ y = 0;
+ z = 0;
+
+ oldfs = get_fs();
+ if (!user_mode(__frame))
+ set_fs(KERNEL_DS);
+
+ switch (__frame->tbr & TBR_TT) {
+ /* TIRA gr0,#120
+ * u32 __atomic_user_cmpxchg32(u32 *ptr, u32 test, u32 new)
+ */
+ case TBR_TT_ATOMIC_CMPXCHG32:
+ p = (unsigned long __user *) __frame->gr8;
+ x = __frame->gr9;
+ y = __frame->gr10;
+
+ for (;;) {
+ ret = get_user(z, p);
+ if (ret < 0)
+ goto error;
+
+ if (z != x)
+ goto done;
+
+ spin_lock_irq(&atomic_op_lock);
+
+ if (__get_user(z, p) == 0) {
+ if (z != x)
+ goto done2;
+
+ if (__put_user(y, p) == 0)
+ goto done2;
+ goto error2;
+ }
+
+ spin_unlock_irq(&atomic_op_lock);
+ }
+
+ /* TIRA gr0,#121
+ * u32 __atomic_kernel_xchg32(void *v, u32 new)
+ */
+ case TBR_TT_ATOMIC_XCHG32:
+ p = (unsigned long __user *) __frame->gr8;
+ y = __frame->gr9;
+
+ for (;;) {
+ ret = get_user(z, p);
+ if (ret < 0)
+ goto error;
+
+ spin_lock_irq(&atomic_op_lock);
+
+ if (__get_user(z, p) == 0) {
+ if (__put_user(y, p) == 0)
+ goto done2;
+ goto error2;
+ }
+
+ spin_unlock_irq(&atomic_op_lock);
+ }
+
+ /* TIRA gr0,#122
+ * ulong __atomic_kernel_XOR_return(ulong i, ulong *v)
+ */
+ case TBR_TT_ATOMIC_XOR:
+ p = (unsigned long __user *) __frame->gr8;
+ x = __frame->gr9;
+
+ for (;;) {
+ ret = get_user(z, p);
+ if (ret < 0)
+ goto error;
+
+ spin_lock_irq(&atomic_op_lock);
+
+ if (__get_user(z, p) == 0) {
+ y = x ^ z;
+ if (__put_user(y, p) == 0)
+ goto done2;
+ goto error2;
+ }
+
+ spin_unlock_irq(&atomic_op_lock);
+ }
+
+ /* TIRA gr0,#123
+ * ulong __atomic_kernel_OR_return(ulong i, ulong *v)
+ */
+ case TBR_TT_ATOMIC_OR:
+ p = (unsigned long __user *) __frame->gr8;
+ x = __frame->gr9;
+
+ for (;;) {
+ ret = get_user(z, p);
+ if (ret < 0)
+ goto error;
+
+ spin_lock_irq(&atomic_op_lock);
+
+ if (__get_user(z, p) == 0) {
+ y = x ^ z;
+ if (__put_user(y, p) == 0)
+ goto done2;
+ goto error2;
+ }
+
+ spin_unlock_irq(&atomic_op_lock);
+ }
+
+ /* TIRA gr0,#124
+ * ulong __atomic_kernel_AND_return(ulong i, ulong *v)
+ */
+ case TBR_TT_ATOMIC_AND:
+ p = (unsigned long __user *) __frame->gr8;
+ x = __frame->gr9;
+
+ for (;;) {
+ ret = get_user(z, p);
+ if (ret < 0)
+ goto error;
+
+ spin_lock_irq(&atomic_op_lock);
+
+ if (__get_user(z, p) == 0) {
+ y = x & z;
+ if (__put_user(y, p) == 0)
+ goto done2;
+ goto error2;
+ }
+
+ spin_unlock_irq(&atomic_op_lock);
+ }
+
+ /* TIRA gr0,#125
+ * int __atomic_user_sub_return(atomic_t *v, int i)
+ */
+ case TBR_TT_ATOMIC_SUB:
+ p = (unsigned long __user *) __frame->gr8;
+ x = __frame->gr9;
+
+ for (;;) {
+ ret = get_user(z, p);
+ if (ret < 0)
+ goto error;
+
+ spin_lock_irq(&atomic_op_lock);
+
+ if (__get_user(z, p) == 0) {
+ y = z - x;
+ if (__put_user(y, p) == 0)
+ goto done2;
+ goto error2;
+ }
+
+ spin_unlock_irq(&atomic_op_lock);
+ }
+
+ /* TIRA gr0,#126
+ * int __atomic_user_add_return(atomic_t *v, int i)
+ */
+ case TBR_TT_ATOMIC_ADD:
+ p = (unsigned long __user *) __frame->gr8;
+ x = __frame->gr9;
+
+ for (;;) {
+ ret = get_user(z, p);
+ if (ret < 0)
+ goto error;
+
+ spin_lock_irq(&atomic_op_lock);
+
+ if (__get_user(z, p) == 0) {
+ y = z + x;
+ if (__put_user(y, p) == 0)
+ goto done2;
+ goto error2;
+ }
+
+ spin_unlock_irq(&atomic_op_lock);
+ }
+
+ default:
+ BUG();
+ }
+
+done2:
+ spin_unlock_irq(&atomic_op_lock);
+done:
+ if (!user_mode(__frame))
+ set_fs(oldfs);
+ __frame->gr5 = z;
+ __frame->gr9 = y;
+ return;
+
+error2:
+ spin_unlock_irq(&atomic_op_lock);
+error:
+ if (!user_mode(__frame))
+ set_fs(oldfs);
+ __frame->pc -= 4;
+
+ die_if_kernel("-- Atomic Op Error --\n");
+
+ info.si_signo = SIGSEGV;
+ info.si_code = SEGV_ACCERR;
+ info.si_errno = 0;
+ info.si_addr = (void __user *) __frame->pc;
+
+ force_sig_info(info.si_signo, &info, current);
+}
+
+/*****************************************************************************/
+/*
*
*/
asmlinkage void media_exception(unsigned long msr0, unsigned long msr1)
@@ -116,7 +343,7 @@ asmlinkage void media_exception(unsigned long msr0, unsigned long msr1)
info.si_signo = SIGFPE;
info.si_code = FPE_MDAOVF;
info.si_errno = 0;
- info.si_addr = (void *) __frame->pc;
+ info.si_addr = (void __user *) __frame->pc;
force_sig_info(info.si_signo, &info, current);
} /* end media_exception() */
@@ -134,11 +361,8 @@ asmlinkage void memory_access_exception(unsigned long esr0,
#ifdef CONFIG_MMU
unsigned long fixup;
- if ((esr0 & ESRx_EC) == ESRx_EC_DATA_ACCESS)
- if (handle_misalignment(esr0, ear0, epcr0) == 0)
- return;
-
- if ((fixup = search_exception_table(__frame->pc)) != 0) {
+ fixup = search_exception_table(__frame->pc);
+ if (fixup) {
__frame->pc = fixup;
return;
}
@@ -156,7 +380,7 @@ asmlinkage void memory_access_exception(unsigned long esr0,
info.si_addr = NULL;
if ((esr0 & (ESRx_VALID | ESR0_EAV)) == (ESRx_VALID | ESR0_EAV))
- info.si_addr = (void *) ear0;
+ info.si_addr = (void __user *) ear0;
force_sig_info(info.si_signo, &info, current);
@@ -185,7 +409,7 @@ asmlinkage void data_access_error(unsigned long esfr1, unsigned long esr15, unsi
info.si_signo = SIGSEGV;
info.si_code = SEGV_ACCERR;
info.si_errno = 0;
- info.si_addr = (void *)
+ info.si_addr = (void __user *)
(((esr15 & (ESRx_VALID|ESR15_EAV)) == (ESRx_VALID|ESR15_EAV)) ? ear15 : 0);
force_sig_info(info.si_signo, &info, current);
@@ -219,7 +443,7 @@ asmlinkage void division_exception(unsigned long esfr1, unsigned long esr0, unsi
info.si_signo = SIGFPE;
info.si_code = FPE_INTDIV;
info.si_errno = 0;
- info.si_addr = (void *) __frame->pc;
+ info.si_addr = (void __user *) __frame->pc;
force_sig_info(info.si_signo, &info, current);
} /* end division_exception() */
@@ -242,17 +466,6 @@ asmlinkage void compound_exception(unsigned long esfr1,
BUG();
} /* end compound_exception() */
-/*****************************************************************************/
-/*
- * The architecture-independent backtrace generator
- */
-void dump_stack(void)
-{
- show_stack(NULL, NULL);
-}
-
-EXPORT_SYMBOL(dump_stack);
-
void show_stack(struct task_struct *task, unsigned long *sp)
{
}
@@ -280,26 +493,25 @@ static const char *regnames[] = {
void show_regs(struct pt_regs *regs)
{
- uint32_t *reg;
+ unsigned long *reg;
int loop;
printk("\n");
+ show_regs_print_info(KERN_DEFAULT);
- printk("Frame: @%08x [%s]\n",
- (uint32_t) regs,
+ printk("Frame: @%08lx [%s]\n",
+ (unsigned long) regs,
regs->psr & PSR_S ? "kernel" : "user");
- reg = (uint32_t *) regs;
- for (loop = 0; loop < REG__END; loop++) {
- printk("%s %08x", regnames[loop + 0], reg[loop + 0]);
+ reg = (unsigned long *) regs;
+ for (loop = 0; loop < NR_PT_REGS; loop++) {
+ printk("%s %08lx", regnames[loop + 0], reg[loop + 0]);
- if (loop == REG__END - 1 || loop % 5 == 4)
+ if (loop == NR_PT_REGS - 1 || loop % 5 == 4)
printk("\n");
else
printk(" | ");
}
-
- printk("Process %s (pid: %d)\n", current->comm, current->pid);
}
void die_if_kernel(const char *str, ...)
@@ -311,7 +523,7 @@ void die_if_kernel(const char *str, ...)
return;
va_start(va, str);
- vsprintf(buffer, str, va);
+ vsnprintf(buffer, sizeof(buffer), str, va);
va_end(va);
console_verbose();
@@ -329,7 +541,7 @@ void die_if_kernel(const char *str, ...)
*/
static void show_backtrace_regs(struct pt_regs *frame)
{
- uint32_t *reg;
+ unsigned long *reg;
int loop;
/* print the registers for this frame */
@@ -337,11 +549,11 @@ static void show_backtrace_regs(struct pt_regs *frame)
frame->psr & PSR_S ? "Kernel Mode" : "User Mode",
frame);
- reg = (uint32_t *) frame;
- for (loop = 0; loop < REG__END; loop++) {
- printk("%s %08x", regnames[loop + 0], reg[loop + 0]);
+ reg = (unsigned long *) frame;
+ for (loop = 0; loop < NR_PT_REGS; loop++) {
+ printk("%s %08lx", regnames[loop + 0], reg[loop + 0]);
- if (loop == REG__END - 1 || loop % 5 == 4)
+ if (loop == NR_PT_REGS - 1 || loop % 5 == 4)
printk("\n");
else
printk(" | ");
diff --git a/arch/frv/kernel/uaccess.c b/arch/frv/kernel/uaccess.c
index 9b751c0f0e8..374f88d6cc0 100644
--- a/arch/frv/kernel/uaccess.c
+++ b/arch/frv/kernel/uaccess.c
@@ -17,14 +17,13 @@
/*
* copy a null terminated string from userspace
*/
-long strncpy_from_user(char *dst, const char *src, long count)
+long strncpy_from_user(char *dst, const char __user *src, long count)
{
unsigned long max;
char *p, ch;
long err = -EFAULT;
- if (count < 0)
- BUG();
+ BUG_ON(count < 0);
p = dst;
@@ -70,14 +69,13 @@ EXPORT_SYMBOL(strncpy_from_user);
*
* Return 0 on exception, a value greater than N if too long
*/
-long strnlen_user(const char *src, long count)
+long strnlen_user(const char __user *src, long count)
{
- const char *p;
+ const char __user *p;
long err = 0;
char ch;
- if (count < 0)
- BUG();
+ BUG_ON(count < 0);
#ifndef CONFIG_MMU
if ((unsigned long) src < memory_start)
diff --git a/arch/frv/kernel/vmlinux.lds.S b/arch/frv/kernel/vmlinux.lds.S
index f474534ba78..7e958d829ec 100644
--- a/arch/frv/kernel/vmlinux.lds.S
+++ b/arch/frv/kernel/vmlinux.lds.S
@@ -13,7 +13,7 @@ ENTRY(_start)
jiffies = jiffies_64 + 4;
-__page_offset = 0xc0000000; /* start of area covered by struct pages */
+__page_offset = CONFIG_PAGE_OFFSET; /* start of area covered by struct pages */
__kernel_image_start = __page_offset; /* address at which kernel image resides */
SECTIONS
@@ -26,62 +26,22 @@ SECTIONS
_sinittext = .;
.init.text : {
- *(.text.head)
+ HEAD_TEXT
#ifndef CONFIG_DEBUG_INFO
- *(.init.text)
- *(.exit.text)
- *(.exit.data)
+ INIT_TEXT
+ EXIT_TEXT
+ EXIT_DATA
*(.exitcall.exit)
#endif
}
_einittext = .;
- .init.data : { *(.init.data) }
-
- . = ALIGN(8);
- __setup_start = .;
- .setup.init : { KEEP(*(.init.setup)) }
- __setup_end = .;
-
- __initcall_start = .;
- .initcall.init : {
- *(.initcall1.init)
- *(.initcall2.init)
- *(.initcall3.init)
- *(.initcall4.init)
- *(.initcall5.init)
- *(.initcall6.init)
- *(.initcall7.init)
- }
- __initcall_end = .;
- __con_initcall_start = .;
- .con_initcall.init : { *(.con_initcall.init) }
- __con_initcall_end = .;
- SECURITY_INIT
- . = ALIGN(4);
- __alt_instructions = .;
- .altinstructions : { *(.altinstructions) }
- __alt_instructions_end = .;
- .altinstr_replacement : { *(.altinstr_replacement) }
- __per_cpu_start = .;
- .data.percpu : { *(.data.percpu) }
- __per_cpu_end = .;
+ INIT_DATA_SECTION(8)
+ PERCPU_SECTION(L1_CACHE_BYTES)
- . = ALIGN(4096);
- __initramfs_start = .;
- .init.ramfs : { *(.init.ramfs) }
- __initramfs_end = .;
-
- . = ALIGN(THREAD_SIZE);
+ . = ALIGN(PAGE_SIZE);
__init_end = .;
- /* put sections together that have massive alignment issues */
- . = ALIGN(THREAD_SIZE);
- .data.init_task : {
- /* init task record & stack */
- *(.data.init_task)
- }
-
.trap : {
/* trap table management - read entry-table.S before modifying */
. = ALIGN(8192);
@@ -92,27 +52,23 @@ SECTIONS
*(.trap.break)
}
- . = ALIGN(4096);
- .data.page_aligned : { *(.data.idt) }
-
- . = ALIGN(L1_CACHE_BYTES);
- .data.cacheline_aligned : { *(.data.cacheline_aligned) }
-
/* Text and read-only data */
. = ALIGN(4);
_text = .;
_stext = .;
.text : {
- *(
- .text.start .text .text.*
-#ifdef CONFIG_DEBUG_INFO
- .init.text
- .exit.text
- .exitcall.exit
-#endif
- )
+ *(.text..start)
+ *(.text..entry)
+ *(.text..break)
+ *(.text..tlbmiss)
+ TEXT_TEXT
SCHED_TEXT
LOCK_TEXT
+#ifdef CONFIG_DEBUG_INFO
+ INIT_TEXT
+ EXIT_TEXT
+ *(.exitcall.exit)
+#endif
*(.fixup)
*(.gnu.warning)
*(.exitcall.exit)
@@ -131,15 +87,15 @@ SECTIONS
}
- . = ALIGN(8); /* Exception table */
- __start___ex_table = .;
- __ex_table : { KEEP(*(__ex_table)) }
- __stop___ex_table = .;
+ EXCEPTION_TABLE(8)
_sdata = .;
.data : { /* Data */
- *(.data .data.*)
- *(.exit.data)
+ INIT_TASK_DATA(THREAD_SIZE)
+ CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES)
+ DATA_DATA
+ *(.data.*)
+ EXIT_DATA
CONSTRUCTORS
}
@@ -158,31 +114,19 @@ SECTIONS
.sbss : { *(.sbss .sbss.*) }
.bss : { *(.bss .bss.*) }
- .bss.stack : { *(.bss) }
+ .bss..stack : { *(.bss) }
__bss_stop = .;
_end = . ;
. = ALIGN(PAGE_SIZE);
__kernel_image_end = .;
- /* Stabs debugging sections. */
- .stab 0 : { *(.stab) }
- .stabstr 0 : { *(.stabstr) }
- .stab.excl 0 : { *(.stab.excl) }
- .stab.exclstr 0 : { *(.stab.exclstr) }
- .stab.index 0 : { *(.stab.index) }
- .stab.indexstr 0 : { *(.stab.indexstr) }
-
- .debug_line 0 : { *(.debug_line) }
- .debug_info 0 : { *(.debug_info) }
- .debug_abbrev 0 : { *(.debug_abbrev) }
- .debug_aranges 0 : { *(.debug_aranges) }
- .debug_frame 0 : { *(.debug_frame) }
- .debug_pubnames 0 : { *(.debug_pubnames) }
- .debug_str 0 : { *(.debug_str) }
- .debug_ranges 0 : { *(.debug_ranges) }
+ STABS_DEBUG
+ DWARF_DEBUG
.comment 0 : { *(.comment) }
+
+ DISCARDS
}
__kernel_image_size_no_bss = __bss_start - __kernel_image_start;
diff --git a/arch/frv/lib/Makefile b/arch/frv/lib/Makefile
index 08be305c9f4..4ff2fb1e6b1 100644
--- a/arch/frv/lib/Makefile
+++ b/arch/frv/lib/Makefile
@@ -4,5 +4,5 @@
lib-y := \
__ashldi3.o __lshrdi3.o __muldi3.o __ashrdi3.o __negdi2.o __ucmpdi2.o \
- checksum.o memcpy.o memset.o atomic-ops.o \
+ checksum.o memcpy.o memset.o atomic-ops.o atomic64-ops.o \
outsl_ns.o outsl_sw.o insl_ns.o insl_sw.o cache.o
diff --git a/arch/frv/lib/atomic-ops.S b/arch/frv/lib/atomic-ops.S
index 545cd325ac5..5e9e6ab5dd0 100644
--- a/arch/frv/lib/atomic-ops.S
+++ b/arch/frv/lib/atomic-ops.S
@@ -1,7 +1,7 @@
/* atomic-ops.S: kernel atomic operations
*
* For an explanation of how atomic ops work in this arch, see:
- * Documentation/fujitsu/frv/atomic-ops.txt
+ * Documentation/frv/atomic-ops.txt
*
* Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
@@ -163,11 +163,10 @@ __cmpxchg_32:
ld.p @(gr11,gr0),gr8
orcr cc7,cc7,cc3
subcc gr8,gr9,gr7,icc0
- bne icc0,#0,1f
+ bnelr icc0,#0
cst.p gr10,@(gr11,gr0) ,cc3,#1
corcc gr29,gr29,gr0 ,cc3,#1
beq icc3,#0,0b
-1:
bralr
.size __cmpxchg_32, .-__cmpxchg_32
diff --git a/arch/frv/lib/atomic64-ops.S b/arch/frv/lib/atomic64-ops.S
new file mode 100644
index 00000000000..b6194eeac12
--- /dev/null
+++ b/arch/frv/lib/atomic64-ops.S
@@ -0,0 +1,162 @@
+/* kernel atomic64 operations
+ *
+ * For an explanation of how atomic ops work in this arch, see:
+ * Documentation/frv/atomic-ops.txt
+ *
+ * Copyright (C) 2009 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 License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <asm/spr-regs.h>
+
+ .text
+ .balign 4
+
+
+###############################################################################
+#
+# long long atomic64_inc_return(atomic64_t *v)
+#
+###############################################################################
+ .globl atomic64_inc_return
+ .type atomic64_inc_return,@function
+atomic64_inc_return:
+ or.p gr8,gr8,gr10
+0:
+ orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */
+ ckeq icc3,cc7
+ ldd.p @(gr10,gr0),gr8 /* LDD.P/ORCR must be atomic */
+ orcr cc7,cc7,cc3 /* set CC3 to true */
+ addicc gr9,#1,gr9,icc0
+ addxi gr8,#0,gr8,icc0
+ cstd.p gr8,@(gr10,gr0) ,cc3,#1
+ corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */
+ beq icc3,#0,0b
+ bralr
+
+ .size atomic64_inc_return, .-atomic64_inc_return
+
+###############################################################################
+#
+# long long atomic64_dec_return(atomic64_t *v)
+#
+###############################################################################
+ .globl atomic64_dec_return
+ .type atomic64_dec_return,@function
+atomic64_dec_return:
+ or.p gr8,gr8,gr10
+0:
+ orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */
+ ckeq icc3,cc7
+ ldd.p @(gr10,gr0),gr8 /* LDD.P/ORCR must be atomic */
+ orcr cc7,cc7,cc3 /* set CC3 to true */
+ subicc gr9,#1,gr9,icc0
+ subxi gr8,#0,gr8,icc0
+ cstd.p gr8,@(gr10,gr0) ,cc3,#1
+ corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */
+ beq icc3,#0,0b
+ bralr
+
+ .size atomic64_dec_return, .-atomic64_dec_return
+
+###############################################################################
+#
+# long long atomic64_add_return(long long i, atomic64_t *v)
+#
+###############################################################################
+ .globl atomic64_add_return
+ .type atomic64_add_return,@function
+atomic64_add_return:
+ or.p gr8,gr8,gr4
+ or gr9,gr9,gr5
+0:
+ orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */
+ ckeq icc3,cc7
+ ldd.p @(gr10,gr0),gr8 /* LDD.P/ORCR must be atomic */
+ orcr cc7,cc7,cc3 /* set CC3 to true */
+ addcc gr9,gr5,gr9,icc0
+ addx gr8,gr4,gr8,icc0
+ cstd.p gr8,@(gr10,gr0) ,cc3,#1
+ corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */
+ beq icc3,#0,0b
+ bralr
+
+ .size atomic64_add_return, .-atomic64_add_return
+
+###############################################################################
+#
+# long long atomic64_sub_return(long long i, atomic64_t *v)
+#
+###############################################################################
+ .globl atomic64_sub_return
+ .type atomic64_sub_return,@function
+atomic64_sub_return:
+ or.p gr8,gr8,gr4
+ or gr9,gr9,gr5
+0:
+ orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */
+ ckeq icc3,cc7
+ ldd.p @(gr10,gr0),gr8 /* LDD.P/ORCR must be atomic */
+ orcr cc7,cc7,cc3 /* set CC3 to true */
+ subcc gr9,gr5,gr9,icc0
+ subx gr8,gr4,gr8,icc0
+ cstd.p gr8,@(gr10,gr0) ,cc3,#1
+ corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */
+ beq icc3,#0,0b
+ bralr
+
+ .size atomic64_sub_return, .-atomic64_sub_return
+
+###############################################################################
+#
+# uint64_t __xchg_64(uint64_t i, uint64_t *v)
+#
+###############################################################################
+ .globl __xchg_64
+ .type __xchg_64,@function
+__xchg_64:
+ or.p gr8,gr8,gr4
+ or gr9,gr9,gr5
+0:
+ orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */
+ ckeq icc3,cc7
+ ldd.p @(gr10,gr0),gr8 /* LDD.P/ORCR must be atomic */
+ orcr cc7,cc7,cc3 /* set CC3 to true */
+ cstd.p gr4,@(gr10,gr0) ,cc3,#1
+ corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */
+ beq icc3,#0,0b
+ bralr
+
+ .size __xchg_64, .-__xchg_64
+
+###############################################################################
+#
+# uint64_t __cmpxchg_64(uint64_t test, uint64_t new, uint64_t *v)
+#
+###############################################################################
+ .globl __cmpxchg_64
+ .type __cmpxchg_64,@function
+__cmpxchg_64:
+ or.p gr8,gr8,gr4
+ or gr9,gr9,gr5
+0:
+ orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */
+ ckeq icc3,cc7
+ ldd.p @(gr12,gr0),gr8 /* LDD.P/ORCR must be atomic */
+ orcr cc7,cc7,cc3
+ subcc gr8,gr4,gr0,icc0
+ subcc.p gr9,gr5,gr0,icc1
+ bnelr icc0,#0
+ bnelr icc1,#0
+ cstd.p gr10,@(gr12,gr0) ,cc3,#1
+ corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */
+ beq icc3,#0,0b
+ bralr
+
+ .size __cmpxchg_64, .-__cmpxchg_64
+
diff --git a/arch/frv/lib/cache.S b/arch/frv/lib/cache.S
index 0e10ad8dc46..0c4fb204911 100644
--- a/arch/frv/lib/cache.S
+++ b/arch/frv/lib/cache.S
@@ -1,4 +1,4 @@
-/* cache.S: cache managment routines
+/* cache.S: cache management routines
*
* Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
diff --git a/arch/frv/lib/checksum.c b/arch/frv/lib/checksum.c
index 20e7dfc474e..44e16d59bc1 100644
--- a/arch/frv/lib/checksum.c
+++ b/arch/frv/lib/checksum.c
@@ -32,7 +32,6 @@
of the assembly has to go. */
#include <net/checksum.h>
-#include <asm/checksum.h>
#include <linux/module.h>
static inline unsigned short from32to16(unsigned long x)
@@ -105,15 +104,15 @@ out:
*
* it's best to have buff aligned on a 32-bit boundary
*/
-unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum)
+__wsum csum_partial(const void *buff, int len, __wsum sum)
{
unsigned int result = do_csum(buff, len);
/* add in old sum, and carry.. */
- result += sum;
- if (sum > result)
+ result += (__force u32)sum;
+ if ((__force u32)sum > result)
result += 1;
- return result;
+ return (__force __wsum)result;
}
EXPORT_SYMBOL(csum_partial);
@@ -122,9 +121,9 @@ EXPORT_SYMBOL(csum_partial);
* this routine is used for miscellaneous IP-like checksums, mainly
* in icmp.c
*/
-unsigned short ip_compute_csum(const unsigned char * buff, int len)
+__sum16 ip_compute_csum(const void *buff, int len)
{
- return ~do_csum(buff, len);
+ return (__force __sum16)~do_csum(buff, len);
}
EXPORT_SYMBOL(ip_compute_csum);
@@ -132,9 +131,9 @@ EXPORT_SYMBOL(ip_compute_csum);
/*
* copy from fs while checksumming, otherwise like csum_partial
*/
-unsigned int
-csum_partial_copy_from_user(const char __user *src, char *dst,
- int len, int sum, int *csum_err)
+__wsum
+csum_partial_copy_from_user(const void __user *src, void *dst,
+ int len, __wsum sum, int *csum_err)
{
int rem;
@@ -157,11 +156,11 @@ EXPORT_SYMBOL(csum_partial_copy_from_user);
/*
* copy from ds while checksumming, otherwise like csum_partial
*/
-unsigned int
-csum_partial_copy(const char *src, char *dst, int len, int sum)
+__wsum
+csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum)
{
memcpy(dst, src, len);
return csum_partial(dst, len, sum);
}
-EXPORT_SYMBOL(csum_partial_copy);
+EXPORT_SYMBOL(csum_partial_copy_nocheck);
diff --git a/arch/frv/mb93090-mb00/Makefile b/arch/frv/mb93090-mb00/Makefile
index 76595e87073..21f1df1b378 100644
--- a/arch/frv/mb93090-mb00/Makefile
+++ b/arch/frv/mb93090-mb00/Makefile
@@ -3,7 +3,7 @@
#
ifeq "$(CONFIG_PCI)" "y"
-obj-y := pci-frv.o pci-irq.o pci-vdk.o pci-iomap.o
+obj-y := pci-frv.o pci-irq.o pci-vdk.o
ifeq "$(CONFIG_MMU)" "y"
obj-y += pci-dma.o
@@ -11,3 +11,5 @@ else
obj-y += pci-dma-nommu.o
endif
endif
+
+obj-$(CONFIG_MTD) += flash.o
diff --git a/arch/frv/mb93090-mb00/flash.c b/arch/frv/mb93090-mb00/flash.c
new file mode 100644
index 00000000000..c0e3707c229
--- /dev/null
+++ b/arch/frv/mb93090-mb00/flash.c
@@ -0,0 +1,90 @@
+/* Flash mappings for the MB93090-MB00 motherboard
+ *
+ * Copyright (C) 2009 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.
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+
+#define MB93090_BOOTROM_ADDR 0xFF000000 /* Boot ROM */
+#define MB93090_BOOTROM_SIZE (2 * 1024 * 1024)
+#define MB93090_USERROM_ADDR 0xFF200000 /* User ROM */
+#define MB93090_USERROM_SIZE (2 * 1024 * 1024)
+
+/*
+ * default MTD partition table for both main flash devices, expected to be
+ * overridden by RedBoot
+ */
+static struct mtd_partition mb93090_partitions[] = {
+ {
+ .name = "Filesystem",
+ .size = MTDPART_SIZ_FULL,
+ .offset = 0,
+ }
+};
+
+/*
+ * Definition of the MB93090 Boot ROM (on the CPU card)
+ */
+static struct physmap_flash_data mb93090_bootrom_data = {
+ .width = 2,
+ .nr_parts = 2,
+ .parts = mb93090_partitions,
+};
+
+static struct resource mb93090_bootrom_resource = {
+ .start = MB93090_BOOTROM_ADDR,
+ .end = MB93090_BOOTROM_ADDR + MB93090_BOOTROM_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device mb93090_bootrom = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev.platform_data = &mb93090_bootrom_data,
+ .num_resources = 1,
+ .resource = &mb93090_bootrom_resource,
+};
+
+/*
+ * Definition of the MB93090 User ROM definition (on the motherboard)
+ */
+static struct physmap_flash_data mb93090_userrom_data = {
+ .width = 2,
+ .nr_parts = 2,
+ .parts = mb93090_partitions,
+};
+
+static struct resource mb93090_userrom_resource = {
+ .start = MB93090_USERROM_ADDR,
+ .end = MB93090_USERROM_ADDR + MB93090_USERROM_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device mb93090_userrom = {
+ .name = "physmap-flash",
+ .id = 1,
+ .dev.platform_data = &mb93090_userrom_data,
+ .num_resources = 1,
+ .resource = &mb93090_userrom_resource,
+};
+
+/*
+ * register the MB93090 flashes
+ */
+static int __init mb93090_mtd_init(void)
+{
+ platform_device_register(&mb93090_bootrom);
+ platform_device_register(&mb93090_userrom);
+ return 0;
+}
+
+module_init(mb93090_mtd_init);
diff --git a/arch/frv/mb93090-mb00/pci-dma-nommu.c b/arch/frv/mb93090-mb00/pci-dma-nommu.c
index 4985466b1a7..b99c2a7cc7a 100644
--- a/arch/frv/mb93090-mb00/pci-dma-nommu.c
+++ b/arch/frv/mb93090-mb00/pci-dma-nommu.c
@@ -1,7 +1,7 @@
/* pci-dma-nommu.c: Dynamic DMA mapping support for the FRV
*
* Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
- * Written by David Woodhouse (dwmw2@redhat.com)
+ * Written by David Woodhouse (dwmw2@infradead.org)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -11,6 +11,7 @@
#include <linux/types.h>
#include <linux/slab.h>
+#include <linux/export.h>
#include <linux/dma-mapping.h>
#include <linux/list.h>
#include <linux/pci.h>
@@ -106,18 +107,10 @@ void dma_free_coherent(struct device *hwdev, size_t size, void *vaddr, dma_addr_
EXPORT_SYMBOL(dma_free_coherent);
-/*
- * Map a single buffer of the indicated size for DMA in streaming mode.
- * The 32-bit bus address to use is returned.
- *
- * Once the device is given the dma address, the device owns this memory
- * until either pci_unmap_single or pci_dma_sync_single is performed.
- */
dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction direction)
{
- if (direction == DMA_NONE)
- BUG();
+ BUG_ON(direction == DMA_NONE);
frv_cache_wback_inv((unsigned long) ptr, (unsigned long) ptr + size);
@@ -126,22 +119,6 @@ dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
EXPORT_SYMBOL(dma_map_single);
-/*
- * Map a set of buffers described by scatterlist in streaming
- * mode for DMA. This is the scather-gather version of the
- * above pci_map_single interface. Here the scatter gather list
- * elements are each tagged with the appropriate dma address
- * and length. They are obtained via sg_dma_{address,length}(SG).
- *
- * NOTE: An implementation may be able to use a smaller number of
- * DMA address/length pairs than there are SG table elements.
- * (for example via virtual mapping capabilities)
- * The routine returns the number of addr/length pairs actually
- * used, at most nents.
- *
- * Device ownership issues as mentioned above for pci_map_single are
- * the same here.
- */
int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
enum dma_data_direction direction)
{
@@ -151,10 +128,19 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
frv_cache_wback_inv(sg_dma_address(&sg[i]),
sg_dma_address(&sg[i]) + sg_dma_len(&sg[i]));
- if (direction == DMA_NONE)
- BUG();
+ BUG_ON(direction == DMA_NONE);
return nents;
}
EXPORT_SYMBOL(dma_map_sg);
+
+dma_addr_t dma_map_page(struct device *dev, struct page *page, unsigned long offset,
+ size_t size, enum dma_data_direction direction)
+{
+ BUG_ON(direction == DMA_NONE);
+ flush_dcache_page(page);
+ return (dma_addr_t) page_to_phys(page) + offset;
+}
+
+EXPORT_SYMBOL(dma_map_page);
diff --git a/arch/frv/mb93090-mb00/pci-dma.c b/arch/frv/mb93090-mb00/pci-dma.c
index 671ce1e8434..82478979ac9 100644
--- a/arch/frv/mb93090-mb00/pci-dma.c
+++ b/arch/frv/mb93090-mb00/pci-dma.c
@@ -10,11 +10,12 @@
*/
#include <linux/types.h>
-#include <linux/slab.h>
#include <linux/dma-mapping.h>
#include <linux/list.h>
#include <linux/pci.h>
+#include <linux/export.h>
#include <linux/highmem.h>
+#include <linux/scatterlist.h>
#include <asm/io.h>
void *dma_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_handle, gfp_t gfp)
@@ -37,18 +38,10 @@ void dma_free_coherent(struct device *hwdev, size_t size, void *vaddr, dma_addr_
EXPORT_SYMBOL(dma_free_coherent);
-/*
- * Map a single buffer of the indicated size for DMA in streaming mode.
- * The 32-bit bus address to use is returned.
- *
- * Once the device is given the dma address, the device owns this memory
- * until either pci_unmap_single or pci_dma_sync_single is performed.
- */
dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction direction)
{
- if (direction == DMA_NONE)
- BUG();
+ BUG_ON(direction == DMA_NONE);
frv_cache_wback_inv((unsigned long) ptr, (unsigned long) ptr + size);
@@ -57,22 +50,6 @@ dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
EXPORT_SYMBOL(dma_map_single);
-/*
- * Map a set of buffers described by scatterlist in streaming
- * mode for DMA. This is the scather-gather version of the
- * above pci_map_single interface. Here the scatter gather list
- * elements are each tagged with the appropriate dma address
- * and length. They are obtained via sg_dma_{address,length}(SG).
- *
- * NOTE: An implementation may be able to use a smaller number of
- * DMA address/length pairs than there are SG table elements.
- * (for example via virtual mapping capabilities)
- * The routine returns the number of addr/length pairs actually
- * used, at most nents.
- *
- * Device ownership issues as mentioned above for pci_map_single are
- * the same here.
- */
int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
enum dma_data_direction direction)
{
@@ -80,20 +57,19 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
void *vaddr;
int i;
- if (direction == DMA_NONE)
- BUG();
+ BUG_ON(direction == DMA_NONE);
dampr2 = __get_DAMPR(2);
for (i = 0; i < nents; i++) {
- vaddr = kmap_atomic(sg[i].page, __KM_CACHE);
+ vaddr = kmap_atomic_primary(sg_page(&sg[i]));
frv_dcache_writeback((unsigned long) vaddr,
(unsigned long) vaddr + PAGE_SIZE);
}
- kunmap_atomic(vaddr, __KM_CACHE);
+ kunmap_atomic_primary(vaddr);
if (dampr2) {
__set_DAMPR(2, dampr2);
__set_IAMPR(2, dampr2);
diff --git a/arch/frv/mb93090-mb00/pci-frv.c b/arch/frv/mb93090-mb00/pci-frv.c
index 0a26bf6f1cd..67b1d168575 100644
--- a/arch/frv/mb93090-mb00/pci-frv.c
+++ b/arch/frv/mb93090-mb00/pci-frv.c
@@ -19,36 +19,6 @@
#include "pci-frv.h"
-#if 0
-void
-pcibios_update_resource(struct pci_dev *dev, struct resource *root,
- struct resource *res, int resource)
-{
- u32 new, check;
- int reg;
-
- new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
- if (resource < 6) {
- reg = PCI_BASE_ADDRESS_0 + 4*resource;
- } else if (resource == PCI_ROM_RESOURCE) {
- res->flags |= IORESOURCE_ROM_ENABLE;
- new |= PCI_ROM_ADDRESS_ENABLE;
- reg = dev->rom_base_reg;
- } else {
- /* Somebody might have asked allocation of a non-standard resource */
- return;
- }
-
- pci_write_config_dword(dev, reg, new);
- pci_read_config_dword(dev, reg, &check);
- if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) {
- printk(KERN_ERR "PCI: Error while updating region "
- "%s/%d (%08x != %08x)\n", pci_name(dev), resource,
- new, check);
- }
-}
-#endif
-
/*
* We need to avoid collisions with `mirrored' VGA ports
* and other strange ISA hardware, so we always want the
@@ -62,18 +32,16 @@ pcibios_update_resource(struct pci_dev *dev, struct resource *root,
* but we want to try to avoid allocating at 0x2900-0x2bff
* which might have be mirrored at 0x0100-0x03ff..
*/
-void
-pcibios_align_resource(void *data, struct resource *res,
- unsigned long size, unsigned long align)
+resource_size_t
+pcibios_align_resource(void *data, const struct resource *res,
+ resource_size_t size, resource_size_t align)
{
- if (res->flags & IORESOURCE_IO) {
- unsigned long start = res->start;
+ resource_size_t start = res->start;
- if (start & 0x300) {
- start = (start + 0x3ff) & ~0x3ff;
- res->start = start;
- }
- }
+ if ((res->flags & IORESOURCE_IO) && (start & 0x300))
+ start = (start + 0x3ff) & ~0x3ff;
+
+ return start;
}
@@ -116,19 +84,17 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
struct pci_bus *bus;
struct pci_dev *dev;
int idx;
- struct resource *r, *pr;
+ struct resource *r;
/* Depth-First Search on bus tree */
for (ln=bus_list->next; ln != bus_list; ln=ln->next) {
- bus = pci_bus_b(ln);
+ bus = list_entry(ln, struct pci_bus, node);
if ((dev = bus->self)) {
for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) {
r = &dev->resource[idx];
if (!r->start)
continue;
- pr = pci_find_parent_resource(dev, r);
- if (!pr || request_resource(pr, r) < 0)
- printk(KERN_ERR "PCI: Cannot allocate resource region %d of bridge %s\n", idx, pci_name(dev));
+ pci_claim_resource(dev, idx);
}
}
pcibios_allocate_bus_resources(&bus->children);
@@ -140,7 +106,7 @@ static void __init pcibios_allocate_resources(int pass)
struct pci_dev *dev = NULL;
int idx, disabled;
u16 command;
- struct resource *r, *pr;
+ struct resource *r;
for_each_pci_dev(dev) {
pci_read_config_word(dev, PCI_COMMAND, &command);
@@ -157,9 +123,7 @@ static void __init pcibios_allocate_resources(int pass)
if (pass == disabled) {
DBG("PCI: Resource %08lx-%08lx (f=%lx, d=%d, p=%d)\n",
r->start, r->end, r->flags, disabled, pass);
- pr = pci_find_parent_resource(dev, r);
- if (!pr || request_resource(pr, r) < 0) {
- printk(KERN_ERR "PCI: Cannot allocate resource region %d of device %s\n", idx, pci_name(dev));
+ if (pci_claim_resource(dev, idx) < 0) {
/* We'll assign a new address later */
r->end -= r->start;
r->start = 0;
@@ -230,55 +194,3 @@ void __init pcibios_resource_survey(void)
pcibios_allocate_resources(1);
pcibios_assign_resources();
}
-
-int pcibios_enable_resources(struct pci_dev *dev, int mask)
-{
- u16 cmd, old_cmd;
- int idx;
- struct resource *r;
-
- pci_read_config_word(dev, PCI_COMMAND, &cmd);
- old_cmd = cmd;
- for(idx=0; idx<6; idx++) {
- /* Only set up the requested stuff */
- if (!(mask & (1<<idx)))
- continue;
-
- r = &dev->resource[idx];
- if (!r->start && r->end) {
- printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", pci_name(dev));
- return -EINVAL;
- }
- if (r->flags & IORESOURCE_IO)
- cmd |= PCI_COMMAND_IO;
- if (r->flags & IORESOURCE_MEM)
- cmd |= PCI_COMMAND_MEMORY;
- }
- if (dev->resource[PCI_ROM_RESOURCE].start)
- cmd |= PCI_COMMAND_MEMORY;
- if (cmd != old_cmd) {
- printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd);
- pci_write_config_word(dev, PCI_COMMAND, cmd);
- }
- return 0;
-}
-
-/*
- * If we set up a device for bus mastering, we need to check the latency
- * timer as certain crappy BIOSes forget to set it properly.
- */
-unsigned int pcibios_max_latency = 255;
-
-void pcibios_set_master(struct pci_dev *dev)
-{
- u8 lat;
- pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
- if (lat < 16)
- lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
- else if (lat > pcibios_max_latency)
- lat = pcibios_max_latency;
- else
- return;
- printk(KERN_DEBUG "PCI: Setting latency timer of device %s to %d\n", pci_name(dev), lat);
- pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
-}
diff --git a/arch/frv/mb93090-mb00/pci-frv.h b/arch/frv/mb93090-mb00/pci-frv.h
index 7481797ab38..a7e487fe76e 100644
--- a/arch/frv/mb93090-mb00/pci-frv.h
+++ b/arch/frv/mb93090-mb00/pci-frv.h
@@ -17,8 +17,6 @@
#define PCI_PROBE_BIOS 0x0001
#define PCI_PROBE_CONF1 0x0002
#define PCI_PROBE_CONF2 0x0004
-#define PCI_NO_SORT 0x0100
-#define PCI_BIOS_SORT 0x0200
#define PCI_NO_CHECKS 0x0400
#define PCI_ASSIGN_ROMS 0x1000
#define PCI_BIOS_IRQ_SCAN 0x2000
@@ -28,15 +26,10 @@ extern unsigned int __nongpreldata pci_probe;
/* pci-frv.c */
-extern unsigned int pcibios_max_latency;
-
void pcibios_resource_survey(void);
-int pcibios_enable_resources(struct pci_dev *, int);
/* pci-vdk.c */
-extern int __nongpreldata pcibios_last_bus;
-extern struct pci_bus *__nongpreldata pci_root_bus;
extern struct pci_ops *__nongpreldata pci_root_ops;
/* pci-irq.c */
diff --git a/arch/frv/mb93090-mb00/pci-iomap.c b/arch/frv/mb93090-mb00/pci-iomap.c
deleted file mode 100644
index 068fa04bd52..00000000000
--- a/arch/frv/mb93090-mb00/pci-iomap.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/* pci-iomap.c: description
- *
- * Copyright (C) 2006 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 License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#include <linux/pci.h>
-#include <linux/module.h>
-
-void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
-{
- unsigned long start = pci_resource_start(dev, bar);
- unsigned long len = pci_resource_len(dev, bar);
- unsigned long flags = pci_resource_flags(dev, bar);
-
- if (!len || !start)
- return NULL;
-
- if ((flags & IORESOURCE_IO) || (flags & IORESOURCE_MEM))
- return (void __iomem *) start;
-
- return NULL;
-}
-
-EXPORT_SYMBOL(pci_iomap);
diff --git a/arch/frv/mb93090-mb00/pci-irq.c b/arch/frv/mb93090-mb00/pci-irq.c
index c4a1144c98b..1c35c93f942 100644
--- a/arch/frv/mb93090-mb00/pci-irq.c
+++ b/arch/frv/mb93090-mb00/pci-irq.c
@@ -5,18 +5,15 @@
* derived from: arch/i386/kernel/pci-irq.c: (c) 1999--2000 Martin Mares <mj@suse.cz>
*/
-#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/init.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <asm/io.h>
#include <asm/smp.h>
-#include <asm/irq-routing.h>
#include "pci-frv.h"
@@ -31,12 +28,12 @@
*
*/
-static const uint8_t __initdata pci_bus0_irq_routing[32][4] = {
- [0 ] { IRQ_FPGA_MB86943_PCI_INTA },
- [16] { IRQ_FPGA_RTL8029_INTA },
- [17] { IRQ_FPGA_PCI_INTC, IRQ_FPGA_PCI_INTD, IRQ_FPGA_PCI_INTA, IRQ_FPGA_PCI_INTB },
- [18] { IRQ_FPGA_PCI_INTB, IRQ_FPGA_PCI_INTC, IRQ_FPGA_PCI_INTD, IRQ_FPGA_PCI_INTA },
- [19] { IRQ_FPGA_PCI_INTA, IRQ_FPGA_PCI_INTB, IRQ_FPGA_PCI_INTC, IRQ_FPGA_PCI_INTD },
+static const uint8_t __initconst pci_bus0_irq_routing[32][4] = {
+ [0 ] = { IRQ_FPGA_MB86943_PCI_INTA },
+ [16] = { IRQ_FPGA_RTL8029_INTA },
+ [17] = { IRQ_FPGA_PCI_INTC, IRQ_FPGA_PCI_INTD, IRQ_FPGA_PCI_INTA, IRQ_FPGA_PCI_INTB },
+ [18] = { IRQ_FPGA_PCI_INTB, IRQ_FPGA_PCI_INTC, IRQ_FPGA_PCI_INTD, IRQ_FPGA_PCI_INTA },
+ [19] = { IRQ_FPGA_PCI_INTA, IRQ_FPGA_PCI_INTB, IRQ_FPGA_PCI_INTC, IRQ_FPGA_PCI_INTD },
};
void __init pcibios_irq_init(void)
@@ -58,10 +55,6 @@ void __init pcibios_fixup_irqs(void)
}
}
-void __init pcibios_penalize_isa_irq(int irq)
-{
-}
-
void pcibios_enable_irq(struct pci_dev *dev)
{
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
diff --git a/arch/frv/mb93090-mb00/pci-vdk.c b/arch/frv/mb93090-mb00/pci-vdk.c
index c8817f7b860..efa5d65b000 100644
--- a/arch/frv/mb93090-mb00/pci-vdk.c
+++ b/arch/frv/mb93090-mb00/pci-vdk.c
@@ -9,7 +9,6 @@
* 2 of the License, or (at your option) any later version.
*/
-#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
@@ -17,7 +16,6 @@
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/delay.h>
-#include <linux/slab.h>
#include <asm/segment.h>
#include <asm/io.h>
@@ -27,11 +25,32 @@
unsigned int __nongpreldata pci_probe = 1;
-int __nongpreldata pcibios_last_bus = -1;
-struct pci_bus *__nongpreldata pci_root_bus;
struct pci_ops *__nongpreldata pci_root_ops;
/*
+ * The accessible PCI window does not cover the entire CPU address space, but
+ * there are devices we want to access outside of that window, so we need to
+ * insert specific PCI bus resources instead of using the platform-level bus
+ * resources directly for the PCI root bus.
+ *
+ * These are configured and inserted by pcibios_init() and are attached to the
+ * root bus by pcibios_fixup_bus().
+ */
+static struct resource pci_ioport_resource = {
+ .name = "PCI IO",
+ .start = 0,
+ .end = IO_SPACE_LIMIT,
+ .flags = IORESOURCE_IO,
+};
+
+static struct resource pci_iomem_resource = {
+ .name = "PCI mem",
+ .start = 0,
+ .end = -1,
+ .flags = IORESOURCE_MEM,
+};
+
+/*
* Functions for accessing PCI configuration space
*/
@@ -200,89 +219,6 @@ static struct pci_ops * __init pci_check_direct(void)
}
/*
- * Several buggy motherboards address only 16 devices and mirror
- * them to next 16 IDs. We try to detect this `feature' on all
- * primary buses (those containing host bridges as they are
- * expected to be unique) and remove the ghost devices.
- */
-
-static void __init pcibios_fixup_ghosts(struct pci_bus *b)
-{
- struct list_head *ln, *mn;
- struct pci_dev *d, *e;
- int mirror = PCI_DEVFN(16,0);
- int seen_host_bridge = 0;
- int i;
-
- for (ln=b->devices.next; ln != &b->devices; ln=ln->next) {
- d = pci_dev_b(ln);
- if ((d->class >> 8) == PCI_CLASS_BRIDGE_HOST)
- seen_host_bridge++;
- for (mn=ln->next; mn != &b->devices; mn=mn->next) {
- e = pci_dev_b(mn);
- if (e->devfn != d->devfn + mirror ||
- e->vendor != d->vendor ||
- e->device != d->device ||
- e->class != d->class)
- continue;
- for(i=0; i<PCI_NUM_RESOURCES; i++)
- if (e->resource[i].start != d->resource[i].start ||
- e->resource[i].end != d->resource[i].end ||
- e->resource[i].flags != d->resource[i].flags)
- continue;
- break;
- }
- if (mn == &b->devices)
- return;
- }
- if (!seen_host_bridge)
- return;
- printk("PCI: Ignoring ghost devices on bus %02x\n", b->number);
-
- ln = &b->devices;
- while (ln->next != &b->devices) {
- d = pci_dev_b(ln->next);
- if (d->devfn >= mirror) {
- list_del(&d->global_list);
- list_del(&d->bus_list);
- kfree(d);
- } else
- ln = ln->next;
- }
-}
-
-/*
- * Discover remaining PCI buses in case there are peer host bridges.
- * We use the number of last PCI bus provided by the PCI BIOS.
- */
-static void __init pcibios_fixup_peer_bridges(void)
-{
- struct pci_bus bus;
- struct pci_dev dev;
- int n;
- u16 l;
-
- if (pcibios_last_bus <= 0 || pcibios_last_bus >= 0xff)
- return;
- printk("PCI: Peer bridge fixup\n");
- for (n=0; n <= pcibios_last_bus; n++) {
- if (pci_find_bus(0, n))
- continue;
- bus.number = n;
- bus.ops = pci_root_ops;
- dev.bus = &bus;
- for(dev.devfn=0; dev.devfn<256; dev.devfn += 8)
- if (!pci_read_config_word(&dev, PCI_VENDOR_ID, &l) &&
- l != 0x0000 && l != 0xffff) {
- printk("Found device at %02x:%02x [%04x]\n", n, dev.devfn, l);
- printk("PCI: Discovered peer bus %02x\n", n);
- pci_scan_bus(n, pci_root_ops, NULL);
- break;
- }
- }
-}
-
-/*
* Exceptions for specific devices. Usually work-arounds for fatal design flaws.
*/
@@ -299,7 +235,7 @@ static void __init pci_fixup_umc_ide(struct pci_dev *d)
d->resource[i].flags |= PCI_BASE_ADDRESS_SPACE_IO;
}
-static void __init pci_fixup_ide_bases(struct pci_dev *d)
+static void pci_fixup_ide_bases(struct pci_dev *d)
{
int i;
@@ -318,7 +254,7 @@ static void __init pci_fixup_ide_bases(struct pci_dev *d)
}
}
-static void __init pci_fixup_ide_trash(struct pci_dev *d)
+static void pci_fixup_ide_trash(struct pci_dev *d)
{
int i;
@@ -331,7 +267,7 @@ static void __init pci_fixup_ide_trash(struct pci_dev *d)
d->resource[i].start = d->resource[i].end = d->resource[i].flags = 0;
}
-static void __devinit pci_fixup_latency(struct pci_dev *d)
+static void pci_fixup_latency(struct pci_dev *d)
{
/*
* SiS 5597 and 5598 chipsets require latency timer set to
@@ -352,19 +288,17 @@ DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases);
* are examined.
*/
-void __init pcibios_fixup_bus(struct pci_bus *bus)
+void pcibios_fixup_bus(struct pci_bus *bus)
{
#if 0
printk("### PCIBIOS_FIXUP_BUS(%d)\n",bus->number);
#endif
- pcibios_fixup_ghosts(bus);
+
pci_read_bridge_bases(bus);
if (bus->number == 0) {
- struct list_head *ln;
struct pci_dev *dev;
- for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) {
- dev = pci_dev_b(ln);
+ list_for_each_entry(dev, &bus->devices, bus_list) {
if (dev->devfn == 0) {
dev->resource[0].start = 0;
dev->resource[0].end = 0;
@@ -383,6 +317,7 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
int __init pcibios_init(void)
{
struct pci_ops *dir = NULL;
+ LIST_HEAD(resources);
if (!mb93090_mb00_detected)
return -ENXIO;
@@ -401,24 +336,38 @@ int __init pcibios_init(void)
__reg_MB86943_pci_sl_mem_base = __region_CS2 + 0x08000000;
mb();
- *(volatile unsigned long *)(__region_CS2+0x01300014) == 1;
+ /* enable PCI arbitration */
+ __reg_MB86943_pci_arbiter = MB86943_PCIARB_EN;
- ioport_resource.start = (__reg_MB86943_sl_pci_io_base << 9) & 0xfffffc00;
- ioport_resource.end = (__reg_MB86943_sl_pci_io_range << 9) | 0x3ff;
- ioport_resource.end += ioport_resource.start;
+ pci_ioport_resource.start = (__reg_MB86943_sl_pci_io_base << 9) & 0xfffffc00;
+ pci_ioport_resource.end = (__reg_MB86943_sl_pci_io_range << 9) | 0x3ff;
+ pci_ioport_resource.end += pci_ioport_resource.start;
- printk("PCI IO window: %08lx-%08lx\n", ioport_resource.start, ioport_resource.end);
+ printk("PCI IO window: %08llx-%08llx\n",
+ (unsigned long long) pci_ioport_resource.start,
+ (unsigned long long) pci_ioport_resource.end);
- iomem_resource.start = (__reg_MB86943_sl_pci_mem_base << 9) & 0xfffffc00;
+ pci_iomem_resource.start = (__reg_MB86943_sl_pci_mem_base << 9) & 0xfffffc00;
+ pci_iomem_resource.end = (__reg_MB86943_sl_pci_mem_range << 9) | 0x3ff;
+ pci_iomem_resource.end += pci_iomem_resource.start;
- /* Reserve somewhere to write to flush posted writes. */
- iomem_resource.start += 0x400;
+ /* Reserve somewhere to write to flush posted writes. This is used by
+ * __flush_PCI_writes() from asm/io.h to force the write FIFO in the
+ * CPU-PCI bridge to flush as this doesn't happen automatically when a
+ * read is performed on the MB93090 development kit motherboard.
+ */
+ pci_iomem_resource.start += 0x400;
- iomem_resource.end = (__reg_MB86943_sl_pci_mem_range << 9) | 0x3ff;
- iomem_resource.end += iomem_resource.start;
+ printk("PCI MEM window: %08llx-%08llx\n",
+ (unsigned long long) pci_iomem_resource.start,
+ (unsigned long long) pci_iomem_resource.end);
+ printk("PCI DMA memory: %08lx-%08lx\n",
+ dma_coherent_mem_start, dma_coherent_mem_end);
- printk("PCI MEM window: %08lx-%08lx\n", iomem_resource.start, iomem_resource.end);
- printk("PCI DMA memory: %08lx-%08lx\n", dma_coherent_mem_start, dma_coherent_mem_end);
+ if (insert_resource(&iomem_resource, &pci_iomem_resource) < 0)
+ panic("Unable to insert PCI IOMEM resource\n");
+ if (insert_resource(&ioport_resource, &pci_ioport_resource) < 0)
+ panic("Unable to insert PCI IOPORT resource\n");
if (!pci_probe)
return -ENXIO;
@@ -432,10 +381,11 @@ int __init pcibios_init(void)
}
printk("PCI: Probing PCI hardware\n");
- pci_root_bus = pci_scan_bus(0, pci_root_ops, NULL);
+ pci_add_resource(&resources, &pci_ioport_resource);
+ pci_add_resource(&resources, &pci_iomem_resource);
+ pci_scan_root_bus(NULL, 0, pci_root_ops, NULL, &resources);
pcibios_irq_init();
- pcibios_fixup_peer_bridges();
pcibios_fixup_irqs();
pcibios_resource_survey();
@@ -449,9 +399,6 @@ char * __init pcibios_setup(char *str)
if (!strcmp(str, "off")) {
pci_probe = 0;
return NULL;
- } else if (!strncmp(str, "lastbus=", 8)) {
- pcibios_last_bus = simple_strtol(str+8, NULL, 0);
- return NULL;
}
return str;
}
@@ -460,8 +407,9 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
{
int err;
- if ((err = pcibios_enable_resources(dev, mask)) < 0)
+ if ((err = pci_enable_resources(dev, mask)) < 0)
return err;
- pcibios_enable_irq(dev);
+ if (!dev->msi_enabled)
+ pcibios_enable_irq(dev);
return 0;
}
diff --git a/arch/frv/mm/Makefile b/arch/frv/mm/Makefile
index fb8b1d860f4..1bca5ab8a6a 100644
--- a/arch/frv/mm/Makefile
+++ b/arch/frv/mm/Makefile
@@ -6,4 +6,4 @@ obj-y := init.o kmap.o
obj-$(CONFIG_MMU) += \
pgalloc.o highmem.o fault.o extable.o cache-page.o tlb-flush.o tlb-miss.o \
- mmu-context.o dma-alloc.o unaligned.o elf-fdpic.o
+ mmu-context.o dma-alloc.o elf-fdpic.o
diff --git a/arch/frv/mm/cache-page.c b/arch/frv/mm/cache-page.c
index 0261cbe153b..8e09dae0ec3 100644
--- a/arch/frv/mm/cache-page.c
+++ b/arch/frv/mm/cache-page.c
@@ -26,11 +26,11 @@ void flush_dcache_page(struct page *page)
dampr2 = __get_DAMPR(2);
- vaddr = kmap_atomic(page, __KM_CACHE);
+ vaddr = kmap_atomic_primary(page);
frv_dcache_writeback((unsigned long) vaddr, (unsigned long) vaddr + PAGE_SIZE);
- kunmap_atomic(vaddr, __KM_CACHE);
+ kunmap_atomic_primary(vaddr);
if (dampr2) {
__set_DAMPR(2, dampr2);
@@ -54,12 +54,12 @@ void flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
dampr2 = __get_DAMPR(2);
- vaddr = kmap_atomic(page, __KM_CACHE);
+ vaddr = kmap_atomic_primary(page);
start = (start & ~PAGE_MASK) | (unsigned long) vaddr;
frv_cache_wback_inv(start, start + len);
- kunmap_atomic(vaddr, __KM_CACHE);
+ kunmap_atomic_primary(vaddr);
if (dampr2) {
__set_DAMPR(2, dampr2);
diff --git a/arch/frv/mm/dma-alloc.c b/arch/frv/mm/dma-alloc.c
index 342823aad75..7a73aaeae3a 100644
--- a/arch/frv/mm/dma-alloc.c
+++ b/arch/frv/mm/dma-alloc.c
@@ -21,7 +21,6 @@
* published by the Free Software Foundation.
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/signal.h>
#include <linux/sched.h>
@@ -37,10 +36,11 @@
#include <linux/vmalloc.h>
#include <linux/init.h>
#include <linux/pci.h>
+#include <linux/hardirq.h>
+#include <linux/gfp.h>
#include <asm/pgalloc.h>
#include <asm/io.h>
-#include <asm/hardirq.h>
#include <asm/mmu_context.h>
#include <asm/pgtable.h>
#include <asm/mmu.h>
@@ -115,9 +115,7 @@ void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *dma_handle)
*/
if (order > 0) {
struct page *rpage = virt_to_page(page);
-
- for (i = 1; i < (1 << order); i++)
- set_page_count(rpage + i, 1);
+ split_page(rpage, order);
}
err = 0;
diff --git a/arch/frv/mm/elf-fdpic.c b/arch/frv/mm/elf-fdpic.c
index f5a653033fe..836f14707a6 100644
--- a/arch/frv/mm/elf-fdpic.c
+++ b/arch/frv/mm/elf-fdpic.c
@@ -13,6 +13,7 @@
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/elf-fdpic.h>
+#include <asm/mman.h>
/*****************************************************************************/
/*
@@ -59,11 +60,15 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
unsigned long pgoff, unsigned long flags)
{
struct vm_area_struct *vma;
- unsigned long limit;
+ struct vm_unmapped_area_info info;
if (len > TASK_SIZE)
return -ENOMEM;
+ /* handle MAP_FIXED */
+ if (flags & MAP_FIXED)
+ return addr;
+
/* only honour a hint if we're not going to clobber something doing so */
if (addr) {
addr = PAGE_ALIGN(addr);
@@ -74,50 +79,35 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
}
/* search between the bottom of user VM and the stack grow area */
- addr = PAGE_SIZE;
- limit = (current->mm->start_stack - 0x00200000);
- if (addr + len <= limit) {
- limit -= len;
-
- if (addr <= limit) {
- vma = find_vma(current->mm, PAGE_SIZE);
- for (; vma; vma = vma->vm_next) {
- if (addr > limit)
- break;
- if (addr + len <= vma->vm_start)
- goto success;
- addr = vma->vm_end;
- }
- }
- }
+ info.flags = 0;
+ info.length = len;
+ info.low_limit = PAGE_SIZE;
+ info.high_limit = (current->mm->start_stack - 0x00200000);
+ info.align_mask = 0;
+ info.align_offset = 0;
+ addr = vm_unmapped_area(&info);
+ if (!(addr & ~PAGE_MASK))
+ goto success;
+ VM_BUG_ON(addr != -ENOMEM);
/* search from just above the WorkRAM area to the top of memory */
- addr = PAGE_ALIGN(0x80000000);
- limit = TASK_SIZE - len;
- if (addr <= limit) {
- vma = find_vma(current->mm, addr);
- for (; vma; vma = vma->vm_next) {
- if (addr > limit)
- break;
- if (addr + len <= vma->vm_start)
- goto success;
- addr = vma->vm_end;
- }
-
- if (!vma && addr <= limit)
- goto success;
- }
+ info.low_limit = PAGE_ALIGN(0x80000000);
+ info.high_limit = TASK_SIZE;
+ addr = vm_unmapped_area(&info);
+ if (!(addr & ~PAGE_MASK))
+ goto success;
+ VM_BUG_ON(addr != -ENOMEM);
#if 0
printk("[area] l=%lx (ENOMEM) f='%s'\n",
- len, filp ? filp->f_dentry->d_name.name : "");
+ len, filp ? filp->f_path.dentry->d_name.name : "");
#endif
return -ENOMEM;
success:
#if 0
printk("[area] l=%lx ad=%lx f='%s'\n",
- len, addr, filp ? filp->f_dentry->d_name.name : "");
+ len, addr, filp ? filp->f_path.dentry->d_name.name : "");
#endif
return addr;
} /* end arch_get_unmapped_area() */
diff --git a/arch/frv/mm/extable.c b/arch/frv/mm/extable.c
index caacf030ac7..6aea124f574 100644
--- a/arch/frv/mm/extable.c
+++ b/arch/frv/mm/extable.c
@@ -2,7 +2,6 @@
* linux/arch/frv/mm/extable.c
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <asm/uaccess.h>
diff --git a/arch/frv/mm/fault.c b/arch/frv/mm/fault.c
index 8b3eb50c510..9a66372fc7c 100644
--- a/arch/frv/mm/fault.c
+++ b/arch/frv/mm/fault.c
@@ -20,7 +20,6 @@
#include <linux/ptrace.h>
#include <linux/hardirq.h>
-#include <asm/system.h>
#include <asm/pgtable.h>
#include <asm/uaccess.h>
#include <asm/gdb-stub.h>
@@ -35,11 +34,12 @@ asmlinkage void do_page_fault(int datammu, unsigned long esr0, unsigned long ear
struct vm_area_struct *vma;
struct mm_struct *mm;
unsigned long _pme, lrai, lrad, fixup;
+ unsigned long flags = 0;
siginfo_t info;
pgd_t *pge;
pud_t *pue;
pte_t *pte;
- int write;
+ int fault;
#if 0
const char *atxc[16] = {
@@ -78,9 +78,12 @@ asmlinkage void do_page_fault(int datammu, unsigned long esr0, unsigned long ear
* If we're in an interrupt or have no user
* context, we must not take the fault..
*/
- if (in_interrupt() || !mm)
+ if (in_atomic() || !mm)
goto no_context;
+ if (user_mode(__frame))
+ flags |= FAULT_FLAG_USER;
+
down_read(&mm->mmap_sem);
vma = find_vma(mm, ear0);
@@ -129,7 +132,6 @@ asmlinkage void do_page_fault(int datammu, unsigned long esr0, unsigned long ear
*/
good_area:
info.si_code = SEGV_ACCERR;
- write = 0;
switch (esr0 & ESR0_ATXC) {
default:
/* handle write to write protected page */
@@ -140,7 +142,7 @@ asmlinkage void do_page_fault(int datammu, unsigned long esr0, unsigned long ear
#endif
if (!(vma->vm_flags & VM_WRITE))
goto bad_area;
- write = 1;
+ flags |= FAULT_FLAG_WRITE;
break;
/* handle read from protected page */
@@ -162,18 +164,18 @@ asmlinkage void do_page_fault(int datammu, unsigned long esr0, unsigned long ear
* make sure we exit gracefully rather than endlessly redo
* the fault.
*/
- switch (handle_mm_fault(mm, vma, ear0, write)) {
- case VM_FAULT_MINOR:
- current->min_flt++;
- break;
- case VM_FAULT_MAJOR:
- current->maj_flt++;
- break;
- case VM_FAULT_SIGBUS:
- goto do_sigbus;
- default:
- goto out_of_memory;
+ fault = handle_mm_fault(mm, vma, ear0, flags);
+ if (unlikely(fault & VM_FAULT_ERROR)) {
+ if (fault & VM_FAULT_OOM)
+ goto out_of_memory;
+ else if (fault & VM_FAULT_SIGBUS)
+ goto do_sigbus;
+ BUG();
}
+ if (fault & VM_FAULT_MAJOR)
+ current->maj_flt++;
+ else
+ current->min_flt++;
up_read(&mm->mmap_sem);
return;
@@ -256,10 +258,10 @@ asmlinkage void do_page_fault(int datammu, unsigned long esr0, unsigned long ear
*/
out_of_memory:
up_read(&mm->mmap_sem);
- printk("VM: killing process %s\n", current->comm);
- if (user_mode(__frame))
- do_exit(SIGKILL);
- goto no_context;
+ if (!user_mode(__frame))
+ goto no_context;
+ pagefault_out_of_memory();
+ return;
do_sigbus:
up_read(&mm->mmap_sem);
diff --git a/arch/frv/mm/highmem.c b/arch/frv/mm/highmem.c
index 7f77db7fabc..bed9a9bd3c1 100644
--- a/arch/frv/mm/highmem.c
+++ b/arch/frv/mm/highmem.c
@@ -37,5 +37,53 @@ struct page *kmap_atomic_to_page(void *ptr)
return virt_to_page(ptr);
}
+void *kmap_atomic(struct page *page)
+{
+ unsigned long paddr;
+ int type;
+
+ pagefault_disable();
+ type = kmap_atomic_idx_push();
+ paddr = page_to_phys(page);
+
+ switch (type) {
+ /*
+ * The first 4 primary maps are reserved for architecture code
+ */
+ case 0: return __kmap_atomic_primary(0, paddr, 6);
+ case 1: return __kmap_atomic_primary(0, paddr, 7);
+ case 2: return __kmap_atomic_primary(0, paddr, 8);
+ case 3: return __kmap_atomic_primary(0, paddr, 9);
+ case 4: return __kmap_atomic_primary(0, paddr, 10);
+
+ case 5 ... 5 + NR_TLB_LINES - 1:
+ return __kmap_atomic_secondary(type - 5, paddr);
+
+ default:
+ BUG();
+ return NULL;
+ }
+}
+EXPORT_SYMBOL(kmap_atomic);
+
+void __kunmap_atomic(void *kvaddr)
+{
+ int type = kmap_atomic_idx();
+ switch (type) {
+ case 0: __kunmap_atomic_primary(0, 6); break;
+ case 1: __kunmap_atomic_primary(0, 7); break;
+ case 2: __kunmap_atomic_primary(0, 8); break;
+ case 3: __kunmap_atomic_primary(0, 9); break;
+ case 4: __kunmap_atomic_primary(0, 10); break;
-EXPORT_SYMBOL(kmap_atomic_to_page);
+ case 5 ... 5 + NR_TLB_LINES - 1:
+ __kunmap_atomic_secondary(type - 5, kvaddr);
+ break;
+
+ default:
+ BUG();
+ }
+ kmap_atomic_idx_pop();
+ pagefault_enable();
+}
+EXPORT_SYMBOL(__kunmap_atomic);
diff --git a/arch/frv/mm/init.c b/arch/frv/mm/init.c
index 765088ea8a5..88a15974352 100644
--- a/arch/frv/mm/init.c
+++ b/arch/frv/mm/init.c
@@ -16,10 +16,10 @@
* - Copyright (C) 1995 Hamish Macdonald
*/
-#include <linux/config.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/pagemap.h>
+#include <linux/gfp.h>
#include <linux/swap.h>
#include <linux/mm.h>
#include <linux/kernel.h>
@@ -27,12 +27,12 @@
#include <linux/types.h>
#include <linux/bootmem.h>
#include <linux/highmem.h>
+#include <linux/module.h>
#include <asm/setup.h>
#include <asm/segment.h>
#include <asm/page.h>
#include <asm/pgtable.h>
-#include <asm/system.h>
#include <asm/mmu_context.h>
#include <asm/virtconvert.h>
#include <asm/sections.h>
@@ -40,8 +40,6 @@
#undef DEBUG
-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
-
/*
* BAD_PAGE is the page that is used for page faults when linux
* is out-of-memory. Older versions of linux just did a
@@ -57,38 +55,9 @@ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
*/
static unsigned long empty_bad_page_table;
static unsigned long empty_bad_page;
-unsigned long empty_zero_page;
-
-/*****************************************************************************/
-/*
- *
- */
-void show_mem(void)
-{
- unsigned long i;
- int free = 0, total = 0, reserved = 0, shared = 0;
-
- printk("\nMem-info:\n");
- show_free_areas();
- i = max_mapnr;
- while (i-- > 0) {
- struct page *page = &mem_map[i];
-
- total++;
- if (PageReserved(page))
- reserved++;
- else if (!page_count(page))
- free++;
- else
- shared += page_count(page) - 1;
- }
- printk("%d pages of RAM\n",total);
- printk("%d free pages\n",free);
- printk("%d reserved pages\n",reserved);
- printk("%d pages shared\n",shared);
-
-} /* end show_mem() */
+unsigned long empty_zero_page;
+EXPORT_SYMBOL(empty_zero_page);
/*****************************************************************************/
/*
@@ -99,7 +68,7 @@ void show_mem(void)
*/
void __init paging_init(void)
{
- unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
+ unsigned long zones_size[MAX_NR_ZONES] = {0, };
/* allocate some pages for kernel housekeeping tasks */
empty_bad_page_table = (unsigned long) alloc_bootmem_pages(PAGE_SIZE);
@@ -109,15 +78,13 @@ void __init paging_init(void)
memset((void *) empty_zero_page, 0, PAGE_SIZE);
#ifdef CONFIG_HIGHMEM
- if (num_physpages - num_mappedpages) {
+ if (get_num_physpages() - num_mappedpages) {
pgd_t *pge;
pud_t *pue;
pmd_t *pme;
pkmap_page_table = alloc_bootmem_pages(PAGE_SIZE);
- memset(pkmap_page_table, 0, PAGE_SIZE);
-
pge = swapper_pg_dir + pgd_index_k(PKMAP_BASE);
pue = pud_offset(pge, PKMAP_BASE);
pme = pmd_offset(pue, PKMAP_BASE);
@@ -127,10 +94,9 @@ void __init paging_init(void)
/* distribute the allocatable pages across the various zones and pass them to the allocator
*/
- zones_size[ZONE_DMA] = max_low_pfn - min_low_pfn;
- zones_size[ZONE_NORMAL] = 0;
+ zones_size[ZONE_NORMAL] = max_low_pfn - min_low_pfn;
#ifdef CONFIG_HIGHMEM
- zones_size[ZONE_HIGHMEM] = num_physpages - num_mappedpages;
+ zones_size[ZONE_HIGHMEM] = get_num_physpages() - num_mappedpages;
#endif
free_area_init(zones_size);
@@ -148,75 +114,34 @@ void __init paging_init(void)
*/
void __init mem_init(void)
{
- unsigned long npages = (memory_end - memory_start) >> PAGE_SHIFT;
- unsigned long tmp;
-#ifdef CONFIG_MMU
- unsigned long loop, pfn;
- int datapages = 0;
-#endif
- int codek = 0, datak = 0;
+ unsigned long code_size = _etext - _stext;
- /* this will put all memory onto the freelists */
- totalram_pages = free_all_bootmem();
+ /* this will put all low memory onto the freelists */
+ free_all_bootmem();
+#if defined(CONFIG_MMU) && defined(CONFIG_HIGHMEM)
+ {
+ unsigned long pfn;
-#ifdef CONFIG_MMU
- for (loop = 0 ; loop < npages ; loop++)
- if (PageReserved(&mem_map[loop]))
- datapages++;
-
-#ifdef CONFIG_HIGHMEM
- for (pfn = num_physpages - 1; pfn >= num_mappedpages; pfn--) {
- struct page *page = &mem_map[pfn];
-
- ClearPageReserved(page);
- set_page_count(page, 1);
- __free_page(page);
- totalram_pages++;
+ for (pfn = get_num_physpages() - 1;
+ pfn >= num_mappedpages; pfn--)
+ free_highmem_page(&mem_map[pfn]);
}
#endif
- codek = ((unsigned long) &_etext - (unsigned long) &_stext) >> 10;
- datak = datapages << (PAGE_SHIFT - 10);
-
-#else
- codek = (_etext - _stext) >> 10;
- datak = 0; //(_ebss - _sdata) >> 10;
-#endif
-
- tmp = nr_free_pages() << PAGE_SHIFT;
- printk("Memory available: %luKiB/%luKiB RAM, %luKiB/%luKiB ROM (%dKiB kernel code, %dKiB data)\n",
- tmp >> 10,
- npages << (PAGE_SHIFT - 10),
- (rom_length > 0) ? ((rom_length >> 10) - codek) : 0,
- rom_length >> 10,
- codek,
- datak
- );
-
+ mem_init_print_info(NULL);
+ if (rom_length > 0 && rom_length >= code_size)
+ printk("Memory available: %luKiB/%luKiB ROM\n",
+ (rom_length - code_size) >> 10, rom_length >> 10);
} /* end mem_init() */
/*****************************************************************************/
/*
* free the memory that was only required for initialisation
*/
-void __init free_initmem(void)
+void free_initmem(void)
{
#if defined(CONFIG_RAMKERNEL) && !defined(CONFIG_PROTECT_KERNEL)
- unsigned long start, end, addr;
-
- start = PAGE_ALIGN((unsigned long) &__init_begin); /* round up */
- end = ((unsigned long) &__init_end) & PAGE_MASK; /* round down */
-
- /* next to check that the page we free is not a partial page */
- for (addr = start; addr < end; addr += PAGE_SIZE) {
- ClearPageReserved(virt_to_page(addr));
- set_page_count(virt_to_page(addr), 1);
- free_page(addr);
- totalram_pages++;
- }
-
- printk("Freeing unused kernel memory: %ldKiB freed (0x%lx - 0x%lx)\n",
- (end - start) >> 10, start, end);
+ free_initmem_default(-1);
#endif
} /* end free_initmem() */
@@ -227,14 +152,6 @@ void __init free_initmem(void)
#ifdef CONFIG_BLK_DEV_INITRD
void __init free_initrd_mem(unsigned long start, unsigned long end)
{
- int pages = 0;
- for (; start < end; start += PAGE_SIZE) {
- ClearPageReserved(virt_to_page(start));
- set_page_count(virt_to_page(start), 1);
- free_page(start);
- totalram_pages++;
- pages++;
- }
- printk("Freeing initrd memory: %dKiB freed\n", (pages * PAGE_SIZE) >> 10);
+ free_reserved_area((void *)start, (void *)end, -1, "initrd");
} /* end free_initrd_mem() */
#endif
diff --git a/arch/frv/mm/kmap.c b/arch/frv/mm/kmap.c
index 539f45e6d15..e9217e605aa 100644
--- a/arch/frv/mm/kmap.c
+++ b/arch/frv/mm/kmap.c
@@ -10,7 +10,6 @@
* 2 of the License, or (at your option) any later version.
*/
-#include <linux/config.h>
#include <linux/mm.h>
#include <linux/kernel.h>
#include <linux/string.h>
@@ -22,7 +21,6 @@
#include <asm/page.h>
#include <asm/pgalloc.h>
#include <asm/io.h>
-#include <asm/system.h>
#undef DEBUG
@@ -31,24 +29,15 @@
* Map some physical address range into the kernel address space.
*/
-void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag)
+void __iomem *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag)
{
- return (void *)physaddr;
+ return (void __iomem *)physaddr;
}
/*
* Unmap a ioremap()ed region again
*/
-void iounmap(void *addr)
-{
-}
-
-/*
- * __iounmap unmaps nearly everything, so be careful
- * it doesn't free currently pointer/page tables anymore but it
- * wans't used anyway and might be added later.
- */
-void __iounmap(void *addr, unsigned long size)
+void iounmap(void volatile __iomem *addr)
{
}
diff --git a/arch/frv/mm/mmu-context.c b/arch/frv/mm/mmu-context.c
index f2c6866fc88..81757d55a5b 100644
--- a/arch/frv/mm/mmu-context.c
+++ b/arch/frv/mm/mmu-context.c
@@ -54,9 +54,9 @@ static unsigned get_cxn(mm_context_t *ctx)
/* find the first unallocated context number
* - 0 is reserved for the kernel
*/
- cxn = find_next_zero_bit(&cxn_bitmap, NR_CXN, 1);
+ cxn = find_next_zero_bit(cxn_bitmap, NR_CXN, 1);
if (cxn < NR_CXN) {
- set_bit(cxn, &cxn_bitmap);
+ set_bit(cxn, cxn_bitmap);
}
else {
/* none remaining - need to steal someone else's cxn */
@@ -138,7 +138,7 @@ void destroy_context(struct mm_struct *mm)
cxn_pinned = -1;
list_del_init(&ctx->id_link);
- clear_bit(ctx->id, &cxn_bitmap);
+ clear_bit(ctx->id, cxn_bitmap);
__flush_tlb_mm(ctx->id);
ctx->id = 0;
}
@@ -181,7 +181,7 @@ int cxn_pin_by_pid(pid_t pid)
/* get a handle on the mm_struct */
read_lock(&tasklist_lock);
- tsk = find_task_by_pid(pid);
+ tsk = find_task_by_vpid(pid);
if (tsk) {
ret = -EINVAL;
diff --git a/arch/frv/mm/pgalloc.c b/arch/frv/mm/pgalloc.c
index f76dd03ddd9..41907d25ed3 100644
--- a/arch/frv/mm/pgalloc.c
+++ b/arch/frv/mm/pgalloc.c
@@ -10,15 +10,15 @@
*/
#include <linux/sched.h>
-#include <linux/slab.h>
+#include <linux/gfp.h>
#include <linux/mm.h>
#include <linux/highmem.h>
+#include <linux/quicklist.h>
#include <asm/pgalloc.h>
#include <asm/page.h>
#include <asm/cacheflush.h>
pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__((aligned(PAGE_SIZE)));
-kmem_cache_t *pgd_cache;
pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
{
@@ -28,7 +28,7 @@ pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
return pte;
}
-struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
+pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address)
{
struct page *page;
@@ -37,8 +37,14 @@ struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
#else
page = alloc_pages(GFP_KERNEL|__GFP_REPEAT, 0);
#endif
- if (page)
- clear_highpage(page);
+ if (!page)
+ return NULL;
+
+ clear_highpage(page);
+ if (!pgtable_page_ctor(page)) {
+ __free_page(page);
+ return NULL;
+ }
flush_dcache_page(page);
return page;
}
@@ -75,7 +81,7 @@ void __set_pmd(pmd_t *pmdptr, unsigned long pmd)
* checks at dup_mmap(), exec(), and other mmlist addition points
* could be used. The locking scheme was chosen on the basis of
* manfred's recommendations and having no core impact whatsoever.
- * -- wli
+ * -- nyc
*/
DEFINE_SPINLOCK(pgd_lock);
struct page *pgd_list;
@@ -100,7 +106,7 @@ static inline void pgd_list_del(pgd_t *pgd)
set_page_private(next, (unsigned long) pprev);
}
-void pgd_ctor(void *pgd, kmem_cache_t *cache, unsigned long unused)
+void pgd_ctor(void *pgd)
{
unsigned long flags;
@@ -120,7 +126,7 @@ void pgd_ctor(void *pgd, kmem_cache_t *cache, unsigned long unused)
}
/* never called when PTRS_PER_PMD > 1 */
-void pgd_dtor(void *pgd, kmem_cache_t *cache, unsigned long unused)
+void pgd_dtor(void *pgd)
{
unsigned long flags; /* can be called from interrupt context */
@@ -131,29 +137,21 @@ void pgd_dtor(void *pgd, kmem_cache_t *cache, unsigned long unused)
pgd_t *pgd_alloc(struct mm_struct *mm)
{
- pgd_t *pgd;
-
- pgd = kmem_cache_alloc(pgd_cache, GFP_KERNEL);
- if (!pgd)
- return pgd;
-
- return pgd;
+ return quicklist_alloc(0, GFP_KERNEL, pgd_ctor);
}
-void pgd_free(pgd_t *pgd)
+void pgd_free(struct mm_struct *mm, pgd_t *pgd)
{
/* in the non-PAE case, clear_page_tables() clears user pgd entries */
- kmem_cache_free(pgd_cache, pgd);
+ quicklist_free(0, pgd_dtor, pgd);
}
void __init pgtable_cache_init(void)
{
- pgd_cache = kmem_cache_create("pgd",
- PTRS_PER_PGD * sizeof(pgd_t),
- PTRS_PER_PGD * sizeof(pgd_t),
- 0,
- pgd_ctor,
- pgd_dtor);
- if (!pgd_cache)
- panic("pgtable_cache_init(): Cannot create pgd cache");
}
+
+void check_pgt_cache(void)
+{
+ quicklist_trim(0, pgd_dtor, 25, 16);
+}
+
diff --git a/arch/frv/mm/tlb-flush.S b/arch/frv/mm/tlb-flush.S
index 6f43c74c5d9..79b3c70910a 100644
--- a/arch/frv/mm/tlb-flush.S
+++ b/arch/frv/mm/tlb-flush.S
@@ -10,7 +10,6 @@
*/
#include <linux/sys.h>
-#include <linux/config.h>
#include <linux/linkage.h>
#include <asm/page.h>
#include <asm/ptrace.h>
diff --git a/arch/frv/mm/tlb-miss.S b/arch/frv/mm/tlb-miss.S
index 8729f7d7c6e..f3ac019bb18 100644
--- a/arch/frv/mm/tlb-miss.S
+++ b/arch/frv/mm/tlb-miss.S
@@ -10,14 +10,12 @@
*/
#include <linux/sys.h>
-#include <linux/config.h>
#include <linux/linkage.h>
#include <asm/page.h>
#include <asm/pgtable.h>
-#include <asm/highmem.h>
#include <asm/spr-regs.h>
- .section .text
+ .section .text..tlbmiss
.balign 4
.globl __entry_insn_mmu_miss
diff --git a/arch/frv/mm/unaligned.c b/arch/frv/mm/unaligned.c
deleted file mode 100644
index 09b361443fc..00000000000
--- a/arch/frv/mm/unaligned.c
+++ /dev/null
@@ -1,218 +0,0 @@
-/* unaligned.c: unalignment fixup handler for CPUs on which it is supported (FR451 only)
- *
- * Copyright (C) 2004 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 License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include <linux/config.h>
-#include <linux/sched.h>
-#include <linux/signal.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/types.h>
-#include <linux/user.h>
-#include <linux/string.h>
-#include <linux/linkage.h>
-#include <linux/init.h>
-
-#include <asm/setup.h>
-#include <asm/system.h>
-#include <asm/uaccess.h>
-
-#if 0
-#define kdebug(fmt, ...) printk("FDPIC "fmt"\n" ,##__VA_ARGS__ )
-#else
-#define kdebug(fmt, ...) do {} while(0)
-#endif
-
-#define _MA_SIGNED 0x01
-#define _MA_HALF 0x02
-#define _MA_WORD 0x04
-#define _MA_DWORD 0x08
-#define _MA_SZ_MASK 0x0e
-#define _MA_LOAD 0x10
-#define _MA_STORE 0x20
-#define _MA_UPDATE 0x40
-#define _MA_IMM 0x80
-
-#define _MA_LDxU _MA_LOAD | _MA_UPDATE
-#define _MA_LDxI _MA_LOAD | _MA_IMM
-#define _MA_STxU _MA_STORE | _MA_UPDATE
-#define _MA_STxI _MA_STORE | _MA_IMM
-
-static const uint8_t tbl_LDGRk_reg[0x40] = {
- [0x02] = _MA_LOAD | _MA_HALF | _MA_SIGNED, /* LDSH @(GRi,GRj),GRk */
- [0x03] = _MA_LOAD | _MA_HALF, /* LDUH @(GRi,GRj),GRk */
- [0x04] = _MA_LOAD | _MA_WORD, /* LD @(GRi,GRj),GRk */
- [0x05] = _MA_LOAD | _MA_DWORD, /* LDD @(GRi,GRj),GRk */
- [0x12] = _MA_LDxU | _MA_HALF | _MA_SIGNED, /* LDSHU @(GRi,GRj),GRk */
- [0x13] = _MA_LDxU | _MA_HALF, /* LDUHU @(GRi,GRj),GRk */
- [0x14] = _MA_LDxU | _MA_WORD, /* LDU @(GRi,GRj),GRk */
- [0x15] = _MA_LDxU | _MA_DWORD, /* LDDU @(GRi,GRj),GRk */
-};
-
-static const uint8_t tbl_STGRk_reg[0x40] = {
- [0x01] = _MA_STORE | _MA_HALF, /* STH @(GRi,GRj),GRk */
- [0x02] = _MA_STORE | _MA_WORD, /* ST @(GRi,GRj),GRk */
- [0x03] = _MA_STORE | _MA_DWORD, /* STD @(GRi,GRj),GRk */
- [0x11] = _MA_STxU | _MA_HALF, /* STHU @(GRi,GRj),GRk */
- [0x12] = _MA_STxU | _MA_WORD, /* STU @(GRi,GRj),GRk */
- [0x13] = _MA_STxU | _MA_DWORD, /* STDU @(GRi,GRj),GRk */
-};
-
-static const uint8_t tbl_LDSTGRk_imm[0x80] = {
- [0x31] = _MA_LDxI | _MA_HALF | _MA_SIGNED, /* LDSHI @(GRi,d12),GRk */
- [0x32] = _MA_LDxI | _MA_WORD, /* LDI @(GRi,d12),GRk */
- [0x33] = _MA_LDxI | _MA_DWORD, /* LDDI @(GRi,d12),GRk */
- [0x36] = _MA_LDxI | _MA_HALF, /* LDUHI @(GRi,d12),GRk */
- [0x51] = _MA_STxI | _MA_HALF, /* STHI @(GRi,d12),GRk */
- [0x52] = _MA_STxI | _MA_WORD, /* STI @(GRi,d12),GRk */
- [0x53] = _MA_STxI | _MA_DWORD, /* STDI @(GRi,d12),GRk */
-};
-
-
-/*****************************************************************************/
-/*
- * see if we can handle the exception by fixing up a misaligned memory access
- */
-int handle_misalignment(unsigned long esr0, unsigned long ear0, unsigned long epcr0)
-{
- unsigned long insn, addr, *greg;
- int GRi, GRj, GRk, D12, op;
-
- union {
- uint64_t _64;
- uint32_t _32[2];
- uint16_t _16;
- uint8_t _8[8];
- } x;
-
- if (!(esr0 & ESR0_EAV) || !(epcr0 & EPCR0_V) || !(ear0 & 7))
- return -EAGAIN;
-
- epcr0 &= EPCR0_PC;
-
- if (__frame->pc != epcr0) {
- kdebug("MISALIGN: Execution not halted on excepting instruction\n");
- BUG();
- }
-
- if (__get_user(insn, (unsigned long *) epcr0) < 0)
- return -EFAULT;
-
- /* determine the instruction type first */
- switch ((insn >> 18) & 0x7f) {
- case 0x2:
- /* LDx @(GRi,GRj),GRk */
- op = tbl_LDGRk_reg[(insn >> 6) & 0x3f];
- break;
-
- case 0x3:
- /* STx GRk,@(GRi,GRj) */
- op = tbl_STGRk_reg[(insn >> 6) & 0x3f];
- break;
-
- default:
- op = tbl_LDSTGRk_imm[(insn >> 18) & 0x7f];
- break;
- }
-
- if (!op)
- return -EAGAIN;
-
- kdebug("MISALIGN: pc=%08lx insn=%08lx ad=%08lx op=%02x\n", epcr0, insn, ear0, op);
-
- memset(&x, 0xba, 8);
-
- /* validate the instruction parameters */
- greg = (unsigned long *) &__frame->tbr;
-
- GRi = (insn >> 12) & 0x3f;
- GRk = (insn >> 25) & 0x3f;
-
- if (GRi > 31 || GRk > 31)
- return -ENOENT;
-
- if (op & _MA_DWORD && GRk & 1)
- return -EINVAL;
-
- if (op & _MA_IMM) {
- D12 = insn & 0xfff;
- asm ("slli %0,#20,%0 ! srai %0,#20,%0" : "=r"(D12) : "0"(D12)); /* sign extend */
- addr = (GRi ? greg[GRi] : 0) + D12;
- }
- else {
- GRj = (insn >> 0) & 0x3f;
- if (GRj > 31)
- return -ENOENT;
- addr = (GRi ? greg[GRi] : 0) + (GRj ? greg[GRj] : 0);
- }
-
- if (addr != ear0) {
- kdebug("MISALIGN: Calculated addr (%08lx) does not match EAR0 (%08lx)\n",
- addr, ear0);
- return -EFAULT;
- }
-
- /* check the address is okay */
- if (user_mode(__frame) && ___range_ok(ear0, 8) < 0)
- return -EFAULT;
-
- /* perform the memory op */
- if (op & _MA_STORE) {
- /* perform a store */
- x._32[0] = 0;
- if (GRk != 0) {
- if (op & _MA_HALF) {
- x._16 = greg[GRk];
- }
- else {
- x._32[0] = greg[GRk];
- }
- }
- if (op & _MA_DWORD)
- x._32[1] = greg[GRk + 1];
-
- kdebug("MISALIGN: Store GR%d { %08x:%08x } -> %08lx (%dB)\n",
- GRk, x._32[1], x._32[0], addr, op & _MA_SZ_MASK);
-
- if (__memcpy_user((void *) addr, &x, op & _MA_SZ_MASK) != 0)
- return -EFAULT;
- }
- else {
- /* perform a load */
- if (__memcpy_user(&x, (void *) addr, op & _MA_SZ_MASK) != 0)
- return -EFAULT;
-
- if (op & _MA_HALF) {
- if (op & _MA_SIGNED)
- asm ("slli %0,#16,%0 ! srai %0,#16,%0"
- : "=r"(x._32[0]) : "0"(x._16));
- else
- asm ("sethi #0,%0"
- : "=r"(x._32[0]) : "0"(x._16));
- }
-
- kdebug("MISALIGN: Load %08lx (%dB) -> GR%d, { %08x:%08x }\n",
- addr, op & _MA_SZ_MASK, GRk, x._32[1], x._32[0]);
-
- if (GRk != 0)
- greg[GRk] = x._32[0];
- if (op & _MA_DWORD)
- greg[GRk + 1] = x._32[1];
- }
-
- /* update the base pointer if required */
- if (op & _MA_UPDATE)
- greg[GRi] = addr;
-
- /* well... we've done that insn */
- __frame->pc = __frame->pc + 4;
-
- return 0;
-} /* end handle_misalignment() */