aboutsummaryrefslogtreecommitdiffstats
path: root/arch/score
diff options
context:
space:
mode:
authorChen Liqin <liqin.chen@sunplusct.com>2009-06-12 10:01:00 -0400
committerArnd Bergmann <arnd@arndb.de>2009-06-19 05:38:47 -0400
commit6bc9a3966f0395419b09b2ec90f89f7f00341b37 (patch)
tree9c0d9d5376020266f5602501c8376d4a4f13142d /arch/score
parent0732f87761dbe417cb6e084b712d07e879e876ef (diff)
score: Add support for Sunplus S+core architecture
This is the complete set of new arch Score's files for linux. Score instruction set support 16bits, 32bits and 64bits instruction, Score SOC had been used in game machine and LCD TV. Signed-off-by: Chen Liqin <liqin.chen@sunplusct.com> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'arch/score')
-rw-r--r--arch/score/Kconfig141
-rw-r--r--arch/score/Kconfig.debug37
-rw-r--r--arch/score/Makefile43
-rw-r--r--arch/score/boot/Makefile15
-rw-r--r--arch/score/configs/spct6600_defconfig717
-rw-r--r--arch/score/include/asm/Kbuild3
-rw-r--r--arch/score/include/asm/asmmacro.h161
-rw-r--r--arch/score/include/asm/atomic.h6
-rw-r--r--arch/score/include/asm/auxvec.h4
-rw-r--r--arch/score/include/asm/bitops.h16
-rw-r--r--arch/score/include/asm/bitsperlong.h6
-rw-r--r--arch/score/include/asm/bug.h6
-rw-r--r--arch/score/include/asm/bugs.h6
-rw-r--r--arch/score/include/asm/byteorder.h6
-rw-r--r--arch/score/include/asm/cache.h7
-rw-r--r--arch/score/include/asm/cacheflush.h47
-rw-r--r--arch/score/include/asm/checksum.h235
-rw-r--r--arch/score/include/asm/cputime.h6
-rw-r--r--arch/score/include/asm/current.h6
-rw-r--r--arch/score/include/asm/delay.h21
-rw-r--r--arch/score/include/asm/device.h6
-rw-r--r--arch/score/include/asm/div64.h6
-rw-r--r--arch/score/include/asm/dma-mapping.h6
-rw-r--r--arch/score/include/asm/dma.h8
-rw-r--r--arch/score/include/asm/elf.h99
-rw-r--r--arch/score/include/asm/emergency-restart.h6
-rw-r--r--arch/score/include/asm/errno.h7
-rw-r--r--arch/score/include/asm/fcntl.h6
-rw-r--r--arch/score/include/asm/fixmap.h82
-rw-r--r--arch/score/include/asm/ftrace.h4
-rw-r--r--arch/score/include/asm/futex.h6
-rw-r--r--arch/score/include/asm/hardirq.h6
-rw-r--r--arch/score/include/asm/hw_irq.h4
-rw-r--r--arch/score/include/asm/io.h9
-rw-r--r--arch/score/include/asm/ioctl.h6
-rw-r--r--arch/score/include/asm/ioctls.h6
-rw-r--r--arch/score/include/asm/ipcbuf.h6
-rw-r--r--arch/score/include/asm/irq.h33
-rw-r--r--arch/score/include/asm/irq_regs.h6
-rw-r--r--arch/score/include/asm/irqflags.h111
-rw-r--r--arch/score/include/asm/kdebug.h6
-rw-r--r--arch/score/include/asm/kmap_types.h6
-rw-r--r--arch/score/include/asm/linkage.h4
-rw-r--r--arch/score/include/asm/local.h6
-rw-r--r--arch/score/include/asm/mman.h6
-rw-r--r--arch/score/include/asm/mmu.h6
-rw-r--r--arch/score/include/asm/mmu_context.h113
-rw-r--r--arch/score/include/asm/module.h39
-rw-r--r--arch/score/include/asm/msgbuf.h6
-rw-r--r--arch/score/include/asm/mutex.h6
-rw-r--r--arch/score/include/asm/page.h92
-rw-r--r--arch/score/include/asm/param.h6
-rw-r--r--arch/score/include/asm/pci.h4
-rw-r--r--arch/score/include/asm/percpu.h6
-rw-r--r--arch/score/include/asm/pgalloc.h83
-rw-r--r--arch/score/include/asm/pgtable-bits.h23
-rw-r--r--arch/score/include/asm/pgtable.h267
-rw-r--r--arch/score/include/asm/poll.h6
-rw-r--r--arch/score/include/asm/posix_types.h6
-rw-r--r--arch/score/include/asm/processor.h106
-rw-r--r--arch/score/include/asm/ptrace.h87
-rw-r--r--arch/score/include/asm/resource.h6
-rw-r--r--arch/score/include/asm/scatterlist.h6
-rw-r--r--arch/score/include/asm/scoreregs.h51
-rw-r--r--arch/score/include/asm/sections.h6
-rw-r--r--arch/score/include/asm/segment.h21
-rw-r--r--arch/score/include/asm/sembuf.h6
-rw-r--r--arch/score/include/asm/setup.h40
-rw-r--r--arch/score/include/asm/shmbuf.h6
-rw-r--r--arch/score/include/asm/shmparam.h6
-rw-r--r--arch/score/include/asm/sigcontext.h22
-rw-r--r--arch/score/include/asm/siginfo.h6
-rw-r--r--arch/score/include/asm/signal.h6
-rw-r--r--arch/score/include/asm/socket.h6
-rw-r--r--arch/score/include/asm/sockios.h6
-rw-r--r--arch/score/include/asm/stat.h6
-rw-r--r--arch/score/include/asm/statfs.h6
-rw-r--r--arch/score/include/asm/string.h8
-rw-r--r--arch/score/include/asm/swab.h6
-rw-r--r--arch/score/include/asm/syscalls.h9
-rw-r--r--arch/score/include/asm/system.h90
-rw-r--r--arch/score/include/asm/termbits.h6
-rw-r--r--arch/score/include/asm/termios.h6
-rw-r--r--arch/score/include/asm/thread_info.h103
-rw-r--r--arch/score/include/asm/timex.h8
-rw-r--r--arch/score/include/asm/tlb.h17
-rw-r--r--arch/score/include/asm/tlbflush.h142
-rw-r--r--arch/score/include/asm/topology.h6
-rw-r--r--arch/score/include/asm/types.h6
-rw-r--r--arch/score/include/asm/uaccess.h27
-rw-r--r--arch/score/include/asm/unaligned.h6
-rw-r--r--arch/score/include/asm/unistd.h8
-rw-r--r--arch/score/include/asm/user.h4
-rw-r--r--arch/score/kernel/Makefile10
-rw-r--r--arch/score/kernel/asm-offsets.c216
-rw-r--r--arch/score/kernel/entry.S542
-rw-r--r--arch/score/kernel/head.S70
-rw-r--r--arch/score/kernel/init_task.c49
-rw-r--r--arch/score/kernel/irq.c135
-rw-r--r--arch/score/kernel/module.c164
-rw-r--r--arch/score/kernel/process.c165
-rw-r--r--arch/score/kernel/ptrace.c465
-rw-r--r--arch/score/kernel/setup.c157
-rw-r--r--arch/score/kernel/signal.c355
-rw-r--r--arch/score/kernel/sys_score.c147
-rw-r--r--arch/score/kernel/time.c99
-rw-r--r--arch/score/kernel/traps.c349
-rw-r--r--arch/score/kernel/vmlinux.lds.S148
-rw-r--r--arch/score/lib/Makefile8
-rw-r--r--arch/score/lib/ashldi3.c46
-rw-r--r--arch/score/lib/ashrdi3.c48
-rw-r--r--arch/score/lib/checksum.S255
-rw-r--r--arch/score/lib/checksum_copy.c52
-rw-r--r--arch/score/lib/cmpdi2.c44
-rw-r--r--arch/score/lib/libgcc.h37
-rw-r--r--arch/score/lib/lshrdi3.c47
-rw-r--r--arch/score/lib/string.S196
-rw-r--r--arch/score/lib/ucmpdi2.c38
-rw-r--r--arch/score/mm/Makefile6
-rw-r--r--arch/score/mm/cache.c308
-rw-r--r--arch/score/mm/extable.c38
-rw-r--r--arch/score/mm/fault.c235
-rw-r--r--arch/score/mm/init.c173
-rw-r--r--arch/score/mm/pgtable.c60
-rw-r--r--arch/score/mm/tlb-miss.S199
-rw-r--r--arch/score/mm/tlb-score.c251
126 files changed, 8566 insertions, 0 deletions
diff --git a/arch/score/Kconfig b/arch/score/Kconfig
new file mode 100644
index 000000000000..55d413e6dcf2
--- /dev/null
+++ b/arch/score/Kconfig
@@ -0,0 +1,141 @@
1# For a description of the syntax of this configuration file,
2# see Documentation/kbuild/kconfig-language.txt.
3
4mainmenu "Linux/SCORE Kernel Configuration"
5
6menu "Machine selection"
7
8choice
9 prompt "System type"
10 default MACH_SPCT6600
11
12config ARCH_SCORE7
13 bool "SCORE7 processor"
14 select SYS_SUPPORTS_32BIT_KERNEL
15 select CPU_SCORE7
16 select GENERIC_HAS_IOMAP
17
18config MACH_SPCT6600
19 bool "SPCT6600 series based machines"
20 select SYS_SUPPORTS_32BIT_KERNEL
21 select CPU_SCORE7
22 select GENERIC_HAS_IOMAP
23
24config SCORE_SIM
25 bool "Score simulator"
26 select SYS_SUPPORTS_32BIT_KERNEL
27 select CPU_SCORE7
28 select GENERIC_HAS_IOMAP
29endchoice
30
31endmenu
32
33config CPU_SCORE7
34 bool
35
36config GENERIC_IOMAP
37 def_bool y
38
39config NO_DMA
40 bool
41 default y
42
43config RWSEM_GENERIC_SPINLOCK
44 def_bool y
45
46config GENERIC_FIND_NEXT_BIT
47 def_bool y
48
49config GENERIC_HWEIGHT
50 def_bool y
51
52config GENERIC_CALIBRATE_DELAY
53 def_bool y
54
55config GENERIC_CLOCKEVENTS
56 def_bool y
57
58config GENERIC_TIME
59 def_bool y
60
61config SCHED_NO_NO_OMIT_FRAME_POINTER
62 def_bool y
63
64config GENERIC_HARDIRQS_NO__DO_IRQ
65 def_bool y
66
67config GENERIC_SYSCALL_TABLE
68 def_bool y
69
70config SCORE_L1_CACHE_SHIFT
71 int
72 default "4"
73
74menu "Kernel type"
75
76config 32BIT
77 def_bool y
78
79config GENERIC_HARDIRQS
80 def_bool y
81
82config ARCH_FLATMEM_ENABLE
83 def_bool y
84
85config ARCH_POPULATES_NODE_MAP
86 def_bool y
87
88source "mm/Kconfig"
89
90config MEMORY_START
91 hex
92 default 0xa0000000
93
94source "kernel/time/Kconfig"
95source "kernel/Kconfig.hz"
96source "kernel/Kconfig.preempt"
97
98endmenu
99
100config RWSEM_GENERIC_SPINLOCK
101 def_bool y
102
103config LOCKDEP_SUPPORT
104 def_bool y
105
106config STACKTRACE_SUPPORT
107 def_bool y
108
109source "init/Kconfig"
110
111config PROBE_INITRD_HEADER
112 bool "Probe initrd header created by addinitrd"
113 depends on BLK_DEV_INITRD
114 help
115 Probe initrd header at the last page of kernel image.
116 Say Y here if you are using arch/score/boot/addinitrd.c to
117 add initrd or initramfs image to the kernel image.
118 Otherwise, say N.
119
120config MMU
121 def_bool y
122
123menu "Executable file formats"
124
125source "fs/Kconfig.binfmt"
126
127endmenu
128
129source "net/Kconfig"
130
131source "drivers/Kconfig"
132
133source "fs/Kconfig"
134
135source "arch/score/Kconfig.debug"
136
137source "security/Kconfig"
138
139source "crypto/Kconfig"
140
141source "lib/Kconfig"
diff --git a/arch/score/Kconfig.debug b/arch/score/Kconfig.debug
new file mode 100644
index 000000000000..451ed54ce646
--- /dev/null
+++ b/arch/score/Kconfig.debug
@@ -0,0 +1,37 @@
1menu "Kernel hacking"
2
3config TRACE_IRQFLAGS_SUPPORT
4 bool
5 default y
6
7source "lib/Kconfig.debug"
8
9config CMDLINE
10 string "Default kernel command string"
11 default ""
12 help
13 On some platforms, there is currently no way for the boot loader to
14 pass arguments to the kernel. For these platforms, you can supply
15 some command-line options at build time by entering them here. In
16 other cases you can specify kernel args so that you don't have
17 to set them up in board prom initialization routines.
18
19config DEBUG_STACK_USAGE
20 bool "Enable stack utilization instrumentation"
21 depends on DEBUG_KERNEL
22 help
23 Enables the display of the minimum amount of free stack which each
24 task has ever had available in the sysrq-T and sysrq-P debug output.
25
26 This option will slow down process creation somewhat.
27
28config RUNTIME_DEBUG
29 bool "Enable run-time debugging"
30 depends on DEBUG_KERNEL
31 help
32 If you say Y here, some debugging macros will do run-time checking.
33 If you say N here, those macros will mostly turn to no-ops. See
34 include/asm-score/debug.h for debuging macros.
35 If unsure, say N.
36
37endmenu
diff --git a/arch/score/Makefile b/arch/score/Makefile
new file mode 100644
index 000000000000..68e0cd06d5c9
--- /dev/null
+++ b/arch/score/Makefile
@@ -0,0 +1,43 @@
1#
2# arch/score/Makefile
3#
4# This file is subject to the terms and conditions of the GNU General Public
5# License. See the file "COPYING" in the main directory of this archive
6# for more details.
7#
8
9KBUILD_DEFCONFIG := spct6600_defconfig
10CROSS_COMPILE := score-linux-
11
12#
13# CPU-dependent compiler/assembler options for optimization.
14#
15cflags-y += -G0 -pipe -mel -mnhwloop -D__SCOREEL__ \
16 -D__linux__ -ffunction-sections -ffreestanding
17
18#
19# Board-dependent options and extra files
20#
21KBUILD_AFLAGS += $(cflags-y)
22KBUILD_CFLAGS += $(cflags-y)
23MODFLAGS += -mlong-calls
24LDFLAGS += --oformat elf32-littlescore
25LDFLAGS_vmlinux += -G0 -static -nostdlib
26
27head-y := arch/score/kernel/head.o
28libs-y += arch/score/lib/
29core-y += arch/score/kernel/ arch/score/mm/
30
31boot := arch/score/boot
32
33vmlinux.bin: vmlinux
34 $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
35
36archclean:
37 @$(MAKE) $(clean)=$(boot)
38
39define archhelp
40 echo ' vmlinux.bin - Raw binary boot image'
41 echo
42 echo ' These will be default as apropriate for a configured platform.'
43endef
diff --git a/arch/score/boot/Makefile b/arch/score/boot/Makefile
new file mode 100644
index 000000000000..0c5fbd0fb696
--- /dev/null
+++ b/arch/score/boot/Makefile
@@ -0,0 +1,15 @@
1#
2# arch/score/boot/Makefile
3#
4# This file is subject to the terms and conditions of the GNU General Public
5# License. See the file "COPYING" in the main directory of this archive
6# for more details.
7#
8
9targets := vmlinux.bin
10
11$(obj)/vmlinux.bin: vmlinux FORCE
12 $(call if_changed,objcopy)
13 @echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
14
15clean-files += vmlinux.bin
diff --git a/arch/score/configs/spct6600_defconfig b/arch/score/configs/spct6600_defconfig
new file mode 100644
index 000000000000..e064943b13d4
--- /dev/null
+++ b/arch/score/configs/spct6600_defconfig
@@ -0,0 +1,717 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.30-rc5
4# Fri Jun 12 18:57:07 2009
5#
6
7#
8# Machine selection
9#
10# CONFIG_ARCH_SCORE7 is not set
11CONFIG_MACH_SPCT6600=y
12# CONFIG_SCORE_SIM is not set
13CONFIG_CPU_SCORE7=y
14CONFIG_GENERIC_IOMAP=y
15CONFIG_NO_DMA=y
16CONFIG_RWSEM_GENERIC_SPINLOCK=y
17CONFIG_GENERIC_FIND_NEXT_BIT=y
18CONFIG_GENERIC_HWEIGHT=y
19CONFIG_GENERIC_CALIBRATE_DELAY=y
20CONFIG_GENERIC_CLOCKEVENTS=y
21CONFIG_GENERIC_TIME=y
22CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
23CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
24CONFIG_GENERIC_SYSCALL_TABLE=y
25CONFIG_SCORE_L1_CACHE_SHIFT=4
26
27#
28# Kernel type
29#
30CONFIG_32BIT=y
31CONFIG_GENERIC_HARDIRQS=y
32CONFIG_ARCH_FLATMEM_ENABLE=y
33CONFIG_ARCH_POPULATES_NODE_MAP=y
34CONFIG_SELECT_MEMORY_MODEL=y
35CONFIG_FLATMEM_MANUAL=y
36# CONFIG_DISCONTIGMEM_MANUAL is not set
37# CONFIG_SPARSEMEM_MANUAL is not set
38CONFIG_FLATMEM=y
39CONFIG_FLAT_NODE_MEM_MAP=y
40CONFIG_PAGEFLAGS_EXTENDED=y
41CONFIG_SPLIT_PTLOCK_CPUS=4
42# CONFIG_PHYS_ADDR_T_64BIT is not set
43CONFIG_ZONE_DMA_FLAG=0
44CONFIG_VIRT_TO_BUS=y
45CONFIG_UNEVICTABLE_LRU=y
46CONFIG_HAVE_MLOCK=y
47CONFIG_HAVE_MLOCKED_PAGE_BIT=y
48CONFIG_MEMORY_START=0xa0000000
49# CONFIG_NO_HZ is not set
50# CONFIG_HIGH_RES_TIMERS is not set
51CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
52CONFIG_HZ_100=y
53# CONFIG_HZ_250 is not set
54# CONFIG_HZ_300 is not set
55# CONFIG_HZ_1000 is not set
56CONFIG_HZ=100
57# CONFIG_SCHED_HRTICK is not set
58# CONFIG_PREEMPT_NONE is not set
59CONFIG_PREEMPT_VOLUNTARY=y
60# CONFIG_PREEMPT is not set
61CONFIG_LOCKDEP_SUPPORT=y
62CONFIG_STACKTRACE_SUPPORT=y
63CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
64
65#
66# General setup
67#
68CONFIG_EXPERIMENTAL=y
69CONFIG_BROKEN_ON_SMP=y
70CONFIG_INIT_ENV_ARG_LIMIT=32
71CONFIG_LOCALVERSION=""
72# CONFIG_LOCALVERSION_AUTO is not set
73CONFIG_SWAP=y
74CONFIG_SYSVIPC=y
75CONFIG_SYSVIPC_SYSCTL=y
76CONFIG_POSIX_MQUEUE=y
77CONFIG_POSIX_MQUEUE_SYSCTL=y
78CONFIG_BSD_PROCESS_ACCT=y
79# CONFIG_BSD_PROCESS_ACCT_V3 is not set
80# CONFIG_TASKSTATS is not set
81# CONFIG_AUDIT is not set
82
83#
84# RCU Subsystem
85#
86CONFIG_CLASSIC_RCU=y
87# CONFIG_TREE_RCU is not set
88# CONFIG_PREEMPT_RCU is not set
89# CONFIG_TREE_RCU_TRACE is not set
90# CONFIG_PREEMPT_RCU_TRACE is not set
91# CONFIG_IKCONFIG is not set
92CONFIG_LOG_BUF_SHIFT=12
93# CONFIG_GROUP_SCHED is not set
94# CONFIG_CGROUPS is not set
95CONFIG_SYSFS_DEPRECATED=y
96CONFIG_SYSFS_DEPRECATED_V2=y
97# CONFIG_RELAY is not set
98# CONFIG_NAMESPACES is not set
99CONFIG_BLK_DEV_INITRD=y
100CONFIG_INITRAMFS_SOURCE=""
101CONFIG_RD_GZIP=y
102# CONFIG_RD_BZIP2 is not set
103# CONFIG_RD_LZMA is not set
104# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
105CONFIG_SYSCTL=y
106CONFIG_ANON_INODES=y
107CONFIG_EMBEDDED=y
108CONFIG_SYSCTL_SYSCALL=y
109# CONFIG_KALLSYMS is not set
110# CONFIG_STRIP_ASM_SYMS is not set
111# CONFIG_HOTPLUG is not set
112CONFIG_PRINTK=y
113CONFIG_BUG=y
114CONFIG_ELF_CORE=y
115CONFIG_BASE_FULL=y
116CONFIG_FUTEX=y
117CONFIG_EPOLL=y
118CONFIG_SIGNALFD=y
119CONFIG_TIMERFD=y
120CONFIG_EVENTFD=y
121CONFIG_SHMEM=y
122CONFIG_AIO=y
123CONFIG_VM_EVENT_COUNTERS=y
124CONFIG_COMPAT_BRK=y
125CONFIG_SLAB=y
126# CONFIG_SLUB is not set
127# CONFIG_SLOB is not set
128# CONFIG_PROFILING is not set
129# CONFIG_MARKERS is not set
130# CONFIG_SLOW_WORK is not set
131# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
132CONFIG_SLABINFO=y
133CONFIG_RT_MUTEXES=y
134CONFIG_BASE_SMALL=0
135CONFIG_MODULES=y
136CONFIG_MODULE_FORCE_LOAD=y
137CONFIG_MODULE_UNLOAD=y
138CONFIG_MODULE_FORCE_UNLOAD=y
139# CONFIG_MODVERSIONS is not set
140# CONFIG_MODULE_SRCVERSION_ALL is not set
141CONFIG_BLOCK=y
142CONFIG_LBD=y
143# CONFIG_BLK_DEV_BSG is not set
144# CONFIG_BLK_DEV_INTEGRITY is not set
145
146#
147# IO Schedulers
148#
149CONFIG_IOSCHED_NOOP=y
150CONFIG_IOSCHED_AS=y
151CONFIG_IOSCHED_DEADLINE=y
152CONFIG_IOSCHED_CFQ=y
153# CONFIG_DEFAULT_AS is not set
154# CONFIG_DEFAULT_DEADLINE is not set
155CONFIG_DEFAULT_CFQ=y
156# CONFIG_DEFAULT_NOOP is not set
157CONFIG_DEFAULT_IOSCHED="cfq"
158# CONFIG_PROBE_INITRD_HEADER is not set
159CONFIG_MMU=y
160
161#
162# Executable file formats
163#
164CONFIG_BINFMT_ELF=y
165# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
166# CONFIG_HAVE_AOUT is not set
167CONFIG_BINFMT_MISC=y
168CONFIG_NET=y
169
170#
171# Networking options
172#
173# CONFIG_PACKET is not set
174CONFIG_UNIX=y
175CONFIG_XFRM=y
176# CONFIG_XFRM_USER is not set
177# CONFIG_XFRM_SUB_POLICY is not set
178# CONFIG_XFRM_MIGRATE is not set
179# CONFIG_XFRM_STATISTICS is not set
180CONFIG_NET_KEY=y
181# CONFIG_NET_KEY_MIGRATE is not set
182CONFIG_INET=y
183CONFIG_IP_MULTICAST=y
184# CONFIG_IP_ADVANCED_ROUTER is not set
185CONFIG_IP_FIB_HASH=y
186# CONFIG_IP_PNP is not set
187# CONFIG_NET_IPIP is not set
188# CONFIG_NET_IPGRE is not set
189# CONFIG_IP_MROUTE is not set
190CONFIG_ARPD=y
191# CONFIG_SYN_COOKIES is not set
192# CONFIG_INET_AH is not set
193# CONFIG_INET_ESP is not set
194# CONFIG_INET_IPCOMP is not set
195# CONFIG_INET_XFRM_TUNNEL is not set
196# CONFIG_INET_TUNNEL is not set
197CONFIG_INET_XFRM_MODE_TRANSPORT=y
198CONFIG_INET_XFRM_MODE_TUNNEL=y
199CONFIG_INET_XFRM_MODE_BEET=y
200# CONFIG_INET_LRO is not set
201CONFIG_INET_DIAG=y
202CONFIG_INET_TCP_DIAG=y
203# CONFIG_TCP_CONG_ADVANCED is not set
204CONFIG_TCP_CONG_CUBIC=y
205CONFIG_DEFAULT_TCP_CONG="cubic"
206# CONFIG_TCP_MD5SIG is not set
207# CONFIG_IPV6 is not set
208# CONFIG_NETLABEL is not set
209# CONFIG_NETWORK_SECMARK is not set
210# CONFIG_NETFILTER is not set
211# CONFIG_IP_DCCP is not set
212# CONFIG_IP_SCTP is not set
213# CONFIG_TIPC is not set
214# CONFIG_ATM is not set
215# CONFIG_BRIDGE is not set
216# CONFIG_NET_DSA is not set
217# CONFIG_VLAN_8021Q is not set
218# CONFIG_DECNET is not set
219# CONFIG_LLC2 is not set
220# CONFIG_IPX is not set
221# CONFIG_ATALK is not set
222# CONFIG_X25 is not set
223# CONFIG_LAPB is not set
224# CONFIG_ECONET is not set
225# CONFIG_WAN_ROUTER is not set
226# CONFIG_PHONET is not set
227# CONFIG_NET_SCHED is not set
228# CONFIG_DCB is not set
229
230#
231# Network testing
232#
233# CONFIG_NET_PKTGEN is not set
234# CONFIG_HAMRADIO is not set
235# CONFIG_CAN is not set
236# CONFIG_IRDA is not set
237# CONFIG_BT is not set
238# CONFIG_AF_RXRPC is not set
239# CONFIG_WIRELESS is not set
240# CONFIG_WIMAX is not set
241# CONFIG_RFKILL is not set
242# CONFIG_NET_9P is not set
243
244#
245# Device Drivers
246#
247
248#
249# Generic Driver Options
250#
251# CONFIG_STANDALONE is not set
252# CONFIG_PREVENT_FIRMWARE_BUILD is not set
253# CONFIG_SYS_HYPERVISOR is not set
254# CONFIG_CONNECTOR is not set
255# CONFIG_MTD is not set
256# CONFIG_PARPORT is not set
257CONFIG_BLK_DEV=y
258# CONFIG_BLK_DEV_COW_COMMON is not set
259CONFIG_BLK_DEV_LOOP=y
260CONFIG_BLK_DEV_CRYPTOLOOP=y
261# CONFIG_BLK_DEV_NBD is not set
262CONFIG_BLK_DEV_RAM=y
263CONFIG_BLK_DEV_RAM_COUNT=1
264CONFIG_BLK_DEV_RAM_SIZE=4096
265# CONFIG_BLK_DEV_XIP is not set
266# CONFIG_CDROM_PKTCDVD is not set
267# CONFIG_ATA_OVER_ETH is not set
268# CONFIG_MISC_DEVICES is not set
269
270#
271# SCSI device support
272#
273# CONFIG_RAID_ATTRS is not set
274# CONFIG_SCSI is not set
275# CONFIG_SCSI_DMA is not set
276# CONFIG_SCSI_NETLINK is not set
277# CONFIG_MD is not set
278CONFIG_NETDEVICES=y
279CONFIG_COMPAT_NET_DEV_OPS=y
280# CONFIG_DUMMY is not set
281# CONFIG_BONDING is not set
282# CONFIG_MACVLAN is not set
283# CONFIG_EQUALIZER is not set
284# CONFIG_TUN is not set
285# CONFIG_VETH is not set
286# CONFIG_NET_ETHERNET is not set
287# CONFIG_NETDEV_1000 is not set
288# CONFIG_NETDEV_10000 is not set
289
290#
291# Wireless LAN
292#
293# CONFIG_WLAN_PRE80211 is not set
294# CONFIG_WLAN_80211 is not set
295
296#
297# Enable WiMAX (Networking options) to see the WiMAX drivers
298#
299# CONFIG_WAN is not set
300# CONFIG_PPP is not set
301# CONFIG_SLIP is not set
302# CONFIG_NETCONSOLE is not set
303# CONFIG_NETPOLL is not set
304# CONFIG_NET_POLL_CONTROLLER is not set
305# CONFIG_ISDN is not set
306# CONFIG_PHONE is not set
307
308#
309# Input device support
310#
311CONFIG_INPUT=y
312# CONFIG_INPUT_FF_MEMLESS is not set
313# CONFIG_INPUT_POLLDEV is not set
314
315#
316# Userland interfaces
317#
318# CONFIG_INPUT_MOUSEDEV is not set
319# CONFIG_INPUT_JOYDEV is not set
320# CONFIG_INPUT_EVDEV is not set
321# CONFIG_INPUT_EVBUG is not set
322
323#
324# Input Device Drivers
325#
326# CONFIG_INPUT_KEYBOARD is not set
327# CONFIG_INPUT_MOUSE is not set
328# CONFIG_INPUT_JOYSTICK is not set
329# CONFIG_INPUT_TABLET is not set
330# CONFIG_INPUT_TOUCHSCREEN is not set
331# CONFIG_INPUT_MISC is not set
332
333#
334# Hardware I/O ports
335#
336# CONFIG_SERIO is not set
337# CONFIG_GAMEPORT is not set
338
339#
340# Character devices
341#
342CONFIG_VT=y
343CONFIG_CONSOLE_TRANSLATIONS=y
344CONFIG_VT_CONSOLE=y
345CONFIG_HW_CONSOLE=y
346# CONFIG_VT_HW_CONSOLE_BINDING is not set
347CONFIG_DEVKMEM=y
348CONFIG_SERIAL_NONSTANDARD=y
349# CONFIG_N_HDLC is not set
350# CONFIG_RISCOM8 is not set
351# CONFIG_SPECIALIX is not set
352# CONFIG_RIO is not set
353CONFIG_STALDRV=y
354
355#
356# Serial drivers
357#
358# CONFIG_SERIAL_8250 is not set
359
360#
361# Non-8250 serial port support
362#
363CONFIG_UNIX98_PTYS=y
364# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
365CONFIG_LEGACY_PTYS=y
366CONFIG_LEGACY_PTY_COUNT=256
367# CONFIG_IPMI_HANDLER is not set
368# CONFIG_HW_RANDOM is not set
369# CONFIG_RTC is not set
370# CONFIG_GEN_RTC is not set
371# CONFIG_R3964 is not set
372CONFIG_RAW_DRIVER=y
373CONFIG_MAX_RAW_DEVS=8192
374# CONFIG_TCG_TPM is not set
375# CONFIG_I2C is not set
376# CONFIG_SPI is not set
377# CONFIG_W1 is not set
378# CONFIG_POWER_SUPPLY is not set
379# CONFIG_HWMON is not set
380# CONFIG_THERMAL is not set
381# CONFIG_THERMAL_HWMON is not set
382# CONFIG_WATCHDOG is not set
383
384#
385# Multifunction device drivers
386#
387# CONFIG_MFD_CORE is not set
388# CONFIG_MFD_SM501 is not set
389# CONFIG_HTC_PASIC3 is not set
390# CONFIG_MFD_TMIO is not set
391# CONFIG_REGULATOR is not set
392
393#
394# Multimedia devices
395#
396
397#
398# Multimedia core support
399#
400# CONFIG_VIDEO_DEV is not set
401# CONFIG_DVB_CORE is not set
402# CONFIG_VIDEO_MEDIA is not set
403
404#
405# Multimedia drivers
406#
407# CONFIG_DAB is not set
408
409#
410# Graphics support
411#
412# CONFIG_VGASTATE is not set
413# CONFIG_VIDEO_OUTPUT_CONTROL is not set
414# CONFIG_FB is not set
415# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
416
417#
418# Display device support
419#
420# CONFIG_DISPLAY_SUPPORT is not set
421
422#
423# Console display driver support
424#
425# CONFIG_VGA_CONSOLE is not set
426CONFIG_DUMMY_CONSOLE=y
427# CONFIG_SOUND is not set
428# CONFIG_HID_SUPPORT is not set
429# CONFIG_USB_SUPPORT is not set
430# CONFIG_MMC is not set
431# CONFIG_MEMSTICK is not set
432# CONFIG_NEW_LEDS is not set
433# CONFIG_ACCESSIBILITY is not set
434# CONFIG_RTC_CLASS is not set
435# CONFIG_AUXDISPLAY is not set
436# CONFIG_UIO is not set
437# CONFIG_STAGING is not set
438
439#
440# File systems
441#
442CONFIG_EXT2_FS=y
443CONFIG_EXT2_FS_XATTR=y
444CONFIG_EXT2_FS_POSIX_ACL=y
445# CONFIG_EXT2_FS_SECURITY is not set
446# CONFIG_EXT2_FS_XIP is not set
447CONFIG_EXT3_FS=y
448# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
449CONFIG_EXT3_FS_XATTR=y
450CONFIG_EXT3_FS_POSIX_ACL=y
451# CONFIG_EXT3_FS_SECURITY is not set
452# CONFIG_EXT4_FS is not set
453CONFIG_JBD=y
454CONFIG_FS_MBCACHE=y
455# CONFIG_REISERFS_FS is not set
456# CONFIG_JFS_FS is not set
457CONFIG_FS_POSIX_ACL=y
458CONFIG_FILE_LOCKING=y
459# CONFIG_XFS_FS is not set
460# CONFIG_GFS2_FS is not set
461# CONFIG_OCFS2_FS is not set
462# CONFIG_BTRFS_FS is not set
463CONFIG_DNOTIFY=y
464CONFIG_INOTIFY=y
465CONFIG_INOTIFY_USER=y
466# CONFIG_QUOTA is not set
467CONFIG_AUTOFS_FS=y
468CONFIG_AUTOFS4_FS=y
469# CONFIG_FUSE_FS is not set
470CONFIG_GENERIC_ACL=y
471
472#
473# Caches
474#
475# CONFIG_FSCACHE is not set
476
477#
478# CD-ROM/DVD Filesystems
479#
480# CONFIG_ISO9660_FS is not set
481# CONFIG_UDF_FS is not set
482
483#
484# DOS/FAT/NT Filesystems
485#
486# CONFIG_MSDOS_FS is not set
487# CONFIG_VFAT_FS is not set
488# CONFIG_NTFS_FS is not set
489
490#
491# Pseudo filesystems
492#
493CONFIG_PROC_FS=y
494CONFIG_PROC_KCORE=y
495CONFIG_PROC_SYSCTL=y
496# CONFIG_PROC_PAGE_MONITOR is not set
497CONFIG_SYSFS=y
498CONFIG_TMPFS=y
499CONFIG_TMPFS_POSIX_ACL=y
500# CONFIG_HUGETLB_PAGE is not set
501# CONFIG_CONFIGFS_FS is not set
502CONFIG_MISC_FILESYSTEMS=y
503# CONFIG_ADFS_FS is not set
504# CONFIG_AFFS_FS is not set
505# CONFIG_ECRYPT_FS is not set
506# CONFIG_HFS_FS is not set
507# CONFIG_HFSPLUS_FS is not set
508# CONFIG_BEFS_FS is not set
509# CONFIG_BFS_FS is not set
510# CONFIG_EFS_FS is not set
511# CONFIG_CRAMFS is not set
512# CONFIG_SQUASHFS is not set
513# CONFIG_VXFS_FS is not set
514# CONFIG_MINIX_FS is not set
515# CONFIG_OMFS_FS is not set
516# CONFIG_HPFS_FS is not set
517# CONFIG_QNX4FS_FS is not set
518# CONFIG_ROMFS_FS is not set
519# CONFIG_SYSV_FS is not set
520# CONFIG_UFS_FS is not set
521# CONFIG_NILFS2_FS is not set
522CONFIG_NETWORK_FILESYSTEMS=y
523CONFIG_NFS_FS=y
524CONFIG_NFS_V3=y
525CONFIG_NFS_V3_ACL=y
526CONFIG_NFS_V4=y
527CONFIG_NFSD=y
528CONFIG_NFSD_V2_ACL=y
529CONFIG_NFSD_V3=y
530CONFIG_NFSD_V3_ACL=y
531CONFIG_NFSD_V4=y
532CONFIG_LOCKD=y
533CONFIG_LOCKD_V4=y
534CONFIG_EXPORTFS=y
535CONFIG_NFS_ACL_SUPPORT=y
536CONFIG_NFS_COMMON=y
537CONFIG_SUNRPC=y
538CONFIG_SUNRPC_GSS=y
539CONFIG_RPCSEC_GSS_KRB5=y
540# CONFIG_RPCSEC_GSS_SPKM3 is not set
541# CONFIG_SMB_FS is not set
542# CONFIG_CIFS is not set
543# CONFIG_NCP_FS is not set
544# CONFIG_CODA_FS is not set
545# CONFIG_AFS_FS is not set
546
547#
548# Partition Types
549#
550# CONFIG_PARTITION_ADVANCED is not set
551CONFIG_MSDOS_PARTITION=y
552# CONFIG_NLS is not set
553# CONFIG_DLM is not set
554
555#
556# Kernel hacking
557#
558CONFIG_TRACE_IRQFLAGS_SUPPORT=y
559# CONFIG_PRINTK_TIME is not set
560CONFIG_ENABLE_WARN_DEPRECATED=y
561CONFIG_ENABLE_MUST_CHECK=y
562CONFIG_FRAME_WARN=1024
563# CONFIG_MAGIC_SYSRQ is not set
564# CONFIG_UNUSED_SYMBOLS is not set
565# CONFIG_DEBUG_FS is not set
566# CONFIG_HEADERS_CHECK is not set
567# CONFIG_DEBUG_KERNEL is not set
568# CONFIG_DEBUG_MEMORY_INIT is not set
569# CONFIG_RCU_CPU_STALL_DETECTOR is not set
570# CONFIG_SYSCTL_SYSCALL_CHECK is not set
571CONFIG_TRACING_SUPPORT=y
572
573#
574# Tracers
575#
576# CONFIG_IRQSOFF_TRACER is not set
577# CONFIG_SCHED_TRACER is not set
578# CONFIG_CONTEXT_SWITCH_TRACER is not set
579# CONFIG_EVENT_TRACER is not set
580# CONFIG_BOOT_TRACER is not set
581# CONFIG_TRACE_BRANCH_PROFILING is not set
582# CONFIG_KMEMTRACE is not set
583# CONFIG_WORKQUEUE_TRACER is not set
584# CONFIG_BLK_DEV_IO_TRACE is not set
585# CONFIG_SAMPLES is not set
586CONFIG_CMDLINE=""
587
588#
589# Security options
590#
591CONFIG_KEYS=y
592CONFIG_KEYS_DEBUG_PROC_KEYS=y
593CONFIG_SECURITY=y
594# CONFIG_SECURITYFS is not set
595CONFIG_SECURITY_NETWORK=y
596# CONFIG_SECURITY_NETWORK_XFRM is not set
597# CONFIG_SECURITY_PATH is not set
598CONFIG_SECURITY_FILE_CAPABILITIES=y
599CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
600# CONFIG_SECURITY_TOMOYO is not set
601CONFIG_CRYPTO=y
602
603#
604# Crypto core or helper
605#
606# CONFIG_CRYPTO_FIPS is not set
607CONFIG_CRYPTO_ALGAPI=y
608CONFIG_CRYPTO_ALGAPI2=y
609CONFIG_CRYPTO_AEAD=y
610CONFIG_CRYPTO_AEAD2=y
611CONFIG_CRYPTO_BLKCIPHER=y
612CONFIG_CRYPTO_BLKCIPHER2=y
613CONFIG_CRYPTO_HASH=y
614CONFIG_CRYPTO_HASH2=y
615CONFIG_CRYPTO_RNG=y
616CONFIG_CRYPTO_RNG2=y
617CONFIG_CRYPTO_PCOMP=y
618CONFIG_CRYPTO_MANAGER=y
619CONFIG_CRYPTO_MANAGER2=y
620# CONFIG_CRYPTO_GF128MUL is not set
621CONFIG_CRYPTO_NULL=y
622CONFIG_CRYPTO_WORKQUEUE=y
623CONFIG_CRYPTO_CRYPTD=y
624# CONFIG_CRYPTO_AUTHENC is not set
625# CONFIG_CRYPTO_TEST is not set
626
627#
628# Authenticated Encryption with Associated Data
629#
630# CONFIG_CRYPTO_CCM is not set
631# CONFIG_CRYPTO_GCM is not set
632CONFIG_CRYPTO_SEQIV=y
633
634#
635# Block modes
636#
637CONFIG_CRYPTO_CBC=y
638# CONFIG_CRYPTO_CTR is not set
639# CONFIG_CRYPTO_CTS is not set
640# CONFIG_CRYPTO_ECB is not set
641# CONFIG_CRYPTO_LRW is not set
642# CONFIG_CRYPTO_PCBC is not set
643# CONFIG_CRYPTO_XTS is not set
644
645#
646# Hash modes
647#
648# CONFIG_CRYPTO_HMAC is not set
649# CONFIG_CRYPTO_XCBC is not set
650
651#
652# Digest
653#
654CONFIG_CRYPTO_CRC32C=y
655CONFIG_CRYPTO_MD4=y
656CONFIG_CRYPTO_MD5=y
657CONFIG_CRYPTO_MICHAEL_MIC=y
658# CONFIG_CRYPTO_RMD128 is not set
659# CONFIG_CRYPTO_RMD160 is not set
660# CONFIG_CRYPTO_RMD256 is not set
661# CONFIG_CRYPTO_RMD320 is not set
662# CONFIG_CRYPTO_SHA1 is not set
663# CONFIG_CRYPTO_SHA256 is not set
664# CONFIG_CRYPTO_SHA512 is not set
665# CONFIG_CRYPTO_TGR192 is not set
666# CONFIG_CRYPTO_WP512 is not set
667
668#
669# Ciphers
670#
671# CONFIG_CRYPTO_AES is not set
672# CONFIG_CRYPTO_ANUBIS is not set
673# CONFIG_CRYPTO_ARC4 is not set
674# CONFIG_CRYPTO_BLOWFISH is not set
675# CONFIG_CRYPTO_CAMELLIA is not set
676# CONFIG_CRYPTO_CAST5 is not set
677# CONFIG_CRYPTO_CAST6 is not set
678CONFIG_CRYPTO_DES=y
679# CONFIG_CRYPTO_FCRYPT is not set
680# CONFIG_CRYPTO_KHAZAD is not set
681# CONFIG_CRYPTO_SALSA20 is not set
682# CONFIG_CRYPTO_SEED is not set
683# CONFIG_CRYPTO_SERPENT is not set
684# CONFIG_CRYPTO_TEA is not set
685# CONFIG_CRYPTO_TWOFISH is not set
686
687#
688# Compression
689#
690# CONFIG_CRYPTO_DEFLATE is not set
691# CONFIG_CRYPTO_ZLIB is not set
692# CONFIG_CRYPTO_LZO is not set
693
694#
695# Random Number Generation
696#
697# CONFIG_CRYPTO_ANSI_CPRNG is not set
698# CONFIG_CRYPTO_HW is not set
699# CONFIG_BINARY_PRINTF is not set
700
701#
702# Library routines
703#
704CONFIG_BITREVERSE=y
705CONFIG_GENERIC_FIND_LAST_BIT=y
706CONFIG_CRC_CCITT=y
707CONFIG_CRC16=y
708# CONFIG_CRC_T10DIF is not set
709# CONFIG_CRC_ITU_T is not set
710CONFIG_CRC32=y
711# CONFIG_CRC7 is not set
712CONFIG_LIBCRC32C=y
713CONFIG_ZLIB_INFLATE=y
714CONFIG_DECOMPRESS_GZIP=y
715CONFIG_HAS_IOMEM=y
716CONFIG_HAS_IOPORT=y
717CONFIG_NLATTR=y
diff --git a/arch/score/include/asm/Kbuild b/arch/score/include/asm/Kbuild
new file mode 100644
index 000000000000..b367abd4620f
--- /dev/null
+++ b/arch/score/include/asm/Kbuild
@@ -0,0 +1,3 @@
1include include/asm-generic/Kbuild.asm
2
3header-y +=
diff --git a/arch/score/include/asm/asmmacro.h b/arch/score/include/asm/asmmacro.h
new file mode 100644
index 000000000000..a04a54cea25d
--- /dev/null
+++ b/arch/score/include/asm/asmmacro.h
@@ -0,0 +1,161 @@
1#ifndef _ASM_SCORE_ASMMACRO_H
2#define _ASM_SCORE_ASMMACRO_H
3
4#include <asm/asm-offsets.h>
5
6#ifdef __ASSEMBLY__
7
8.macro SAVE_ALL
9 mfcr r30, cr0
10 mv r31, r0
11 nop
12 /* if UMs == 1, change stack. */
13 slli.c r30, r30, 28
14 bpl 1f
15 la r31, kernelsp
16 lw r31, [r31]
171:
18 mv r30, r0
19 addri r0, r31, -PT_SIZE
20
21 sw r30, [r0, PT_R0]
22 .set r1
23 sw r1, [r0, PT_R1]
24 .set nor1
25 sw r2, [r0, PT_R2]
26 sw r3, [r0, PT_R3]
27 sw r4, [r0, PT_R4]
28 sw r5, [r0, PT_R5]
29 sw r6, [r0, PT_R6]
30 sw r7, [r0, PT_R7]
31
32 sw r8, [r0, PT_R8]
33 sw r9, [r0, PT_R9]
34 sw r10, [r0, PT_R10]
35 sw r11, [r0, PT_R11]
36 sw r12, [r0, PT_R12]
37 sw r13, [r0, PT_R13]
38 sw r14, [r0, PT_R14]
39 sw r15, [r0, PT_R15]
40
41 sw r16, [r0, PT_R16]
42 sw r17, [r0, PT_R17]
43 sw r18, [r0, PT_R18]
44 sw r19, [r0, PT_R19]
45 sw r20, [r0, PT_R20]
46 sw r21, [r0, PT_R21]
47 sw r22, [r0, PT_R22]
48 sw r23, [r0, PT_R23]
49
50 sw r24, [r0, PT_R24]
51 sw r25, [r0, PT_R25]
52 sw r25, [r0, PT_R25]
53 sw r26, [r0, PT_R26]
54 sw r27, [r0, PT_R27]
55
56 sw r28, [r0, PT_R28]
57 sw r29, [r0, PT_R29]
58 orri r28, r0, 0x1fff
59 li r31, 0x00001fff
60 xor r28, r28, r31
61
62 mfcehl r30, r31
63 sw r30, [r0, PT_CEH]
64 sw r31, [r0, PT_CEL]
65
66 mfcr r31, cr0
67 sw r31, [r0, PT_PSR]
68
69 mfcr r31, cr1
70 sw r31, [r0, PT_CONDITION]
71
72 mfcr r31, cr2
73 sw r31, [r0, PT_ECR]
74
75 mfcr r31, cr5
76 srli r31, r31, 1
77 slli r31, r31, 1
78 sw r31, [r0, PT_EPC]
79.endm
80
81.macro RESTORE_ALL_AND_RET
82 mfcr r30, cr0
83 srli r30, r30, 1
84 slli r30, r30, 1
85 mtcr r30, cr0
86 nop
87 nop
88 nop
89 nop
90 nop
91
92 .set r1
93 ldis r1, 0x00ff
94 and r30, r30, r1
95 not r1, r1
96 lw r31, [r0, PT_PSR]
97 and r31, r31, r1
98 .set nor1
99 or r31, r31, r30
100 mtcr r31, cr0
101 nop
102 nop
103 nop
104 nop
105 nop
106
107 lw r30, [r0, PT_CONDITION]
108 mtcr r30, cr1
109 nop
110 nop
111 nop
112 nop
113 nop
114
115 lw r30, [r0, PT_CEH]
116 lw r31, [r0, PT_CEL]
117 mtcehl r30, r31
118
119 .set r1
120 lw r1, [r0, PT_R1]
121 .set nor1
122 lw r2, [r0, PT_R2]
123 lw r3, [r0, PT_R3]
124 lw r4, [r0, PT_R4]
125 lw r5, [r0, PT_R5]
126 lw r6, [r0, PT_R6]
127 lw r7, [r0, PT_R7]
128
129 lw r8, [r0, PT_R8]
130 lw r9, [r0, PT_R9]
131 lw r10, [r0, PT_R10]
132 lw r11, [r0, PT_R11]
133 lw r12, [r0, PT_R12]
134 lw r13, [r0, PT_R13]
135 lw r14, [r0, PT_R14]
136 lw r15, [r0, PT_R15]
137
138 lw r16, [r0, PT_R16]
139 lw r17, [r0, PT_R17]
140 lw r18, [r0, PT_R18]
141 lw r19, [r0, PT_R19]
142 lw r20, [r0, PT_R20]
143 lw r21, [r0, PT_R21]
144 lw r22, [r0, PT_R22]
145 lw r23, [r0, PT_R23]
146
147 lw r24, [r0, PT_R24]
148 lw r25, [r0, PT_R25]
149 lw r26, [r0, PT_R26]
150 lw r27, [r0, PT_R27]
151 lw r28, [r0, PT_R28]
152 lw r29, [r0, PT_R29]
153
154 lw r30, [r0, PT_EPC]
155 lw r0, [r0, PT_R0]
156 mtcr r30, cr5
157 rte
158.endm
159
160#endif /* __ASSEMBLY__ */
161#endif /* _ASM_SCORE_ASMMACRO_H */
diff --git a/arch/score/include/asm/atomic.h b/arch/score/include/asm/atomic.h
new file mode 100644
index 000000000000..84eb8ddf9f3f
--- /dev/null
+++ b/arch/score/include/asm/atomic.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_ATOMIC_H
2#define _ASM_SCORE_ATOMIC_H
3
4#include <asm-generic/atomic.h>
5
6#endif /* _ASM_SCORE_ATOMIC_H */
diff --git a/arch/score/include/asm/auxvec.h b/arch/score/include/asm/auxvec.h
new file mode 100644
index 000000000000..f69151565aee
--- /dev/null
+++ b/arch/score/include/asm/auxvec.h
@@ -0,0 +1,4 @@
1#ifndef _ASM_SCORE_AUXVEC_H
2#define _ASM_SCORE_AUXVEC_H
3
4#endif /* _ASM_SCORE_AUXVEC_H */
diff --git a/arch/score/include/asm/bitops.h b/arch/score/include/asm/bitops.h
new file mode 100644
index 000000000000..2763b050fca8
--- /dev/null
+++ b/arch/score/include/asm/bitops.h
@@ -0,0 +1,16 @@
1#ifndef _ASM_SCORE_BITOPS_H
2#define _ASM_SCORE_BITOPS_H
3
4#include <asm/byteorder.h> /* swab32 */
5#include <asm/system.h> /* save_flags */
6
7/*
8 * clear_bit() doesn't provide any barrier for the compiler.
9 */
10#define smp_mb__before_clear_bit() barrier()
11#define smp_mb__after_clear_bit() barrier()
12
13#include <asm-generic/bitops.h>
14#include <asm-generic/bitops/__fls.h>
15
16#endif /* _ASM_SCORE_BITOPS_H */
diff --git a/arch/score/include/asm/bitsperlong.h b/arch/score/include/asm/bitsperlong.h
new file mode 100644
index 000000000000..86ff337aa459
--- /dev/null
+++ b/arch/score/include/asm/bitsperlong.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_BITSPERLONG_H
2#define _ASM_SCORE_BITSPERLONG_H
3
4#include <asm-generic/bitsperlong.h>
5
6#endif /* _ASM_SCORE_BITSPERLONG_H */
diff --git a/arch/score/include/asm/bug.h b/arch/score/include/asm/bug.h
new file mode 100644
index 000000000000..bb76a330bcf1
--- /dev/null
+++ b/arch/score/include/asm/bug.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_BUG_H
2#define _ASM_SCORE_BUG_H
3
4#include <asm-generic/bug.h>
5
6#endif /* _ASM_SCORE_BUG_H */
diff --git a/arch/score/include/asm/bugs.h b/arch/score/include/asm/bugs.h
new file mode 100644
index 000000000000..a062e1056bb3
--- /dev/null
+++ b/arch/score/include/asm/bugs.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_BUGS_H
2#define _ASM_SCORE_BUGS_H
3
4#include <asm-generic/bugs.h>
5
6#endif /* _ASM_SCORE_BUGS_H */
diff --git a/arch/score/include/asm/byteorder.h b/arch/score/include/asm/byteorder.h
new file mode 100644
index 000000000000..88cbebc79212
--- /dev/null
+++ b/arch/score/include/asm/byteorder.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_BYTEORDER_H
2#define _ASM_SCORE_BYTEORDER_H
3
4#include <linux/byteorder/little_endian.h>
5
6#endif /* _ASM_SCORE_BYTEORDER_H */
diff --git a/arch/score/include/asm/cache.h b/arch/score/include/asm/cache.h
new file mode 100644
index 000000000000..ae3d59f2d2c4
--- /dev/null
+++ b/arch/score/include/asm/cache.h
@@ -0,0 +1,7 @@
1#ifndef _ASM_SCORE_CACHE_H
2#define _ASM_SCORE_CACHE_H
3
4#define L1_CACHE_SHIFT 4
5#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
6
7#endif /* _ASM_SCORE_CACHE_H */
diff --git a/arch/score/include/asm/cacheflush.h b/arch/score/include/asm/cacheflush.h
new file mode 100644
index 000000000000..1c74628caf71
--- /dev/null
+++ b/arch/score/include/asm/cacheflush.h
@@ -0,0 +1,47 @@
1#ifndef _ASM_SCORE_CACHEFLUSH_H
2#define _ASM_SCORE_CACHEFLUSH_H
3
4/* Keep includes the same across arches. */
5#include <linux/mm.h>
6
7extern void (*flush_cache_all)(void);
8extern void (*flush_cache_mm)(struct mm_struct *mm);
9extern void (*flush_cache_range)(struct vm_area_struct *vma,
10 unsigned long start, unsigned long end);
11extern void (*flush_cache_page)(struct vm_area_struct *vma,
12 unsigned long page, unsigned long pfn);
13extern void (*flush_cache_sigtramp)(unsigned long addr);
14extern void (*flush_icache_all)(void);
15extern void (*flush_icache_range)(unsigned long start, unsigned long end);
16extern void (*flush_data_cache_page)(unsigned long addr);
17
18extern void s7_flush_cache_all(void);
19
20#define flush_cache_dup_mm(mm) do {} while (0)
21#define flush_dcache_page(page) do {} while (0)
22#define flush_dcache_mmap_lock(mapping) do {} while (0)
23#define flush_dcache_mmap_unlock(mapping) do {} while (0)
24#define flush_cache_vmap(start, end) do {} while (0)
25#define flush_cache_vunmap(start, end) do {} while (0)
26
27static inline void flush_icache_page(struct vm_area_struct *vma,
28 struct page *page)
29{
30 if (vma->vm_flags & VM_EXEC) {
31 void *v = page_address(page);
32 flush_icache_range((unsigned long) v,
33 (unsigned long) v + PAGE_SIZE);
34 }
35}
36
37#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
38 memcpy(dst, src, len)
39
40#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
41 do { \
42 memcpy(dst, src, len); \
43 if ((vma->vm_flags & VM_EXEC)) \
44 flush_cache_page(vma, vaddr, page_to_pfn(page));\
45 } while (0)
46
47#endif /* _ASM_SCORE_CACHEFLUSH_H */
diff --git a/arch/score/include/asm/checksum.h b/arch/score/include/asm/checksum.h
new file mode 100644
index 000000000000..f909ac3144a4
--- /dev/null
+++ b/arch/score/include/asm/checksum.h
@@ -0,0 +1,235 @@
1#ifndef _ASM_SCORE_CHECKSUM_H
2#define _ASM_SCORE_CHECKSUM_H
3
4#include <linux/in6.h>
5#include <asm/uaccess.h>
6
7/*
8 * computes the checksum of a memory block at buff, length len,
9 * and adds in "sum" (32-bit)
10 *
11 * returns a 32-bit number suitable for feeding into itself
12 * or csum_tcpudp_magic
13 *
14 * this function must be called with even lengths, except
15 * for the last fragment, which may be odd
16 *
17 * it's best to have buff aligned on a 32-bit boundary
18 */
19unsigned int csum_partial(const void *buff, int len, __wsum sum);
20unsigned int csum_partial_copy_from_user(const char *src, char *dst, int len,
21 unsigned int sum, int *csum_err);
22unsigned int csum_partial_copy(const char *src, char *dst,
23 int len, unsigned int sum);
24
25/*
26 * this is a new version of the above that records errors it finds in *errp,
27 * but continues and zeros the rest of the buffer.
28 */
29
30/*
31 * Copy and checksum to user
32 */
33#define HAVE_CSUM_COPY_USER
34static inline
35__wsum csum_and_copy_to_user(const void *src, void __user *dst, int len,
36 __wsum sum, int *err_ptr)
37{
38 sum = csum_partial(src, len, sum);
39 if (copy_to_user(dst, src, len)) {
40 *err_ptr = -EFAULT;
41 return (__force __wsum) -1; /* invalid checksum */
42 }
43 return sum;
44}
45
46
47#define csum_partial_copy_nocheck csum_partial_copy
48/*
49 * Fold a partial checksum without adding pseudo headers
50 */
51
52static inline __sum16 csum_fold(__wsum sum)
53{
54 /* the while loop is unnecessary really, it's always enough with two
55 iterations */
56 __asm__ __volatile__(
57 ".set volatile\n\t"
58 ".set\tr1\n\t"
59 "slli\tr1,%0, 16\n\t"
60 "add\t%0,%0, r1\n\t"
61 "cmp.c\tr1, %0\n\t"
62 "srli\t%0, %0, 16\n\t"
63 "bleu\t1f\n\t"
64 "addi\t%0, 0x1\n\t"
65 "1:ldi\tr30, 0xffff\n\t"
66 "xor\t%0, %0, r30\n\t"
67 "slli\t%0, %0, 16\n\t"
68 "srli\t%0, %0, 16\n\t"
69 ".set\tnor1\n\t"
70 ".set optimize\n\t"
71 : "=r" (sum)
72 : "0" (sum));
73 return sum;
74}
75
76/*
77 * This is a version of ip_compute_csum() optimized for IP headers,
78 * which always checksum on 4 octet boundaries.
79 *
80 * By Jorge Cwik <jorge@laser.satlink.net>, adapted for linux by
81 * Arnt Gulbrandsen.
82 */
83static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
84{
85 unsigned int sum;
86 unsigned long dummy;
87
88 __asm__ __volatile__(
89 ".set volatile\n\t"
90 ".set\tnor1\n\t"
91 "lw\t%0, [%1]\n\t"
92 "subri\t%2, %2, 4\n\t"
93 "slli\t%2, %2, 2\n\t"
94 "lw\t%3, [%1, 4]\n\t"
95 "add\t%2, %2, %1\n\t"
96 "add\t%0, %0, %3\n\t"
97 "cmp.c\t%3, %0\n\t"
98 "lw\t%3, [%1, 8]\n\t"
99 "bleu\t1f\n\t"
100 "addi\t%0, 0x1\n\t"
101 "1:\n\t"
102 "add\t%0, %0, %3\n\t"
103 "cmp.c\t%3, %0\n\t"
104 "lw\t%3, [%1, 12]\n\t"
105 "bleu\t1f\n\t"
106 "addi\t%0, 0x1\n\t"
107 "1:add\t%0, %0, %3\n\t"
108 "cmp.c\t%3, %0\n\t"
109 "bleu\t1f\n\t"
110 "addi\t%0, 0x1\n"
111
112 "1:\tlw\t%3, [%1, 16]\n\t"
113 "addi\t%1, 4\n\t"
114 "add\t%0, %0, %3\n\t"
115 "cmp.c\t%3, %0\n\t"
116 "bleu\t2f\n\t"
117 "addi\t%0, 0x1\n"
118 "2:cmp.c\t%2, %1\n\t"
119 "bne\t1b\n\t"
120
121 ".set\tr1\n\t"
122 ".set optimize\n\t"
123 : "=&r" (sum), "=&r" (iph), "=&r" (ihl), "=&r" (dummy)
124 : "1" (iph), "2" (ihl));
125
126 return csum_fold(sum);
127}
128
129static inline __wsum
130csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
131 unsigned short proto, __wsum sum)
132{
133 unsigned long tmp = (ntohs(len) << 16) + proto * 256;
134 __asm__ __volatile__(
135 ".set volatile\n\t"
136 "add\t%0, %0, %2\n\t"
137 "cmp.c\t%2, %0\n\t"
138 "bleu\t1f\n\t"
139 "addi\t%0, 0x1\n\t"
140 "1:\n\t"
141 "add\t%0, %0, %3\n\t"
142 "cmp.c\t%3, %0\n\t"
143 "bleu\t1f\n\t"
144 "addi\t%0, 0x1\n\t"
145 "1:\n\t"
146 "add\t%0, %0, %4\n\t"
147 "cmp.c\t%4, %0\n\t"
148 "bleu\t1f\n\t"
149 "addi\t%0, 0x1\n\t"
150 "1:\n\t"
151 ".set optimize\n\t"
152 : "=r" (sum)
153 : "0" (daddr), "r"(saddr),
154 "r" (tmp),
155 "r" (sum));
156 return sum;
157}
158
159/*
160 * computes the checksum of the TCP/UDP pseudo-header
161 * returns a 16-bit checksum, already complemented
162 */
163static inline __sum16
164csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len,
165 unsigned short proto, __wsum sum)
166{
167 return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
168}
169
170/*
171 * this routine is used for miscellaneous IP-like checksums, mainly
172 * in icmp.c
173 */
174
175static inline unsigned short ip_compute_csum(const void *buff, int len)
176{
177 return csum_fold(csum_partial(buff, len, 0));
178}
179
180#define _HAVE_ARCH_IPV6_CSUM
181static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
182 const struct in6_addr *daddr,
183 __u32 len, unsigned short proto,
184 __wsum sum)
185{
186 __asm__ __volatile__(
187 ".set\tnoreorder\t\t\t# csum_ipv6_magic\n\t"
188 ".set\tnoat\n\t"
189 "addu\t%0, %5\t\t\t# proto (long in network byte order)\n\t"
190 "sltu\t$1, %0, %5\n\t"
191 "addu\t%0, $1\n\t"
192 "addu\t%0, %6\t\t\t# csum\n\t"
193 "sltu\t$1, %0, %6\n\t"
194 "lw\t%1, 0(%2)\t\t\t# four words source address\n\t"
195 "addu\t%0, $1\n\t"
196 "addu\t%0, %1\n\t"
197 "sltu\t$1, %0, %1\n\t"
198 "lw\t%1, 4(%2)\n\t"
199 "addu\t%0, $1\n\t"
200 "addu\t%0, %1\n\t"
201 "sltu\t$1, %0, %1\n\t"
202 "lw\t%1, 8(%2)\n\t"
203 "addu\t%0, $1\n\t"
204 "addu\t%0, %1\n\t"
205 "sltu\t$1, %0, %1\n\t"
206 "lw\t%1, 12(%2)\n\t"
207 "addu\t%0, $1\n\t"
208 "addu\t%0, %1\n\t"
209 "sltu\t$1, %0, %1\n\t"
210 "lw\t%1, 0(%3)\n\t"
211 "addu\t%0, $1\n\t"
212 "addu\t%0, %1\n\t"
213 "sltu\t$1, %0, %1\n\t"
214 "lw\t%1, 4(%3)\n\t"
215 "addu\t%0, $1\n\t"
216 "addu\t%0, %1\n\t"
217 "sltu\t$1, %0, %1\n\t"
218 "lw\t%1, 8(%3)\n\t"
219 "addu\t%0, $1\n\t"
220 "addu\t%0, %1\n\t"
221 "sltu\t$1, %0, %1\n\t"
222 "lw\t%1, 12(%3)\n\t"
223 "addu\t%0, $1\n\t"
224 "addu\t%0, %1\n\t"
225 "sltu\t$1, %0, %1\n\t"
226 "addu\t%0, $1\t\t\t# Add final carry\n\t"
227 ".set\tnoat\n\t"
228 ".set\tnoreorder"
229 : "=r" (sum), "=r" (proto)
230 : "r" (saddr), "r" (daddr),
231 "0" (htonl(len)), "1" (htonl(proto)), "r" (sum));
232
233 return csum_fold(sum);
234}
235#endif /* _ASM_SCORE_CHECKSUM_H */
diff --git a/arch/score/include/asm/cputime.h b/arch/score/include/asm/cputime.h
new file mode 100644
index 000000000000..1fced99f0d67
--- /dev/null
+++ b/arch/score/include/asm/cputime.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_CPUTIME_H
2#define _ASM_SCORE_CPUTIME_H
3
4#include <asm-generic/cputime.h>
5
6#endif /* _ASM_SCORE_CPUTIME_H */
diff --git a/arch/score/include/asm/current.h b/arch/score/include/asm/current.h
new file mode 100644
index 000000000000..16eae9cbaf1a
--- /dev/null
+++ b/arch/score/include/asm/current.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_CURRENT_H
2#define _ASM_SCORE_CURRENT_H
3
4#include <asm-generic/current.h>
5
6#endif /* _ASM_SCORE_CURRENT_H */
diff --git a/arch/score/include/asm/delay.h b/arch/score/include/asm/delay.h
new file mode 100644
index 000000000000..ad716f6d922d
--- /dev/null
+++ b/arch/score/include/asm/delay.h
@@ -0,0 +1,21 @@
1#ifndef _ASM_SCORE_DELAY_H
2#define _ASM_SCORE_DELAY_H
3
4static inline void __delay(unsigned long loops)
5{
6 __asm__ __volatile__ (
7 "1:\tsubi\t%0,1\n\t"
8 "cmpz.c\t%0\n\t"
9 "bne\t1b\n\t"
10 : "=r" (loops)
11 : "0" (loops));
12}
13
14static inline void __udelay(unsigned long usecs)
15{
16 __delay(usecs);
17}
18
19#define udelay(usecs) __udelay(usecs)
20
21#endif /* _ASM_SCORE_DELAY_H */
diff --git a/arch/score/include/asm/device.h b/arch/score/include/asm/device.h
new file mode 100644
index 000000000000..2dc7cc5d5ef9
--- /dev/null
+++ b/arch/score/include/asm/device.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_DEVICE_H
2#define _ASM_SCORE_DEVICE_H
3
4#include <asm-generic/device.h>
5
6#endif /* _ASM_SCORE_DEVICE_H */
diff --git a/arch/score/include/asm/div64.h b/arch/score/include/asm/div64.h
new file mode 100644
index 000000000000..75fae19824eb
--- /dev/null
+++ b/arch/score/include/asm/div64.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_DIV64_H
2#define _ASM_SCORE_DIV64_H
3
4#include <asm-generic/div64.h>
5
6#endif /* _ASM_SCORE_DIV64_H */
diff --git a/arch/score/include/asm/dma-mapping.h b/arch/score/include/asm/dma-mapping.h
new file mode 100644
index 000000000000..f9c0193c7a53
--- /dev/null
+++ b/arch/score/include/asm/dma-mapping.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_DMA_MAPPING_H
2#define _ASM_SCORE_DMA_MAPPING_H
3
4#include <asm-generic/dma-mapping-broken.h>
5
6#endif /* _ASM_SCORE_DMA_MAPPING_H */
diff --git a/arch/score/include/asm/dma.h b/arch/score/include/asm/dma.h
new file mode 100644
index 000000000000..9f44185298bf
--- /dev/null
+++ b/arch/score/include/asm/dma.h
@@ -0,0 +1,8 @@
1#ifndef _ASM_SCORE_DMA_H
2#define _ASM_SCORE_DMA_H
3
4#include <asm/io.h>
5
6#define MAX_DMA_ADDRESS (0)
7
8#endif /* _ASM_SCORE_DMA_H */
diff --git a/arch/score/include/asm/elf.h b/arch/score/include/asm/elf.h
new file mode 100644
index 000000000000..832436375ac3
--- /dev/null
+++ b/arch/score/include/asm/elf.h
@@ -0,0 +1,99 @@
1#ifndef _ASM_SCORE_ELF_H
2#define _ASM_SCORE_ELF_H
3
4/* ELF register definitions */
5#define ELF_NGREG 45
6#define ELF_NFPREG 33
7#define EM_SCORE7 135
8
9/* Relocation types. */
10#define R_SCORE_NONE 0
11#define R_SCORE_HI16 1
12#define R_SCORE_LO16 2
13#define R_SCORE_BCMP 3
14#define R_SCORE_24 4
15#define R_SCORE_PC19 5
16#define R_SCORE16_11 6
17#define R_SCORE16_PC8 7
18#define R_SCORE_ABS32 8
19#define R_SCORE_ABS16 9
20#define R_SCORE_DUMMY2 10
21#define R_SCORE_GP15 11
22#define R_SCORE_GNU_VTINHERIT 12
23#define R_SCORE_GNU_VTENTRY 13
24#define R_SCORE_GOT15 14
25#define R_SCORE_GOT_LO16 15
26#define R_SCORE_CALL15 16
27#define R_SCORE_GPREL32 17
28#define R_SCORE_REL32 18
29#define R_SCORE_DUMMY_HI16 19
30#define R_SCORE_IMM30 20
31#define R_SCORE_IMM32 21
32
33typedef unsigned long elf_greg_t;
34typedef elf_greg_t elf_gregset_t[ELF_NGREG];
35
36typedef double elf_fpreg_t;
37typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
38
39#define elf_check_arch(x) ((x)->e_machine == EM_SCORE7)
40
41/*
42 * These are used to set parameters in the core dumps.
43 */
44#define ELF_CLASS ELFCLASS32
45
46/*
47 * These are used to set parameters in the core dumps.
48 */
49#define ELF_DATA ELFDATA2LSB
50#define ELF_ARCH EM_SCORE7
51
52#define SET_PERSONALITY(ex) \
53do { \
54 set_personality(PER_LINUX); \
55} while (0)
56
57struct task_struct;
58struct pt_regs;
59
60#define USE_ELF_CORE_DUMP
61#define ELF_EXEC_PAGESIZE PAGE_SIZE
62
63/* This yields a mask that user programs can use to figure out what
64 instruction set this cpu supports. This could be done in userspace,
65 but it's not easy, and we've already done it here. */
66
67#define ELF_HWCAP (0)
68
69/* This yields a string that ld.so will use to load implementation
70 specific libraries for optimization. This is more specific in
71 intent than poking at uname or /proc/cpuinfo.
72
73 For the moment, we have only optimizations for the Intel generations,
74 but that could change... */
75
76#define ELF_PLATFORM (NULL)
77
78#define ELF_PLAT_INIT(_r, load_addr) \
79do { \
80 _r->regs[1] = _r->regs[2] = _r->regs[3] = _r->regs[4] = 0; \
81 _r->regs[5] = _r->regs[6] = _r->regs[7] = _r->regs[8] = 0; \
82 _r->regs[9] = _r->regs[10] = _r->regs[11] = _r->regs[12] = 0; \
83 _r->regs[13] = _r->regs[14] = _r->regs[15] = _r->regs[16] = 0; \
84 _r->regs[17] = _r->regs[18] = _r->regs[19] = _r->regs[20] = 0; \
85 _r->regs[21] = _r->regs[22] = _r->regs[23] = _r->regs[24] = 0; \
86 _r->regs[25] = _r->regs[26] = _r->regs[27] = _r->regs[28] = 0; \
87 _r->regs[30] = _r->regs[31] = 0; \
88} while (0)
89
90/* This is the location that an ET_DYN program is loaded if exec'ed. Typical
91 use of this is to invoke "./ld.so someprog" to test out a new version of
92 the loader. We need to make sure that it is out of the way of the program
93 that it will "exec", and that there is sufficient room for the brk. */
94
95#ifndef ELF_ET_DYN_BASE
96#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
97#endif
98
99#endif /* _ASM_SCORE_ELF_H */
diff --git a/arch/score/include/asm/emergency-restart.h b/arch/score/include/asm/emergency-restart.h
new file mode 100644
index 000000000000..ca31e9803a8a
--- /dev/null
+++ b/arch/score/include/asm/emergency-restart.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_EMERGENCY_RESTART_H
2#define _ASM_SCORE_EMERGENCY_RESTART_H
3
4#include <asm-generic/emergency-restart.h>
5
6#endif /* _ASM_SCORE_EMERGENCY_RESTART_H */
diff --git a/arch/score/include/asm/errno.h b/arch/score/include/asm/errno.h
new file mode 100644
index 000000000000..7cd3e1f07c0b
--- /dev/null
+++ b/arch/score/include/asm/errno.h
@@ -0,0 +1,7 @@
1#ifndef _ASM_SCORE_ERRNO_H
2#define _ASM_SCORE_ERRNO_H
3
4#include <asm-generic/errno.h>
5#define EMAXERRNO 1024
6
7#endif /* _ASM_SCORE_ERRNO_H */
diff --git a/arch/score/include/asm/fcntl.h b/arch/score/include/asm/fcntl.h
new file mode 100644
index 000000000000..03968a3103a4
--- /dev/null
+++ b/arch/score/include/asm/fcntl.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_FCNTL_H
2#define _ASM_SCORE_FCNTL_H
3
4#include <asm-generic/fcntl.h>
5
6#endif /* _ASM_SCORE_FCNTL_H */
diff --git a/arch/score/include/asm/fixmap.h b/arch/score/include/asm/fixmap.h
new file mode 100644
index 000000000000..ee1676694024
--- /dev/null
+++ b/arch/score/include/asm/fixmap.h
@@ -0,0 +1,82 @@
1#ifndef _ASM_SCORE_FIXMAP_H
2#define _ASM_SCORE_FIXMAP_H
3
4#include <asm/page.h>
5
6#define PHY_RAM_BASE 0x00000000
7#define PHY_IO_BASE 0x10000000
8
9#define VIRTUAL_RAM_BASE 0xa0000000
10#define VIRTUAL_IO_BASE 0xb0000000
11
12#define RAM_SPACE_SIZE 0x10000000
13#define IO_SPACE_SIZE 0x10000000
14
15/* Kernel unmapped, cached 512MB */
16#define KSEG1 0xa0000000
17
18/*
19 * Here we define all the compile-time 'special' virtual
20 * addresses. The point is to have a constant address at
21 * compile time, but to set the physical address only
22 * in the boot process. We allocate these special addresses
23 * from the end of virtual memory (0xfffff000) backwards.
24 * Also this lets us do fail-safe vmalloc(), we
25 * can guarantee that these special addresses and
26 * vmalloc()-ed addresses never overlap.
27 *
28 * these 'compile-time allocated' memory buffers are
29 * fixed-size 4k pages. (or larger if used with an increment
30 * highger than 1) use fixmap_set(idx,phys) to associate
31 * physical memory with fixmap indices.
32 *
33 * TLB entries of such buffers will not be flushed across
34 * task switches.
35 */
36
37/*
38 * on UP currently we will have no trace of the fixmap mechanizm,
39 * no page table allocations, etc. This might change in the
40 * future, say framebuffers for the console driver(s) could be
41 * fix-mapped?
42 */
43enum fixed_addresses {
44#define FIX_N_COLOURS 8
45 FIX_CMAP_BEGIN,
46 FIX_CMAP_END = FIX_CMAP_BEGIN + FIX_N_COLOURS,
47 __end_of_fixed_addresses
48};
49
50/*
51 * used by vmalloc.c.
52 *
53 * Leave one empty page between vmalloc'ed areas and
54 * the start of the fixmap, and leave one page empty
55 * at the top of mem..
56 */
57#define FIXADDR_TOP ((unsigned long)(long)(int)0xfefe0000)
58#define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)
59#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE)
60
61#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
62#define __virt_to_fix(x) \
63 ((FIXADDR_TOP - ((x) & PAGE_MASK)) >> PAGE_SHIFT)
64
65extern void __this_fixmap_does_not_exist(void);
66
67/*
68 * 'index to address' translation. If anyone tries to use the idx
69 * directly without tranlation, we catch the bug with a NULL-deference
70 * kernel oops. Illegal ranges of incoming indices are caught too.
71 */
72static inline unsigned long fix_to_virt(const unsigned int idx)
73{
74 return __fix_to_virt(idx);
75}
76
77static inline unsigned long virt_to_fix(const unsigned long vaddr)
78{
79 return __virt_to_fix(vaddr);
80}
81
82#endif /* _ASM_SCORE_FIXMAP_H */
diff --git a/arch/score/include/asm/ftrace.h b/arch/score/include/asm/ftrace.h
new file mode 100644
index 000000000000..79d6f10e1f5b
--- /dev/null
+++ b/arch/score/include/asm/ftrace.h
@@ -0,0 +1,4 @@
1#ifndef _ASM_SCORE_FTRACE_H
2#define _ASM_SCORE_FTRACE_H
3
4#endif /* _ASM_SCORE_FTRACE_H */
diff --git a/arch/score/include/asm/futex.h b/arch/score/include/asm/futex.h
new file mode 100644
index 000000000000..1dca2420f8db
--- /dev/null
+++ b/arch/score/include/asm/futex.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_FUTEX_H
2#define _ASM_SCORE_FUTEX_H
3
4#include <asm-generic/futex.h>
5
6#endif /* _ASM_SCORE_FUTEX_H */
diff --git a/arch/score/include/asm/hardirq.h b/arch/score/include/asm/hardirq.h
new file mode 100644
index 000000000000..dc932c50d3ee
--- /dev/null
+++ b/arch/score/include/asm/hardirq.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_HARDIRQ_H
2#define _ASM_SCORE_HARDIRQ_H
3
4#include <asm-generic/hardirq.h>
5
6#endif /* _ASM_SCORE_HARDIRQ_H */
diff --git a/arch/score/include/asm/hw_irq.h b/arch/score/include/asm/hw_irq.h
new file mode 100644
index 000000000000..4caafb2b509a
--- /dev/null
+++ b/arch/score/include/asm/hw_irq.h
@@ -0,0 +1,4 @@
1#ifndef _ASM_SCORE_HW_IRQ_H
2#define _ASM_SCORE_HW_IRQ_H
3
4#endif /* _ASM_SCORE_HW_IRQ_H */
diff --git a/arch/score/include/asm/io.h b/arch/score/include/asm/io.h
new file mode 100644
index 000000000000..fbbfd7132e3b
--- /dev/null
+++ b/arch/score/include/asm/io.h
@@ -0,0 +1,9 @@
1#ifndef _ASM_SCORE_IO_H
2#define _ASM_SCORE_IO_H
3
4#include <asm-generic/io.h>
5
6#define virt_to_bus virt_to_phys
7#define bus_to_virt phys_to_virt
8
9#endif /* _ASM_SCORE_IO_H */
diff --git a/arch/score/include/asm/ioctl.h b/arch/score/include/asm/ioctl.h
new file mode 100644
index 000000000000..a351d2194bfd
--- /dev/null
+++ b/arch/score/include/asm/ioctl.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_IOCTL_H
2#define _ASM_SCORE_IOCTL_H
3
4#include <asm-generic/ioctl.h>
5
6#endif /* _ASM_SCORE_IOCTL_H */
diff --git a/arch/score/include/asm/ioctls.h b/arch/score/include/asm/ioctls.h
new file mode 100644
index 000000000000..ed01d2b9aeab
--- /dev/null
+++ b/arch/score/include/asm/ioctls.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_IOCTLS_H
2#define _ASM_SCORE_IOCTLS_H
3
4#include <asm-generic/ioctls.h>
5
6#endif /* _ASM_SCORE_IOCTLS_H */
diff --git a/arch/score/include/asm/ipcbuf.h b/arch/score/include/asm/ipcbuf.h
new file mode 100644
index 000000000000..e082ceff1818
--- /dev/null
+++ b/arch/score/include/asm/ipcbuf.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_IPCBUF_H
2#define _ASM_SCORE_IPCBUF_H
3
4#include <asm-generic/ipcbuf.h>
5
6#endif /* _ASM_SCORE_IPCBUF_H */
diff --git a/arch/score/include/asm/irq.h b/arch/score/include/asm/irq.h
new file mode 100644
index 000000000000..401f6704848c
--- /dev/null
+++ b/arch/score/include/asm/irq.h
@@ -0,0 +1,33 @@
1#ifndef _ASM_SCORE_IRQ_H
2#define _ASM_SCORE_IRQ_H
3
4#define EXCEPTION_VECTOR_BASE_ADDR 0xa0000000
5#define VECTOR_ADDRESS_OFFSET_MODE4 0
6#define VECTOR_ADDRESS_OFFSET_MODE16 1
7
8#define DEBUG_VECTOR_SIZE (0x4)
9#define DEBUG_VECTOR_BASE_ADDR ((EXCEPTION_VECTOR_BASE_ADDR) + 0x1fc)
10
11#define GENERAL_VECTOR_SIZE (0x10)
12#define GENERAL_VECTOR_BASE_ADDR ((EXCEPTION_VECTOR_BASE_ADDR) + 0x200)
13
14#define NR_IRQS 64
15#define IRQ_VECTOR_SIZE (0x10)
16#define IRQ_VECTOR_BASE_ADDR ((EXCEPTION_VECTOR_BASE_ADDR) + 0x210)
17#define IRQ_VECTOR_END_ADDR ((EXCEPTION_VECTOR_BASE_ADDR) + 0x5f0)
18
19#define irq_canonicalize(irq) (irq)
20
21#define P_INT_PNDL 0x95F50000
22#define P_INT_PNDH 0x95F50004
23#define P_INT_PRIORITY_M 0x95F50008
24#define P_INT_PRIORITY_SG0 0x95F50010
25#define P_INT_PRIORITY_SG1 0x95F50014
26#define P_INT_PRIORITY_SG2 0x95F50018
27#define P_INT_PRIORITY_SG3 0x95F5001C
28#define P_INT_MASKL 0x95F50020
29#define P_INT_MASKH 0x95F50024
30
31#define IRQ_TIMER (7) /* Timer IRQ number of SPCT6600 */
32
33#endif /* _ASM_SCORE_IRQ_H */
diff --git a/arch/score/include/asm/irq_regs.h b/arch/score/include/asm/irq_regs.h
new file mode 100644
index 000000000000..905b7b078bae
--- /dev/null
+++ b/arch/score/include/asm/irq_regs.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_IRQ_REGS_H
2#define _ASM_SCORE_IRQ_REGS_H
3
4#include <asm-generic/irq_regs.h>
5
6#endif /* _ASM_SCORE_IRQ_REGS_H */
diff --git a/arch/score/include/asm/irqflags.h b/arch/score/include/asm/irqflags.h
new file mode 100644
index 000000000000..92eeb33dd72b
--- /dev/null
+++ b/arch/score/include/asm/irqflags.h
@@ -0,0 +1,111 @@
1#ifndef _ASM_SCORE_IRQFLAGS_H
2#define _ASM_SCORE_IRQFLAGS_H
3
4#ifndef __ASSEMBLY__
5
6#define raw_local_irq_save(x) \
7{ \
8 __asm__ __volatile__( \
9 "mfcr r8, cr0;" \
10 "li r9, 0xfffffffe;" \
11 "nop;" \
12 "mv %0, r8;" \
13 "and r8, r8, r9;" \
14 "mtcr r8, cr0;" \
15 "nop;" \
16 "nop;" \
17 "nop;" \
18 "nop;" \
19 "nop;" \
20 "ldi r9, 0x1;" \
21 "and %0, %0, r9;" \
22 : "=r" (x) \
23 : \
24 : "r8", "r9" \
25 ); \
26}
27
28#define raw_local_irq_restore(x) \
29{ \
30 __asm__ __volatile__( \
31 "mfcr r8, cr0;" \
32 "ldi r9, 0x1;" \
33 "and %0, %0, r9;" \
34 "or r8, r8, %0;" \
35 "mtcr r8, cr0;" \
36 "nop;" \
37 "nop;" \
38 "nop;" \
39 "nop;" \
40 "nop;" \
41 : \
42 : "r"(x) \
43 : "r8", "r9" \
44 ); \
45}
46
47#define raw_local_irq_enable(void) \
48{ \
49 __asm__ __volatile__( \
50 "mfcr\tr8,cr0;" \
51 "nop;" \
52 "nop;" \
53 "ori\tr8,0x1;" \
54 "mtcr\tr8,cr0;" \
55 "nop;" \
56 "nop;" \
57 "nop;" \
58 "nop;" \
59 "nop;" \
60 : \
61 : \
62 : "r8"); \
63}
64
65#define raw_local_irq_disable(void) \
66{ \
67 __asm__ __volatile__( \
68 "mfcr\tr8,cr0;" \
69 "nop;" \
70 "nop;" \
71 "srli\tr8,r8,1;" \
72 "slli\tr8,r8,1;" \
73 "mtcr\tr8,cr0;" \
74 "nop;" \
75 "nop;" \
76 "nop;" \
77 "nop;" \
78 "nop;" \
79 : \
80 : \
81 : "r8"); \
82}
83
84#define raw_local_save_flags(x) \
85{ \
86 __asm__ __volatile__( \
87 "mfcr r8, cr0;" \
88 "nop;" \
89 "nop;" \
90 "mv %0, r8;" \
91 "nop;" \
92 "nop;" \
93 "nop;" \
94 "nop;" \
95 "nop;" \
96 "ldi r9, 0x1;" \
97 "and %0, %0, r9;" \
98 : "=r" (x) \
99 : \
100 : "r8", "r9" \
101 ); \
102}
103
104static inline int raw_irqs_disabled_flags(unsigned long flags)
105{
106 return !(flags & 1);
107}
108
109#endif
110
111#endif /* _ASM_SCORE_IRQFLAGS_H */
diff --git a/arch/score/include/asm/kdebug.h b/arch/score/include/asm/kdebug.h
new file mode 100644
index 000000000000..a666e513f747
--- /dev/null
+++ b/arch/score/include/asm/kdebug.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_KDEBUG_H
2#define _ASM_SCORE_KDEBUG_H
3
4#include <asm-generic/kdebug.h>
5
6#endif /* _ASM_SCORE_KDEBUG_H */
diff --git a/arch/score/include/asm/kmap_types.h b/arch/score/include/asm/kmap_types.h
new file mode 100644
index 000000000000..6c46eb5077d3
--- /dev/null
+++ b/arch/score/include/asm/kmap_types.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_KMAP_TYPES_H
2#define _ASM_SCORE_KMAP_TYPES_H
3
4#include <asm-generic/kmap_types.h>
5
6#endif /* _ASM_SCORE_KMAP_TYPES_H */
diff --git a/arch/score/include/asm/linkage.h b/arch/score/include/asm/linkage.h
new file mode 100644
index 000000000000..2580fbbfe946
--- /dev/null
+++ b/arch/score/include/asm/linkage.h
@@ -0,0 +1,4 @@
1#ifndef _ASM_SCORE_LINKAGE_H
2#define _ASM_SCORE_LINKAGE_H
3
4#endif /* _ASM_SCORE_LINKAGE_H */
diff --git a/arch/score/include/asm/local.h b/arch/score/include/asm/local.h
new file mode 100644
index 000000000000..7e02f13dbba8
--- /dev/null
+++ b/arch/score/include/asm/local.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_LOCAL_H
2#define _ASM_SCORE_LOCAL_H
3
4#include <asm-generic/local.h>
5
6#endif /* _ASM_SCORE_LOCAL_H */
diff --git a/arch/score/include/asm/mman.h b/arch/score/include/asm/mman.h
new file mode 100644
index 000000000000..84d85ddfed8d
--- /dev/null
+++ b/arch/score/include/asm/mman.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_MMAN_H
2#define _ASM_SCORE_MMAN_H
3
4#include <asm-generic/mman.h>
5
6#endif /* _ASM_SCORE_MMAN_H */
diff --git a/arch/score/include/asm/mmu.h b/arch/score/include/asm/mmu.h
new file mode 100644
index 000000000000..676828e4c10a
--- /dev/null
+++ b/arch/score/include/asm/mmu.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_MMU_H
2#define _ASM_SCORE_MMU_H
3
4typedef unsigned long mm_context_t;
5
6#endif /* _ASM_SCORE_MMU_H */
diff --git a/arch/score/include/asm/mmu_context.h b/arch/score/include/asm/mmu_context.h
new file mode 100644
index 000000000000..2644577c96e8
--- /dev/null
+++ b/arch/score/include/asm/mmu_context.h
@@ -0,0 +1,113 @@
1#ifndef _ASM_SCORE_MMU_CONTEXT_H
2#define _ASM_SCORE_MMU_CONTEXT_H
3
4#include <linux/errno.h>
5#include <linux/sched.h>
6#include <linux/slab.h>
7#include <asm-generic/mm_hooks.h>
8
9#include <asm/cacheflush.h>
10#include <asm/tlbflush.h>
11#include <asm/scoreregs.h>
12
13/*
14 * For the fast tlb miss handlers, we keep a per cpu array of pointers
15 * to the current pgd for each processor. Also, the proc. id is stuffed
16 * into the context register.
17 */
18extern unsigned long asid_cache;
19extern unsigned long pgd_current;
20
21#define TLBMISS_HANDLER_SETUP_PGD(pgd) (pgd_current = (unsigned long)(pgd))
22
23#define TLBMISS_HANDLER_SETUP() \
24do { \
25 write_c0_context(0); \
26 TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir) \
27} while (0)
28
29/*
30 * All unused by hardware upper bits will be considered
31 * as a software asid extension.
32 */
33#define ASID_VERSION_MASK 0xfffff000
34#define ASID_FIRST_VERSION 0x1000
35
36/* PEVN --------- VPN ---------- --ASID--- -NA- */
37/* binary: 0000 0000 0000 0000 0000 0000 0001 0000 */
38/* binary: 0000 0000 0000 0000 0000 1111 1111 0000 */
39#define ASID_INC 0x10
40#define ASID_MASK 0xff0
41
42static inline void enter_lazy_tlb(struct mm_struct *mm,
43 struct task_struct *tsk)
44{}
45
46static inline void
47get_new_mmu_context(struct mm_struct *mm)
48{
49 unsigned long asid = asid_cache + ASID_INC;
50
51 if (!(asid & ASID_MASK)) {
52 local_flush_tlb_all(); /* start new asid cycle */
53 if (!asid) /* fix version if needed */
54 asid = ASID_FIRST_VERSION;
55 }
56
57 mm->context = asid;
58 asid_cache = asid;
59}
60
61/*
62 * Initialize the context related info for a new mm_struct
63 * instance.
64 */
65static inline int
66init_new_context(struct task_struct *tsk, struct mm_struct *mm)
67{
68 mm->context = 0;
69 return 0;
70}
71
72static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
73 struct task_struct *tsk)
74{
75 unsigned long flags;
76
77 local_irq_save(flags);
78 if ((next->context ^ asid_cache) & ASID_VERSION_MASK)
79 get_new_mmu_context(next);
80
81 pevn_set(next->context);
82 TLBMISS_HANDLER_SETUP_PGD(next->pgd);
83 local_irq_restore(flags);
84}
85
86/*
87 * Destroy context related info for an mm_struct that is about
88 * to be put to rest.
89 */
90static inline void destroy_context(struct mm_struct *mm)
91{}
92
93static inline void
94deactivate_mm(struct task_struct *task, struct mm_struct *mm)
95{}
96
97/*
98 * After we have set current->mm to a new value, this activates
99 * the context for the new mm so we see the new mappings.
100 */
101static inline void
102activate_mm(struct mm_struct *prev, struct mm_struct *next)
103{
104 unsigned long flags;
105
106 local_irq_save(flags);
107 get_new_mmu_context(next);
108 pevn_set(next->context);
109 TLBMISS_HANDLER_SETUP_PGD(next->pgd);
110 local_irq_restore(flags);
111}
112
113#endif /* _ASM_SCORE_MMU_CONTEXT_H */
diff --git a/arch/score/include/asm/module.h b/arch/score/include/asm/module.h
new file mode 100644
index 000000000000..f0b5dc0bd023
--- /dev/null
+++ b/arch/score/include/asm/module.h
@@ -0,0 +1,39 @@
1#ifndef _ASM_SCORE_MODULE_H
2#define _ASM_SCORE_MODULE_H
3
4#include <linux/list.h>
5#include <asm/uaccess.h>
6
7struct mod_arch_specific {
8 /* Data Bus Error exception tables */
9 struct list_head dbe_list;
10 const struct exception_table_entry *dbe_start;
11 const struct exception_table_entry *dbe_end;
12};
13
14typedef uint8_t Elf64_Byte; /* Type for a 8-bit quantity. */
15
16#define Elf_Shdr Elf32_Shdr
17#define Elf_Sym Elf32_Sym
18#define Elf_Ehdr Elf32_Ehdr
19#define Elf_Addr Elf32_Addr
20
21/* Given an address, look for it in the exception tables. */
22#ifdef CONFIG_MODULES
23const struct exception_table_entry *search_module_dbetables(unsigned long addr);
24#else
25static inline const struct exception_table_entry
26*search_module_dbetables(unsigned long addr)
27{
28 return NULL;
29}
30#endif
31
32#define MODULE_PROC_FAMILY "SCORE7"
33#define MODULE_KERNEL_TYPE "32BIT "
34#define MODULE_KERNEL_SMTC ""
35
36#define MODULE_ARCH_VERMAGIC \
37 MODULE_PROC_FAMILY MODULE_KERNEL_TYPE MODULE_KERNEL_SMTC
38
39#endif /* _ASM_SCORE_MODULE_H */
diff --git a/arch/score/include/asm/msgbuf.h b/arch/score/include/asm/msgbuf.h
new file mode 100644
index 000000000000..7506721e29fa
--- /dev/null
+++ b/arch/score/include/asm/msgbuf.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_MSGBUF_H
2#define _ASM_SCORE_MSGBUF_H
3
4#include <asm-generic/msgbuf.h>
5
6#endif /* _ASM_SCORE_MSGBUF_H */
diff --git a/arch/score/include/asm/mutex.h b/arch/score/include/asm/mutex.h
new file mode 100644
index 000000000000..10d48fe4db97
--- /dev/null
+++ b/arch/score/include/asm/mutex.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_MUTEX_H
2#define _ASM_SCORE_MUTEX_H
3
4#include <asm-generic/mutex-dec.h>
5
6#endif /* _ASM_SCORE_MUTEX_H */
diff --git a/arch/score/include/asm/page.h b/arch/score/include/asm/page.h
new file mode 100644
index 000000000000..67e98206be6a
--- /dev/null
+++ b/arch/score/include/asm/page.h
@@ -0,0 +1,92 @@
1#ifndef _ASM_SCORE_PAGE_H
2#define _ASM_SCORE_PAGE_H
3
4#include <linux/pfn.h>
5
6/* PAGE_SHIFT determines the page size */
7#define PAGE_SHIFT (12)
8#define PAGE_SIZE (1UL << PAGE_SHIFT)
9#define PAGE_MASK (~(PAGE_SIZE-1))
10
11#ifdef __KERNEL__
12
13#ifndef __ASSEMBLY__
14
15#define PAGE_UP(addr) (((addr)+((PAGE_SIZE)-1))&(~((PAGE_SIZE)-1)))
16#define PAGE_DOWN(addr) ((addr)&(~((PAGE_SIZE)-1)))
17
18/* align addr on a size boundary - adjust address up/down if needed */
19#define _ALIGN_UP(addr, size) (((addr)+((size)-1))&(~((size)-1)))
20#define _ALIGN_DOWN(addr, size) ((addr)&(~((size)-1)))
21
22/* align addr on a size boundary - adjust address up if needed */
23#define _ALIGN(addr, size) _ALIGN_UP(addr, size)
24
25/*
26 * PAGE_OFFSET -- the first address of the first page of memory. When not
27 * using MMU this corresponds to the first free page in physical memory (aligned
28 * on a page boundary).
29 */
30#define PAGE_OFFSET (0xA0000000UL)
31
32#define clear_page(pgaddr) memset((pgaddr), 0, PAGE_SIZE)
33#define copy_page(to, from) memcpy((to), (from), PAGE_SIZE)
34
35#define clear_user_page(pgaddr, vaddr, page) memset((pgaddr), 0, PAGE_SIZE)
36#define copy_user_page(vto, vfrom, vaddr, topg) \
37 memcpy((vto), (vfrom), PAGE_SIZE)
38
39/*
40 * These are used to make use of C type-checking..
41 */
42
43typedef struct { unsigned long pte; } pte_t; /* page table entry */
44typedef struct { unsigned long pgd; } pgd_t; /* PGD table entry */
45typedef struct { unsigned long pgprot; } pgprot_t;
46typedef struct page *pgtable_t;
47
48#define pte_val(x) ((x).pte)
49#define pgd_val(x) ((x).pgd)
50#define pgprot_val(x) ((x).pgprot)
51
52#define __pte(x) ((pte_t) { (x) })
53#define __pgd(x) ((pgd_t) { (x) })
54#define __pgprot(x) ((pgprot_t) { (x) })
55
56extern unsigned long max_low_pfn;
57extern unsigned long min_low_pfn;
58extern unsigned long max_pfn;
59
60#define __pa(vaddr) ((unsigned long) (vaddr))
61#define __va(paddr) ((void *) (paddr))
62
63#define phys_to_pfn(phys) (PFN_DOWN(phys))
64#define pfn_to_phys(pfn) (PFN_PHYS(pfn))
65
66#define virt_to_pfn(vaddr) (phys_to_pfn((__pa(vaddr))))
67#define pfn_to_virt(pfn) __va(pfn_to_phys((pfn)))
68
69#define virt_to_page(vaddr) (pfn_to_page(virt_to_pfn(vaddr)))
70#define page_to_virt(page) (pfn_to_virt(page_to_pfn(page)))
71
72#define page_to_phys(page) (pfn_to_phys(page_to_pfn(page)))
73#define page_to_bus(page) (page_to_phys(page))
74#define phys_to_page(paddr) (pfn_to_page(phys_to_pfn(paddr)))
75
76#define pfn_valid(pfn) ((pfn) >= min_low_pfn && (pfn) < max_mapnr)
77
78#define ARCH_PFN_OFFSET (PAGE_OFFSET >> PAGE_SHIFT)
79
80#endif /* __ASSEMBLY__ */
81
82#define virt_addr_valid(vaddr) (pfn_valid(virt_to_pfn(vaddr)))
83
84#endif /* __KERNEL__ */
85
86#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
87 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
88
89#include <asm-generic/memory_model.h>
90#include <asm-generic/getorder.h>
91
92#endif /* _ASM_SCORE_PAGE_H */
diff --git a/arch/score/include/asm/param.h b/arch/score/include/asm/param.h
new file mode 100644
index 000000000000..916b8690b6aa
--- /dev/null
+++ b/arch/score/include/asm/param.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_PARAM_H
2#define _ASM_SCORE_PARAM_H
3
4#include <asm-generic/param.h>
5
6#endif /* _ASM_SCORE_PARAM_H */
diff --git a/arch/score/include/asm/pci.h b/arch/score/include/asm/pci.h
new file mode 100644
index 000000000000..3f3cfd82549c
--- /dev/null
+++ b/arch/score/include/asm/pci.h
@@ -0,0 +1,4 @@
1#ifndef _ASM_SCORE_PCI_H
2#define _ASM_SCORE_PCI_H
3
4#endif /* _ASM_SCORE_PCI_H */
diff --git a/arch/score/include/asm/percpu.h b/arch/score/include/asm/percpu.h
new file mode 100644
index 000000000000..e7bd4e05b475
--- /dev/null
+++ b/arch/score/include/asm/percpu.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_PERCPU_H
2#define _ASM_SCORE_PERCPU_H
3
4#include <asm-generic/percpu.h>
5
6#endif /* _ASM_SCORE_PERCPU_H */
diff --git a/arch/score/include/asm/pgalloc.h b/arch/score/include/asm/pgalloc.h
new file mode 100644
index 000000000000..28dacc1cbbab
--- /dev/null
+++ b/arch/score/include/asm/pgalloc.h
@@ -0,0 +1,83 @@
1#ifndef _ASM_SCORE_PGALLOC_H
2#define _ASM_SCORE_PGALLOC_H
3
4#include <linux/mm.h>
5
6static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd,
7 pte_t *pte)
8{
9 set_pmd(pmd, __pmd((unsigned long)pte));
10}
11
12static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
13 pgtable_t pte)
14{
15 set_pmd(pmd, __pmd((unsigned long)page_address(pte)));
16}
17
18#define pmd_pgtable(pmd) pmd_page(pmd)
19
20static inline pgd_t *pgd_alloc(struct mm_struct *mm)
21{
22 pgd_t *ret, *init;
23
24 ret = (pgd_t *) __get_free_pages(GFP_KERNEL, PGD_ORDER);
25 if (ret) {
26 init = pgd_offset(&init_mm, 0UL);
27 pgd_init((unsigned long)ret);
28 memcpy(ret + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
29 (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
30 }
31
32 return ret;
33}
34
35static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
36{
37 free_pages((unsigned long)pgd, PGD_ORDER);
38}
39
40static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
41 unsigned long address)
42{
43 pte_t *pte;
44
45 pte = (pte_t *) __get_free_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO,
46 PTE_ORDER);
47
48 return pte;
49}
50
51static inline struct page *pte_alloc_one(struct mm_struct *mm,
52 unsigned long address)
53{
54 struct page *pte;
55
56 pte = alloc_pages(GFP_KERNEL | __GFP_REPEAT, PTE_ORDER);
57 if (pte) {
58 clear_highpage(pte);
59 pgtable_page_ctor(pte);
60 }
61 return pte;
62}
63
64static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
65{
66 free_pages((unsigned long)pte, PTE_ORDER);
67}
68
69static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
70{
71 pgtable_page_dtor(pte);
72 __free_pages(pte, PTE_ORDER);
73}
74
75#define __pte_free_tlb(tlb, pte) \
76do { \
77 pgtable_page_dtor(pte); \
78 tlb_remove_page((tlb), pte); \
79} while (0)
80
81#define check_pgt_cache() do {} while (0)
82
83#endif /* _ASM_SCORE_PGALLOC_H */
diff --git a/arch/score/include/asm/pgtable-bits.h b/arch/score/include/asm/pgtable-bits.h
new file mode 100644
index 000000000000..ca16d357a644
--- /dev/null
+++ b/arch/score/include/asm/pgtable-bits.h
@@ -0,0 +1,23 @@
1#ifndef _ASM_SCORE_PGTABLE_BITS_H
2#define _ASM_SCORE_PGTABLE_BITS_H
3
4#define _PAGE_ACCESSED (1<<5) /* implemented in software */
5#define _PAGE_READ (1<<6) /* implemented in software */
6#define _PAGE_WRITE (1<<7) /* implemented in software */
7#define _PAGE_PRESENT (1<<9) /* implemented in software */
8#define _PAGE_MODIFIED (1<<10) /* implemented in software */
9#define _PAGE_FILE (1<<10)
10
11#define _PAGE_GLOBAL (1<<0)
12#define _PAGE_VALID (1<<1)
13#define _PAGE_SILENT_READ (1<<1) /* synonym */
14#define _PAGE_DIRTY (1<<2) /* Write bit */
15#define _PAGE_SILENT_WRITE (1<<2)
16#define _PAGE_CACHE (1<<3) /* cache */
17#define _CACHE_MASK (1<<3)
18#define _PAGE_BUFFERABLE (1<<4) /*Fallow Spec. */
19
20#define _PAGE_CHG_MASK \
21 (PAGE_MASK | _PAGE_ACCESSED | _PAGE_MODIFIED | _PAGE_CACHE)
22
23#endif /* _ASM_SCORE_PGTABLE_BITS_H */
diff --git a/arch/score/include/asm/pgtable.h b/arch/score/include/asm/pgtable.h
new file mode 100644
index 000000000000..0f7177a42205
--- /dev/null
+++ b/arch/score/include/asm/pgtable.h
@@ -0,0 +1,267 @@
1#ifndef _ASM_SCORE_PGTABLE_H
2#define _ASM_SCORE_PGTABLE_H
3
4#include <linux/const.h>
5#include <asm-generic/pgtable-nopmd.h>
6
7#include <asm/fixmap.h>
8#include <asm/setup.h>
9#include <asm/pgtable-bits.h>
10
11extern void load_pgd(unsigned long pg_dir);
12extern pte_t invalid_pte_table[PAGE_SIZE/sizeof(pte_t)];
13
14/* PGDIR_SHIFT determines what a third-level page table entry can map */
15#define PGDIR_SHIFT 22
16#define PGDIR_SIZE (_AC(1, UL) << PGDIR_SHIFT)
17#define PGDIR_MASK (~(PGDIR_SIZE - 1))
18
19/*
20 * Entries per page directory level: we use two-level, so
21 * we don't really have any PUD/PMD directory physically.
22 */
23#define PGD_ORDER 0
24#define PTE_ORDER 0
25
26#define PTRS_PER_PGD 1024
27#define PTRS_PER_PTE 1024
28
29#define USER_PTRS_PER_PGD (0x80000000UL/PGDIR_SIZE)
30#define FIRST_USER_ADDRESS 0
31
32#define VMALLOC_START (0xc0000000UL)
33
34#define PKMAP_BASE (0xfd000000UL)
35
36#define VMALLOC_END (FIXADDR_START - 2*PAGE_SIZE)
37
38#define pte_ERROR(e) \
39 printk(KERN_ERR "%s:%d: bad pte %08lx.\n", \
40 __FILE__, __LINE__, pte_val(e))
41#define pgd_ERROR(e) \
42 printk(KERN_ERR "%s:%d: bad pgd %08lx.\n", \
43 __FILE__, __LINE__, pgd_val(e))
44
45/*
46 * Empty pgd/pmd entries point to the invalid_pte_table.
47 */
48static inline int pmd_none(pmd_t pmd)
49{
50 return pmd_val(pmd) == (unsigned long) invalid_pte_table;
51}
52
53#define pmd_bad(pmd) (pmd_val(pmd) & ~PAGE_MASK)
54
55static inline int pmd_present(pmd_t pmd)
56{
57 return pmd_val(pmd) != (unsigned long) invalid_pte_table;
58}
59
60static inline void pmd_clear(pmd_t *pmdp)
61{
62 pmd_val(*pmdp) = ((unsigned long) invalid_pte_table);
63}
64
65#define pte_page(x) pfn_to_page(pte_pfn(x))
66#define pte_pfn(x) ((unsigned long)((x).pte >> PAGE_SHIFT))
67#define pfn_pte(pfn, prot) \
68 __pte(((unsigned long long)(pfn) << PAGE_SHIFT) | pgprot_val(prot))
69
70#define __pgd_offset(address) pgd_index(address)
71#define __pud_offset(address) (((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1))
72#define __pmd_offset(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
73
74/* to find an entry in a kernel page-table-directory */
75#define pgd_offset_k(address) pgd_offset(&init_mm, address)
76#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
77
78/* to find an entry in a page-table-directory */
79#define pgd_offset(mm, addr) ((mm)->pgd + pgd_index(addr))
80
81/* Find an entry in the third-level page table.. */
82#define __pte_offset(address) \
83 (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
84#define pte_offset(dir, address) \
85 ((pte_t *) pmd_page_vaddr(*(dir)) + __pte_offset(address))
86#define pte_offset_kernel(dir, address) \
87 ((pte_t *) pmd_page_vaddr(*(dir)) + __pte_offset(address))
88
89#define pte_offset_map(dir, address) \
90 ((pte_t *)page_address(pmd_page(*(dir))) + __pte_offset(address))
91#define pte_offset_map_nested(dir, address) \
92 ((pte_t *)page_address(pmd_page(*(dir))) + __pte_offset(address))
93#define pte_unmap(pte) ((void)(pte))
94#define pte_unmap_nested(pte) ((void)(pte))
95
96/*
97 * Bits 9(_PAGE_PRESENT) and 10(_PAGE_FILE)are taken,
98 * split up 30 bits of offset into this range:
99 */
100#define PTE_FILE_MAX_BITS 30
101#define pte_to_pgoff(_pte) \
102 (((_pte).pte & 0x1ff) | (((_pte).pte >> 11) << 9))
103#define pgoff_to_pte(off) \
104 ((pte_t) {((off) & 0x1ff) | (((off) >> 9) << 11) | _PAGE_FILE})
105#define __pte_to_swp_entry(pte) \
106 ((swp_entry_t) { pte_val(pte)})
107#define __swp_entry_to_pte(x) ((pte_t) {(x).val})
108
109#define __P000 __pgprot(0)
110#define __P001 __pgprot(0)
111#define __P010 __pgprot(0)
112#define __P011 __pgprot(0)
113#define __P100 __pgprot(0)
114#define __P101 __pgprot(0)
115#define __P110 __pgprot(0)
116#define __P111 __pgprot(0)
117
118#define __S000 __pgprot(0)
119#define __S001 __pgprot(0)
120#define __S010 __pgprot(0)
121#define __S011 __pgprot(0)
122#define __S100 __pgprot(0)
123#define __S101 __pgprot(0)
124#define __S110 __pgprot(0)
125#define __S111 __pgprot(0)
126
127#define pmd_page(pmd) virt_to_page(__va(pmd_val(pmd)))
128#define mk_pte(page, prot) pfn_pte(page_to_pfn(page), prot)
129static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
130
131#define set_pte(pteptr, pteval) (*(pteptr) = pteval)
132#define set_pte_at(mm, addr, ptep, pteval) set_pte(ptep, pteval)
133#define pte_clear(mm, addr, xp) \
134 do { set_pte_at(mm, addr, xp, __pte(0)); } while (0)
135
136#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
137 remap_pfn_range(vma, vaddr, pfn, size, prot)
138
139#define pgd_present(pgd) (1) /* pages are always present on non MMU */
140#define pgd_none(pgd) (0)
141#define pgd_bad(pgd) (0)
142#define pgd_clear(pgdp)
143
144#define kern_addr_valid(addr) (1)
145#define pmd_offset(a, b) ((void *) 0)
146#define pmd_page_vaddr(pmd) pmd_val(pmd)
147
148#define pte_none(pte) (!(pte_val(pte) & ~_PAGE_GLOBAL))
149#define pte_present(pte) (pte_val(pte) & _PAGE_PRESENT)
150
151#define pud_offset(pgd, address) ((pud_t *) pgd)
152
153#define PAGE_NONE __pgprot(0) /* these mean nothing to non MMU */
154#define PAGE_SHARED __pgprot(0) /* these mean nothing to non MMU */
155#define PAGE_COPY __pgprot(0) /* these mean nothing to non MMU */
156#define PAGE_READONLY __pgprot(0) /* these mean nothing to non MMU */
157#define PAGE_KERNEL __pgprot(0) /* these mean nothing to non MMU */
158
159#define pgprot_noncached(x) (x)
160
161#define __swp_type(x) (0)
162#define __swp_offset(x) (0)
163#define __swp_entry(typ, off) ((swp_entry_t) { ((typ) | ((off) << 7)) })
164
165#define ZERO_PAGE(vaddr) ({ BUG(); NULL; })
166
167#define swapper_pg_dir ((pgd_t *) NULL)
168
169#define pgtable_cache_init() do {} while (0)
170
171#define arch_enter_lazy_cpu_mode() do {} while (0)
172
173static inline int pte_write(pte_t pte)
174{
175 return pte_val(pte) & _PAGE_WRITE;
176}
177
178static inline int pte_dirty(pte_t pte)
179{
180 return pte_val(pte) & _PAGE_MODIFIED;
181}
182
183static inline int pte_young(pte_t pte)
184{
185 return pte_val(pte) & _PAGE_ACCESSED;
186}
187
188static inline int pte_file(pte_t pte)
189{
190 return pte_val(pte) & _PAGE_FILE;
191}
192
193#define pte_special(pte) (0)
194
195static inline pte_t pte_wrprotect(pte_t pte)
196{
197 pte_val(pte) &= ~(_PAGE_WRITE | _PAGE_SILENT_WRITE);
198 return pte;
199}
200
201static inline pte_t pte_mkclean(pte_t pte)
202{
203 pte_val(pte) &= ~(_PAGE_MODIFIED|_PAGE_SILENT_WRITE);
204 return pte;
205}
206
207static inline pte_t pte_mkold(pte_t pte)
208{
209 pte_val(pte) &= ~(_PAGE_ACCESSED|_PAGE_SILENT_READ);
210 return pte;
211}
212
213static inline pte_t pte_mkwrite(pte_t pte)
214{
215 pte_val(pte) |= _PAGE_WRITE;
216 if (pte_val(pte) & _PAGE_MODIFIED)
217 pte_val(pte) |= _PAGE_SILENT_WRITE;
218 return pte;
219}
220
221static inline pte_t pte_mkdirty(pte_t pte)
222{
223 pte_val(pte) |= _PAGE_MODIFIED;
224 if (pte_val(pte) & _PAGE_WRITE)
225 pte_val(pte) |= _PAGE_SILENT_WRITE;
226 return pte;
227}
228
229static inline pte_t pte_mkyoung(pte_t pte)
230{
231 pte_val(pte) |= _PAGE_ACCESSED;
232 if (pte_val(pte) & _PAGE_READ)
233 pte_val(pte) |= _PAGE_SILENT_READ;
234 return pte;
235}
236
237#define set_pmd(pmdptr, pmdval) \
238 do { *(pmdptr) = (pmdval); } while (0)
239#define pte_present(pte) (pte_val(pte) & _PAGE_PRESENT)
240
241extern unsigned long pgd_current;
242extern void paging_init(void);
243
244static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
245{
246 return __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot));
247}
248
249extern void __update_tlb(struct vm_area_struct *vma,
250 unsigned long address, pte_t pte);
251extern void __update_cache(struct vm_area_struct *vma,
252 unsigned long address, pte_t pte);
253
254static inline void update_mmu_cache(struct vm_area_struct *vma,
255 unsigned long address, pte_t pte)
256{
257 __update_tlb(vma, address, pte);
258 __update_cache(vma, address, pte);
259}
260
261#ifndef __ASSEMBLY__
262#include <asm-generic/pgtable.h>
263
264void setup_memory(void);
265#endif /* __ASSEMBLY__ */
266
267#endif /* _ASM_SCORE_PGTABLE_H */
diff --git a/arch/score/include/asm/poll.h b/arch/score/include/asm/poll.h
new file mode 100644
index 000000000000..18532db02861
--- /dev/null
+++ b/arch/score/include/asm/poll.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_POLL_H
2#define _ASM_SCORE_POLL_H
3
4#include <asm-generic/poll.h>
5
6#endif /* _ASM_SCORE_POLL_H */
diff --git a/arch/score/include/asm/posix_types.h b/arch/score/include/asm/posix_types.h
new file mode 100644
index 000000000000..b88acf80048a
--- /dev/null
+++ b/arch/score/include/asm/posix_types.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_POSIX_TYPES_H
2#define _ASM_SCORE_POSIX_TYPES_H
3
4#include <asm-generic/posix_types.h>
5
6#endif /* _ASM_SCORE_POSIX_TYPES_H */
diff --git a/arch/score/include/asm/processor.h b/arch/score/include/asm/processor.h
new file mode 100644
index 000000000000..7e22f216d771
--- /dev/null
+++ b/arch/score/include/asm/processor.h
@@ -0,0 +1,106 @@
1#ifndef _ASM_SCORE_PROCESSOR_H
2#define _ASM_SCORE_PROCESSOR_H
3
4#include <linux/cpumask.h>
5#include <linux/threads.h>
6
7#include <asm/segment.h>
8
9struct task_struct;
10
11/*
12 * System setup and hardware flags..
13 */
14extern void (*cpu_wait)(void);
15
16extern long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
17extern unsigned long thread_saved_pc(struct task_struct *tsk);
18extern void start_thread(struct pt_regs *regs,
19 unsigned long pc, unsigned long sp);
20extern unsigned long get_wchan(struct task_struct *p);
21
22/*
23 * Return current * instruction pointer ("program counter").
24 */
25#define current_text_addr() ({ __label__ _l; _l: &&_l; })
26
27#define cpu_relax() barrier()
28#define release_thread(thread) do {} while (0)
29#define prepare_to_copy(tsk) do {} while (0)
30
31/*
32 * User space process size: 2GB. This is hardcoded into a few places,
33 * so don't change it unless you know what you are doing.
34 */
35#define TASK_SIZE 0x7fff8000UL
36
37/*
38 * This decides where the kernel will search for a free chunk of vm
39 * space during mmap's.
40 */
41#define TASK_UNMAPPED_BASE ((TASK_SIZE / 3) & ~(PAGE_SIZE))
42
43#ifdef __KERNEL__
44#define STACK_TOP TASK_SIZE
45#define STACK_TOP_MAX TASK_SIZE
46#endif
47
48/*
49 * If you change thread_struct remember to change the #defines below too!
50 */
51struct thread_struct {
52 unsigned long reg0, reg2, reg3;
53 unsigned long reg12, reg13, reg14, reg15, reg16;
54 unsigned long reg17, reg18, reg19, reg20, reg21;
55
56 unsigned long cp0_psr;
57 unsigned long cp0_ema; /* Last user fault */
58 unsigned long cp0_badvaddr; /* Last user fault */
59 unsigned long cp0_baduaddr; /* Last kernel fault accessing USEG */
60 unsigned long error_code;
61 unsigned long trap_no;
62
63 unsigned long mflags;
64 unsigned long reg29;
65
66 unsigned long single_step;
67 unsigned long ss_nextcnt;
68
69 unsigned long insn1_type;
70 unsigned long addr1;
71 unsigned long insn1;
72
73 unsigned long insn2_type;
74 unsigned long addr2;
75 unsigned long insn2;
76
77 mm_segment_t current_ds;
78};
79
80#define INIT_THREAD { \
81 .reg0 = 0, \
82 .reg2 = 0, \
83 .reg3 = 0, \
84 .reg12 = 0, \
85 .reg13 = 0, \
86 .reg14 = 0, \
87 .reg15 = 0, \
88 .reg16 = 0, \
89 .reg17 = 0, \
90 .reg18 = 0, \
91 .reg19 = 0, \
92 .reg20 = 0, \
93 .reg21 = 0, \
94 .cp0_psr = 0, \
95 .error_code = 0, \
96 .trap_no = 0, \
97}
98
99#define kstk_tos(tsk) \
100 ((unsigned long)task_stack_page(tsk) + THREAD_SIZE - 32)
101#define task_pt_regs(tsk) ((struct pt_regs *)kstk_tos(tsk) - 1)
102
103#define KSTK_EIP(tsk) (task_pt_regs(tsk)->cp0_epc)
104#define KSTK_ESP(tsk) (task_pt_regs(tsk)->regs[29])
105
106#endif /* _ASM_SCORE_PROCESSOR_H */
diff --git a/arch/score/include/asm/ptrace.h b/arch/score/include/asm/ptrace.h
new file mode 100644
index 000000000000..1a4900ac49f3
--- /dev/null
+++ b/arch/score/include/asm/ptrace.h
@@ -0,0 +1,87 @@
1#ifndef _ASM_SCORE_PTRACE_H
2#define _ASM_SCORE_PTRACE_H
3
4#define PC 32
5#define CONDITION 33
6#define ECR 34
7#define EMA 35
8#define CEH 36
9#define CEL 37
10#define COUNTER 38
11#define LDCR 39
12#define STCR 40
13#define PSR 41
14
15#define SINGLESTEP16_INSN 0x7006
16#define SINGLESTEP32_INSN 0x840C8000
17#define BREAKPOINT16_INSN 0x7002 /* work on SPG300 */
18#define BREAKPOINT32_INSN 0x84048000 /* work on SPG300 */
19
20/* Define instruction mask */
21#define INSN32_MASK 0x80008000
22
23#define J32 0x88008000 /* 1_00010_0000000000_1_000000000000000 */
24#define J32M 0xFC008000 /* 1_11111_0000000000_1_000000000000000 */
25
26#define B32 0x90008000 /* 1_00100_0000000000_1_000000000000000 */
27#define B32M 0xFC008000
28#define BL32 0x90008001 /* 1_00100_0000000000_1_000000000000001 */
29#define BL32M B32
30#define BR32 0x80008008 /* 1_00000_0000000000_1_00000000_000100_0 */
31#define BR32M 0xFFE0807E
32#define BRL32 0x80008009 /* 1_00000_0000000000_1_00000000_000100_1 */
33#define BRL32M BR32M
34
35#define B32_SET (J32 | B32 | BL32 | BR32 | BRL32)
36
37#define J16 0x3000 /* 0_011_....... */
38#define J16M 0xF000
39#define B16 0x4000 /* 0_100_....... */
40#define B16M 0xF000
41#define BR16 0x0004 /* 0_000.......0100 */
42#define BR16M 0xF00F
43#define B16_SET (J16 | B16 | BR16)
44
45
46/*
47 * This struct defines the way the registers are stored on the stack during a
48 * system call/exception. As usual the registers k0/k1 aren't being saved.
49 */
50struct pt_regs {
51 unsigned long pad0[6];
52 unsigned long orig_r4;
53 unsigned long orig_r7;
54 unsigned long regs[32];
55
56 unsigned long cel;
57 unsigned long ceh;
58
59 unsigned long sr0; /* cnt */
60 unsigned long sr1; /* lcr */
61 unsigned long sr2; /* scr */
62
63 unsigned long cp0_epc;
64 unsigned long cp0_ema;
65 unsigned long cp0_psr;
66 unsigned long cp0_ecr;
67 unsigned long cp0_condition;
68
69 long is_syscall;
70};
71
72#ifdef __KERNEL__
73
74/*
75 * Does the process account for user or for system time?
76 */
77#define user_mode(regs) ((regs->cp0_psr & 8) == 8)
78
79#define instruction_pointer(regs) (0)
80#define profile_pc(regs) instruction_pointer(regs)
81
82extern asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit);
83extern int read_tsk_long(struct task_struct *, unsigned long, unsigned long *);
84extern void clear_single_step(struct task_struct *);
85#endif
86
87#endif /* _ASM_SCORE_PTRACE_H */
diff --git a/arch/score/include/asm/resource.h b/arch/score/include/asm/resource.h
new file mode 100644
index 000000000000..9ce22bc7b475
--- /dev/null
+++ b/arch/score/include/asm/resource.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_RESOURCE_H
2#define _ASM_SCORE_RESOURCE_H
3
4#include <asm-generic/resource.h>
5
6#endif /* _ASM_SCORE_RESOURCE_H */
diff --git a/arch/score/include/asm/scatterlist.h b/arch/score/include/asm/scatterlist.h
new file mode 100644
index 000000000000..9f533b8362c7
--- /dev/null
+++ b/arch/score/include/asm/scatterlist.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_SCATTERLIST_H
2#define _ASM_SCORE_SCATTERLIST_H
3
4#include <asm-generic/scatterlist.h>
5
6#endif /* _ASM_SCORE_SCATTERLIST_H */
diff --git a/arch/score/include/asm/scoreregs.h b/arch/score/include/asm/scoreregs.h
new file mode 100644
index 000000000000..d0ad29204518
--- /dev/null
+++ b/arch/score/include/asm/scoreregs.h
@@ -0,0 +1,51 @@
1#ifndef _ASM_SCORE_SCOREREGS_H
2#define _ASM_SCORE_SCOREREGS_H
3
4#include <linux/linkage.h>
5
6/* TIMER register */
7#define TIME0BASE 0x96080000
8#define P_TIMER0_CTRL (TIME0BASE + 0x00)
9#define P_TIMER0_CPP_CTRL (TIME0BASE + 0x04)
10#define P_TIMER0_PRELOAD (TIME0BASE + 0x08)
11#define P_TIMER0_CPP_REG (TIME0BASE + 0x0C)
12#define P_TIMER0_UPCNT (TIME0BASE + 0x10)
13
14/* Timer Controller Register */
15/* bit 0 Timer enable */
16#define TMR_DISABLE 0x0000
17#define TMR_ENABLE 0x0001
18
19/* bit 1 Interrupt enable */
20#define TMR_IE_DISABLE 0x0000
21#define TMR_IE_ENABLE 0x0002
22
23/* bit 2 Output enable */
24#define TMR_OE_DISABLE 0x0004
25#define TMR_OE_ENABLE 0x0000
26
27/* bit4 Up/Down counting selection */
28#define TMR_UD_DOWN 0x0000
29#define TMR_UD_UP 0x0010
30
31/* bit5 Up/Down counting control selection */
32#define TMR_UDS_UD 0x0000
33#define TMR_UDS_EXTUD 0x0020
34
35/* bit6 Time output mode */
36#define TMR_OM_TOGGLE 0x0000
37#define TMR_OM_PILSE 0x0040
38
39/* bit 8..9 External input active edge selection */
40#define TMR_ES_PE 0x0000
41#define TMR_ES_NE 0x0100
42#define TMR_ES_BOTH 0x0200
43
44/* bit 10..11 Operating mode */
45#define TMR_M_FREE 0x0000 /* free running timer mode */
46#define TMR_M_PERIODIC 0x0400 /* periodic timer mode */
47#define TMR_M_FC 0x0800 /* free running counter mode */
48#define TMR_M_PC 0x0c00 /* periodic counter mode */
49
50#define SYSTEM_CLOCK (27*1000000/4) /* 27 MHz */
51#endif /* _ASM_SCORE_SCOREREGS_H */
diff --git a/arch/score/include/asm/sections.h b/arch/score/include/asm/sections.h
new file mode 100644
index 000000000000..9441d23af005
--- /dev/null
+++ b/arch/score/include/asm/sections.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_SECTIONS_H
2#define _ASM_SCORE_SECTIONS_H
3
4#include <asm-generic/sections.h>
5
6#endif /* _ASM_SCORE_SECTIONS_H */
diff --git a/arch/score/include/asm/segment.h b/arch/score/include/asm/segment.h
new file mode 100644
index 000000000000..e16cf6afb495
--- /dev/null
+++ b/arch/score/include/asm/segment.h
@@ -0,0 +1,21 @@
1#ifndef _ASM_SCORE_SEGMENT_H
2#define _ASM_SCORE_SEGMENT_H
3
4#ifndef __ASSEMBLY__
5
6typedef struct {
7 unsigned long seg;
8} mm_segment_t;
9
10#define KERNEL_DS ((mm_segment_t){0})
11#define USER_DS KERNEL_DS
12
13# define get_ds() (KERNEL_DS)
14# define get_fs() (current_thread_info()->addr_limit)
15# define set_fs(x) \
16 do { current_thread_info()->addr_limit = (x); } while (0)
17
18# define segment_eq(a, b) ((a).seg == (b).seg)
19
20# endif /* __ASSEMBLY__ */
21#endif /* _ASM_SCORE_SEGMENT_H */
diff --git a/arch/score/include/asm/sembuf.h b/arch/score/include/asm/sembuf.h
new file mode 100644
index 000000000000..dae5e835ce9e
--- /dev/null
+++ b/arch/score/include/asm/sembuf.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_SEMBUF_H
2#define _ASM_SCORE_SEMBUF_H
3
4#include <asm-generic/sembuf.h>
5
6#endif /* _ASM_SCORE_SEMBUF_H */
diff --git a/arch/score/include/asm/setup.h b/arch/score/include/asm/setup.h
new file mode 100644
index 000000000000..de89eff98dae
--- /dev/null
+++ b/arch/score/include/asm/setup.h
@@ -0,0 +1,40 @@
1#ifndef _ASM_SCORE_SETUP_H
2#define _ASM_SCORE_SETUP_H
3
4#define COMMAND_LINE_SIZE 256
5#define MEM_SIZE 0x2000000
6
7#ifdef __KERNEL__
8
9extern void pagetable_init(void);
10extern void pgd_init(unsigned long page);
11
12extern void setup_early_printk(void);
13extern void cpu_cache_init(void);
14extern void tlb_init(void);
15
16extern void handle_nmi(void);
17extern void handle_adelinsn(void);
18extern void handle_adedata(void);
19extern void handle_ibe(void);
20extern void handle_pel(void);
21extern void handle_sys(void);
22extern void handle_ccu(void);
23extern void handle_ri(void);
24extern void handle_tr(void);
25extern void handle_ades(void);
26extern void handle_cee(void);
27extern void handle_cpe(void);
28extern void handle_dve(void);
29extern void handle_dbe(void);
30extern void handle_reserved(void);
31extern void handle_tlb_refill(void);
32extern void handle_tlb_invaild(void);
33extern void handle_mod(void);
34extern void debug_exception_vector(void);
35extern void general_exception_vector(void);
36extern void interrupt_exception_vector(void);
37
38#endif /* __KERNEL__ */
39
40#endif /* _ASM_SCORE_SETUP_H */
diff --git a/arch/score/include/asm/shmbuf.h b/arch/score/include/asm/shmbuf.h
new file mode 100644
index 000000000000..c85b2429ba21
--- /dev/null
+++ b/arch/score/include/asm/shmbuf.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_SHMBUF_H
2#define _ASM_SCORE_SHMBUF_H
3
4#include <asm-generic/shmbuf.h>
5
6#endif /* _ASM_SCORE_SHMBUF_H */
diff --git a/arch/score/include/asm/shmparam.h b/arch/score/include/asm/shmparam.h
new file mode 100644
index 000000000000..1d60813141b6
--- /dev/null
+++ b/arch/score/include/asm/shmparam.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_SHMPARAM_H
2#define _ASM_SCORE_SHMPARAM_H
3
4#include <asm-generic/shmparam.h>
5
6#endif /* _ASM_SCORE_SHMPARAM_H */
diff --git a/arch/score/include/asm/sigcontext.h b/arch/score/include/asm/sigcontext.h
new file mode 100644
index 000000000000..5ffda39ddb90
--- /dev/null
+++ b/arch/score/include/asm/sigcontext.h
@@ -0,0 +1,22 @@
1#ifndef _ASM_SCORE_SIGCONTEXT_H
2#define _ASM_SCORE_SIGCONTEXT_H
3
4/*
5 * Keep this struct definition in sync with the sigcontext fragment
6 * in arch/score/tools/offset.c
7 */
8struct sigcontext {
9 unsigned int sc_regmask;
10 unsigned int sc_psr;
11 unsigned int sc_condition;
12 unsigned long sc_pc;
13 unsigned long sc_regs[32];
14 unsigned int sc_ssflags;
15 unsigned int sc_mdceh;
16 unsigned int sc_mdcel;
17 unsigned int sc_ecr;
18 unsigned long sc_ema;
19 unsigned long sc_sigset[4];
20};
21
22#endif /* _ASM_SCORE_SIGCONTEXT_H */
diff --git a/arch/score/include/asm/siginfo.h b/arch/score/include/asm/siginfo.h
new file mode 100644
index 000000000000..87ca35607a28
--- /dev/null
+++ b/arch/score/include/asm/siginfo.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_SIGINFO_H
2#define _ASM_SCORE_SIGINFO_H
3
4#include <asm-generic/siginfo.h>
5
6#endif /* _ASM_SCORE_SIGINFO_H */
diff --git a/arch/score/include/asm/signal.h b/arch/score/include/asm/signal.h
new file mode 100644
index 000000000000..2605bc06b64f
--- /dev/null
+++ b/arch/score/include/asm/signal.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_SIGNAL_H
2#define _ASM_SCORE_SIGNAL_H
3
4#include <asm-generic/signal.h>
5
6#endif /* _ASM_SCORE_SIGNAL_H */
diff --git a/arch/score/include/asm/socket.h b/arch/score/include/asm/socket.h
new file mode 100644
index 000000000000..612a70e385ba
--- /dev/null
+++ b/arch/score/include/asm/socket.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_SOCKET_H
2#define _ASM_SCORE_SOCKET_H
3
4#include <asm-generic/socket.h>
5
6#endif /* _ASM_SCORE_SOCKET_H */
diff --git a/arch/score/include/asm/sockios.h b/arch/score/include/asm/sockios.h
new file mode 100644
index 000000000000..ba8256480189
--- /dev/null
+++ b/arch/score/include/asm/sockios.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_SOCKIOS_H
2#define _ASM_SCORE_SOCKIOS_H
3
4#include <asm-generic/sockios.h>
5
6#endif /* _ASM_SCORE_SOCKIOS_H */
diff --git a/arch/score/include/asm/stat.h b/arch/score/include/asm/stat.h
new file mode 100644
index 000000000000..5037055500a2
--- /dev/null
+++ b/arch/score/include/asm/stat.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_STAT_H
2#define _ASM_SCORE_STAT_H
3
4#include <asm-generic/stat.h>
5
6#endif /* _ASM_SCORE_STAT_H */
diff --git a/arch/score/include/asm/statfs.h b/arch/score/include/asm/statfs.h
new file mode 100644
index 000000000000..36e41004e996
--- /dev/null
+++ b/arch/score/include/asm/statfs.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_STATFS_H
2#define _ASM_SCORE_STATFS_H
3
4#include <asm-generic/statfs.h>
5
6#endif /* _ASM_SCORE_STATFS_H */
diff --git a/arch/score/include/asm/string.h b/arch/score/include/asm/string.h
new file mode 100644
index 000000000000..8a6bf5063aa5
--- /dev/null
+++ b/arch/score/include/asm/string.h
@@ -0,0 +1,8 @@
1#ifndef _ASM_SCORE_STRING_H
2#define _ASM_SCORE_STRING_H
3
4extern void *memset(void *__s, int __c, size_t __count);
5extern void *memcpy(void *__to, __const__ void *__from, size_t __n);
6extern void *memmove(void *__dest, __const__ void *__src, size_t __n);
7
8#endif /* _ASM_SCORE_STRING_H */
diff --git a/arch/score/include/asm/swab.h b/arch/score/include/asm/swab.h
new file mode 100644
index 000000000000..fadc3cc6d8a2
--- /dev/null
+++ b/arch/score/include/asm/swab.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_SWAB_H
2#define _ASM_SCORE_SWAB_H
3
4#include <asm-generic/swab.h>
5
6#endif /* _ASM_SCORE_SWAB_H */
diff --git a/arch/score/include/asm/syscalls.h b/arch/score/include/asm/syscalls.h
new file mode 100644
index 000000000000..00c28e04fdfc
--- /dev/null
+++ b/arch/score/include/asm/syscalls.h
@@ -0,0 +1,9 @@
1#ifndef _ASM_SCORE_SYSCALLS_H
2#define _ASM_SCORE_SYSCALLS_H
3
4asmlinkage long sys_clone(int flags, unsigned long stack, struct pt_regs *regs);
5#define sys_clone sys_clone
6
7#include <asm-generic/syscalls.h>
8
9#endif /* _ASM_SCORE_SYSCALLS_H */
diff --git a/arch/score/include/asm/system.h b/arch/score/include/asm/system.h
new file mode 100644
index 000000000000..589d5c7e171c
--- /dev/null
+++ b/arch/score/include/asm/system.h
@@ -0,0 +1,90 @@
1#ifndef _ASM_SCORE_SYSTEM_H
2#define _ASM_SCORE_SYSTEM_H
3
4#include <linux/types.h>
5#include <linux/irqflags.h>
6
7struct pt_regs;
8struct task_struct;
9
10extern void *resume(void *last, void *next, void *next_ti);
11
12#define switch_to(prev, next, last) \
13do { \
14 (last) = resume(prev, next, task_thread_info(next)); \
15} while (0)
16
17#define finish_arch_switch(prev) do {} while (0)
18
19typedef void (*vi_handler_t)(void);
20extern unsigned long arch_align_stack(unsigned long sp);
21
22#define mb() barrier()
23#define rmb() barrier()
24#define wmb() barrier()
25#define smp_mb() barrier()
26#define smp_rmb() barrier()
27#define smp_wmb() barrier()
28
29#define read_barrier_depends() do {} while (0)
30#define smp_read_barrier_depends() do {} while (0)
31
32#define set_mb(var, value) do {var = value; wmb(); } while (0)
33
34#define __HAVE_ARCH_CMPXCHG 1
35
36#include <asm-generic/cmpxchg-local.h>
37
38#ifndef __ASSEMBLY__
39
40struct __xchg_dummy { unsigned long a[100]; };
41#define __xg(x) ((struct __xchg_dummy *)(x))
42
43static inline
44unsigned long __xchg(volatile unsigned long *m, unsigned long val)
45{
46 unsigned long retval;
47 unsigned long flags;
48
49 local_irq_save(flags);
50 retval = *m;
51 *m = val;
52 local_irq_restore(flags);
53 return retval;
54}
55
56#define xchg(ptr, v) \
57 ((__typeof__(*(ptr))) __xchg((unsigned long *)(ptr), \
58 (unsigned long)(v)))
59
60static inline unsigned long __cmpxchg(volatile unsigned long *m,
61 unsigned long old, unsigned long new)
62{
63 unsigned long retval;
64 unsigned long flags;
65
66 local_irq_save(flags);
67 retval = *m;
68 if (retval == old)
69 *m = new;
70 local_irq_restore(flags);
71 return retval;
72}
73
74#define cmpxchg(ptr, o, n) \
75 ((__typeof__(*(ptr))) __cmpxchg((unsigned long *)(ptr), \
76 (unsigned long)(o), \
77 (unsigned long)(n)))
78
79extern void __die(const char *, struct pt_regs *, const char *,
80 const char *, unsigned long) __attribute__((noreturn));
81extern void __die_if_kernel(const char *, struct pt_regs *, const char *,
82 const char *, unsigned long);
83
84#define die(msg, regs) \
85 __die(msg, regs, __FILE__ ":", __func__, __LINE__)
86#define die_if_kernel(msg, regs) \
87 __die_if_kernel(msg, regs, __FILE__ ":", __func__, __LINE__)
88
89#endif /* !__ASSEMBLY__ */
90#endif /* _ASM_SCORE_SYSTEM_H */
diff --git a/arch/score/include/asm/termbits.h b/arch/score/include/asm/termbits.h
new file mode 100644
index 000000000000..9a95c1412437
--- /dev/null
+++ b/arch/score/include/asm/termbits.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_TERMBITS_H
2#define _ASM_SCORE_TERMBITS_H
3
4#include <asm-generic/termbits.h>
5
6#endif /* _ASM_SCORE_TERMBITS_H */
diff --git a/arch/score/include/asm/termios.h b/arch/score/include/asm/termios.h
new file mode 100644
index 000000000000..40984e811ad6
--- /dev/null
+++ b/arch/score/include/asm/termios.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_TERMIOS_H
2#define _ASM_SCORE_TERMIOS_H
3
4#include <asm-generic/termios.h>
5
6#endif /* _ASM_SCORE_TERMIOS_H */
diff --git a/arch/score/include/asm/thread_info.h b/arch/score/include/asm/thread_info.h
new file mode 100644
index 000000000000..0af8ca074c8d
--- /dev/null
+++ b/arch/score/include/asm/thread_info.h
@@ -0,0 +1,103 @@
1#ifndef _ASM_SCORE_THREAD_INFO_H
2#define _ASM_SCORE_THREAD_INFO_H
3
4#ifdef __KERNEL__
5
6#define KU_MASK 0x08
7#define KU_USER 0x08
8#define KU_KERN 0x00
9
10#ifndef __ASSEMBLY__
11
12#include <asm/processor.h>
13
14/*
15 * low level task data that entry.S needs immediate access to
16 * - this struct should fit entirely inside of one cache line
17 * - this struct shares the supervisor stack pages
18 * - if the contents of this structure are changed, the assembly constants
19 * must also be changed
20 */
21struct thread_info {
22 struct task_struct *task; /* main task structure */
23 struct exec_domain *exec_domain; /* execution domain */
24 unsigned long flags; /* low level flags */
25 unsigned long tp_value; /* thread pointer */
26 __u32 cpu; /* current CPU */
27
28 /* 0 => preemptable, < 0 => BUG */
29 int preempt_count;
30
31 /*
32 * thread address space:
33 * 0-0xBFFFFFFF for user-thead
34 * 0-0xFFFFFFFF for kernel-thread
35 */
36 mm_segment_t addr_limit;
37 struct restart_block restart_block;
38 struct pt_regs *regs;
39};
40
41/*
42 * macros/functions for gaining access to the thread information structure
43 *
44 * preempt_count needs to be 1 initially, until the scheduler is functional.
45 */
46#define INIT_THREAD_INFO(tsk) \
47{ \
48 .task = &tsk, \
49 .exec_domain = &default_exec_domain, \
50 .cpu = 0, \
51 .preempt_count = 1, \
52 .addr_limit = KERNEL_DS, \
53 .restart_block = { \
54 .fn = do_no_restart_syscall, \
55 }, \
56}
57
58#define init_thread_info (init_thread_union.thread_info)
59#define init_stack (init_thread_union.stack)
60
61/* How to get the thread information struct from C. */
62register struct thread_info *__current_thread_info __asm__("r28");
63#define current_thread_info() __current_thread_info
64
65/* thread information allocation */
66#define THREAD_SIZE_ORDER (1)
67#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)
68#define THREAD_MASK (THREAD_SIZE - 1UL)
69#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR
70
71#define alloc_thread_info(tsk) kmalloc(THREAD_SIZE, GFP_KERNEL)
72#define free_thread_info(info) kfree(info)
73
74#endif /* !__ASSEMBLY__ */
75
76#define PREEMPT_ACTIVE 0x10000000
77
78/*
79 * thread information flags
80 * - these are process state flags that various assembly files may need to
81 * access
82 * - pending work-to-be-done flags are in LSW
83 * - other flags in MSW
84 */
85#define TIF_SYSCALL_TRACE 0 /* syscall trace active */
86#define TIF_SIGPENDING 1 /* signal pending */
87#define TIF_NEED_RESCHED 2 /* rescheduling necessary */
88#define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal() */
89#define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling
90 TIF_NEED_RESCHED */
91#define TIF_MEMDIE 18
92
93#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
94#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
95#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
96#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
97#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
98
99#define _TIF_WORK_MASK (0x0000ffff)
100
101#endif /* __KERNEL__ */
102
103#endif /* _ASM_SCORE_THREAD_INFO_H */
diff --git a/arch/score/include/asm/timex.h b/arch/score/include/asm/timex.h
new file mode 100644
index 000000000000..a524ae0c5e7b
--- /dev/null
+++ b/arch/score/include/asm/timex.h
@@ -0,0 +1,8 @@
1#ifndef _ASM_SCORE_TIMEX_H
2#define _ASM_SCORE_TIMEX_H
3
4#define CLOCK_TICK_RATE 27000000 /* Timer input freq. */
5
6#include <asm-generic/timex.h>
7
8#endif /* _ASM_SCORE_TIMEX_H */
diff --git a/arch/score/include/asm/tlb.h b/arch/score/include/asm/tlb.h
new file mode 100644
index 000000000000..46882ed524e6
--- /dev/null
+++ b/arch/score/include/asm/tlb.h
@@ -0,0 +1,17 @@
1#ifndef _ASM_SCORE_TLB_H
2#define _ASM_SCORE_TLB_H
3
4/*
5 * SCORE doesn't need any special per-pte or per-vma handling, except
6 * we need to flush cache for area to be unmapped.
7 */
8#define tlb_start_vma(tlb, vma) do {} while (0)
9#define tlb_end_vma(tlb, vma) do {} while (0)
10#define __tlb_remove_tlb_entry(tlb, ptep, address) do {} while (0)
11#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
12
13extern void score7_FTLB_refill_Handler(void);
14
15#include <asm-generic/tlb.h>
16
17#endif /* _ASM_SCORE_TLB_H */
diff --git a/arch/score/include/asm/tlbflush.h b/arch/score/include/asm/tlbflush.h
new file mode 100644
index 000000000000..9cce978367d5
--- /dev/null
+++ b/arch/score/include/asm/tlbflush.h
@@ -0,0 +1,142 @@
1#ifndef _ASM_SCORE_TLBFLUSH_H
2#define _ASM_SCORE_TLBFLUSH_H
3
4#include <linux/mm.h>
5
6/*
7 * TLB flushing:
8 *
9 * - flush_tlb_all() flushes all processes TLB entries
10 * - flush_tlb_mm(mm) flushes the specified mm context TLB entries
11 * - flush_tlb_page(vma, vmaddr) flushes one page
12 * - flush_tlb_range(vma, start, end) flushes a range of pages
13 * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
14 */
15extern void local_flush_tlb_all(void);
16extern void local_flush_tlb_mm(struct mm_struct *mm);
17extern void local_flush_tlb_range(struct vm_area_struct *vma,
18 unsigned long start, unsigned long end);
19extern void local_flush_tlb_kernel_range(unsigned long start,
20 unsigned long end);
21extern void local_flush_tlb_page(struct vm_area_struct *vma,
22 unsigned long page);
23extern void local_flush_tlb_one(unsigned long vaddr);
24
25#define flush_tlb_all() local_flush_tlb_all()
26#define flush_tlb_mm(mm) local_flush_tlb_mm(mm)
27#define flush_tlb_range(vma, vmaddr, end) \
28 local_flush_tlb_range(vma, vmaddr, end)
29#define flush_tlb_kernel_range(vmaddr, end) \
30 local_flush_tlb_kernel_range(vmaddr, end)
31#define flush_tlb_page(vma, page) local_flush_tlb_page(vma, page)
32#define flush_tlb_one(vaddr) local_flush_tlb_one(vaddr)
33
34#ifndef __ASSEMBLY__
35
36static inline unsigned long pevn_get(void)
37{
38 unsigned long val;
39
40 __asm__ __volatile__(
41 "mfcr %0, cr11\n"
42 "nop\nnop\n"
43 : "=r" (val));
44
45 return val;
46}
47
48static inline void pevn_set(unsigned long val)
49{
50 __asm__ __volatile__(
51 "mtcr %0, cr11\n"
52 "nop\nnop\nnop\nnop\nnop\n"
53 : : "r" (val));
54}
55
56static inline void pectx_set(unsigned long val)
57{
58 __asm__ __volatile__(
59 "mtcr %0, cr12\n"
60 "nop\nnop\nnop\nnop\nnop\n"
61 : : "r" (val));
62}
63
64static inline unsigned long pectx_get(void)
65{
66 unsigned long val;
67 __asm__ __volatile__(
68 "mfcr %0, cr12\n"
69 "nop\nnop\n"
70 : "=r" (val));
71 return val;
72}
73static inline unsigned long tlblock_get(void)
74{
75 unsigned long val;
76
77 __asm__ __volatile__(
78 "mfcr %0, cr7\n"
79 "nop\nnop\n"
80 : "=r" (val));
81 return val;
82}
83static inline void tlblock_set(unsigned long val)
84{
85 __asm__ __volatile__(
86 "mtcr %0, cr7\n"
87 "nop\nnop\nnop\nnop\nnop\n"
88 : : "r" (val));
89}
90
91static inline void tlbpt_set(unsigned long val)
92{
93 __asm__ __volatile__(
94 "mtcr %0, cr8\n"
95 "nop\nnop\nnop\nnop\nnop\n"
96 : : "r" (val));
97}
98
99static inline long tlbpt_get(void)
100{
101 long val;
102
103 __asm__ __volatile__(
104 "mfcr %0, cr8\n"
105 "nop\nnop\n"
106 : "=r" (val));
107
108 return val;
109}
110
111static inline void peaddr_set(unsigned long val)
112{
113 __asm__ __volatile__(
114 "mtcr %0, cr9\n"
115 "nop\nnop\nnop\nnop\nnop\n"
116 : : "r" (val));
117}
118
119/* TLB operations. */
120static inline void tlb_probe(void)
121{
122 __asm__ __volatile__("stlb;nop;nop;nop;nop;nop");
123}
124
125static inline void tlb_read(void)
126{
127 __asm__ __volatile__("mftlb;nop;nop;nop;nop;nop");
128}
129
130static inline void tlb_write_indexed(void)
131{
132 __asm__ __volatile__("mtptlb;nop;nop;nop;nop;nop");
133}
134
135static inline void tlb_write_random(void)
136{
137 __asm__ __volatile__("mtrtlb;nop;nop;nop;nop;nop");
138}
139
140#endif /* Not __ASSEMBLY__ */
141
142#endif /* _ASM_SCORE_TLBFLUSH_H */
diff --git a/arch/score/include/asm/topology.h b/arch/score/include/asm/topology.h
new file mode 100644
index 000000000000..425fba381f88
--- /dev/null
+++ b/arch/score/include/asm/topology.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_TOPOLOGY_H
2#define _ASM_SCORE_TOPOLOGY_H
3
4#include <asm-generic/topology.h>
5
6#endif /* _ASM_SCORE_TOPOLOGY_H */
diff --git a/arch/score/include/asm/types.h b/arch/score/include/asm/types.h
new file mode 100644
index 000000000000..2140032778ee
--- /dev/null
+++ b/arch/score/include/asm/types.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_TYPES_H
2#define _ASM_SCORE_TYPES_H
3
4#include <asm-generic/types.h>
5
6#endif /* _ASM_SCORE_TYPES_H */
diff --git a/arch/score/include/asm/uaccess.h b/arch/score/include/asm/uaccess.h
new file mode 100644
index 000000000000..43ce28a1d0fc
--- /dev/null
+++ b/arch/score/include/asm/uaccess.h
@@ -0,0 +1,27 @@
1#ifndef _ASM_SCORE_UACCESS_H
2#define _ASM_SCORE_UACCESS_H
3/*
4 * Copyright (C) 2006 Atmark Techno, Inc.
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10struct pt_regs;
11extern int fixup_exception(struct pt_regs *regs);
12
13#ifndef __ASSEMBLY__
14
15#define __range_ok(addr, size) \
16 ((((unsigned long)(addr) >= 0x80000000) \
17 || ((unsigned long)(size) > 0x80000000) \
18 || (((unsigned long)(addr) + (unsigned long)(size)) > 0x80000000)))
19
20#define __access_ok(addr, size) \
21 (__range_ok((addr), (size)) == 0)
22
23#include <asm-generic/uaccess.h>
24
25#endif /* __ASSEMBLY__ */
26
27#endif /* _ASM_SCORE_UACCESS_H */
diff --git a/arch/score/include/asm/unaligned.h b/arch/score/include/asm/unaligned.h
new file mode 100644
index 000000000000..2fc06de51c62
--- /dev/null
+++ b/arch/score/include/asm/unaligned.h
@@ -0,0 +1,6 @@
1#ifndef _ASM_SCORE_UNALIGNED_H
2#define _ASM_SCORE_UNALIGNED_H
3
4#include <asm-generic/unaligned.h>
5
6#endif /* _ASM_SCORE_UNALIGNED_H */
diff --git a/arch/score/include/asm/unistd.h b/arch/score/include/asm/unistd.h
new file mode 100644
index 000000000000..9aa3a159bbf6
--- /dev/null
+++ b/arch/score/include/asm/unistd.h
@@ -0,0 +1,8 @@
1#ifndef _ASM_SCORE_UNISTD_H
2#define _ASM_SCORE_UNISTD_H
3
4#define __ARCH_HAVE_MMU
5
6#include <asm-generic/unistd.h>
7
8#endif /* _ASM_SCORE_UNISTD_H */
diff --git a/arch/score/include/asm/user.h b/arch/score/include/asm/user.h
new file mode 100644
index 000000000000..3cf75720fe08
--- /dev/null
+++ b/arch/score/include/asm/user.h
@@ -0,0 +1,4 @@
1#ifndef _ASM_SCORE_USER_H
2#define _ASM_SCORE_USER_H
3
4#endif /* _ASM_SCORE_USER_H */
diff --git a/arch/score/kernel/Makefile b/arch/score/kernel/Makefile
new file mode 100644
index 000000000000..1e5de89d5c73
--- /dev/null
+++ b/arch/score/kernel/Makefile
@@ -0,0 +1,10 @@
1#
2# Makefile for the Linux/SCORE kernel.
3#
4
5extra-y := head.o vmlinux.lds
6
7obj-y += entry.o init_task.o irq.o process.o ptrace.o \
8 setup.o signal.o sys_score.o time.o traps.o
9
10obj-$(CONFIG_MODULES) += module.o
diff --git a/arch/score/kernel/asm-offsets.c b/arch/score/kernel/asm-offsets.c
new file mode 100644
index 000000000000..57788f44c6fb
--- /dev/null
+++ b/arch/score/kernel/asm-offsets.c
@@ -0,0 +1,216 @@
1/*
2 * arch/score/kernel/asm-offsets.c
3 *
4 * Score Processor version.
5 *
6 * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
7 * Chen Liqin <liqin.chen@sunplusct.com>
8 * Lennox Wu <lennox.wu@sunplusct.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see the file COPYING, or write
22 * to the Free Software Foundation, Inc.,
23 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26#include <linux/kbuild.h>
27#include <linux/interrupt.h>
28#include <linux/mm.h>
29#include <linux/sched.h>
30
31#include <asm-generic/cmpxchg-local.h>
32
33void output_ptreg_defines(void)
34{
35 COMMENT("SCORE pt_regs offsets.");
36 OFFSET(PT_R0, pt_regs, regs[0]);
37 OFFSET(PT_R1, pt_regs, regs[1]);
38 OFFSET(PT_R2, pt_regs, regs[2]);
39 OFFSET(PT_R3, pt_regs, regs[3]);
40 OFFSET(PT_R4, pt_regs, regs[4]);
41 OFFSET(PT_R5, pt_regs, regs[5]);
42 OFFSET(PT_R6, pt_regs, regs[6]);
43 OFFSET(PT_R7, pt_regs, regs[7]);
44 OFFSET(PT_R8, pt_regs, regs[8]);
45 OFFSET(PT_R9, pt_regs, regs[9]);
46 OFFSET(PT_R10, pt_regs, regs[10]);
47 OFFSET(PT_R11, pt_regs, regs[11]);
48 OFFSET(PT_R12, pt_regs, regs[12]);
49 OFFSET(PT_R13, pt_regs, regs[13]);
50 OFFSET(PT_R14, pt_regs, regs[14]);
51 OFFSET(PT_R15, pt_regs, regs[15]);
52 OFFSET(PT_R16, pt_regs, regs[16]);
53 OFFSET(PT_R17, pt_regs, regs[17]);
54 OFFSET(PT_R18, pt_regs, regs[18]);
55 OFFSET(PT_R19, pt_regs, regs[19]);
56 OFFSET(PT_R20, pt_regs, regs[20]);
57 OFFSET(PT_R21, pt_regs, regs[21]);
58 OFFSET(PT_R22, pt_regs, regs[22]);
59 OFFSET(PT_R23, pt_regs, regs[23]);
60 OFFSET(PT_R24, pt_regs, regs[24]);
61 OFFSET(PT_R25, pt_regs, regs[25]);
62 OFFSET(PT_R26, pt_regs, regs[26]);
63 OFFSET(PT_R27, pt_regs, regs[27]);
64 OFFSET(PT_R28, pt_regs, regs[28]);
65 OFFSET(PT_R29, pt_regs, regs[29]);
66 OFFSET(PT_R30, pt_regs, regs[30]);
67 OFFSET(PT_R31, pt_regs, regs[31]);
68
69 OFFSET(PT_ORIG_R4, pt_regs, orig_r4);
70 OFFSET(PT_ORIG_R7, pt_regs, orig_r7);
71 OFFSET(PT_CEL, pt_regs, cel);
72 OFFSET(PT_CEH, pt_regs, ceh);
73 OFFSET(PT_SR0, pt_regs, sr0);
74 OFFSET(PT_SR1, pt_regs, sr1);
75 OFFSET(PT_SR2, pt_regs, sr2);
76 OFFSET(PT_EPC, pt_regs, cp0_epc);
77 OFFSET(PT_EMA, pt_regs, cp0_ema);
78 OFFSET(PT_PSR, pt_regs, cp0_psr);
79 OFFSET(PT_ECR, pt_regs, cp0_ecr);
80 OFFSET(PT_CONDITION, pt_regs, cp0_condition);
81 OFFSET(PT_IS_SYSCALL, pt_regs, is_syscall);
82
83 DEFINE(PT_SIZE, sizeof(struct pt_regs));
84 BLANK();
85}
86
87void output_task_defines(void)
88{
89 COMMENT("SCORE task_struct offsets.");
90 OFFSET(TASK_STATE, task_struct, state);
91 OFFSET(TASK_THREAD_INFO, task_struct, stack);
92 OFFSET(TASK_FLAGS, task_struct, flags);
93 OFFSET(TASK_MM, task_struct, mm);
94 OFFSET(TASK_PID, task_struct, pid);
95 DEFINE(TASK_STRUCT_SIZE, sizeof(struct task_struct));
96 BLANK();
97}
98
99void output_thread_info_defines(void)
100{
101 COMMENT("SCORE thread_info offsets.");
102 OFFSET(TI_TASK, thread_info, task);
103 OFFSET(TI_EXEC_DOMAIN, thread_info, exec_domain);
104 OFFSET(TI_FLAGS, thread_info, flags);
105 OFFSET(TI_TP_VALUE, thread_info, tp_value);
106 OFFSET(TI_CPU, thread_info, cpu);
107 OFFSET(TI_PRE_COUNT, thread_info, preempt_count);
108 OFFSET(TI_ADDR_LIMIT, thread_info, addr_limit);
109 OFFSET(TI_RESTART_BLOCK, thread_info, restart_block);
110 OFFSET(TI_REGS, thread_info, regs);
111 DEFINE(KERNEL_STACK_SIZE, THREAD_SIZE);
112 DEFINE(KERNEL_STACK_MASK, THREAD_MASK);
113 BLANK();
114}
115
116void output_thread_defines(void)
117{
118 COMMENT("SCORE specific thread_struct offsets.");
119 OFFSET(THREAD_REG0, task_struct, thread.reg0);
120 OFFSET(THREAD_REG2, task_struct, thread.reg2);
121 OFFSET(THREAD_REG3, task_struct, thread.reg3);
122 OFFSET(THREAD_REG12, task_struct, thread.reg12);
123 OFFSET(THREAD_REG13, task_struct, thread.reg13);
124 OFFSET(THREAD_REG14, task_struct, thread.reg14);
125 OFFSET(THREAD_REG15, task_struct, thread.reg15);
126 OFFSET(THREAD_REG16, task_struct, thread.reg16);
127 OFFSET(THREAD_REG17, task_struct, thread.reg17);
128 OFFSET(THREAD_REG18, task_struct, thread.reg18);
129 OFFSET(THREAD_REG19, task_struct, thread.reg19);
130 OFFSET(THREAD_REG20, task_struct, thread.reg20);
131 OFFSET(THREAD_REG21, task_struct, thread.reg21);
132 OFFSET(THREAD_REG29, task_struct, thread.reg29);
133
134 OFFSET(THREAD_PSR, task_struct, thread.cp0_psr);
135 OFFSET(THREAD_EMA, task_struct, thread.cp0_ema);
136 OFFSET(THREAD_BADUADDR, task_struct, thread.cp0_baduaddr);
137 OFFSET(THREAD_ECODE, task_struct, thread.error_code);
138 OFFSET(THREAD_TRAPNO, task_struct, thread.trap_no);
139 BLANK();
140}
141
142void output_mm_defines(void)
143{
144 COMMENT("Size of struct page");
145 DEFINE(STRUCT_PAGE_SIZE, sizeof(struct page));
146 BLANK();
147 COMMENT("Linux mm_struct offsets.");
148 OFFSET(MM_USERS, mm_struct, mm_users);
149 OFFSET(MM_PGD, mm_struct, pgd);
150 OFFSET(MM_CONTEXT, mm_struct, context);
151 BLANK();
152 DEFINE(_PAGE_SIZE, PAGE_SIZE);
153 DEFINE(_PAGE_SHIFT, PAGE_SHIFT);
154 BLANK();
155 DEFINE(_PGD_T_SIZE, sizeof(pgd_t));
156 DEFINE(_PTE_T_SIZE, sizeof(pte_t));
157 BLANK();
158 DEFINE(_PGD_ORDER, PGD_ORDER);
159 DEFINE(_PTE_ORDER, PTE_ORDER);
160 BLANK();
161 DEFINE(_PGDIR_SHIFT, PGDIR_SHIFT);
162 BLANK();
163 DEFINE(_PTRS_PER_PGD, PTRS_PER_PGD);
164 DEFINE(_PTRS_PER_PTE, PTRS_PER_PTE);
165 BLANK();
166}
167
168void output_sc_defines(void)
169{
170 COMMENT("Linux sigcontext offsets.");
171 OFFSET(SC_REGS, sigcontext, sc_regs);
172 OFFSET(SC_MDCEH, sigcontext, sc_mdceh);
173 OFFSET(SC_MDCEL, sigcontext, sc_mdcel);
174 OFFSET(SC_PC, sigcontext, sc_pc);
175 OFFSET(SC_PSR, sigcontext, sc_psr);
176 OFFSET(SC_ECR, sigcontext, sc_ecr);
177 OFFSET(SC_EMA, sigcontext, sc_ema);
178 BLANK();
179}
180
181void output_signal_defined(void)
182{
183 COMMENT("Linux signal numbers.");
184 DEFINE(_SIGHUP, SIGHUP);
185 DEFINE(_SIGINT, SIGINT);
186 DEFINE(_SIGQUIT, SIGQUIT);
187 DEFINE(_SIGILL, SIGILL);
188 DEFINE(_SIGTRAP, SIGTRAP);
189 DEFINE(_SIGIOT, SIGIOT);
190 DEFINE(_SIGABRT, SIGABRT);
191 DEFINE(_SIGFPE, SIGFPE);
192 DEFINE(_SIGKILL, SIGKILL);
193 DEFINE(_SIGBUS, SIGBUS);
194 DEFINE(_SIGSEGV, SIGSEGV);
195 DEFINE(_SIGSYS, SIGSYS);
196 DEFINE(_SIGPIPE, SIGPIPE);
197 DEFINE(_SIGALRM, SIGALRM);
198 DEFINE(_SIGTERM, SIGTERM);
199 DEFINE(_SIGUSR1, SIGUSR1);
200 DEFINE(_SIGUSR2, SIGUSR2);
201 DEFINE(_SIGCHLD, SIGCHLD);
202 DEFINE(_SIGPWR, SIGPWR);
203 DEFINE(_SIGWINCH, SIGWINCH);
204 DEFINE(_SIGURG, SIGURG);
205 DEFINE(_SIGIO, SIGIO);
206 DEFINE(_SIGSTOP, SIGSTOP);
207 DEFINE(_SIGTSTP, SIGTSTP);
208 DEFINE(_SIGCONT, SIGCONT);
209 DEFINE(_SIGTTIN, SIGTTIN);
210 DEFINE(_SIGTTOU, SIGTTOU);
211 DEFINE(_SIGVTALRM, SIGVTALRM);
212 DEFINE(_SIGPROF, SIGPROF);
213 DEFINE(_SIGXCPU, SIGXCPU);
214 DEFINE(_SIGXFSZ, SIGXFSZ);
215 BLANK();
216}
diff --git a/arch/score/kernel/entry.S b/arch/score/kernel/entry.S
new file mode 100644
index 000000000000..6c6b7ea58afa
--- /dev/null
+++ b/arch/score/kernel/entry.S
@@ -0,0 +1,542 @@
1/*
2 * arch/score/kernel/entry.S
3 *
4 * Score Processor version.
5 *
6 * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
7 * Chen Liqin <liqin.chen@sunplusct.com>
8 * Lennox Wu <lennox.wu@sunplusct.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see the file COPYING, or write
22 * to the Free Software Foundation, Inc.,
23 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26#include <linux/errno.h>
27#include <linux/init.h>
28#include <linux/linkage.h>
29
30#include <asm/asmmacro.h>
31#include <asm/thread_info.h>
32#include <asm/unistd.h>
33
34/*
35 * disable interrupts.
36 */
37.macro disable_irq
38 mfcr r8, cr0
39 srli r8, r8, 1
40 slli r8, r8, 1
41 mtcr r8, cr0
42 nop
43 nop
44 nop
45 nop
46 nop
47.endm
48
49/*
50 * enable interrupts.
51 */
52.macro enable_irq
53 mfcr r8, cr0
54 ori r8, 1
55 mtcr r8, cr0
56 nop
57 nop
58 nop
59 nop
60 nop
61.endm
62
63__INIT
64ENTRY(debug_exception_vector)
65 nop!
66 nop!
67 nop!
68 nop!
69 nop!
70 nop!
71 nop!
72 nop!
73
74ENTRY(general_exception_vector) # should move to addr 0x200
75 j general_exception
76 nop!
77 nop!
78 nop!
79 nop!
80 nop!
81 nop!
82
83ENTRY(interrupt_exception_vector) # should move to addr 0x210
84 j interrupt_exception
85 nop!
86 nop!
87 nop!
88 nop!
89 nop!
90 nop!
91
92 .section ".text", "ax"
93 .align 2;
94general_exception:
95 mfcr r31, cr2
96 nop
97 la r30, exception_handlers
98 andi r31, 0x1f # get ecr.exc_code
99 slli r31, r31, 2
100 add r30, r30, r31
101 lw r30, [r30]
102 br r30
103
104interrupt_exception:
105 SAVE_ALL
106 mfcr r4, cr2
107 nop
108 lw r16, [r28, TI_REGS]
109 sw r0, [r28, TI_REGS]
110 la r3, ret_from_irq
111 srli r4, r4, 18 # get ecr.ip[7:2], interrupt No.
112 mv r5, r0
113 j do_IRQ
114
115ENTRY(handle_nmi) # NMI #1
116 SAVE_ALL
117 mv r4, r0
118 la r8, nmi_exception_handler
119 brl r8
120 j restore_all
121
122ENTRY(handle_adelinsn) # AdEL-instruction #2
123 SAVE_ALL
124 mfcr r8, cr6
125 nop
126 nop
127 sw r8, [r0, PT_EMA]
128 mv r4, r0
129 la r8, do_adelinsn
130 brl r8
131 mv r4, r0
132 j ret_from_exception
133 nop
134
135ENTRY(handle_ibe) # BusEL-instruction #5
136 SAVE_ALL
137 mv r4, r0
138 la r8, do_be
139 brl r8
140 mv r4, r0
141 j ret_from_exception
142 nop
143
144ENTRY(handle_pel) # P-EL #6
145 SAVE_ALL
146 mv r4, r0
147 la r8, do_pel
148 brl r8
149 mv r4, r0
150 j ret_from_exception
151 nop
152
153ENTRY(handle_ccu) # CCU #8
154 SAVE_ALL
155 mv r4, r0
156 la r8, do_ccu
157 brl r8
158 mv r4, r0
159 j ret_from_exception
160 nop
161
162ENTRY(handle_ri) # RI #9
163 SAVE_ALL
164 mv r4, r0
165 la r8, do_ri
166 brl r8
167 mv r4, r0
168 j ret_from_exception
169 nop
170
171ENTRY(handle_tr) # Trap #10
172 SAVE_ALL
173 mv r4, r0
174 la r8, do_tr
175 brl r8
176 mv r4, r0
177 j ret_from_exception
178 nop
179
180ENTRY(handle_adedata) # AdES-instruction #12
181 SAVE_ALL
182 mfcr r8, cr6
183 nop
184 nop
185 sw r8, [r0, PT_EMA]
186 mv r4, r0
187 la r8, do_adedata
188 brl r8
189 mv r4, r0
190 j ret_from_exception
191 nop
192
193ENTRY(handle_cee) # CeE #16
194 SAVE_ALL
195 mv r4, r0
196 la r8, do_cee
197 brl r8
198 mv r4, r0
199 j ret_from_exception
200 nop
201
202ENTRY(handle_cpe) # CpE #17
203 SAVE_ALL
204 mv r4, r0
205 la r8, do_cpe
206 brl r8
207 mv r4, r0
208 j ret_from_exception
209 nop
210
211ENTRY(handle_dbe) # BusEL-data #18
212 SAVE_ALL
213 mv r4, r0
214 la r8, do_be
215 brl r8
216 mv r4, r0
217 j ret_from_exception
218 nop
219
220ENTRY(handle_reserved) # others
221 SAVE_ALL
222 mv r4, r0
223 la r8, do_reserved
224 brl r8
225 mv r4, r0
226 j ret_from_exception
227 nop
228
229#ifndef CONFIG_PREEMPT
230#define resume_kernel restore_all
231#else
232#define __ret_from_irq ret_from_exception
233#endif
234
235 .align 2
236#ifndef CONFIG_PREEMPT
237ENTRY(ret_from_exception)
238 disable_irq # preempt stop
239 nop
240 j __ret_from_irq
241 nop
242#endif
243
244ENTRY(ret_from_irq)
245 sw r16, [r28, TI_REGS]
246
247ENTRY(__ret_from_irq)
248 lw r8, [r0, PT_PSR] # returning to kernel mode?
249 andri.c r8, r8, KU_USER
250 beq resume_kernel
251
252resume_userspace:
253 disable_irq
254 lw r6, [r28, TI_FLAGS] # current->work
255 li r8, _TIF_WORK_MASK
256 and.c r8, r8, r6 # ignoring syscall_trace
257 bne work_pending
258 nop
259 j restore_all
260 nop
261
262#ifdef CONFIG_PREEMPT
263resume_kernel:
264 disable_irq
265 lw r8, [r28, TI_PRE_COUNT]
266 cmpz.c r8
267 bne r8, restore_all
268need_resched:
269 lw r8, [r28, TI_FLAGS]
270 andri.c r9, r8, _TIF_NEED_RESCHED
271 beq restore_all
272 lw r8, [r28, PT_PSR] # Interrupts off?
273 andri.c r8, r8, 1
274 beq restore_all
275 bl preempt_schedule_irq
276 nop
277 j need_resched
278 nop
279#endif
280
281ENTRY(ret_from_fork)
282 bl schedule_tail # r4=struct task_struct *prev
283
284ENTRY(syscall_exit)
285 nop
286 disable_irq
287 lw r6, [r28, TI_FLAGS] # current->work
288 li r8, _TIF_WORK_MASK
289 and.c r8, r6, r8
290 bne syscall_exit_work
291
292ENTRY(restore_all) # restore full frame
293 RESTORE_ALL_AND_RET
294
295work_pending:
296 andri.c r8, r6, _TIF_NEED_RESCHED # r6 is preloaded with TI_FLAGS
297 beq work_notifysig
298work_resched:
299 bl schedule
300 nop
301 disable_irq
302 lw r6, [r28, TI_FLAGS]
303 li r8, _TIF_WORK_MASK
304 and.c r8, r6, r8 # is there any work to be done
305 # other than syscall tracing?
306 beq restore_all
307 andri.c r8, r6, _TIF_NEED_RESCHED
308 bne work_resched
309
310work_notifysig:
311 mv r4, r0
312 li r5, 0
313 bl do_notify_resume # r6 already loaded
314 nop
315 j resume_userspace
316 nop
317
318ENTRY(syscall_exit_work)
319 li r8, _TIF_SYSCALL_TRACE
320 and.c r8, r8, r6 # r6 is preloaded with TI_FLAGS
321 beq work_pending # trace bit set?
322 nop
323 enable_irq
324 mv r4, r0
325 li r5, 1
326 bl do_syscall_trace
327 nop
328 b resume_userspace
329 nop
330
331.macro save_context reg
332 sw r12, [\reg, THREAD_REG12];
333 sw r13, [\reg, THREAD_REG13];
334 sw r14, [\reg, THREAD_REG14];
335 sw r15, [\reg, THREAD_REG15];
336 sw r16, [\reg, THREAD_REG16];
337 sw r17, [\reg, THREAD_REG17];
338 sw r18, [\reg, THREAD_REG18];
339 sw r19, [\reg, THREAD_REG19];
340 sw r20, [\reg, THREAD_REG20];
341 sw r21, [\reg, THREAD_REG21];
342 sw r29, [\reg, THREAD_REG29];
343 sw r2, [\reg, THREAD_REG2];
344 sw r0, [\reg, THREAD_REG0]
345.endm
346
347.macro restore_context reg
348 lw r12, [\reg, THREAD_REG12];
349 lw r13, [\reg, THREAD_REG13];
350 lw r14, [\reg, THREAD_REG14];
351 lw r15, [\reg, THREAD_REG15];
352 lw r16, [\reg, THREAD_REG16];
353 lw r17, [\reg, THREAD_REG17];
354 lw r18, [\reg, THREAD_REG18];
355 lw r19, [\reg, THREAD_REG19];
356 lw r20, [\reg, THREAD_REG20];
357 lw r21, [\reg, THREAD_REG21];
358 lw r29, [\reg, THREAD_REG29];
359 lw r0, [\reg, THREAD_REG0];
360 lw r2, [\reg, THREAD_REG2];
361 lw r3, [\reg, THREAD_REG3]
362.endm
363
364/*
365 * task_struct *resume(task_struct *prev, task_struct *next,
366 * struct thread_info *next_ti)
367 */
368ENTRY(resume)
369 mfcr r9, cr0
370 nop
371 nop
372 sw r9, [r4, THREAD_PSR]
373 save_context r4
374 sw r3, [r4, THREAD_REG3]
375
376 mv r28, r6
377 restore_context r5
378 mv r8, r6
379 addi r8, KERNEL_STACK_SIZE
380 subi r8, 32
381 la r9, kernelsp;
382 sw r8, [r9];
383
384 mfcr r9, cr0
385 ldis r7, 0x00ff
386 nop
387 and r9, r9, r7
388 lw r6, [r5, THREAD_PSR]
389 not r7, r7
390 and r6, r6, r7
391 or r6, r6, r9
392 mtcr r6, cr0
393 nop; nop; nop; nop; nop
394 br r3
395
396ENTRY(handle_sys)
397 SAVE_ALL
398 enable_irq
399
400 sw r4, [r0, PT_ORIG_R4] #for restart syscall
401 sw r7, [r0, PT_ORIG_R7] #for restart syscall
402 sw r27, [r0, PT_IS_SYSCALL] # it from syscall
403
404 lw r9, [r0, PT_EPC] # skip syscall on return
405 addi r9, 4
406 sw r9, [r0, PT_EPC]
407
408 cmpi.c r27, __NR_syscalls # check syscall number
409 bgtu illegal_syscall
410
411 slli r8, r27, 3 # get syscall routine
412 la r11, sys_call_table
413 add r11, r11, r8
414 lw r10, [r11] # get syscall entry
415 lw r11, [r11, 4] # get number of args
416
417 cmpz.c r10
418 beq illegal_syscall
419
420 cmpi.c r11, 4 # more than 4 arguments?
421 bgtu stackargs
422
423stack_done:
424 lw r8, [r28, TI_FLAGS]
425 li r9, _TIF_SYSCALL_TRACE
426 and.c r8, r8, r9
427 bne syscall_trace_entry
428
429 brl r10 # Do The Real system call
430
431 cmpi.c r4, 0
432 blt 1f
433 ldi r8, 0
434 sw r8, [r0, PT_R7]
435 b 2f
4361:
437 cmpi.c r4, -EMAXERRNO-1 # -EMAXERRNO - 1=-1134
438 ble 2f
439 ldi r8, 0x1;
440 sw r8, [r0, PT_R7]
441 neg r4, r4
4422:
443 sw r4, [r0, PT_R4] # save result
444
445syscall_return:
446 disable_irq
447 lw r6, [r28, TI_FLAGS] # current->work
448 li r8, _TIF_WORK_MASK
449 and.c r8, r6, r8
450 bne syscall_return_work
451 j restore_all
452
453syscall_return_work:
454 j syscall_exit_work
455
456syscall_trace_entry:
457 mv r16, r10
458 mv r4, r0
459 li r5, 0
460 bl do_syscall_trace
461
462 mv r8, r16
463 lw r4, [r0, PT_R4] # Restore argument registers
464 lw r5, [r0, PT_R5]
465 lw r6, [r0, PT_R6]
466 lw r7, [r0, PT_R7]
467 brl r8
468
469 li r8, -EMAXERRNO - 1 # error?
470 sw r8, [r0, PT_R7] # set error flag
471
472 neg r4, r4 # error
473 sw r4, [r0, PT_R0] # set flag for syscall
474 # restarting
4751: sw r4, [r0, PT_R2] # result
476 j syscall_exit
477
478stackargs:
479 lw r8, [r0, PT_R0]
480 andri.c r9, r8, 3 # test whether user sp is align a word
481 bne bad_stack
482 subi r11, 5
483 slli r9, r11, 2
484 add.c r9, r9, r8
485
486 bmi bad_stack
487 la r9, 3f # calculate branch address
488 slli r11, r11, 3
489 sub r9, r9, r11
490 br r9
491
4922: lw r9, [r8, 20] # argument 6 from usp
493 sw r9, [r0, 20]
494
4953: lw r9, [r8, 16] # argument 5 from usp
496 sw r9, [r0, 16]
497 j stack_done
498
499 .section __ex_table,"a"
500 .word 2b, bad_stack
501 .word 3b, bad_stack
502 .previous
503
504 /*
505 * The stackpointer for a call with more than 4 arguments is bad.
506 * We probably should handle this case a bit more drastic.
507 */
508bad_stack:
509 neg r27, r27 # error
510 sw r27, [r0, PT_ORIG_R4]
511 sw r27, [r0, PT_R4]
512 ldi r8, 1 # set error flag
513 sw r8, [r0, PT_R7]
514 j syscall_return
515
516illegal_syscall:
517 ldi r4, -ENOSYS # error
518 sw r4, [r0, PT_ORIG_R4]
519 sw r4, [r0, PT_R4]
520 ldi r9, 1 # set error flag
521 sw r9, [r0, PT_R7]
522 j syscall_return
523
524ENTRY(sys_execve)
525 mv r4, r0
526 la r8, score_execve
527 br r8
528
529ENTRY(sys_clone)
530 mv r4, r0
531 la r8, score_clone
532 br r8
533
534ENTRY(sys_rt_sigreturn)
535 mv r4, r0
536 la r8, score_rt_sigreturn
537 br r8
538
539ENTRY(sys_sigaltstack)
540 mv r4, r0
541 la r8, score_sigaltstack
542 br r8
diff --git a/arch/score/kernel/head.S b/arch/score/kernel/head.S
new file mode 100644
index 000000000000..22a7e3c7292b
--- /dev/null
+++ b/arch/score/kernel/head.S
@@ -0,0 +1,70 @@
1/*
2 * arch/score/kernel/head.S
3 *
4 * Score Processor version.
5 *
6 * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
7 * Chen Liqin <liqin.chen@sunplusct.com>
8 * Lennox Wu <lennox.wu@sunplusct.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see the file COPYING, or write
22 * to the Free Software Foundation, Inc.,
23 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25#include <linux/init.h>
26#include <linux/linkage.h>
27
28#include <asm/asm-offsets.h>
29
30 .extern start_kernel
31 .global init_thread_union
32 .global kernelsp
33
34__INIT
35ENTRY(_stext)
36 la r30, __bss_start /* initialize BSS segment. */
37 la r31, _end
38 xor r8, r8, r8
39
401: cmp.c r31, r30
41 beq 2f
42
43 sw r8, [r30] /* clean memory. */
44 addi r30, 4
45 b 1b
46
472: la r28, init_thread_union /* set kernel stack. */
48 mv r0, r28
49 addi r0, KERNEL_STACK_SIZE - 32
50 la r30, kernelsp
51 sw r0, [r30]
52 subi r0, 4*4
53 xor r30, r30, r30
54 ori r30, 0x02 /* enable MMU. */
55 mtcr r30, cr4
56 nop
57 nop
58 nop
59 nop
60 nop
61 nop
62 nop
63
64 /* there is no parameter */
65 xor r4, r4, r4
66 xor r5, r5, r5
67 xor r6, r6, r6
68 xor r7, r7, r7
69 la r30, start_kernel /* jump to init_arch */
70 br r30
diff --git a/arch/score/kernel/init_task.c b/arch/score/kernel/init_task.c
new file mode 100644
index 000000000000..9eecde00932f
--- /dev/null
+++ b/arch/score/kernel/init_task.c
@@ -0,0 +1,49 @@
1/*
2 * arch/score/kernel/init_task.c
3 *
4 * Score Processor version.
5 *
6 * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, see the file COPYING, or write
20 * to the Free Software Foundation, Inc.,
21 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24#include <linux/init_task.h>
25#include <linux/mqueue.h>
26
27static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
28static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
29struct mm_struct init_mm = INIT_MM(init_mm);
30EXPORT_SYMBOL(init_mm);
31
32/*
33 * Initial thread structure.
34 *
35 * We need to make sure that this is THREAD_SIZE aligned due to the
36 * way process stacks are handled. This is done by having a special
37 * "init_task" linker map entry..
38 */
39union thread_union init_thread_union
40 __attribute__((__section__(".data.init_task"))) =
41 { INIT_THREAD_INFO(init_task) };
42
43/*
44 * Initial task structure.
45 *
46 * All other task structs will be allocated on slabs in fork.c
47 */
48struct task_struct init_task = INIT_TASK(init_task);
49EXPORT_SYMBOL(init_task);
diff --git a/arch/score/kernel/irq.c b/arch/score/kernel/irq.c
new file mode 100644
index 000000000000..55474e8e9725
--- /dev/null
+++ b/arch/score/kernel/irq.c
@@ -0,0 +1,135 @@
1/*
2 * arch/score/kernel/irq.c
3 *
4 * Score Processor version.
5 *
6 * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
7 * Chen Liqin <liqin.chen@sunplusct.com>
8 * Lennox Wu <lennox.wu@sunplusct.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see the file COPYING, or write
22 * to the Free Software Foundation, Inc.,
23 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26#include <linux/interrupt.h>
27#include <linux/kernel_stat.h>
28#include <linux/seq_file.h>
29
30#include <asm/io.h>
31
32/*
33 * handles all normal device IRQs
34 */
35asmlinkage void do_IRQ(int irq)
36{
37 irq_enter();
38 generic_handle_irq(irq);
39 irq_exit();
40}
41
42static void score_mask(unsigned int irq_nr)
43{
44 unsigned int irq_source = 63 - irq_nr;
45
46 if (irq_source < 32)
47 __raw_writel((__raw_readl((void *)P_INT_MASKL) | \
48 (1 << irq_source)), (void *)P_INT_MASKL);
49 else
50 __raw_writel((__raw_readl((void *)P_INT_MASKH) | \
51 (1 << (irq_source - 32))), (void *)P_INT_MASKH);
52}
53
54static void score_unmask(unsigned int irq_nr)
55{
56 unsigned int irq_source = 63 - irq_nr;
57
58 if (irq_source < 32)
59 __raw_writel((__raw_readl((void *)P_INT_MASKL) & \
60 ~(1 << irq_source)), (void *)P_INT_MASKL);
61 else
62 __raw_writel((__raw_readl((void *)P_INT_MASKH) & \
63 ~(1 << (irq_source - 32))), (void *)P_INT_MASKH);
64}
65
66struct irq_chip score_irq_chip = {
67 .name = "Score7-level",
68 .mask = score_mask,
69 .mask_ack = score_mask,
70 .unmask = score_unmask,
71};
72
73/*
74 * initialise the interrupt system
75 */
76void __init init_IRQ(void)
77{
78 int index;
79 unsigned long target_addr;
80
81 for (index = 0; index < NR_IRQS; ++index)
82 set_irq_chip_and_handler(index, &score_irq_chip,
83 handle_level_irq);
84
85 for (target_addr = IRQ_VECTOR_BASE_ADDR;
86 target_addr <= IRQ_VECTOR_END_ADDR;
87 target_addr += IRQ_VECTOR_SIZE)
88 memcpy((void *)target_addr, \
89 interrupt_exception_vector, IRQ_VECTOR_SIZE);
90
91 __raw_writel(0xffffffff, (void *)P_INT_MASKL);
92 __raw_writel(0xffffffff, (void *)P_INT_MASKH);
93
94 __asm__ __volatile__(
95 "mtcr %0, cr3\n\t"
96 : : "r" (EXCEPTION_VECTOR_BASE_ADDR | \
97 VECTOR_ADDRESS_OFFSET_MODE16));
98}
99
100/*
101 * Generic, controller-independent functions:
102 */
103int show_interrupts(struct seq_file *p, void *v)
104{
105 int i = *(loff_t *)v, cpu;
106 struct irqaction *action;
107 unsigned long flags;
108
109 if (i == 0) {
110 seq_puts(p, " ");
111 for_each_online_cpu(cpu)
112 seq_printf(p, "CPU%d ", cpu);
113 seq_putc(p, '\n');
114 }
115
116 if (i < NR_IRQS) {
117 spin_lock_irqsave(&irq_desc[i].lock, flags);
118 action = irq_desc[i].action;
119 if (!action)
120 goto unlock;
121
122 seq_printf(p, "%3d: ", i);
123 seq_printf(p, "%10u ", kstat_irqs(i));
124 seq_printf(p, " %8s", irq_desc[i].chip->name ? : "-");
125 seq_printf(p, " %s", action->name);
126 for (action = action->next; action; action = action->next)
127 seq_printf(p, ", %s", action->name);
128
129 seq_putc(p, '\n');
130unlock:
131 spin_unlock_irqrestore(&irq_desc[i].lock, flags);
132 }
133
134 return 0;
135}
diff --git a/arch/score/kernel/module.c b/arch/score/kernel/module.c
new file mode 100644
index 000000000000..4ffce7fe1560
--- /dev/null
+++ b/arch/score/kernel/module.c
@@ -0,0 +1,164 @@
1/*
2 * arch/score/kernel/module.c
3 *
4 * Score Processor version.
5 *
6 * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
7 * Chen Liqin <liqin.chen@sunplusct.com>
8 * Lennox Wu <lennox.wu@sunplusct.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see the file COPYING, or write
22 * to the Free Software Foundation, Inc.,
23 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26#include <linux/module.h>
27#include <linux/vmalloc.h>
28
29void *module_alloc(unsigned long size)
30{
31 return size ? vmalloc(size) : NULL;
32}
33
34/* Free memory returned from module_alloc */
35void module_free(struct module *mod, void *module_region)
36{
37 vfree(module_region);
38}
39
40int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
41 char *secstrings, struct module *mod)
42{
43 return 0;
44}
45
46int apply_relocate(Elf_Shdr *sechdrs, const char *strtab,
47 unsigned int symindex, unsigned int relindex,
48 struct module *me)
49{
50 Elf32_Shdr *symsec = sechdrs + symindex;
51 Elf32_Shdr *relsec = sechdrs + relindex;
52 Elf32_Shdr *dstsec = sechdrs + relsec->sh_info;
53 Elf32_Rel *rel = (void *)relsec->sh_addr;
54 unsigned int i;
55
56 for (i = 0; i < relsec->sh_size / sizeof(Elf32_Rel); i++, rel++) {
57 unsigned long loc;
58 Elf32_Sym *sym;
59 s32 offset;
60
61 offset = ELF32_R_SYM(rel->r_info);
62 if ((offset < 0) ||
63 (offset > (symsec->sh_size / sizeof(Elf32_Sym)))) {
64 printk(KERN_ERR "%s: bad relocation, section %d reloc %d\n",
65 me->name, relindex, i);
66 return -ENOEXEC;
67 }
68
69 sym = ((Elf32_Sym *)symsec->sh_addr) + offset;
70
71 if ((rel->r_offset < 0) ||
72 (rel->r_offset > dstsec->sh_size - sizeof(u32))) {
73 printk(KERN_ERR "%s: out of bounds relocation, "
74 "section %d reloc %d offset %d size %d\n",
75 me->name, relindex, i, rel->r_offset,
76 dstsec->sh_size);
77 return -ENOEXEC;
78 }
79
80 loc = dstsec->sh_addr + rel->r_offset;
81 switch (ELF32_R_TYPE(rel->r_info)) {
82 case R_SCORE_NONE:
83 break;
84 case R_SCORE_ABS32:
85 *(unsigned long *)loc += sym->st_value;
86 break;
87 case R_SCORE_HI16:
88 break;
89 case R_SCORE_LO16: {
90 unsigned long hi16_offset, offset;
91 unsigned long uvalue;
92 unsigned long temp, temp_hi;
93 temp_hi = *((unsigned long *)loc - 1);
94 temp = *(unsigned long *)loc;
95
96 hi16_offset = (((((temp_hi) >> 16) & 0x3) << 15) |
97 ((temp_hi) & 0x7fff)) >> 1;
98 offset = ((temp >> 16 & 0x03) << 15) |
99 ((temp & 0x7fff) >> 1);
100 offset = (hi16_offset << 16) | (offset & 0xffff);
101 uvalue = sym->st_value + offset;
102 hi16_offset = (uvalue >> 16) << 1;
103
104 temp_hi = ((temp_hi) & (~(0x37fff))) |
105 (hi16_offset & 0x7fff) |
106 ((hi16_offset << 1) & 0x30000);
107 *((unsigned long *)loc - 1) = temp_hi;
108
109 offset = (uvalue & 0xffff) << 1;
110 temp = (temp & (~(0x37fff))) | (offset & 0x7fff) |
111 ((offset << 1) & 0x30000);
112 *(unsigned long *)loc = temp;
113 break;
114 }
115 case R_SCORE_24: {
116 unsigned long hi16_offset, offset;
117 unsigned long uvalue;
118 unsigned long temp;
119
120 temp = *(unsigned long *)loc;
121 offset = (temp & 0x03FF7FFE);
122 hi16_offset = (offset & 0xFFFF0000);
123 offset = (hi16_offset | ((offset & 0xFFFF) << 1)) >> 2;
124
125 uvalue = (sym->st_value + offset) >> 1;
126 uvalue = uvalue & 0x00ffffff;
127
128 temp = (temp & 0xfc008001) |
129 ((uvalue << 2) & 0x3ff0000) |
130 ((uvalue & 0x3fff) << 1);
131 *(unsigned long *)loc = temp;
132 break;
133 }
134 default:
135 printk(KERN_ERR "%s: unknown relocation: %u\n",
136 me->name, ELF32_R_TYPE(rel->r_info));
137 return -ENOEXEC;
138 }
139 }
140
141 return 0;
142}
143
144int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
145 unsigned int symindex, unsigned int relsec,
146 struct module *me)
147{
148 return 0;
149}
150
151/* Given an address, look for it in the module exception tables. */
152const struct exception_table_entry *search_module_dbetables(unsigned long addr)
153{
154 return 0;
155}
156
157/* Put in dbe list if necessary. */
158int module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
159 struct module *me)
160{
161 return 0;
162}
163
164void module_arch_cleanup(struct module *mod) {}
diff --git a/arch/score/kernel/process.c b/arch/score/kernel/process.c
new file mode 100644
index 000000000000..aaa3085251fa
--- /dev/null
+++ b/arch/score/kernel/process.c
@@ -0,0 +1,165 @@
1/*
2 * arch/score/kernel/process.c
3 *
4 * Score Processor version.
5 *
6 * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
7 * Chen Liqin <liqin.chen@sunplusct.com>
8 * Lennox Wu <lennox.wu@sunplusct.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see the file COPYING, or write
22 * to the Free Software Foundation, Inc.,
23 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26#include <linux/module.h>
27
28void (*pm_power_off)(void);
29EXPORT_SYMBOL(pm_power_off);
30
31/* If or when software machine-restart is implemented, add code here. */
32void machine_restart(char *command) {}
33
34/* If or when software machine-halt is implemented, add code here. */
35void machine_halt(void) {}
36
37/* If or when software machine-power-off is implemented, add code here. */
38void machine_power_off(void) {}
39
40/*
41 * The idle thread. There's no useful work to be
42 * done, so just try to conserve power and have a
43 * low exit latency (ie sit in a loop waiting for
44 * somebody to say that they'd like to reschedule)
45 */
46void __noreturn cpu_idle(void)
47{
48 /* endless idle loop with no priority at all */
49 while (1) {
50 while (!need_resched())
51 barrier();
52
53 preempt_enable_no_resched();
54 schedule();
55 preempt_disable();
56 }
57}
58
59asmlinkage void ret_from_fork(void);
60
61void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long sp)
62{
63 unsigned long status;
64
65 /* New thread loses kernel privileges. */
66 status = regs->cp0_psr & ~(KU_MASK);
67 status |= KU_USER;
68 regs->cp0_psr = status;
69 regs->cp0_epc = pc;
70 regs->regs[0] = sp;
71}
72
73void exit_thread(void) {}
74
75/*
76 * When a process does an "exec", machine state like FPU and debug
77 * registers need to be reset. This is a hook function for that.
78 * Currently we don't have any such state to reset, so this is empty.
79 */
80void flush_thread(void) {}
81
82/*
83 * set up the kernel stack and exception frames for a new process
84 */
85int copy_thread(unsigned long clone_flags, unsigned long usp,
86 unsigned long unused,
87 struct task_struct *p, struct pt_regs *regs)
88{
89 struct thread_info *ti = task_thread_info(p);
90 struct pt_regs *childregs = task_pt_regs(p);
91
92 p->set_child_tid = NULL;
93 p->clear_child_tid = NULL;
94
95 *childregs = *regs;
96 childregs->regs[7] = 0; /* Clear error flag */
97 childregs->regs[4] = 0; /* Child gets zero as return value */
98 regs->regs[4] = p->pid;
99
100 if (childregs->cp0_psr & 0x8) { /* test kernel fork or user fork */
101 childregs->regs[0] = usp; /* user fork */
102 } else {
103 childregs->regs[28] = (unsigned long) ti; /* kernel fork */
104 childregs->regs[0] = (unsigned long) childregs;
105 }
106
107 p->thread.reg0 = (unsigned long) childregs;
108 p->thread.reg3 = (unsigned long) ret_from_fork;
109 p->thread.cp0_psr = 0;
110
111 return 0;
112}
113
114/* Fill in the fpu structure for a core dump. */
115int dump_fpu(struct pt_regs *regs, elf_fpregset_t *r)
116{
117 return 1;
118}
119
120static void __noreturn
121kernel_thread_helper(void *unused0, int (*fn)(void *),
122 void *arg, void *unused1)
123{
124 do_exit(fn(arg));
125}
126
127/*
128 * Create a kernel thread.
129 */
130long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
131{
132 struct pt_regs regs;
133
134 memset(&regs, 0, sizeof(regs));
135
136 regs.regs[6] = (unsigned long) arg;
137 regs.regs[5] = (unsigned long) fn;
138 regs.cp0_epc = (unsigned long) kernel_thread_helper;
139 regs.cp0_psr = (regs.cp0_psr & ~(0x1|0x4|0x8)) | \
140 ((regs.cp0_psr & 0x3) << 2);
141
142 return do_fork(flags | CLONE_VM | CLONE_UNTRACED, \
143 0, &regs, 0, NULL, NULL);
144}
145
146unsigned long thread_saved_pc(struct task_struct *tsk)
147{
148 return task_pt_regs(tsk)->cp0_epc;
149}
150
151unsigned long get_wchan(struct task_struct *task)
152{
153 if (!task || task == current || task->state == TASK_RUNNING)
154 return 0;
155
156 if (!task_stack_page(task))
157 return 0;
158
159 return task_pt_regs(task)->cp0_epc;
160}
161
162unsigned long arch_align_stack(unsigned long sp)
163{
164 return sp;
165}
diff --git a/arch/score/kernel/ptrace.c b/arch/score/kernel/ptrace.c
new file mode 100644
index 000000000000..8fe7209355aa
--- /dev/null
+++ b/arch/score/kernel/ptrace.c
@@ -0,0 +1,465 @@
1/*
2 * arch/score/kernel/ptrace.c
3 *
4 * Score Processor version.
5 *
6 * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
7 * Chen Liqin <liqin.chen@sunplusct.com>
8 * Lennox Wu <lennox.wu@sunplusct.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see the file COPYING, or write
22 * to the Free Software Foundation, Inc.,
23 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26#include <linux/kernel.h>
27#include <linux/ptrace.h>
28
29#include <asm/uaccess.h>
30
31static int is_16bitinsn(unsigned long insn)
32{
33 if ((insn & INSN32_MASK) == INSN32_MASK)
34 return 0;
35 else
36 return 1;
37}
38
39int
40read_tsk_long(struct task_struct *child,
41 unsigned long addr, unsigned long *res)
42{
43 int copied;
44
45 copied = access_process_vm(child, addr, res, sizeof(*res), 0);
46
47 return copied != sizeof(*res) ? -EIO : 0;
48}
49
50int
51read_tsk_short(struct task_struct *child,
52 unsigned long addr, unsigned short *res)
53{
54 int copied;
55
56 copied = access_process_vm(child, addr, res, sizeof(*res), 0);
57
58 return copied != sizeof(*res) ? -EIO : 0;
59}
60
61static int
62write_tsk_short(struct task_struct *child,
63 unsigned long addr, unsigned short val)
64{
65 int copied;
66
67 copied = access_process_vm(child, addr, &val, sizeof(val), 1);
68
69 return copied != sizeof(val) ? -EIO : 0;
70}
71
72static int
73write_tsk_long(struct task_struct *child,
74 unsigned long addr, unsigned long val)
75{
76 int copied;
77
78 copied = access_process_vm(child, addr, &val, sizeof(val), 1);
79
80 return copied != sizeof(val) ? -EIO : 0;
81}
82
83void set_single_step(struct task_struct *child)
84{
85 /* far_epc is the target of branch */
86 unsigned int epc, far_epc = 0;
87 unsigned long epc_insn, far_epc_insn;
88 int ninsn_type; /* next insn type 0=16b, 1=32b */
89 unsigned int tmp, tmp2;
90 struct pt_regs *regs = task_pt_regs(child);
91 child->thread.single_step = 1;
92 child->thread.ss_nextcnt = 1;
93 epc = regs->cp0_epc;
94
95 read_tsk_long(child, epc, &epc_insn);
96
97 if (is_16bitinsn(epc_insn)) {
98 if ((epc_insn & J16M) == J16) {
99 tmp = epc_insn & 0xFFE;
100 epc = (epc & 0xFFFFF000) | tmp;
101 } else if ((epc_insn & B16M) == B16) {
102 child->thread.ss_nextcnt = 2;
103 tmp = (epc_insn & 0xFF) << 1;
104 tmp = tmp << 23;
105 tmp = (unsigned int)((int) tmp >> 23);
106 far_epc = epc + tmp;
107 epc += 2;
108 } else if ((epc_insn & BR16M) == BR16) {
109 child->thread.ss_nextcnt = 2;
110 tmp = (epc_insn >> 4) & 0xF;
111 far_epc = regs->regs[tmp];
112 epc += 2;
113 } else
114 epc += 2;
115 } else {
116 if ((epc_insn & J32M) == J32) {
117 tmp = epc_insn & 0x03FFFFFE;
118 tmp2 = tmp & 0x7FFF;
119 tmp = (((tmp >> 16) & 0x3FF) << 15) | tmp2;
120 epc = (epc & 0xFFC00000) | tmp;
121 } else if ((epc_insn & B32M) == B32) {
122 child->thread.ss_nextcnt = 2;
123 tmp = epc_insn & 0x03FFFFFE; /* discard LK bit */
124 tmp2 = tmp & 0x3FF;
125 tmp = (((tmp >> 16) & 0x3FF) << 10) | tmp2; /* 20bit */
126 tmp = tmp << 12;
127 tmp = (unsigned int)((int) tmp >> 12);
128 far_epc = epc + tmp;
129 epc += 4;
130 } else if ((epc_insn & BR32M) == BR32) {
131 child->thread.ss_nextcnt = 2;
132 tmp = (epc_insn >> 16) & 0x1F;
133 far_epc = regs->regs[tmp];
134 epc += 4;
135 } else
136 epc += 4;
137 }
138
139 if (child->thread.ss_nextcnt == 1) {
140 read_tsk_long(child, epc, &epc_insn);
141
142 if (is_16bitinsn(epc_insn)) {
143 write_tsk_short(child, epc, SINGLESTEP16_INSN);
144 ninsn_type = 0;
145 } else {
146 write_tsk_long(child, epc, SINGLESTEP32_INSN);
147 ninsn_type = 1;
148 }
149
150 if (ninsn_type == 0) { /* 16bits */
151 child->thread.insn1_type = 0;
152 child->thread.addr1 = epc;
153 /* the insn may have 32bit data */
154 child->thread.insn1 = (short)epc_insn;
155 } else {
156 child->thread.insn1_type = 1;
157 child->thread.addr1 = epc;
158 child->thread.insn1 = epc_insn;
159 }
160 } else {
161 /* branch! have two target child->thread.ss_nextcnt=2 */
162 read_tsk_long(child, epc, &epc_insn);
163 read_tsk_long(child, far_epc, &far_epc_insn);
164 if (is_16bitinsn(epc_insn)) {
165 write_tsk_short(child, epc, SINGLESTEP16_INSN);
166 ninsn_type = 0;
167 } else {
168 write_tsk_long(child, epc, SINGLESTEP32_INSN);
169 ninsn_type = 1;
170 }
171
172 if (ninsn_type == 0) { /* 16bits */
173 child->thread.insn1_type = 0;
174 child->thread.addr1 = epc;
175 /* the insn may have 32bit data */
176 child->thread.insn1 = (short)epc_insn;
177 } else {
178 child->thread.insn1_type = 1;
179 child->thread.addr1 = epc;
180 child->thread.insn1 = epc_insn;
181 }
182
183 if (is_16bitinsn(far_epc_insn)) {
184 write_tsk_short(child, far_epc, SINGLESTEP16_INSN);
185 ninsn_type = 0;
186 } else {
187 write_tsk_long(child, far_epc, SINGLESTEP32_INSN);
188 ninsn_type = 1;
189 }
190
191 if (ninsn_type == 0) { /* 16bits */
192 child->thread.insn2_type = 0;
193 child->thread.addr2 = far_epc;
194 /* the insn may have 32bit data */
195 child->thread.insn2 = (short)far_epc_insn;
196 } else {
197 child->thread.insn2_type = 1;
198 child->thread.addr2 = far_epc;
199 child->thread.insn2 = far_epc_insn;
200 }
201 }
202}
203
204void clear_single_step(struct task_struct *child)
205{
206 if (child->thread.insn1_type == 0)
207 write_tsk_short(child, child->thread.addr1,
208 child->thread.insn1);
209
210 if (child->thread.insn1_type == 1)
211 write_tsk_long(child, child->thread.addr1,
212 child->thread.insn1);
213
214 if (child->thread.ss_nextcnt == 2) { /* branch */
215 if (child->thread.insn1_type == 0)
216 write_tsk_short(child, child->thread.addr1,
217 child->thread.insn1);
218 if (child->thread.insn1_type == 1)
219 write_tsk_long(child, child->thread.addr1,
220 child->thread.insn1);
221 if (child->thread.insn2_type == 0)
222 write_tsk_short(child, child->thread.addr2,
223 child->thread.insn2);
224 if (child->thread.insn2_type == 1)
225 write_tsk_long(child, child->thread.addr2,
226 child->thread.insn2);
227 }
228
229 child->thread.single_step = 0;
230 child->thread.ss_nextcnt = 0;
231}
232
233
234void ptrace_disable(struct task_struct *child) {}
235
236long
237arch_ptrace(struct task_struct *child, long request, long addr, long data)
238{
239 int ret;
240
241 if (request == PTRACE_TRACEME) {
242 /* are we already being traced? */
243 if (current->ptrace & PT_PTRACED)
244 return -EPERM;
245
246 /* set the ptrace bit in the process flags. */
247 current->ptrace |= PT_PTRACED;
248 return 0;
249 }
250
251 ret = -ESRCH;
252 if (!child)
253 return ret;
254
255 ret = -EPERM;
256
257 if (request == PTRACE_ATTACH) {
258 ret = ptrace_attach(child);
259 return ret;
260 }
261
262 ret = ptrace_check_attach(child, request == PTRACE_KILL);
263 if (ret < 0)
264 return ret;
265
266 switch (request) {
267 case PTRACE_PEEKTEXT: /* read word at location addr. */
268 case PTRACE_PEEKDATA: {
269 unsigned long tmp;
270 int copied;
271
272 copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
273 ret = -EIO;
274 if (copied != sizeof(tmp))
275 break;
276
277 ret = put_user(tmp, (unsigned long *) data);
278 return ret;
279 }
280
281 /* Read the word at location addr in the USER area. */
282 case PTRACE_PEEKUSR: {
283 struct pt_regs *regs;
284 unsigned long tmp;
285
286 regs = task_pt_regs(child);
287
288 tmp = 0; /* Default return value. */
289 switch (addr) {
290 case 0 ... 31:
291 tmp = regs->regs[addr];
292 break;
293 case PC:
294 tmp = regs->cp0_epc;
295 break;
296 case ECR:
297 tmp = regs->cp0_ecr;
298 break;
299 case EMA:
300 tmp = regs->cp0_ema;
301 break;
302 case CEH:
303 tmp = regs->ceh;
304 break;
305 case CEL:
306 tmp = regs->cel;
307 break;
308 case CONDITION:
309 tmp = regs->cp0_condition;
310 break;
311 case PSR:
312 tmp = regs->cp0_psr;
313 break;
314 case COUNTER:
315 tmp = regs->sr0;
316 break;
317 case LDCR:
318 tmp = regs->sr1;
319 break;
320 case STCR:
321 tmp = regs->sr2;
322 break;
323 default:
324 tmp = 0;
325 return -EIO;
326 }
327
328 ret = put_user(tmp, (unsigned long *) data);
329 return ret;
330 }
331
332 case PTRACE_POKETEXT: /* write the word at location addr. */
333 case PTRACE_POKEDATA:
334 ret = 0;
335 if (access_process_vm(child, addr, &data, sizeof(data), 1)
336 == sizeof(data))
337 break;
338 ret = -EIO;
339 return ret;
340
341 case PTRACE_POKEUSR: {
342 struct pt_regs *regs;
343 ret = 0;
344 regs = task_pt_regs(child);
345
346 switch (addr) {
347 case 0 ... 31:
348 regs->regs[addr] = data;
349 break;
350 case PC:
351 regs->cp0_epc = data;
352 break;
353 case CEH:
354 regs->ceh = data;
355 break;
356 case CEL:
357 regs->cel = data;
358 break;
359 case CONDITION:
360 regs->cp0_condition = data;
361 break;
362 case PSR:
363 case COUNTER:
364 case STCR:
365 case LDCR:
366 break; /* user can't write the reg */
367 default:
368 /* The rest are not allowed. */
369 ret = -EIO;
370 break;
371 }
372 break;
373 }
374
375 case PTRACE_SYSCALL: /* continue and stop at next
376 (return from) syscall. */
377 case PTRACE_CONT: { /* restart after signal. */
378 ret = -EIO;
379 if (!valid_signal(data))
380 break;
381 if (request == PTRACE_SYSCALL)
382 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
383 else
384 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
385
386 child->exit_code = data;
387 wake_up_process(child);
388 ret = 0;
389 break;
390 }
391
392 /*
393 * make the child exit. Best I can do is send it a sigkill.
394 * perhaps it should be put in the status that it wants to
395 * exit.
396 */
397 case PTRACE_KILL:
398 ret = 0;
399 if (child->state == EXIT_ZOMBIE) /* already dead. */
400 break;
401 child->exit_code = SIGKILL;
402 clear_single_step(child);
403 wake_up_process(child);
404 break;
405
406 case PTRACE_SINGLESTEP: { /* set the trap flag. */
407 ret = -EIO;
408 if ((unsigned long) data > _NSIG)
409 break;
410 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
411 set_single_step(child);
412 child->exit_code = data;
413 /* give it a chance to run. */
414 wake_up_process(child);
415 ret = 0;
416 break;
417 }
418
419 case PTRACE_DETACH: /* detach a process that was attached. */
420 ret = ptrace_detach(child, data);
421 break;
422
423 case PTRACE_SETOPTIONS:
424 if (data & PTRACE_O_TRACESYSGOOD)
425 child->ptrace |= PT_TRACESYSGOOD;
426 else
427 child->ptrace &= ~PT_TRACESYSGOOD;
428 ret = 0;
429 break;
430
431 default:
432 ret = -EIO;
433 break;
434 }
435
436 return ret;
437}
438
439/*
440 * Notification of system call entry/exit
441 * - triggered by current->work.syscall_trace
442 */
443asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit)
444{
445 if (!(current->ptrace & PT_PTRACED))
446 return;
447
448 if (!test_thread_flag(TIF_SYSCALL_TRACE))
449 return;
450
451 /* The 0x80 provides a way for the tracing parent to distinguish
452 between a syscall stop and SIGTRAP delivery. */
453 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ?
454 0x80 : 0));
455
456 /*
457 * this isn't the same as continuing with a signal, but it will do
458 * for normal use. strace only continues with a signal if the
459 * stopping signal is not SIGTRAP. -brl
460 */
461 if (current->exit_code) {
462 send_sig(current->exit_code, current, 1);
463 current->exit_code = 0;
464 }
465}
diff --git a/arch/score/kernel/setup.c b/arch/score/kernel/setup.c
new file mode 100644
index 000000000000..a172ce170f62
--- /dev/null
+++ b/arch/score/kernel/setup.c
@@ -0,0 +1,157 @@
1/*
2 * arch/score/kernel/setup.c
3 *
4 * Score Processor version.
5 *
6 * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
7 * Chen Liqin <liqin.chen@sunplusct.com>
8 * Lennox Wu <lennox.wu@sunplusct.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see the file COPYING, or write
22 * to the Free Software Foundation, Inc.,
23 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26#include <linux/bootmem.h>
27#include <linux/initrd.h>
28#include <linux/ioport.h>
29#include <linux/seq_file.h>
30#include <linux/screen_info.h>
31
32#include <asm-generic/sections.h>
33
34struct screen_info screen_info;
35unsigned long kernelsp;
36
37static char command_line[COMMAND_LINE_SIZE];
38static struct resource code_resource = { .name = "Kernel code",};
39static struct resource data_resource = { .name = "Kernel data",};
40
41static void __init bootmem_init(void)
42{
43 unsigned long reserved_end, bootmap_size;
44 unsigned long size = initrd_end - initrd_start;
45
46 reserved_end = (unsigned long)_end;
47
48 min_low_pfn = 0;
49 max_low_pfn = MEM_SIZE / PAGE_SIZE;
50
51 /* Initialize the boot-time allocator with low memory only. */
52 bootmap_size = init_bootmem_node(NODE_DATA(0), reserved_end,
53 min_low_pfn, max_low_pfn);
54 add_active_range(0, min_low_pfn, max_low_pfn);
55
56 free_bootmem(PFN_PHYS(reserved_end),
57 (max_low_pfn - reserved_end) << PAGE_SHIFT);
58 memory_present(0, reserved_end, max_low_pfn);
59
60 /* Reserve space for the bootmem bitmap. */
61 reserve_bootmem(PFN_PHYS(reserved_end), bootmap_size, BOOTMEM_DEFAULT);
62
63 if (size == 0) {
64 printk(KERN_INFO "Initrd not found or empty");
65 goto disable;
66 }
67
68 if (__pa(initrd_end) > PFN_PHYS(max_low_pfn)) {
69 printk(KERN_ERR "Initrd extends beyond end of memory");
70 goto disable;
71 }
72
73 /* Reserve space for the initrd bitmap. */
74 reserve_bootmem(__pa(initrd_start), size, BOOTMEM_DEFAULT);
75 initrd_below_start_ok = 1;
76
77 pr_info("Initial ramdisk at: 0x%lx (%lu bytes)\n",
78 initrd_start, size);
79 return;
80disable:
81 printk(KERN_CONT " - disabling initrd\n");
82 initrd_start = 0;
83 initrd_end = 0;
84}
85
86static void __init resource_init(void)
87{
88 struct resource *res;
89
90 code_resource.start = (unsigned long)_text;
91 code_resource.end = (unsigned long)_etext - 1;
92 data_resource.start = (unsigned long)_etext;
93 data_resource.end = (unsigned long)_edata - 1;
94
95 res = alloc_bootmem(sizeof(struct resource));
96 res->name = "System RAM";
97 res->start = 0;
98 res->end = MEM_SIZE - 1;
99 res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
100 request_resource(&iomem_resource, res);
101
102 request_resource(res, &code_resource);
103 request_resource(res, &data_resource);
104}
105
106void __init setup_arch(char **cmdline_p)
107{
108 randomize_va_space = 0;
109 *cmdline_p = command_line;
110
111 cpu_cache_init();
112 tlb_init();
113 bootmem_init();
114 paging_init();
115 resource_init();
116}
117
118static int show_cpuinfo(struct seq_file *m, void *v)
119{
120 unsigned long n = (unsigned long) v - 1;
121
122 seq_printf(m, "processor\t\t: %ld\n", n);
123 seq_printf(m, "\n");
124
125 return 0;
126}
127
128static void *c_start(struct seq_file *m, loff_t *pos)
129{
130 unsigned long i = *pos;
131
132 return i < 1 ? (void *) (i + 1) : NULL;
133}
134
135static void *c_next(struct seq_file *m, void *v, loff_t *pos)
136{
137 ++*pos;
138 return c_start(m, pos);
139}
140
141static void c_stop(struct seq_file *m, void *v)
142{
143}
144
145const struct seq_operations cpuinfo_op = {
146 .start = c_start,
147 .next = c_next,
148 .stop = c_stop,
149 .show = show_cpuinfo,
150};
151
152static int __init topology_init(void)
153{
154 return 0;
155}
156
157subsys_initcall(topology_init);
diff --git a/arch/score/kernel/signal.c b/arch/score/kernel/signal.c
new file mode 100644
index 000000000000..b4ed1b3f8072
--- /dev/null
+++ b/arch/score/kernel/signal.c
@@ -0,0 +1,355 @@
1/*
2 * arch/score/kernel/signal.c
3 *
4 * Score Processor version.
5 *
6 * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
7 * Chen Liqin <liqin.chen@sunplusct.com>
8 * Lennox Wu <lennox.wu@sunplusct.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see the file COPYING, or write
22 * to the Free Software Foundation, Inc.,
23 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26#include <linux/errno.h>
27#include <linux/signal.h>
28#include <linux/unistd.h>
29#include <linux/uaccess.h>
30#include <asm-generic/ucontext.h>
31
32#include <asm/cacheflush.h>
33
34#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
35
36struct rt_sigframe {
37 u32 rs_ass[4]; /* argument save space */
38 u32 rs_code[2]; /* signal trampoline */
39 struct siginfo rs_info;
40 struct ucontext rs_uc;
41};
42
43int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
44{
45 int err = 0;
46 unsigned long reg;
47
48 reg = regs->cp0_epc; err |= __put_user(reg, &sc->sc_pc);
49 err |= __put_user(regs->cp0_psr, &sc->sc_psr);
50 err |= __put_user(regs->cp0_condition, &sc->sc_condition);
51
52
53#define save_gp_reg(i) { \
54 reg = regs->regs[i]; \
55 err |= __put_user(reg, &sc->sc_regs[i]); \
56} while (0)
57 save_gp_reg(0); save_gp_reg(1); save_gp_reg(2);
58 save_gp_reg(3); save_gp_reg(4); save_gp_reg(5);
59 save_gp_reg(6); save_gp_reg(7); save_gp_reg(8);
60 save_gp_reg(9); save_gp_reg(10); save_gp_reg(11);
61 save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
62 save_gp_reg(15); save_gp_reg(16); save_gp_reg(17);
63 save_gp_reg(18); save_gp_reg(19); save_gp_reg(20);
64 save_gp_reg(21); save_gp_reg(22); save_gp_reg(23);
65 save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
66 save_gp_reg(27); save_gp_reg(28); save_gp_reg(29);
67#undef save_gp_reg
68
69 reg = regs->ceh; err |= __put_user(reg, &sc->sc_mdceh);
70 reg = regs->cel; err |= __put_user(reg, &sc->sc_mdcel);
71 err |= __put_user(regs->cp0_ecr, &sc->sc_ecr);
72 err |= __put_user(regs->cp0_ema, &sc->sc_ema);
73
74 return err;
75}
76
77int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
78{
79 int err = 0;
80 u32 reg;
81
82 err |= __get_user(regs->cp0_epc, &sc->sc_pc);
83 err |= __get_user(regs->cp0_condition, &sc->sc_condition);
84
85 err |= __get_user(reg, &sc->sc_mdceh);
86 regs->ceh = (int) reg;
87 err |= __get_user(reg, &sc->sc_mdcel);
88 regs->cel = (int) reg;
89
90 err |= __get_user(reg, &sc->sc_psr);
91 regs->cp0_psr = (int) reg;
92 err |= __get_user(reg, &sc->sc_ecr);
93 regs->cp0_ecr = (int) reg;
94 err |= __get_user(reg, &sc->sc_ema);
95 regs->cp0_ema = (int) reg;
96
97#define restore_gp_reg(i) do { \
98 err |= __get_user(reg, &sc->sc_regs[i]); \
99 regs->regs[i] = reg; \
100} while (0)
101 restore_gp_reg(0); restore_gp_reg(1); restore_gp_reg(2);
102 restore_gp_reg(3); restore_gp_reg(4); restore_gp_reg(5);
103 restore_gp_reg(6); restore_gp_reg(7); restore_gp_reg(8);
104 restore_gp_reg(9); restore_gp_reg(10); restore_gp_reg(11);
105 restore_gp_reg(12); restore_gp_reg(13); restore_gp_reg(14);
106 restore_gp_reg(15); restore_gp_reg(16); restore_gp_reg(17);
107 restore_gp_reg(18); restore_gp_reg(19); restore_gp_reg(20);
108 restore_gp_reg(21); restore_gp_reg(22); restore_gp_reg(23);
109 restore_gp_reg(24); restore_gp_reg(25); restore_gp_reg(26);
110 restore_gp_reg(27); restore_gp_reg(28); restore_gp_reg(29);
111#undef restore_gp_reg
112
113 return err;
114}
115
116/*
117 * Determine which stack to use..
118 */
119void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
120 size_t frame_size)
121{
122 unsigned long sp;
123
124 /* Default to using normal stack */
125 sp = regs->regs[0];
126 sp -= 32;
127
128 /* This is the X/Open sanctioned signal stack switching. */
129 if ((ka->sa.sa_flags & SA_ONSTACK) && (!on_sig_stack(sp)))
130 sp = current->sas_ss_sp + current->sas_ss_size;
131
132 return (void *)((sp - frame_size) & ~7);
133}
134
135asmlinkage int score_sigaltstack(struct pt_regs *regs)
136{
137 const stack_t *uss = (const stack_t *) regs->regs[4];
138 stack_t *uoss = (stack_t *) regs->regs[5];
139 unsigned long usp = regs->regs[0];
140
141 return do_sigaltstack(uss, uoss, usp);
142}
143
144asmlinkage void score_rt_sigreturn(struct pt_regs *regs)
145{
146 struct rt_sigframe __user *frame;
147 sigset_t set;
148 stack_t st;
149 int sig;
150
151 frame = (struct rt_sigframe __user *) regs->regs[0];
152 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
153 goto badframe;
154 if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set)))
155 goto badframe;
156
157 sigdelsetmask(&set, ~_BLOCKABLE);
158 spin_lock_irq(&current->sighand->siglock);
159 current->blocked = set;
160 recalc_sigpending();
161 spin_unlock_irq(&current->sighand->siglock);
162
163 sig = restore_sigcontext(regs, &frame->rs_uc.uc_mcontext);
164 if (sig < 0)
165 goto badframe;
166 else if (sig)
167 force_sig(sig, current);
168
169 if (__copy_from_user(&st, &frame->rs_uc.uc_stack, sizeof(st)))
170 goto badframe;
171
172 /* It is more difficult to avoid calling this function than to
173 call it and ignore errors. */
174 do_sigaltstack((stack_t __user *)&st, NULL, regs->regs[0]);
175
176 __asm__ __volatile__(
177 "mv\tr0, %0\n\t"
178 "la\tr8, syscall_exit\n\t"
179 "br\tr8\n\t"
180 : : "r" (regs) : "r8");
181
182badframe:
183 force_sig(SIGSEGV, current);
184}
185
186int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
187 int signr, sigset_t *set, siginfo_t *info)
188{
189 struct rt_sigframe *frame;
190 int err = 0;
191
192 frame = get_sigframe(ka, regs, sizeof(*frame));
193 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
194 goto give_sigsegv;
195
196 /*
197 * Set up the return code ...
198 *
199 * li v0, __NR_rt_sigreturn
200 * syscall
201 */
202 err |= __put_user(0x87788000 + __NR_rt_sigreturn*2,
203 frame->rs_code + 0);
204 err |= __put_user(0x80008002, frame->rs_code + 1);
205 flush_cache_sigtramp((unsigned long) frame->rs_code);
206
207 err |= copy_siginfo_to_user(&frame->rs_info, info);
208 err |= __put_user(0, &frame->rs_uc.uc_flags);
209 err |= __put_user(0, &frame->rs_uc.uc_link);
210 err |= __put_user((void *)current->sas_ss_sp,
211 &frame->rs_uc.uc_stack.ss_sp);
212 err |= __put_user(sas_ss_flags(regs->regs[0]),
213 &frame->rs_uc.uc_stack.ss_flags);
214 err |= __put_user(current->sas_ss_size,
215 &frame->rs_uc.uc_stack.ss_size);
216 err |= setup_sigcontext(regs, &frame->rs_uc.uc_mcontext);
217 err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set));
218
219 if (err)
220 goto give_sigsegv;
221
222 regs->regs[0] = (unsigned long) frame;
223 regs->regs[3] = (unsigned long) frame->rs_code;
224 regs->regs[4] = signr;
225 regs->regs[5] = (unsigned long) &frame->rs_info;
226 regs->regs[6] = (unsigned long) &frame->rs_uc;
227 regs->regs[29] = (unsigned long) ka->sa.sa_handler;
228 regs->cp0_epc = (unsigned long) ka->sa.sa_handler;
229
230 return 0;
231
232give_sigsegv:
233 if (signr == SIGSEGV)
234 ka->sa.sa_handler = SIG_DFL;
235 force_sig(SIGSEGV, current);
236 return -EFAULT;
237}
238
239int handle_signal(unsigned long sig, siginfo_t *info,
240 struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs)
241{
242 int ret;
243
244 if (regs->is_syscall) {
245 switch (regs->regs[4]) {
246 case ERESTART_RESTARTBLOCK:
247 case ERESTARTNOHAND:
248 regs->regs[4] = EINTR;
249 break;
250 case ERESTARTSYS:
251 if (!(ka->sa.sa_flags & SA_RESTART)) {
252 regs->regs[4] = EINTR;
253 break;
254 }
255 case ERESTARTNOINTR:
256 regs->regs[4] = regs->orig_r4;
257 regs->regs[7] = regs->orig_r7;
258 regs->cp0_epc -= 8;
259 }
260
261 regs->is_syscall = 0;
262 }
263
264 /*
265 * Set up the stack frame
266 */
267 ret = setup_rt_frame(ka, regs, sig, oldset, info);
268
269 spin_lock_irq(&current->sighand->siglock);
270 sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
271 if (!(ka->sa.sa_flags & SA_NODEFER))
272 sigaddset(&current->blocked, sig);
273 recalc_sigpending();
274 spin_unlock_irq(&current->sighand->siglock);
275
276 return ret;
277}
278
279asmlinkage void do_signal(struct pt_regs *regs)
280{
281 struct k_sigaction ka;
282 sigset_t *oldset;
283 siginfo_t info;
284 int signr;
285
286 /*
287 * We want the common case to go fast, which is why we may in certain
288 * cases get here from kernel mode. Just return without doing anything
289 * if so.
290 */
291 if (!user_mode(regs))
292 return;
293
294 if (test_thread_flag(TIF_RESTORE_SIGMASK))
295 oldset = &current->saved_sigmask;
296 else
297 oldset = &current->blocked;
298
299 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
300 if (signr > 0) {
301 /* Actually deliver the signal. */
302 if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
303 /*
304 * A signal was successfully delivered; the saved
305 * sigmask will have been stored in the signal frame,
306 * and will be restored by sigreturn, so we can simply
307 * clear the TIF_RESTORE_SIGMASK flag.
308 */
309 if (test_thread_flag(TIF_RESTORE_SIGMASK))
310 clear_thread_flag(TIF_RESTORE_SIGMASK);
311 }
312
313 return;
314 }
315
316 if (regs->is_syscall) {
317 if (regs->regs[4] == ERESTARTNOHAND ||
318 regs->regs[4] == ERESTARTSYS ||
319 regs->regs[4] == ERESTARTNOINTR) {
320 regs->regs[4] = regs->orig_r4;
321 regs->regs[7] = regs->orig_r7;
322 regs->cp0_epc -= 8;
323 }
324
325 if (regs->regs[4] == ERESTART_RESTARTBLOCK) {
326 regs->regs[27] = __NR_restart_syscall;
327 regs->regs[4] = regs->orig_r4;
328 regs->regs[7] = regs->orig_r7;
329 regs->cp0_epc -= 8;
330 }
331
332 regs->is_syscall = 0; /* Don't deal with this again. */
333 }
334
335 /*
336 * If there's no signal to deliver, we just put the saved sigmask
337 * back
338 */
339 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
340 clear_thread_flag(TIF_RESTORE_SIGMASK);
341 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
342 }
343}
344
345/*
346 * notification of userspace execution resumption
347 * - triggered by the TIF_WORK_MASK flags
348 */
349asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused,
350 __u32 thread_info_flags)
351{
352 /* deal with pending signal delivery */
353 if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
354 do_signal(regs);
355}
diff --git a/arch/score/kernel/sys_score.c b/arch/score/kernel/sys_score.c
new file mode 100644
index 000000000000..6a60d1ee5330
--- /dev/null
+++ b/arch/score/kernel/sys_score.c
@@ -0,0 +1,147 @@
1/*
2 * arch/score/kernel/syscall.c
3 *
4 * Score Processor version.
5 *
6 * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
7 * Chen Liqin <liqin.chen@sunplusct.com>
8 * Lennox Wu <lennox.wu@sunplusct.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see the file COPYING, or write
22 * to the Free Software Foundation, Inc.,
23 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26#include <linux/file.h>
27#include <linux/fs.h>
28#include <linux/mman.h>
29#include <linux/module.h>
30#include <linux/unistd.h>
31
32unsigned long shm_align_mask = PAGE_SIZE - 1;
33EXPORT_SYMBOL(shm_align_mask);
34
35asmlinkage unsigned long
36sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
37 unsigned long flags, unsigned long fd, unsigned long pgoff)
38{
39 int error = -EBADF;
40 struct file *file = NULL;
41
42 if (pgoff & (~PAGE_MASK >> 12))
43 return -EINVAL;
44
45 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
46 if (!(flags & MAP_ANONYMOUS)) {
47 file = fget(fd);
48 if (!file)
49 return error;
50 }
51
52 down_write(&current->mm->mmap_sem);
53 error = do_mmap_pgoff(file, addr, len, prot, flags,
54 pgoff >> (PAGE_SHIFT - 12));
55 up_write(&current->mm->mmap_sem);
56
57 if (file)
58 fput(file);
59
60 return error;
61}
62
63/*
64 * Clone a task - this clones the calling program thread.
65 * This is called indirectly via a small wrapper
66 */
67asmlinkage int
68score_clone(struct pt_regs *regs)
69{
70 unsigned long clone_flags;
71 unsigned long newsp;
72 int __user *parent_tidptr, *child_tidptr;
73
74 clone_flags = regs->regs[4];
75 newsp = regs->regs[5];
76 if (!newsp)
77 newsp = regs->regs[0];
78 parent_tidptr = (int __user *)regs->regs[6];
79
80 child_tidptr = NULL;
81 if (clone_flags & (CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)) {
82 int __user *__user *usp = (int __user *__user *)regs->regs[0];
83
84 if (get_user(child_tidptr, &usp[4]))
85 return -EFAULT;
86 }
87
88 return do_fork(clone_flags, newsp, regs, 0,
89 parent_tidptr, child_tidptr);
90}
91
92/*
93 * sys_execve() executes a new program.
94 * This is called indirectly via a small wrapper
95 */
96asmlinkage int score_execve(struct pt_regs *regs)
97{
98 int error;
99 char *filename;
100
101 filename = getname((char *) (long) regs->regs[4]);
102 error = PTR_ERR(filename);
103 if (IS_ERR(filename))
104 return error;
105
106 error = do_execve(filename, (char **) (long) regs->regs[5],
107 (char **) (long) regs->regs[6], regs);
108
109 putname(filename);
110 return error;
111}
112
113/*
114 * If we ever come here the user sp is bad. Zap the process right away.
115 * Due to the bad stack signaling wouldn't work.
116 */
117asmlinkage void bad_stack(void)
118{
119 do_exit(SIGSEGV);
120}
121
122/*
123 * Do a system call from kernel instead of calling sys_execve so we
124 * end up with proper pt_regs.
125 */
126int kernel_execve(const char *filename, char *const argv[], char *const envp[])
127{
128 register unsigned long __r4 asm("r4") = (unsigned long) filename;
129 register unsigned long __r5 asm("r5") = (unsigned long) argv;
130 register unsigned long __r6 asm("r6") = (unsigned long) envp;
131 register unsigned long __r7 asm("r7");
132
133 __asm__ __volatile__ (" \n"
134 "ldi r27, %5 \n"
135 "syscall \n"
136 "mv %0, r4 \n"
137 "mv %1, r7 \n"
138 : "=&r" (__r4), "=r" (__r7)
139 : "r" (__r4), "r" (__r5), "r" (__r6), "i" (__NR_execve)
140 : "r8", "r9", "r10", "r11", "r22", "r23", "r24", "r25",
141 "r26", "r27", "memory");
142
143 if (__r7 == 0)
144 return __r4;
145
146 return -__r4;
147}
diff --git a/arch/score/kernel/time.c b/arch/score/kernel/time.c
new file mode 100644
index 000000000000..cd66ba327ca7
--- /dev/null
+++ b/arch/score/kernel/time.c
@@ -0,0 +1,99 @@
1/*
2 * arch/score/kernel/time.c
3 *
4 * Score Processor version.
5 *
6 * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
7 * Chen Liqin <liqin.chen@sunplusct.com>
8 * Lennox Wu <lennox.wu@sunplusct.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see the file COPYING, or write
22 * to the Free Software Foundation, Inc.,
23 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26#include <linux/clockchips.h>
27#include <linux/interrupt.h>
28
29#include <asm/scoreregs.h>
30
31irqreturn_t timer_interrupt(int irq, void *dev_id)
32{
33 struct clock_event_device *evdev = dev_id;
34
35 /* clear timer interrupt flag */
36 outl(1, P_TIMER0_CPP_REG);
37 evdev->event_handler(evdev);
38
39 return IRQ_HANDLED;
40}
41
42static struct irqaction timer_irq = {
43 .handler = timer_interrupt,
44 .flags = IRQF_DISABLED | IRQF_TIMER,
45 .name = "timer",
46};
47
48static int score_timer_set_next_event(unsigned long delta,
49 struct clock_event_device *evdev)
50{
51 outl((TMR_M_PERIODIC | TMR_IE_ENABLE), P_TIMER0_CTRL);
52 outl(delta, P_TIMER0_PRELOAD);
53 outl(inl(P_TIMER0_CTRL) | TMR_ENABLE, P_TIMER0_CTRL);
54
55 return 0;
56}
57
58static void score_timer_set_mode(enum clock_event_mode mode,
59 struct clock_event_device *evdev)
60{
61 switch (mode) {
62 case CLOCK_EVT_MODE_PERIODIC:
63 outl((TMR_M_PERIODIC | TMR_IE_ENABLE), P_TIMER0_CTRL);
64 outl(SYSTEM_CLOCK/HZ, P_TIMER0_PRELOAD);
65 outl(inl(P_TIMER0_CTRL) | TMR_ENABLE, P_TIMER0_CTRL);
66 break;
67 case CLOCK_EVT_MODE_ONESHOT:
68 case CLOCK_EVT_MODE_SHUTDOWN:
69 case CLOCK_EVT_MODE_RESUME:
70 case CLOCK_EVT_MODE_UNUSED:
71 break;
72 default:
73 BUG();
74 }
75}
76
77static struct clock_event_device score_clockevent = {
78 .name = "score_clockevent",
79 .features = CLOCK_EVT_FEAT_PERIODIC,
80 .shift = 16,
81 .set_next_event = score_timer_set_next_event,
82 .set_mode = score_timer_set_mode,
83};
84
85void __init time_init(void)
86{
87 timer_irq.dev_id = &score_clockevent;
88 setup_irq(IRQ_TIMER , &timer_irq);
89
90 /* setup COMPARE clockevent */
91 score_clockevent.mult = div_sc(SYSTEM_CLOCK, NSEC_PER_SEC,
92 score_clockevent.shift);
93 score_clockevent.max_delta_ns = clockevent_delta2ns((u32)~0,
94 &score_clockevent);
95 score_clockevent.min_delta_ns = clockevent_delta2ns(50,
96 &score_clockevent) + 1;
97 score_clockevent.cpumask = cpumask_of(0);
98 clockevents_register_device(&score_clockevent);
99}
diff --git a/arch/score/kernel/traps.c b/arch/score/kernel/traps.c
new file mode 100644
index 000000000000..957ae9eb3567
--- /dev/null
+++ b/arch/score/kernel/traps.c
@@ -0,0 +1,349 @@
1/*
2 * arch/score/kernel/traps.c
3 *
4 * Score Processor version.
5 *
6 * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
7 * Chen Liqin <liqin.chen@sunplusct.com>
8 * Lennox Wu <lennox.wu@sunplusct.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see the file COPYING, or write
22 * to the Free Software Foundation, Inc.,
23 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26#include <linux/module.h>
27#include <linux/sched.h>
28
29#include <asm/cacheflush.h>
30#include <asm/irq.h>
31#include <asm/irq_regs.h>
32
33unsigned long exception_handlers[32];
34
35/*
36 * The architecture-independent show_stack generator
37 */
38void show_stack(struct task_struct *task, unsigned long *sp)
39{
40 int i;
41 long stackdata;
42
43 sp = sp ? sp : (unsigned long *)&sp;
44
45 printk(KERN_NOTICE "Stack: ");
46 i = 1;
47 while ((long) sp & (PAGE_SIZE - 1)) {
48 if (i && ((i % 8) == 0))
49 printk(KERN_NOTICE "\n");
50 if (i > 40) {
51 printk(KERN_NOTICE " ...");
52 break;
53 }
54
55 if (__get_user(stackdata, sp++)) {
56 printk(KERN_NOTICE " (Bad stack address)");
57 break;
58 }
59
60 printk(KERN_NOTICE " %08lx", stackdata);
61 i++;
62 }
63 printk(KERN_NOTICE "\n");
64}
65
66static void show_trace(long *sp)
67{
68 int i;
69 long addr;
70
71 sp = sp ? sp : (long *) &sp;
72
73 printk(KERN_NOTICE "Call Trace: ");
74 i = 1;
75 while ((long) sp & (PAGE_SIZE - 1)) {
76 if (__get_user(addr, sp++)) {
77 if (i && ((i % 6) == 0))
78 printk(KERN_NOTICE "\n");
79 printk(KERN_NOTICE " (Bad stack address)\n");
80 break;
81 }
82
83 if (kernel_text_address(addr)) {
84 if (i && ((i % 6) == 0))
85 printk(KERN_NOTICE "\n");
86 if (i > 40) {
87 printk(KERN_NOTICE " ...");
88 break;
89 }
90
91 printk(KERN_NOTICE " [<%08lx>]", addr);
92 i++;
93 }
94 }
95 printk(KERN_NOTICE "\n");
96}
97
98static void show_code(unsigned int *pc)
99{
100 long i;
101
102 printk(KERN_NOTICE "\nCode:");
103
104 for (i = -3; i < 6; i++) {
105 unsigned long insn;
106 if (__get_user(insn, pc + i)) {
107 printk(KERN_NOTICE " (Bad address in epc)\n");
108 break;
109 }
110 printk(KERN_NOTICE "%c%08lx%c", (i ? ' ' : '<'),
111 insn, (i ? ' ' : '>'));
112 }
113}
114
115/*
116 * FIXME: really the generic show_regs should take a const pointer argument.
117 */
118void show_regs(struct pt_regs *regs)
119{
120 printk("r0 : %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
121 regs->regs[0], regs->regs[1], regs->regs[2], regs->regs[3],
122 regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]);
123 printk("r8 : %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
124 regs->regs[8], regs->regs[9], regs->regs[10], regs->regs[11],
125 regs->regs[12], regs->regs[13], regs->regs[14], regs->regs[15]);
126 printk("r16: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
127 regs->regs[16], regs->regs[17], regs->regs[18], regs->regs[19],
128 regs->regs[20], regs->regs[21], regs->regs[22], regs->regs[23]);
129 printk("r24: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
130 regs->regs[24], regs->regs[25], regs->regs[26], regs->regs[27],
131 regs->regs[28], regs->regs[29], regs->regs[30], regs->regs[31]);
132
133 printk("CEH : %08lx\n", regs->ceh);
134 printk("CEL : %08lx\n", regs->cel);
135
136 printk("EMA:%08lx, epc:%08lx %s\nPSR: %08lx\nECR:%08lx\nCondition : %08lx\n",
137 regs->cp0_ema, regs->cp0_epc, print_tainted(), regs->cp0_psr,
138 regs->cp0_ecr, regs->cp0_condition);
139}
140
141static void show_registers(struct pt_regs *regs)
142{
143 show_regs(regs);
144 printk(KERN_NOTICE "Process %s (pid: %d, stackpage=%08lx)\n",
145 current->comm, current->pid, (unsigned long) current);
146 show_stack(current_thread_info()->task, (long *) regs->regs[0]);
147 show_trace((long *) regs->regs[0]);
148 show_code((unsigned int *) regs->cp0_epc);
149 printk(KERN_NOTICE "\n");
150}
151
152/*
153 * The architecture-independent dump_stack generator
154 */
155void dump_stack(void)
156{
157 show_stack(current_thread_info()->task,
158 (long *) get_irq_regs()->regs[0]);
159}
160EXPORT_SYMBOL(dump_stack);
161
162void __die(const char *str, struct pt_regs *regs, const char *file,
163 const char *func, unsigned long line)
164{
165 console_verbose();
166 printk("%s", str);
167 if (file && func)
168 printk(" in %s:%s, line %ld", file, func, line);
169 printk(":\n");
170 show_registers(regs);
171 do_exit(SIGSEGV);
172}
173
174void __die_if_kernel(const char *str, struct pt_regs *regs,
175 const char *file, const char *func, unsigned long line)
176{
177 if (!user_mode(regs))
178 __die(str, regs, file, func, line);
179}
180
181asmlinkage void do_adelinsn(struct pt_regs *regs)
182{
183 printk("do_ADE-linsn:ema:0x%08lx:epc:0x%08lx\n",
184 regs->cp0_ema, regs->cp0_epc);
185 die_if_kernel("do_ade execution Exception\n", regs);
186 force_sig(SIGBUS, current);
187}
188
189asmlinkage void do_adedata(struct pt_regs *regs)
190{
191 const struct exception_table_entry *fixup;
192 fixup = search_exception_tables(regs->cp0_epc);
193 if (fixup) {
194 regs->cp0_epc = fixup->fixup;
195 return;
196 }
197 printk("do_ADE-data:ema:0x%08lx:epc:0x%08lx\n",
198 regs->cp0_ema, regs->cp0_epc);
199 die_if_kernel("do_ade execution Exception\n", regs);
200 force_sig(SIGBUS, current);
201}
202
203asmlinkage void do_pel(struct pt_regs *regs)
204{
205 die_if_kernel("do_pel execution Exception", regs);
206 force_sig(SIGFPE, current);
207}
208
209asmlinkage void do_cee(struct pt_regs *regs)
210{
211 die_if_kernel("do_cee execution Exception", regs);
212 force_sig(SIGFPE, current);
213}
214
215asmlinkage void do_cpe(struct pt_regs *regs)
216{
217 die_if_kernel("do_cpe execution Exception", regs);
218 force_sig(SIGFPE, current);
219}
220
221asmlinkage void do_be(struct pt_regs *regs)
222{
223 die_if_kernel("do_be execution Exception", regs);
224 force_sig(SIGBUS, current);
225}
226
227asmlinkage void do_ov(struct pt_regs *regs)
228{
229 siginfo_t info;
230
231 die_if_kernel("do_ov execution Exception", regs);
232
233 info.si_code = FPE_INTOVF;
234 info.si_signo = SIGFPE;
235 info.si_errno = 0;
236 info.si_addr = (void *)regs->cp0_epc;
237 force_sig_info(SIGFPE, &info, current);
238}
239
240asmlinkage void do_tr(struct pt_regs *regs)
241{
242 die_if_kernel("do_tr execution Exception", regs);
243 force_sig(SIGTRAP, current);
244}
245
246asmlinkage void do_ri(struct pt_regs *regs)
247{
248 unsigned long epc_insn;
249 unsigned long epc = regs->cp0_epc;
250
251 read_tsk_long(current, epc, &epc_insn);
252 if (current->thread.single_step == 1) {
253 if ((epc == current->thread.addr1) ||
254 (epc == current->thread.addr2)) {
255 clear_single_step(current);
256 force_sig(SIGTRAP, current);
257 return;
258 } else
259 BUG();
260 } else if ((epc_insn == BREAKPOINT32_INSN) ||
261 ((epc_insn & 0x0000FFFF) == 0x7002) ||
262 ((epc_insn & 0xFFFF0000) == 0x70020000)) {
263 force_sig(SIGTRAP, current);
264 return;
265 } else {
266 die_if_kernel("do_ri execution Exception", regs);
267 force_sig(SIGILL, current);
268 }
269}
270
271asmlinkage void do_ccu(struct pt_regs *regs)
272{
273 die_if_kernel("do_ccu execution Exception", regs);
274 force_sig(SIGILL, current);
275}
276
277asmlinkage void do_reserved(struct pt_regs *regs)
278{
279 /*
280 * Game over - no way to handle this if it ever occurs. Most probably
281 * caused by a new unknown cpu type or after another deadly
282 * hard/software error.
283 */
284 die_if_kernel("do_reserved execution Exception", regs);
285 show_regs(regs);
286 panic("Caught reserved exception - should not happen.");
287}
288
289/*
290 * NMI exception handler.
291 */
292void nmi_exception_handler(struct pt_regs *regs)
293{
294 die_if_kernel("nmi_exception_handler execution Exception", regs);
295 die("NMI", regs);
296}
297
298/* Install CPU exception handler */
299void *set_except_vector(int n, void *addr)
300{
301 unsigned long handler = (unsigned long) addr;
302 unsigned long old_handler = exception_handlers[n];
303
304 exception_handlers[n] = handler;
305 return (void *)old_handler;
306}
307
308void __init trap_init(void)
309{
310 int i;
311
312 pgd_current = (unsigned long)init_mm.pgd;
313 /* DEBUG EXCEPTION */
314 memcpy((void *)DEBUG_VECTOR_BASE_ADDR,
315 &debug_exception_vector, DEBUG_VECTOR_SIZE);
316 /* NMI EXCEPTION */
317 memcpy((void *)GENERAL_VECTOR_BASE_ADDR,
318 &general_exception_vector, GENERAL_VECTOR_SIZE);
319
320 /*
321 * Initialise exception handlers
322 */
323 for (i = 0; i <= 31; i++)
324 set_except_vector(i, handle_reserved);
325
326 set_except_vector(1, handle_nmi);
327 set_except_vector(2, handle_adelinsn);
328 set_except_vector(3, handle_tlb_refill);
329 set_except_vector(4, handle_tlb_invaild);
330 set_except_vector(5, handle_ibe);
331 set_except_vector(6, handle_pel);
332 set_except_vector(7, handle_sys);
333 set_except_vector(8, handle_ccu);
334 set_except_vector(9, handle_ri);
335 set_except_vector(10, handle_tr);
336 set_except_vector(11, handle_adedata);
337 set_except_vector(12, handle_adedata);
338 set_except_vector(13, handle_tlb_refill);
339 set_except_vector(14, handle_tlb_invaild);
340 set_except_vector(15, handle_mod);
341 set_except_vector(16, handle_cee);
342 set_except_vector(17, handle_cpe);
343 set_except_vector(18, handle_dbe);
344 flush_icache_range(DEBUG_VECTOR_BASE_ADDR, IRQ_VECTOR_BASE_ADDR);
345
346 atomic_inc(&init_mm.mm_count);
347 current->active_mm = &init_mm;
348 cpu_cache_init();
349}
diff --git a/arch/score/kernel/vmlinux.lds.S b/arch/score/kernel/vmlinux.lds.S
new file mode 100644
index 000000000000..f85569831d5c
--- /dev/null
+++ b/arch/score/kernel/vmlinux.lds.S
@@ -0,0 +1,148 @@
1/*
2 * arch/score/kernel/vmlinux.lds.S
3 *
4 * Score Processor version.
5 *
6 * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
7 * Chen Liqin <liqin.chen@sunplusct.com>
8 * Lennox Wu <lennox.wu@sunplusct.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see the file COPYING, or write
22 * to the Free Software Foundation, Inc.,
23 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26#include <asm-generic/vmlinux.lds.h>
27
28OUTPUT_ARCH(score)
29ENTRY(_stext)
30
31jiffies = jiffies_64;
32
33SECTIONS
34{
35 . = CONFIG_MEMORY_START + 0x2000;
36 /* read-only */
37 .text : {
38 _text = .; /* Text and read-only data */
39 TEXT_TEXT
40 SCHED_TEXT
41 LOCK_TEXT
42 KPROBES_TEXT
43 *(.text.*)
44 *(.fixup)
45 . = ALIGN (4) ;
46 _etext = .; /* End of text section */
47 }
48
49 . = ALIGN(16);
50 RODATA
51
52 /* Exception table */
53 . = ALIGN(16);
54 __ex_table : {
55 __start___ex_table = .;
56 *(__ex_table)
57 __stop___ex_table = .;
58 }
59
60 /* writeable */
61 .data ALIGN (4096): {
62 *(.data.init_task)
63
64 DATA_DATA
65 CONSTRUCTORS
66 }
67
68 /* We want the small data sections together, so single-instruction offsets
69 can access them all, and initialized data all before uninitialized, so
70 we can shorten the on-disk segment size. */
71 . = ALIGN(8);
72 .sdata : {
73 *(.sdata)
74 }
75
76 . = ALIGN(32);
77 .data.cacheline_aligned : {
78 *(.data.cacheline_aligned)
79 }
80 _edata = .; /* End of data section */
81
82 /* will be freed after init */
83 . = ALIGN(4096); /* Init code and data */
84 __init_begin = .;
85
86 . = ALIGN(4096);
87 .init.text : {
88 _sinittext = .;
89 INIT_TEXT
90 _einittext = .;
91 }
92 .init.data : {
93 INIT_DATA
94 }
95 . = ALIGN(16);
96 .init.setup : {
97 __setup_start = .;
98 *(.init.setup)
99 __setup_end = .;
100 }
101
102 .initcall.init : {
103 __initcall_start = .;
104 INITCALLS
105 __initcall_end = .;
106 }
107
108 .con_initcall.init : {
109 __con_initcall_start = .;
110 *(.con_initcall.init)
111 __con_initcall_end = .;
112 }
113 SECURITY_INIT
114
115 /* .exit.text is discarded at runtime, not link time, to deal with
116 * references from .rodata
117 */
118 .exit.text : {
119 EXIT_TEXT
120 }
121 .exit.data : {
122 EXIT_DATA
123 }
124#if defined(CONFIG_BLK_DEV_INITRD)
125 .init.ramfs ALIGN(4096): {
126 __initramfs_start = .;
127 *(.init.ramfs)
128 __initramfs_end = .;
129 . = ALIGN(4);
130 LONG(0);
131 }
132#endif
133 . = ALIGN(4096);
134 __init_end = .;
135 /* freed after init ends here */
136
137 __bss_start = .; /* BSS */
138 .sbss : {
139 *(.sbss)
140 *(.scommon)
141 }
142 .bss : {
143 *(.bss)
144 *(COMMON)
145 }
146 __bss_stop = .;
147 _end = .;
148}
diff --git a/arch/score/lib/Makefile b/arch/score/lib/Makefile
new file mode 100644
index 000000000000..553e30e81faf
--- /dev/null
+++ b/arch/score/lib/Makefile
@@ -0,0 +1,8 @@
1#
2# Makefile for SCORE-specific library files..
3#
4
5lib-y += string.o checksum.o checksum_copy.o
6
7# libgcc-style stuff needed in the kernel
8obj-y += ashldi3.o ashrdi3.o cmpdi2.o lshrdi3.o ucmpdi2.o
diff --git a/arch/score/lib/ashldi3.c b/arch/score/lib/ashldi3.c
new file mode 100644
index 000000000000..15691a910431
--- /dev/null
+++ b/arch/score/lib/ashldi3.c
@@ -0,0 +1,46 @@
1/*
2 * arch/score/lib/ashldi3.c
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see the file COPYING, or write
16 * to the Free Software Foundation, Inc.,
17 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include <linux/module.h>
21#include "libgcc.h"
22
23long long __ashldi3(long long u, word_type b)
24{
25 DWunion uu, w;
26 word_type bm;
27
28 if (b == 0)
29 return u;
30
31 uu.ll = u;
32 bm = 32 - b;
33
34 if (bm <= 0) {
35 w.s.low = 0;
36 w.s.high = (unsigned int) uu.s.low << -bm;
37 } else {
38 const unsigned int carries = (unsigned int) uu.s.low >> bm;
39
40 w.s.low = (unsigned int) uu.s.low << b;
41 w.s.high = ((unsigned int) uu.s.high << b) | carries;
42 }
43
44 return w.ll;
45}
46EXPORT_SYMBOL(__ashldi3);
diff --git a/arch/score/lib/ashrdi3.c b/arch/score/lib/ashrdi3.c
new file mode 100644
index 000000000000..d9814a5d8d30
--- /dev/null
+++ b/arch/score/lib/ashrdi3.c
@@ -0,0 +1,48 @@
1/*
2 * arch/score/lib/ashrdi3.c
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see the file COPYING, or write
16 * to the Free Software Foundation, Inc.,
17 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include <linux/module.h>
21#include "libgcc.h"
22
23long long __ashrdi3(long long u, word_type b)
24{
25 DWunion uu, w;
26 word_type bm;
27
28 if (b == 0)
29 return u;
30
31 uu.ll = u;
32 bm = 32 - b;
33
34 if (bm <= 0) {
35 /* w.s.high = 1..1 or 0..0 */
36 w.s.high =
37 uu.s.high >> 31;
38 w.s.low = uu.s.high >> -bm;
39 } else {
40 const unsigned int carries = (unsigned int) uu.s.high << bm;
41
42 w.s.high = uu.s.high >> b;
43 w.s.low = ((unsigned int) uu.s.low >> b) | carries;
44 }
45
46 return w.ll;
47}
48EXPORT_SYMBOL(__ashrdi3);
diff --git a/arch/score/lib/checksum.S b/arch/score/lib/checksum.S
new file mode 100644
index 000000000000..706157edc7d5
--- /dev/null
+++ b/arch/score/lib/checksum.S
@@ -0,0 +1,255 @@
1/*
2 * arch/score/lib/csum_partial.S
3 *
4 * Score Processor version.
5 *
6 * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
7 * Lennox Wu <lennox.wu@sunplusct.com>
8 * Chen Liqin <liqin.chen@sunplusct.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see the file COPYING, or write
22 * to the Free Software Foundation, Inc.,
23 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25#include <linux/linkage.h>
26
27#define ADDC(sum,reg) \
28 add sum, sum, reg; \
29 cmp.c reg, sum; \
30 bleu 9f; \
31 addi sum, 0x1; \
329:
33
34#define CSUM_BIGCHUNK(src, offset, sum) \
35 lw r8, [src, offset + 0x00]; \
36 lw r9, [src, offset + 0x04]; \
37 lw r10, [src, offset + 0x08]; \
38 lw r11, [src, offset + 0x0c]; \
39 ADDC(sum, r8); \
40 ADDC(sum, r9); \
41 ADDC(sum, r10); \
42 ADDC(sum, r11); \
43 lw r8, [src, offset + 0x10]; \
44 lw r9, [src, offset + 0x14]; \
45 lw r10, [src, offset + 0x18]; \
46 lw r11, [src, offset + 0x1c]; \
47 ADDC(sum, r8); \
48 ADDC(sum, r9); \
49 ADDC(sum, r10); \
50 ADDC(sum, r11); \
51
52#define src r4
53#define dest r5
54#define sum r27
55
56 .text
57/* unknown src alignment and < 8 bytes to go */
58small_csumcpy:
59 mv r5, r10
60 ldi r9, 0x0
61 cmpi.c r25, 0x1
62 beq pass_small_set_t7 /*already set, jump to pass_small_set_t7*/
63 andri.c r25,r4 , 0x1 /*Is src 2 bytes aligned?*/
64
65pass_small_set_t7:
66 beq aligned
67 cmpi.c r5, 0x0
68 beq fold
69 lbu r9, [src]
70 slli r9,r9, 0x8 /*Little endian*/
71 ADDC(sum, r9)
72 addi src, 0x1
73 subi.c r5, 0x1
74
75 /*len still a full word */
76aligned:
77 andri.c r8, r5, 0x4 /*Len >= 4?*/
78 beq len_less_4bytes
79
80 /* Still a full word (4byte) to go,and the src is word aligned.*/
81 andri.c r8, src, 0x3 /*src is 4bytes aligned, so use LW!!*/
82 beq four_byte_aligned
83 lhu r9, [src]
84 addi src, 2
85 ADDC(sum, r9)
86 lhu r9, [src]
87 addi src, 2
88 ADDC(sum, r9)
89 b len_less_4bytes
90
91four_byte_aligned: /* Len >=4 and four byte aligned */
92 lw r9, [src]
93 addi src, 4
94 ADDC(sum, r9)
95
96len_less_4bytes: /* 2 byte aligned aligned and length<4B */
97 andri.c r8, r5, 0x2
98 beq len_less_2bytes
99 lhu r9, [src]
100 addi src, 0x2 /* src+=2 */
101 ADDC(sum, r9)
102
103len_less_2bytes: /* len = 1 */
104 andri.c r8, r5, 0x1
105 beq fold /* less than 2 and not equal 1--> len=0 -> fold */
106 lbu r9, [src]
107
108fold_ADDC:
109 ADDC(sum, r9)
110fold:
111 /* fold checksum */
112 slli r26, sum, 16
113 add sum, sum, r26
114 cmp.c r26, sum
115 srli sum, sum, 16
116 bleu 1f /* if r26<=sum */
117 addi sum, 0x1 /* r26>sum */
1181:
119 /* odd buffer alignment? r25 was set in csum_partial */
120 cmpi.c r25, 0x0
121 beq 1f
122 slli r26, sum, 8
123 srli sum, sum, 8
124 or sum, sum, r26
125 andi sum, 0xffff
1261:
127 .set optimize
128 /* Add the passed partial csum. */
129 ADDC(sum, r6)
130 mv r4, sum
131 br r3
132 .set volatile
133
134 .align 5
135ENTRY(csum_partial)
136 ldi sum, 0
137 ldi r25, 0
138 mv r10, r5
139 cmpi.c r5, 0x8
140 blt small_csumcpy /* < 8(singed) bytes to copy */
141 cmpi.c r5, 0x0
142 beq out
143 andri.c r25, src, 0x1 /* odd buffer? */
144
145 beq word_align
146hword_align: /* 1 byte */
147 lbu r8, [src]
148 subi r5, 0x1
149 slli r8, r8, 8
150 ADDC(sum, r8)
151 addi src, 0x1
152
153word_align: /* 2 bytes */
154 andri.c r8, src, 0x2 /* 4bytes(dword)_aligned? */
155 beq dword_align /* not, maybe dword_align */
156 lhu r8, [src]
157 subi r5, 0x2
158 ADDC(sum, r8)
159 addi src, 0x2
160
161dword_align: /* 4bytes */
162 mv r26, r5 /* maybe useless when len >=56 */
163 ldi r8, 56
164 cmp.c r8, r5
165 bgtu do_end_words /* if a1(len)<t0(56) ,unsigned */
166 andri.c r26, src, 0x4
167 beq qword_align
168 lw r8, [src]
169 subi r5, 0x4
170 ADDC(sum, r8)
171 addi src, 0x4
172
173qword_align: /* 8 bytes */
174 andri.c r26, src, 0x8
175 beq oword_align
176 lw r8, [src, 0x0]
177 lw r9, [src, 0x4]
178 subi r5, 0x8 /* len-=0x8 */
179 ADDC(sum, r8)
180 ADDC(sum, r9)
181 addi src, 0x8
182
183oword_align: /* 16bytes */
184 andri.c r26, src, 0x10
185 beq begin_movement
186 lw r10, [src, 0x08]
187 lw r11, [src, 0x0c]
188 lw r8, [src, 0x00]
189 lw r9, [src, 0x04]
190 ADDC(sum, r10)
191 ADDC(sum, r11)
192 ADDC(sum, r8)
193 ADDC(sum, r9)
194 subi r5, 0x10
195 addi src, 0x10
196
197begin_movement:
198 srli.c r26, r5, 0x7 /* len>=128? */
199 beq 1f /* len<128 */
200
201/* r26 is the result that computed in oword_align */
202move_128bytes:
203 CSUM_BIGCHUNK(src, 0x00, sum)
204 CSUM_BIGCHUNK(src, 0x20, sum)
205 CSUM_BIGCHUNK(src, 0x40, sum)
206 CSUM_BIGCHUNK(src, 0x60, sum)
207 subi.c r26, 0x01 /* r26 equals len/128 */
208 addi src, 0x80
209 bne move_128bytes
210
2111: /* len<128,we process 64byte here */
212 andri.c r10, r5, 0x40
213 beq 1f
214
215move_64bytes:
216 CSUM_BIGCHUNK(src, 0x00, sum)
217 CSUM_BIGCHUNK(src, 0x20, sum)
218 addi src, 0x40
219
2201: /* len<64 */
221 andri r26, r5, 0x1c /* 0x1c=28 */
222 andri.c r10, r5, 0x20
223 beq do_end_words /* decided by andri */
224
225move_32bytes:
226 CSUM_BIGCHUNK(src, 0x00, sum)
227 andri r26, r5, 0x1c
228 addri src, src, 0x20
229
230do_end_words: /* len<32 */
231 /* r26 was set already in dword_align */
232 cmpi.c r26, 0x0
233 beq maybe_end_cruft /* len<28 or len<56 */
234 srli r26, r26, 0x2
235
236end_words:
237 lw r8, [src]
238 subi.c r26, 0x1 /* unit is 4 byte */
239 ADDC(sum, r8)
240 addi src, 0x4
241 cmpi.c r26, 0x0
242 bne end_words /* r26!=0 */
243
244maybe_end_cruft: /* len<4 */
245 andri r10, r5, 0x3
246
247small_memcpy:
248 mv r5, r10
249 j small_csumcpy
250
251out:
252 mv r4, sum
253 br r3
254
255END(csum_partial)
diff --git a/arch/score/lib/checksum_copy.c b/arch/score/lib/checksum_copy.c
new file mode 100644
index 000000000000..04565dd3ded8
--- /dev/null
+++ b/arch/score/lib/checksum_copy.c
@@ -0,0 +1,52 @@
1/*
2 * arch/score/lib/csum_partial_copy.c
3 *
4 * Score Processor version.
5 *
6 * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
7 * Lennox Wu <lennox.wu@sunplusct.com>
8 * Chen Liqin <liqin.chen@sunplusct.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see the file COPYING, or write
22 * to the Free Software Foundation, Inc.,
23 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26#include <net/checksum.h>
27
28#include <asm/uaccess.h>
29
30unsigned int csum_partial_copy(const char *src, char *dst,
31 int len, unsigned int sum)
32{
33 sum = csum_partial(src, len, sum);
34 memcpy(dst, src, len);
35
36 return sum;
37}
38
39unsigned int csum_partial_copy_from_user(const char *src, char *dst,
40 int len, unsigned int sum,
41 int *err_ptr)
42{
43 int missing;
44
45 missing = copy_from_user(dst, src, len);
46 if (missing) {
47 memset(dst + len - missing, 0, missing);
48 *err_ptr = -EFAULT;
49 }
50
51 return csum_partial(dst, len, sum);
52}
diff --git a/arch/score/lib/cmpdi2.c b/arch/score/lib/cmpdi2.c
new file mode 100644
index 000000000000..1ed5290c66ed
--- /dev/null
+++ b/arch/score/lib/cmpdi2.c
@@ -0,0 +1,44 @@
1/*
2 * arch/score/lib/cmpdi2.c
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see the file COPYING, or write
16 * to the Free Software Foundation, Inc.,
17 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include <linux/module.h>
21#include "libgcc.h"
22
23word_type __cmpdi2(long long a, long long b)
24{
25 const DWunion au = {
26 .ll = a
27 };
28 const DWunion bu = {
29 .ll = b
30 };
31
32 if (au.s.high < bu.s.high)
33 return 0;
34 else if (au.s.high > bu.s.high)
35 return 2;
36
37 if ((unsigned int) au.s.low < (unsigned int) bu.s.low)
38 return 0;
39 else if ((unsigned int) au.s.low > (unsigned int) bu.s.low)
40 return 2;
41
42 return 1;
43}
44EXPORT_SYMBOL(__cmpdi2);
diff --git a/arch/score/lib/libgcc.h b/arch/score/lib/libgcc.h
new file mode 100644
index 000000000000..0f12543d9f31
--- /dev/null
+++ b/arch/score/lib/libgcc.h
@@ -0,0 +1,37 @@
1/*
2 * arch/score/lib/libgcc.h
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see the file COPYING, or write
16 * to the Free Software Foundation, Inc.,
17 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20
21#ifndef __ASM_LIBGCC_H
22#define __ASM_LIBGCC_H
23
24#include <asm/byteorder.h>
25
26typedef int word_type __attribute__((mode(__word__)));
27
28struct DWstruct {
29 int low, high;
30};
31
32typedef union {
33 struct DWstruct s;
34 long long ll;
35} DWunion;
36
37#endif /* __ASM_LIBGCC_H */
diff --git a/arch/score/lib/lshrdi3.c b/arch/score/lib/lshrdi3.c
new file mode 100644
index 000000000000..ce21175fd791
--- /dev/null
+++ b/arch/score/lib/lshrdi3.c
@@ -0,0 +1,47 @@
1/*
2 * arch/score/lib/lshrdi3.c
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see the file COPYING, or write
16 * to the Free Software Foundation, Inc.,
17 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20
21#include <linux/module.h>
22#include "libgcc.h"
23
24long long __lshrdi3(long long u, word_type b)
25{
26 DWunion uu, w;
27 word_type bm;
28
29 if (b == 0)
30 return u;
31
32 uu.ll = u;
33 bm = 32 - b;
34
35 if (bm <= 0) {
36 w.s.high = 0;
37 w.s.low = (unsigned int) uu.s.high >> -bm;
38 } else {
39 const unsigned int carries = (unsigned int) uu.s.high << bm;
40
41 w.s.high = (unsigned int) uu.s.high >> b;
42 w.s.low = ((unsigned int) uu.s.low >> b) | carries;
43 }
44
45 return w.ll;
46}
47EXPORT_SYMBOL(__lshrdi3);
diff --git a/arch/score/lib/string.S b/arch/score/lib/string.S
new file mode 100644
index 000000000000..943d0911ea89
--- /dev/null
+++ b/arch/score/lib/string.S
@@ -0,0 +1,196 @@
1/*
2 * arch/score/lib/string.S
3 *
4 * Score Processor version.
5 *
6 * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
7 * Chen Liqin <liqin.chen@sunplusct.com>
8 * Lennox Wu <lennox.wu@sunplusct.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see the file COPYING, or write
22 * to the Free Software Foundation, Inc.,
23 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26#include <linux/linkage.h>
27#include <asm-generic/errno.h>
28
29 .text
30 .align 2
31ENTRY(__strncpy_from_user)
32 cmpi.c r6, 0
33 mv r9, r6
34 ble .L2
350: lbu r7, [r5]
36 ldi r8, 0
371: sb r7, [r4]
382: lb r6, [r5]
39 cmp.c r6, r8
40 beq .L2
41
42.L5:
43 addi r8, 1
44 cmp.c r8, r9
45 beq .L7
463: lbu r6, [r5, 1]+
474: sb r6, [r4, 1]+
485: lb r7, [r5]
49 cmpi.c r7, 0
50 bne .L5
51.L7:
52 mv r4, r8
53 br r3
54.L2:
55 ldi r8, 0
56 mv r4, r8
57 br r3
58 .section .fixup, "ax"
5999:
60 ldi r4, -EFAULT
61 br r3
62 .previous
63 .section __ex_table, "a"
64 .align 2
65 .word 0b ,99b
66 .word 1b ,99b
67 .word 2b ,99b
68 .word 3b ,99b
69 .word 4b ,99b
70 .word 5b ,99b
71 .previous
72
73 .align 2
74ENTRY(__strnlen_user)
75 cmpi.c r5, 0
76 ble .L11
770: lb r6, [r4]
78 ldi r7, 0
79 cmp.c r6, r7
80 beq .L11
81.L15:
82 addi r7, 1
83 cmp.c r7, r5
84 beq .L23
851: lb r6, [r4,1]+
86 cmpi.c r6, 0
87 bne .L15
88.L23:
89 addri r4, r7, 1
90 br r3
91
92.L11:
93 ldi r4, 1
94 br r3
95 .section .fixup, "ax"
9699:
97 ldi r4, 0
98 br r3
99
100 .section __ex_table,"a"
101 .align 2
102 .word 0b, 99b
103 .word 1b, 99b
104 .previous
105
106 .align 2
107ENTRY(__strlen_user)
1080: lb r6, [r4]
109 mv r7, r4
110 extsb r6, r6
111 cmpi.c r6, 0
112 mv r4, r6
113 beq .L27
114.L28:
1151: lb r6, [r7, 1]+
116 addi r6, 1
117 cmpi.c r6, 0
118 bne .L28
119.L27:
120 br r3
121 .section .fixup, "ax"
122 ldi r4, 0x0
123 br r3
12499:
125 ldi r4, 0
126 br r3
127 .previous
128 .section __ex_table, "a"
129 .align 2
130 .word 0b ,99b
131 .word 1b ,99b
132 .previous
133
134 .align 2
135ENTRY(__copy_tofrom_user)
136 cmpi.c r6, 0
137 mv r10,r6
138 beq .L32
139 ldi r9, 0
140.L34:
141 add r6, r5, r9
1420: lbu r8, [r6]
143 add r7, r4, r9
1441: sb r8, [r7]
145 addi r9, 1
146 cmp.c r9, r10
147 bne .L34
148.L32:
149 ldi r4, 0
150 br r3
151 .section .fixup, "ax"
15299:
153 sub r4, r10, r9
154 br r3
155 .previous
156 .section __ex_table, "a"
157 .align 2
158 .word 0b, 99b
159 .word 1b, 99b
160 .previous
161
162 .align 2
163ENTRY(__clear_user)
164 cmpi.c r5, 0
165 beq .L38
166 ldi r6, 0
167 mv r7, r6
168.L40:
169 addi r6, 1
1700: sb r7, [r4]+, 1
171 cmp.c r6, r5
172 bne .L40
173.L38:
174 ldi r4, 0
175 br r3
176
177 .section .fixup, "ax"
178 br r3
179 .previous
180 .section __ex_table, "a"
181 .align 2
18299:
183 .word 0b, 99b
184 .previous
185
186 .align 2
187ENTRY(__put_user_unknown)
188 .set volatile
189 ldi r4, -EFAULT
190 br r3
191
192 .align 2
193ENTRY(__get_user_unknown)
194 ldi r5, 0
195 ldi r4, -EFAULT
196 br r3
diff --git a/arch/score/lib/ucmpdi2.c b/arch/score/lib/ucmpdi2.c
new file mode 100644
index 000000000000..b15241e0b079
--- /dev/null
+++ b/arch/score/lib/ucmpdi2.c
@@ -0,0 +1,38 @@
1/*
2 * arch/score/lib/ucmpdi2.c
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see the file COPYING, or write
16 * to the Free Software Foundation, Inc.,
17 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include <linux/module.h>
21#include "libgcc.h"
22
23word_type __ucmpdi2(unsigned long long a, unsigned long long b)
24{
25 const DWunion au = {.ll = a};
26 const DWunion bu = {.ll = b};
27
28 if ((unsigned int) au.s.high < (unsigned int) bu.s.high)
29 return 0;
30 else if ((unsigned int) au.s.high > (unsigned int) bu.s.high)
31 return 2;
32 if ((unsigned int) au.s.low < (unsigned int) bu.s.low)
33 return 0;
34 else if ((unsigned int) au.s.low > (unsigned int) bu.s.low)
35 return 2;
36 return 1;
37}
38EXPORT_SYMBOL(__ucmpdi2);
diff --git a/arch/score/mm/Makefile b/arch/score/mm/Makefile
new file mode 100644
index 000000000000..7b1e29b1f8cd
--- /dev/null
+++ b/arch/score/mm/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile for the Linux/SCORE-specific parts of the memory manager.
3#
4
5obj-y += cache.o extable.o fault.o init.o \
6 tlb-miss.o tlb-score.o pgtable.o
diff --git a/arch/score/mm/cache.c b/arch/score/mm/cache.c
new file mode 100644
index 000000000000..1ebc67f18c6d
--- /dev/null
+++ b/arch/score/mm/cache.c
@@ -0,0 +1,308 @@
1/*
2 * arch/score/mm/cache.c
3 *
4 * Score Processor version.
5 *
6 * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
7 * Lennox Wu <lennox.wu@sunplusct.com>
8 * Chen Liqin <liqin.chen@sunplusct.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see the file COPYING, or write
22 * to the Free Software Foundation, Inc.,
23 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26#include <linux/init.h>
27#include <linux/linkage.h>
28#include <linux/kernel.h>
29#include <linux/mm.h>
30#include <linux/module.h>
31#include <linux/sched.h>
32
33#include <asm/mmu_context.h>
34
35/* Cache operations. */
36void (*flush_cache_all)(void);
37void (*__flush_cache_all)(void);
38void (*flush_cache_mm)(struct mm_struct *mm);
39void (*flush_cache_range)(struct vm_area_struct *vma,
40 unsigned long start, unsigned long end);
41void (*flush_cache_page)(struct vm_area_struct *vma,
42 unsigned long page, unsigned long pfn);
43void (*flush_icache_range)(unsigned long start, unsigned long end);
44void (*__flush_cache_vmap)(void);
45void (*__flush_cache_vunmap)(void);
46void (*flush_cache_sigtramp)(unsigned long addr);
47void (*flush_data_cache_page)(unsigned long addr);
48EXPORT_SYMBOL(flush_data_cache_page);
49void (*flush_icache_all)(void);
50
51/*Score 7 cache operations*/
52static inline void s7___flush_cache_all(void);
53static void s7_flush_cache_mm(struct mm_struct *mm);
54static void s7_flush_cache_range(struct vm_area_struct *vma,
55 unsigned long start, unsigned long end);
56static void s7_flush_cache_page(struct vm_area_struct *vma,
57 unsigned long page, unsigned long pfn);
58static void s7_flush_icache_range(unsigned long start, unsigned long end);
59static void s7_flush_cache_sigtramp(unsigned long addr);
60static void s7_flush_data_cache_page(unsigned long addr);
61static void s7_flush_dcache_range(unsigned long start, unsigned long end);
62
63void __update_cache(struct vm_area_struct *vma, unsigned long address,
64 pte_t pte)
65{
66 struct page *page;
67 unsigned long pfn, addr;
68 int exec = (vma->vm_flags & VM_EXEC);
69
70 pfn = pte_pfn(pte);
71 if (unlikely(!pfn_valid(pfn)))
72 return;
73 page = pfn_to_page(pfn);
74 if (page_mapping(page) && test_bit(PG_arch_1, &page->flags)) {
75 addr = (unsigned long) page_address(page);
76 if (exec)
77 s7_flush_data_cache_page(addr);
78 clear_bit(PG_arch_1, &page->flags);
79 }
80}
81
82static inline void setup_protection_map(void)
83{
84 protection_map[0] = PAGE_NONE;
85 protection_map[1] = PAGE_READONLY;
86 protection_map[2] = PAGE_COPY;
87 protection_map[3] = PAGE_COPY;
88 protection_map[4] = PAGE_READONLY;
89 protection_map[5] = PAGE_READONLY;
90 protection_map[6] = PAGE_COPY;
91 protection_map[7] = PAGE_COPY;
92 protection_map[8] = PAGE_NONE;
93 protection_map[9] = PAGE_READONLY;
94 protection_map[10] = PAGE_SHARED;
95 protection_map[11] = PAGE_SHARED;
96 protection_map[12] = PAGE_READONLY;
97 protection_map[13] = PAGE_READONLY;
98 protection_map[14] = PAGE_SHARED;
99 protection_map[15] = PAGE_SHARED;
100}
101
102void __devinit cpu_cache_init(void)
103{
104 flush_cache_all = s7_flush_cache_all;
105 __flush_cache_all = s7___flush_cache_all;
106 flush_cache_mm = s7_flush_cache_mm;
107 flush_cache_range = s7_flush_cache_range;
108 flush_cache_page = s7_flush_cache_page;
109 flush_icache_range = s7_flush_icache_range;
110 flush_cache_sigtramp = s7_flush_cache_sigtramp;
111 flush_data_cache_page = s7_flush_data_cache_page;
112
113 setup_protection_map();
114}
115
116void s7_flush_icache_all(void)
117{
118 __asm__ __volatile__(
119 "la r8, s7_flush_icache_all\n"
120 "cache 0x10, [r8, 0]\n"
121 "nop\nnop\nnop\nnop\nnop\nnop\n"
122 : : : "r8");
123}
124
125void s7_flush_dcache_all(void)
126{
127 __asm__ __volatile__(
128 "la r8, s7_flush_dcache_all\n"
129 "cache 0x1f, [r8, 0]\n"
130 "nop\nnop\nnop\nnop\nnop\nnop\n"
131 "cache 0x1a, [r8, 0]\n"
132 "nop\nnop\nnop\nnop\nnop\nnop\n"
133 : : : "r8");
134}
135
136void s7_flush_cache_all(void)
137{
138 __asm__ __volatile__(
139 "la r8, s7_flush_cache_all\n"
140 "cache 0x10, [r8, 0]\n"
141 "nop\nnop\nnop\nnop\nnop\nnop\n"
142 "cache 0x1f, [r8, 0]\n"
143 "nop\nnop\nnop\nnop\nnop\nnop\n"
144 "cache 0x1a, [r8, 0]\n"
145 "nop\nnop\nnop\nnop\nnop\nnop\n"
146 : : : "r8");
147}
148
149void s7___flush_cache_all(void)
150{
151 __asm__ __volatile__(
152 "la r8, s7_flush_cache_all\n"
153 "cache 0x10, [r8, 0]\n"
154 "nop\nnop\nnop\nnop\nnop\nnop\n"
155 "cache 0x1f, [r8, 0]\n"
156 "nop\nnop\nnop\nnop\nnop\nnop\n"
157 "cache 0x1a, [r8, 0]\n"
158 "nop\nnop\nnop\nnop\nnop\nnop\n"
159 : : : "r8");
160}
161
162static void s7_flush_cache_mm(struct mm_struct *mm)
163{
164 if (!(mm->context))
165 return;
166 s7_flush_cache_all();
167}
168
169/*if we flush a range precisely , the processing may be very long.
170We must check each page in the range whether present. If the page is present,
171we can flush the range in the page. Be careful, the range may be cross two
172page, a page is present and another is not present.
173*/
174/*
175The interface is provided in hopes that the port can find
176a suitably efficient method for removing multiple page
177sized regions from the cache.
178*/
179static void
180s7_flush_cache_range(struct vm_area_struct *vma,
181 unsigned long start, unsigned long end)
182{
183 struct mm_struct *mm = vma->vm_mm;
184 int exec = vma->vm_flags & VM_EXEC;
185 pgd_t *pgdp;
186 pud_t *pudp;
187 pmd_t *pmdp;
188 pte_t *ptep;
189
190 if (!(mm->context))
191 return;
192
193 pgdp = pgd_offset(mm, start);
194 pudp = pud_offset(pgdp, start);
195 pmdp = pmd_offset(pudp, start);
196 ptep = pte_offset(pmdp, start);
197
198 while (start <= end) {
199 unsigned long tmpend;
200 pgdp = pgd_offset(mm, start);
201 pudp = pud_offset(pgdp, start);
202 pmdp = pmd_offset(pudp, start);
203 ptep = pte_offset(pmdp, start);
204
205 if (!(pte_val(*ptep) & _PAGE_PRESENT)) {
206 start = (start + PAGE_SIZE) & ~(PAGE_SIZE - 1);
207 continue;
208 }
209 tmpend = (start | (PAGE_SIZE-1)) > end ?
210 end : (start | (PAGE_SIZE-1));
211
212 s7_flush_dcache_range(start, tmpend);
213 if (exec)
214 s7_flush_icache_range(start, tmpend);
215 start = (start + PAGE_SIZE) & ~(PAGE_SIZE - 1);
216 }
217}
218
219static void
220s7_flush_cache_page(struct vm_area_struct *vma,
221 unsigned long addr, unsigned long pfn)
222{
223 int exec = vma->vm_flags & VM_EXEC;
224 unsigned long kaddr = 0xa0000000 | (pfn << PAGE_SHIFT);
225
226 s7_flush_dcache_range(kaddr, kaddr + PAGE_SIZE);
227
228 if (exec)
229 s7_flush_icache_range(kaddr, kaddr + PAGE_SIZE);
230}
231
232static void s7_flush_cache_sigtramp(unsigned long addr)
233{
234 __asm__ __volatile__(
235 "cache 0x02, [%0, 0]\n"
236 "nop\nnop\nnop\nnop\nnop\n"
237 "cache 0x02, [%0, 0x4]\n"
238 "nop\nnop\nnop\nnop\nnop\n"
239
240 "cache 0x0d, [%0, 0]\n"
241 "nop\nnop\nnop\nnop\nnop\n"
242 "cache 0x0d, [%0, 0x4]\n"
243 "nop\nnop\nnop\nnop\nnop\n"
244
245 "cache 0x1a, [%0, 0]\n"
246 "nop\nnop\nnop\nnop\nnop\n"
247 : : "r" (addr));
248}
249
250/*
251Just flush entire Dcache!!
252You must ensure the page doesn't include instructions, because
253the function will not flush the Icache.
254The addr must be cache aligned.
255*/
256static void s7_flush_data_cache_page(unsigned long addr)
257{
258 unsigned int i;
259 for (i = 0; i < (PAGE_SIZE / L1_CACHE_BYTES); i += L1_CACHE_BYTES) {
260 __asm__ __volatile__(
261 "cache 0x0e, [%0, 0]\n"
262 "cache 0x1a, [%0, 0]\n"
263 "nop\n"
264 : : "r" (addr));
265 addr += L1_CACHE_BYTES;
266 }
267}
268
269/*
2701. WB and invalid a cache line of Dcache
2712. Drain Write Buffer
272the range must be smaller than PAGE_SIZE
273*/
274static void s7_flush_dcache_range(unsigned long start, unsigned long end)
275{
276 int size, i;
277
278 start = start & ~(L1_CACHE_BYTES - 1);
279 end = end & ~(L1_CACHE_BYTES - 1);
280 size = end - start;
281 /* flush dcache to ram, and invalidate dcache lines. */
282 for (i = 0; i < size; i += L1_CACHE_BYTES) {
283 __asm__ __volatile__(
284 "cache 0x0e, [%0, 0]\n"
285 "nop\nnop\nnop\nnop\nnop\n"
286 "cache 0x1a, [%0, 0]\n"
287 "nop\nnop\nnop\nnop\nnop\n"
288 : : "r" (start));
289 start += L1_CACHE_BYTES;
290 }
291}
292
293static void s7_flush_icache_range(unsigned long start, unsigned long end)
294{
295 int size, i;
296 start = start & ~(L1_CACHE_BYTES - 1);
297 end = end & ~(L1_CACHE_BYTES - 1);
298
299 size = end - start;
300 /* invalidate icache lines. */
301 for (i = 0; i < size; i += L1_CACHE_BYTES) {
302 __asm__ __volatile__(
303 "cache 0x02, [%0, 0]\n"
304 "nop\nnop\nnop\nnop\nnop\n"
305 : : "r" (start));
306 start += L1_CACHE_BYTES;
307 }
308}
diff --git a/arch/score/mm/extable.c b/arch/score/mm/extable.c
new file mode 100644
index 000000000000..01ff6445171c
--- /dev/null
+++ b/arch/score/mm/extable.c
@@ -0,0 +1,38 @@
1/*
2 * arch/score/mm/extable.c
3 *
4 * Score Processor version.
5 *
6 * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
7 * Lennox Wu <lennox.wu@sunplusct.com>
8 * Chen Liqin <liqin.chen@sunplusct.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see the file COPYING, or write
22 * to the Free Software Foundation, Inc.,
23 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26#include <linux/module.h>
27
28int fixup_exception(struct pt_regs *regs)
29{
30 const struct exception_table_entry *fixup;
31
32 fixup = search_exception_tables(regs->cp0_epc);
33 if (fixup) {
34 regs->cp0_epc = fixup->fixup;
35 return 1;
36 }
37 return 0;
38}
diff --git a/arch/score/mm/fault.c b/arch/score/mm/fault.c
new file mode 100644
index 000000000000..47b600e4b2c5
--- /dev/null
+++ b/arch/score/mm/fault.c
@@ -0,0 +1,235 @@
1/*
2 * arch/score/mm/fault.c
3 *
4 * Score Processor version.
5 *
6 * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
7 * Lennox Wu <lennox.wu@sunplusct.com>
8 * Chen Liqin <liqin.chen@sunplusct.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see the file COPYING, or write
22 * to the Free Software Foundation, Inc.,
23 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26#include <linux/errno.h>
27#include <linux/interrupt.h>
28#include <linux/kernel.h>
29#include <linux/mm.h>
30#include <linux/mman.h>
31#include <linux/module.h>
32#include <linux/signal.h>
33#include <linux/sched.h>
34#include <linux/string.h>
35#include <linux/types.h>
36#include <linux/ptrace.h>
37
38/*
39 * This routine handles page faults. It determines the address,
40 * and the problem, and then passes it off to one of the appropriate
41 * routines.
42 */
43asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write,
44 unsigned long address)
45{
46 struct vm_area_struct *vma = NULL;
47 struct task_struct *tsk = current;
48 struct mm_struct *mm = tsk->mm;
49 const int field = sizeof(unsigned long) * 2;
50 siginfo_t info;
51 int fault;
52
53 info.si_code = SEGV_MAPERR;
54
55 /*
56 * We fault-in kernel-space virtual memory on-demand. The
57 * 'reference' page table is init_mm.pgd.
58 *
59 * NOTE! We MUST NOT take any locks for this case. We may
60 * be in an interrupt or a critical region, and should
61 * only copy the information from the master page table,
62 * nothing more.
63 */
64 if (unlikely(address >= VMALLOC_START && address <= VMALLOC_END))
65 goto vmalloc_fault;
66#ifdef MODULE_START
67 if (unlikely(address >= MODULE_START && address < MODULE_END))
68 goto vmalloc_fault;
69#endif
70
71 /*
72 * If we're in an interrupt or have no user
73 * context, we must not take the fault..
74 */
75 if (in_atomic() || !mm)
76 goto bad_area_nosemaphore;
77
78 down_read(&mm->mmap_sem);
79 vma = find_vma(mm, address);
80 if (!vma)
81 goto bad_area;
82 if (vma->vm_start <= address)
83 goto good_area;
84 if (!(vma->vm_flags & VM_GROWSDOWN))
85 goto bad_area;
86 if (expand_stack(vma, address))
87 goto bad_area;
88 /*
89 * Ok, we have a good vm_area for this memory access, so
90 * we can handle it..
91 */
92good_area:
93 info.si_code = SEGV_ACCERR;
94
95 if (write) {
96 if (!(vma->vm_flags & VM_WRITE))
97 goto bad_area;
98 } else {
99 if (!(vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC)))
100 goto bad_area;
101 }
102
103survive:
104 /*
105 * If for any reason at all we couldn't handle the fault,
106 * make sure we exit gracefully rather than endlessly redo
107 * the fault.
108 */
109 fault = handle_mm_fault(mm, vma, address, write);
110 if (unlikely(fault & VM_FAULT_ERROR)) {
111 if (fault & VM_FAULT_OOM)
112 goto out_of_memory;
113 else if (fault & VM_FAULT_SIGBUS)
114 goto do_sigbus;
115 BUG();
116 }
117 if (fault & VM_FAULT_MAJOR)
118 tsk->maj_flt++;
119 else
120 tsk->min_flt++;
121
122 up_read(&mm->mmap_sem);
123 return;
124
125 /*
126 * Something tried to access memory that isn't in our memory map..
127 * Fix it, but check if it's kernel or user first..
128 */
129bad_area:
130 up_read(&mm->mmap_sem);
131
132bad_area_nosemaphore:
133 /* User mode accesses just cause a SIGSEGV */
134 if (user_mode(regs)) {
135 tsk->thread.cp0_badvaddr = address;
136 tsk->thread.error_code = write;
137 info.si_signo = SIGSEGV;
138 info.si_errno = 0;
139 /* info.si_code has been set above */
140 info.si_addr = (void __user *) address;
141 force_sig_info(SIGSEGV, &info, tsk);
142 return;
143 }
144
145no_context:
146 /* Are we prepared to handle this kernel fault? */
147 if (fixup_exception(regs)) {
148 current->thread.cp0_baduaddr = address;
149 return;
150 }
151
152 /*
153 * Oops. The kernel tried to access some bad page. We'll have to
154 * terminate things with extreme prejudice.
155 */
156 bust_spinlocks(1);
157
158 printk(KERN_ALERT "CPU %d Unable to handle kernel paging request at "
159 "virtual address %0*lx, epc == %0*lx, ra == %0*lx\n",
160 0, field, address, field, regs->cp0_epc,
161 field, regs->regs[3]);
162 die("Oops", regs);
163
164 /*
165 * We ran out of memory, or some other thing happened to us that made
166 * us unable to handle the page fault gracefully.
167 */
168out_of_memory:
169 up_read(&mm->mmap_sem);
170 if (is_global_init(tsk)) {
171 yield();
172 down_read(&mm->mmap_sem);
173 goto survive;
174 }
175 printk("VM: killing process %s\n", tsk->comm);
176 if (user_mode(regs))
177 do_group_exit(SIGKILL);
178 goto no_context;
179
180do_sigbus:
181 up_read(&mm->mmap_sem);
182 /* Kernel mode? Handle exceptions or die */
183 if (!user_mode(regs))
184 goto no_context;
185 else
186 /*
187 * Send a sigbus, regardless of whether we were in kernel
188 * or user mode.
189 */
190 tsk->thread.cp0_badvaddr = address;
191 info.si_signo = SIGBUS;
192 info.si_errno = 0;
193 info.si_code = BUS_ADRERR;
194 info.si_addr = (void __user *) address;
195 force_sig_info(SIGBUS, &info, tsk);
196 return;
197vmalloc_fault:
198 {
199 /*
200 * Synchronize this task's top level page-table
201 * with the 'reference' page table.
202 *
203 * Do _not_ use "tsk" here. We might be inside
204 * an interrupt in the middle of a task switch..
205 */
206 int offset = __pgd_offset(address);
207 pgd_t *pgd, *pgd_k;
208 pud_t *pud, *pud_k;
209 pmd_t *pmd, *pmd_k;
210 pte_t *pte_k;
211
212 pgd = (pgd_t *) pgd_current + offset;
213 pgd_k = init_mm.pgd + offset;
214
215 if (!pgd_present(*pgd_k))
216 goto no_context;
217 set_pgd(pgd, *pgd_k);
218
219 pud = pud_offset(pgd, address);
220 pud_k = pud_offset(pgd_k, address);
221 if (!pud_present(*pud_k))
222 goto no_context;
223
224 pmd = pmd_offset(pud, address);
225 pmd_k = pmd_offset(pud_k, address);
226 if (!pmd_present(*pmd_k))
227 goto no_context;
228 set_pmd(pmd, *pmd_k);
229
230 pte_k = pte_offset_kernel(pmd_k, address);
231 if (!pte_present(*pte_k))
232 goto no_context;
233 return;
234 }
235}
diff --git a/arch/score/mm/init.c b/arch/score/mm/init.c
new file mode 100644
index 000000000000..7780eecc5a43
--- /dev/null
+++ b/arch/score/mm/init.c
@@ -0,0 +1,173 @@
1/*
2 * arch/score/mm/init.c
3 *
4 * Score Processor version.
5 *
6 * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
7 * Lennox Wu <lennox.wu@sunplusct.com>
8 * Chen Liqin <liqin.chen@sunplusct.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see the file COPYING, or write
22 * to the Free Software Foundation, Inc.,
23 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26#include <linux/errno.h>
27#include <linux/bootmem.h>
28#include <linux/kernel.h>
29#include <linux/init.h>
30#include <linux/mm.h>
31#include <linux/mman.h>
32#include <linux/pagemap.h>
33#include <linux/proc_fs.h>
34#include <linux/sched.h>
35#include <asm-generic/sections.h>
36
37#include <asm/tlb.h>
38
39DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
40
41/*
42 * We have up to 8 empty zeroed pages so we can map one of the right colour
43 * when needed.
44 */
45unsigned long zero_page_mask;
46unsigned long empty_zero_page;
47EXPORT_SYMBOL_GPL(empty_zero_page);
48
49static struct kcore_list kcore_mem, kcore_vmalloc;
50
51unsigned long setup_zero_pages(void)
52{
53 unsigned int order = 0;
54 unsigned long size;
55 struct page *page;
56
57 empty_zero_page = __get_free_pages(GFP_KERNEL | __GFP_ZERO, order);
58 if (!empty_zero_page)
59 panic("Oh boy, that early out of memory?");
60
61 page = virt_to_page((void *) empty_zero_page);
62 split_page(page, order);
63 while (page < virt_to_page((void *) (empty_zero_page +
64 (PAGE_SIZE << order)))) {
65 SetPageReserved(page);
66 page++;
67 }
68
69 size = PAGE_SIZE << order;
70 zero_page_mask = (size - 1) & PAGE_MASK;
71
72 return 1UL << order;
73}
74
75#ifndef CONFIG_NEED_MULTIPLE_NODES
76static int __init page_is_ram(unsigned long pagenr)
77{
78 if (pagenr >= min_low_pfn && pagenr < max_low_pfn)
79 return 1;
80 else
81 return 0;
82}
83
84void __init paging_init(void)
85{
86 unsigned long max_zone_pfns[MAX_NR_ZONES];
87 unsigned long lastpfn;
88
89 pagetable_init();
90 max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
91 lastpfn = max_low_pfn;
92 free_area_init_nodes(max_zone_pfns);
93}
94
95void __init mem_init(void)
96{
97 unsigned long codesize, reservedpages, datasize, initsize;
98 unsigned long tmp, ram = 0;
99
100 max_mapnr = max_low_pfn;
101 high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT);
102 totalram_pages += free_all_bootmem();
103 totalram_pages -= setup_zero_pages(); /* Setup zeroed pages. */
104 reservedpages = 0;
105
106 for (tmp = 0; tmp < max_low_pfn; tmp++)
107 if (page_is_ram(tmp)) {
108 ram++;
109 if (PageReserved(pfn_to_page(tmp)))
110 reservedpages++;
111 }
112
113 num_physpages = ram;
114 codesize = (unsigned long) &_etext - (unsigned long) &_text;
115 datasize = (unsigned long) &_edata - (unsigned long) &_etext;
116 initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
117
118 kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT);
119 kclist_add(&kcore_vmalloc, (void *) VMALLOC_START,
120 VMALLOC_END - VMALLOC_START);
121
122 printk(KERN_INFO "Memory: %luk/%luk available (%ldk kernel code, "
123 "%ldk reserved, %ldk data, %ldk init, %ldk highmem)\n",
124 (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
125 ram << (PAGE_SHIFT-10), codesize >> 10,
126 reservedpages << (PAGE_SHIFT-10), datasize >> 10,
127 initsize >> 10,
128 (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10)));
129}
130#endif /* !CONFIG_NEED_MULTIPLE_NODES */
131
132void free_init_pages(const char *what, unsigned long begin, unsigned long end)
133{
134 unsigned long pfn;
135
136 for (pfn = PFN_UP(begin); pfn < PFN_DOWN(end); pfn++) {
137 struct page *page = pfn_to_page(pfn);
138 void *addr = phys_to_virt(PFN_PHYS(pfn));
139
140 ClearPageReserved(page);
141 init_page_count(page);
142 memset(addr, POISON_FREE_INITMEM, PAGE_SIZE);
143 __free_page(page);
144 totalram_pages++;
145 }
146 printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10);
147}
148
149#ifdef CONFIG_BLK_DEV_INITRD
150void free_initrd_mem(unsigned long start, unsigned long end)
151{
152 free_init_pages("initrd memory",
153 virt_to_phys((void *) start),
154 virt_to_phys((void *) end));
155}
156#endif
157
158void __init_refok free_initmem(void)
159{
160 free_init_pages("unused kernel memory",
161 (unsigned long)__init_begin, (unsigned long)__init_end);
162}
163
164unsigned long pgd_current;
165
166#define __page_aligned(order) __attribute__((__aligned__(PAGE_SIZE<<order)))
167
168/*
169 * gcc 3.3 and older have trouble determining that PTRS_PER_PGD and PGD_ORDER
170 * are constants. So we use the variants from asm-offset.h until that gcc
171 * will officially be retired.
172 */
173pte_t invalid_pte_table[PTRS_PER_PTE] __page_aligned(PTE_ORDER);
diff --git a/arch/score/mm/pgtable.c b/arch/score/mm/pgtable.c
new file mode 100644
index 000000000000..10b0962f83d4
--- /dev/null
+++ b/arch/score/mm/pgtable.c
@@ -0,0 +1,60 @@
1/*
2 * arch/score/mm/pgtable-32.c
3 *
4 * Score Processor version.
5 *
6 * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
7 * Lennox Wu <lennox.wu@sunplusct.com>
8 * Chen Liqin <liqin.chen@sunplusct.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see the file COPYING, or write
22 * to the Free Software Foundation, Inc.,
23 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26#include <linux/bootmem.h>
27#include <linux/init.h>
28#include <linux/pfn.h>
29#include <linux/mm.h>
30
31void pgd_init(unsigned long page)
32{
33 unsigned long *p = (unsigned long *) page;
34 int i;
35
36 for (i = 0; i < USER_PTRS_PER_PGD; i += 8) {
37 p[i + 0] = (unsigned long) invalid_pte_table;
38 p[i + 1] = (unsigned long) invalid_pte_table;
39 p[i + 2] = (unsigned long) invalid_pte_table;
40 p[i + 3] = (unsigned long) invalid_pte_table;
41 p[i + 4] = (unsigned long) invalid_pte_table;
42 p[i + 5] = (unsigned long) invalid_pte_table;
43 p[i + 6] = (unsigned long) invalid_pte_table;
44 p[i + 7] = (unsigned long) invalid_pte_table;
45 }
46}
47
48void __init pagetable_init(void)
49{
50 unsigned long vaddr;
51 pgd_t *pgd_base;
52
53 /* Initialize the entire pgd. */
54 pgd_init((unsigned long) swapper_pg_dir);
55 pgd_init((unsigned long) swapper_pg_dir
56 + sizeof(pgd_t) * USER_PTRS_PER_PGD);
57
58 pgd_base = swapper_pg_dir;
59 vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
60}
diff --git a/arch/score/mm/tlb-miss.S b/arch/score/mm/tlb-miss.S
new file mode 100644
index 000000000000..f27651914e8d
--- /dev/null
+++ b/arch/score/mm/tlb-miss.S
@@ -0,0 +1,199 @@
1/*
2 * arch/score/mm/tlbex.S
3 *
4 * Score Processor version.
5 *
6 * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
7 * Lennox Wu <lennox.wu@sunplusct.com>
8 * Chen Liqin <liqin.chen@sunplusct.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see the file COPYING, or write
22 * to the Free Software Foundation, Inc.,
23 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26#include <asm/asmmacro.h>
27#include <asm/pgtable-bits.h>
28#include <asm/scoreregs.h>
29
30/*
31* After this macro runs, the pte faulted on is
32* in register PTE, a ptr into the table in which
33* the pte belongs is in PTR.
34*/
35 .macro load_pte, pte, ptr
36 la \ptr, pgd_current
37 lw \ptr, [\ptr, 0]
38 mfcr \pte, cr6
39 srli \pte, \pte, 22
40 slli \pte, \pte, 2
41 add \ptr, \ptr, \pte
42 lw \ptr, [\ptr, 0]
43 mfcr \pte, cr6
44 srli \pte, \pte, 10
45 andi \pte, 0xffc
46 add \ptr, \ptr, \pte
47 lw \pte, [\ptr, 0]
48 .endm
49
50 .macro pte_reload, ptr
51 lw \ptr, [\ptr, 0]
52 mtcr \ptr, cr12
53 nop
54 nop
55 nop
56 nop
57 nop
58 .endm
59
60 .macro do_fault, write
61 SAVE_ALL
62 mfcr r6, cr6
63 mv r4, r0
64 ldi r5, \write
65 la r8, do_page_fault
66 brl r8
67 j ret_from_exception
68 .endm
69
70 .macro pte_writable, pte, ptr, label
71 andi \pte, 0x280
72 cmpi.c \pte, 0x280
73 bne \label
74 lw \pte, [\ptr, 0] /*reload PTE*/
75 .endm
76
77/*
78 * Make PTE writable, update software status bits as well,
79 * then store at PTR.
80 */
81 .macro pte_makewrite, pte, ptr
82 ori \pte, 0x426
83 sw \pte, [\ptr, 0]
84 .endm
85
86 .text
87ENTRY(score7_FTLB_refill_Handler)
88 la r31, pgd_current /* get pgd pointer */
89 lw r31, [r31, 0] /* get the address of PGD */
90 mfcr r30, cr6
91 srli r30, r30, 22 /* PGDIR_SHIFT = 22*/
92 slli r30, r30, 2
93 add r31, r31, r30
94 lw r31, [r31, 0] /* get the address of the start address of PTE table */
95
96 mfcr r30, cr9
97 andi r30, 0xfff /* equivalent to get PET index and right shift 2 bits */
98 add r31, r31, r30
99 lw r30, [r31, 0] /* load pte entry */
100 mtcr r30, cr12
101 nop
102 nop
103 nop
104 nop
105 nop
106 mtrtlb
107 nop
108 nop
109 nop
110 nop
111 nop
112 rte /* 6 cycles to make sure tlb entry works */
113
114ENTRY(score7_KSEG_refill_Handler)
115 la r31, pgd_current /* get pgd pointer */
116 lw r31, [r31, 0] /* get the address of PGD */
117 mfcr r30, cr6
118 srli r30, r30, 22 /* PGDIR_SHIFT = 22 */
119 slli r30, r30, 2
120 add r31, r31, r30
121 lw r31, [r31, 0] /* get the address of the start address of PTE table */
122
123 mfcr r30, cr6 /* get Bad VPN */
124 srli r30, r30, 10
125 andi r30, 0xffc /* PTE VPN mask (bit 11~2) */
126
127 add r31, r31, r30
128 lw r30, [r31, 0] /* load pte entry */
129 mtcr r30, cr12
130 nop
131 nop
132 nop
133 nop
134 nop
135 mtrtlb
136 nop
137 nop
138 nop
139 nop
140 nop
141 rte /* 6 cycles to make sure tlb entry works */
142
143nopage_tlbl:
144 do_fault 0 /* Read */
145
146ENTRY(handle_tlb_refill)
147 load_pte r30, r31
148 pte_writable r30, r31, handle_tlb_refill_nopage
149 pte_makewrite r30, r31 /* Access|Modify|Dirty|Valid */
150 pte_reload r31
151 mtrtlb
152 nop
153 nop
154 nop
155 nop
156 nop
157 rte
158handle_tlb_refill_nopage:
159 do_fault 0 /* Read */
160
161ENTRY(handle_tlb_invaild)
162 load_pte r30, r31
163 stlb /* find faulting entry */
164 pte_writable r30, r31, handle_tlb_invaild_nopage
165 pte_makewrite r30, r31 /* Access|Modify|Dirty|Valid */
166 pte_reload r31
167 mtptlb
168 nop
169 nop
170 nop
171 nop
172 nop
173 rte
174handle_tlb_invaild_nopage:
175 do_fault 0 /* Read */
176
177ENTRY(handle_mod)
178 load_pte r30, r31
179 stlb /* find faulting entry */
180 andi r30, _PAGE_WRITE /* Writable? */
181 cmpz.c r30
182 beq nowrite_mod
183 lw r30, [r31, 0] /* reload into r30 */
184
185 /* Present and writable bits set, set accessed and dirty bits. */
186 pte_makewrite r30, r31
187
188 /* Now reload the entry into the tlb. */
189 pte_reload r31
190 mtptlb
191 nop
192 nop
193 nop
194 nop
195 nop
196 rte
197
198nowrite_mod:
199 do_fault 1 /* Write */
diff --git a/arch/score/mm/tlb-score.c b/arch/score/mm/tlb-score.c
new file mode 100644
index 000000000000..4fa5aa5afecc
--- /dev/null
+++ b/arch/score/mm/tlb-score.c
@@ -0,0 +1,251 @@
1/*
2 * arch/score/mm/tlb-score.c
3 *
4 * Score Processor version.
5 *
6 * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
7 * Lennox Wu <lennox.wu@sunplusct.com>
8 * Chen Liqin <liqin.chen@sunplusct.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see the file COPYING, or write
22 * to the Free Software Foundation, Inc.,
23 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26#include <linux/highmem.h>
27#include <linux/module.h>
28
29#include <asm/irq.h>
30#include <asm/mmu_context.h>
31#include <asm/tlb.h>
32
33#define TLBSIZE 32
34
35unsigned long asid_cache = ASID_FIRST_VERSION;
36EXPORT_SYMBOL(asid_cache);
37
38void local_flush_tlb_all(void)
39{
40 unsigned long flags;
41 unsigned long old_ASID;
42 int entry;
43
44 local_irq_save(flags);
45 old_ASID = pevn_get() & ASID_MASK;
46 pectx_set(0); /* invalid */
47 entry = tlblock_get(); /* skip locked entries*/
48
49 for (; entry < TLBSIZE; entry++) {
50 tlbpt_set(entry);
51 pevn_set(KSEG1);
52 barrier();
53 tlb_write_indexed();
54 }
55 pevn_set(old_ASID);
56 local_irq_restore(flags);
57}
58
59/*
60 * If mm is currently active_mm, we can't really drop it. Instead,
61 * we will get a new one for it.
62 */
63static inline void
64drop_mmu_context(struct mm_struct *mm)
65{
66 unsigned long flags;
67
68 local_irq_save(flags);
69 get_new_mmu_context(mm);
70 pevn_set(mm->context & ASID_MASK);
71 local_irq_restore(flags);
72}
73
74void local_flush_tlb_mm(struct mm_struct *mm)
75{
76 if (mm->context != 0)
77 drop_mmu_context(mm);
78}
79
80void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
81 unsigned long end)
82{
83 struct mm_struct *mm = vma->vm_mm;
84 unsigned long vma_mm_context = mm->context;
85 if (mm->context != 0) {
86 unsigned long flags;
87 int size;
88
89 local_irq_save(flags);
90 size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
91 if (size <= TLBSIZE) {
92 int oldpid = pevn_get() & ASID_MASK;
93 int newpid = vma_mm_context & ASID_MASK;
94
95 start &= PAGE_MASK;
96 end += (PAGE_SIZE - 1);
97 end &= PAGE_MASK;
98 while (start < end) {
99 int idx;
100
101 pevn_set(start | newpid);
102 start += PAGE_SIZE;
103 barrier();
104 tlb_probe();
105 idx = tlbpt_get();
106 pectx_set(0);
107 pevn_set(KSEG1);
108 if (idx < 0)
109 continue;
110 tlb_write_indexed();
111 }
112 pevn_set(oldpid);
113 } else {
114 /* Bigger than TLBSIZE, get new ASID directly */
115 get_new_mmu_context(mm);
116 if (mm == current->active_mm)
117 pevn_set(vma_mm_context & ASID_MASK);
118 }
119 local_irq_restore(flags);
120 }
121}
122
123void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
124{
125 unsigned long flags;
126 int size;
127
128 local_irq_save(flags);
129 size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
130 if (size <= TLBSIZE) {
131 int pid = pevn_get();
132
133 start &= PAGE_MASK;
134 end += PAGE_SIZE - 1;
135 end &= PAGE_MASK;
136
137 while (start < end) {
138 long idx;
139
140 pevn_set(start);
141 start += PAGE_SIZE;
142 tlb_probe();
143 idx = tlbpt_get();
144 if (idx < 0)
145 continue;
146 pectx_set(0);
147 pevn_set(KSEG1);
148 barrier();
149 tlb_write_indexed();
150 }
151 pevn_set(pid);
152 } else {
153 local_flush_tlb_all();
154 }
155
156 local_irq_restore(flags);
157}
158
159void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
160{
161 if (!vma || vma->vm_mm->context != 0) {
162 unsigned long flags;
163 int oldpid, newpid, idx;
164 unsigned long vma_ASID = vma->vm_mm->context;
165
166 newpid = vma_ASID & ASID_MASK;
167 page &= PAGE_MASK;
168 local_irq_save(flags);
169 oldpid = pevn_get() & ASID_MASK;
170 pevn_set(page | newpid);
171 barrier();
172 tlb_probe();
173 idx = tlbpt_get();
174 pectx_set(0);
175 pevn_set(KSEG1);
176 if (idx < 0) /* p_bit(31) - 1: miss, 0: hit*/
177 goto finish;
178 barrier();
179 tlb_write_indexed();
180finish:
181 pevn_set(oldpid);
182 local_irq_restore(flags);
183 }
184}
185
186/*
187 * This one is only used for pages with the global bit set so we don't care
188 * much about the ASID.
189 */
190void local_flush_tlb_one(unsigned long page)
191{
192 unsigned long flags;
193 int oldpid, idx;
194
195 local_irq_save(flags);
196 oldpid = pevn_get();
197 page &= (PAGE_MASK << 1);
198 pevn_set(page);
199 barrier();
200 tlb_probe();
201 idx = tlbpt_get();
202 pectx_set(0);
203 if (idx >= 0) {
204 /* Make sure all entries differ. */
205 pevn_set(KSEG1);
206 barrier();
207 tlb_write_indexed();
208 }
209 pevn_set(oldpid);
210 local_irq_restore(flags);
211}
212
213void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte)
214{
215 unsigned long flags;
216 int idx, pid;
217
218 /*
219 * Handle debugger faulting in for debugee.
220 */
221 if (current->active_mm != vma->vm_mm)
222 return;
223
224 pid = pevn_get() & ASID_MASK;
225
226 local_irq_save(flags);
227 address &= PAGE_MASK;
228 pevn_set(address | pid);
229 barrier();
230 tlb_probe();
231 idx = tlbpt_get();
232 pectx_set(pte_val(pte));
233 pevn_set(address | pid);
234 if (idx < 0)
235 tlb_write_random();
236 else
237 tlb_write_indexed();
238
239 pevn_set(pid);
240 local_irq_restore(flags);
241}
242
243void __cpuinit tlb_init(void)
244{
245 tlblock_set(0);
246 local_flush_tlb_all();
247 memcpy((void *)(EXCEPTION_VECTOR_BASE_ADDR + 0x100),
248 &score7_FTLB_refill_Handler, 0xFC);
249 flush_icache_range(EXCEPTION_VECTOR_BASE_ADDR + 0x100,
250 EXCEPTION_VECTOR_BASE_ADDR + 0x1FC);
251}