diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-04-13 18:02:16 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-04-13 18:02:22 -0400 |
commit | b5c851a88a369854c04e511cefb84ea2d0cfa209 (patch) | |
tree | 55084d3d51708f90f27d0a70db5ab63916942f14 /arch/microblaze | |
parent | eb02ce017dd83985041a7e54c6449f92d53b026f (diff) | |
parent | 80a04d3f2f94fb68b5df05e3ac6697130bc3467a (diff) |
Merge branch 'linus' into tracing/core
Merge reason: merge latest tracing fixes to avoid conflicts in
kernel/trace/trace_events_filter.c with upcoming change
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/microblaze')
157 files changed, 15708 insertions, 0 deletions
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig new file mode 100644 index 000000000000..8cc312b5d4dc --- /dev/null +++ b/arch/microblaze/Kconfig | |||
@@ -0,0 +1,141 @@ | |||
1 | # For a description of the syntax of this configuration file, | ||
2 | # see Documentation/kbuild/kconfig-language.txt. | ||
3 | |||
4 | mainmenu "Linux/Microblaze Kernel Configuration" | ||
5 | |||
6 | config MICROBLAZE | ||
7 | def_bool y | ||
8 | select HAVE_LMB | ||
9 | |||
10 | config SWAP | ||
11 | def_bool n | ||
12 | |||
13 | config RWSEM_GENERIC_SPINLOCK | ||
14 | def_bool y | ||
15 | |||
16 | config RWSEM_XCHGADD_ALGORITHM | ||
17 | bool | ||
18 | |||
19 | config ARCH_HAS_ILOG2_U32 | ||
20 | def_bool n | ||
21 | |||
22 | config ARCH_HAS_ILOG2_U64 | ||
23 | def_bool n | ||
24 | |||
25 | config GENERIC_FIND_NEXT_BIT | ||
26 | def_bool y | ||
27 | |||
28 | config GENERIC_HWEIGHT | ||
29 | def_bool y | ||
30 | |||
31 | config GENERIC_HARDIRQS | ||
32 | def_bool y | ||
33 | |||
34 | config GENERIC_IRQ_PROBE | ||
35 | def_bool y | ||
36 | |||
37 | config GENERIC_CALIBRATE_DELAY | ||
38 | def_bool y | ||
39 | |||
40 | config GENERIC_TIME | ||
41 | def_bool y | ||
42 | |||
43 | config GENERIC_TIME_VSYSCALL | ||
44 | def_bool n | ||
45 | |||
46 | config GENERIC_CLOCKEVENTS | ||
47 | def_bool y | ||
48 | |||
49 | config GENERIC_HARDIRQS_NO__DO_IRQ | ||
50 | def_bool y | ||
51 | |||
52 | config PCI | ||
53 | depends on !MMU | ||
54 | def_bool n | ||
55 | |||
56 | config NO_DMA | ||
57 | depends on !MMU | ||
58 | def_bool n | ||
59 | |||
60 | source "init/Kconfig" | ||
61 | |||
62 | source "kernel/Kconfig.freezer" | ||
63 | |||
64 | source "arch/microblaze/platform/Kconfig.platform" | ||
65 | |||
66 | menu "Processor type and features" | ||
67 | |||
68 | source kernel/time/Kconfig | ||
69 | |||
70 | source "kernel/Kconfig.preempt" | ||
71 | |||
72 | source "kernel/Kconfig.hz" | ||
73 | |||
74 | config MMU | ||
75 | def_bool n | ||
76 | |||
77 | config NO_MMU | ||
78 | bool | ||
79 | depends on !MMU | ||
80 | default y | ||
81 | |||
82 | comment "Boot options" | ||
83 | |||
84 | config CMDLINE_BOOL | ||
85 | bool "Default bootloader kernel arguments" | ||
86 | |||
87 | config CMDLINE | ||
88 | string "Default kernel command string" | ||
89 | depends on CMDLINE_BOOL | ||
90 | default "console=ttyUL0,115200" | ||
91 | help | ||
92 | On some architectures there is currently no way for the boot loader | ||
93 | to pass arguments to the kernel. For these architectures, you should | ||
94 | supply some command-line options at build time by entering them | ||
95 | here. | ||
96 | |||
97 | config CMDLINE_FORCE | ||
98 | bool "Force default kernel command string" | ||
99 | depends on CMDLINE_BOOL | ||
100 | default n | ||
101 | help | ||
102 | Set this to have arguments from the default kernel command string | ||
103 | override those passed by the boot loader. | ||
104 | |||
105 | config OF | ||
106 | def_bool y | ||
107 | |||
108 | config OF_DEVICE | ||
109 | def_bool y | ||
110 | |||
111 | config PROC_DEVICETREE | ||
112 | bool "Support for device tree in /proc" | ||
113 | depends on PROC_FS | ||
114 | help | ||
115 | This option adds a device-tree directory under /proc which contains | ||
116 | an image of the device tree that the kernel copies from Open | ||
117 | Firmware or other boot firmware. If unsure, say Y here. | ||
118 | |||
119 | endmenu | ||
120 | |||
121 | source "mm/Kconfig" | ||
122 | |||
123 | menu "Exectuable file formats" | ||
124 | |||
125 | source "fs/Kconfig.binfmt" | ||
126 | |||
127 | endmenu | ||
128 | |||
129 | source "net/Kconfig" | ||
130 | |||
131 | source "drivers/Kconfig" | ||
132 | |||
133 | source "fs/Kconfig" | ||
134 | |||
135 | source "arch/microblaze/Kconfig.debug" | ||
136 | |||
137 | source "security/Kconfig" | ||
138 | |||
139 | source "crypto/Kconfig" | ||
140 | |||
141 | source "lib/Kconfig" | ||
diff --git a/arch/microblaze/Kconfig.debug b/arch/microblaze/Kconfig.debug new file mode 100644 index 000000000000..242cd35bdb4b --- /dev/null +++ b/arch/microblaze/Kconfig.debug | |||
@@ -0,0 +1,26 @@ | |||
1 | # For a description of the syntax of this configuration file, | ||
2 | # see Documentation/kbuild/kconfig-language.txt. | ||
3 | |||
4 | menu "Kernel hacking" | ||
5 | |||
6 | source "lib/Kconfig.debug" | ||
7 | |||
8 | config EARLY_PRINTK | ||
9 | bool "Early printk function for kernel" | ||
10 | default n | ||
11 | help | ||
12 | This option turns on/off early printk messages to console. | ||
13 | First Uartlite node is taken. | ||
14 | |||
15 | config HEART_BEAT | ||
16 | bool "Heart beat function for kernel" | ||
17 | default n | ||
18 | help | ||
19 | This option turns on/off heart beat kernel functionality. | ||
20 | First GPIO node is taken. | ||
21 | |||
22 | config DEBUG_BOOTMEM | ||
23 | depends on DEBUG_KERNEL | ||
24 | bool "Debug BOOTMEM initialization" | ||
25 | |||
26 | endmenu | ||
diff --git a/arch/microblaze/Makefile b/arch/microblaze/Makefile new file mode 100644 index 000000000000..0dcbb9832974 --- /dev/null +++ b/arch/microblaze/Makefile | |||
@@ -0,0 +1,69 @@ | |||
1 | UTS_SYSNAME = -DUTS_SYSNAME=\"uClinux\" | ||
2 | |||
3 | # What CPU vesion are we building for, and crack it open | ||
4 | # as major.minor.rev | ||
5 | CPU_VER=$(subst ",,$(CONFIG_XILINX_MICROBLAZE0_HW_VER) ) | ||
6 | CPU_MAJOR=$(shell echo $(CPU_VER) | cut -d '.' -f 1) | ||
7 | CPU_MINOR=$(shell echo $(CPU_VER) | cut -d '.' -f 2) | ||
8 | CPU_REV=$(shell echo $(CPU_VER) | cut -d '.' -f 3) | ||
9 | |||
10 | export CPU_VER CPU_MAJOR CPU_MINOR CPU_REV | ||
11 | |||
12 | # Use cpu-related CONFIG_ vars to set compile options. | ||
13 | |||
14 | # Work out HW multipler support. This is icky. | ||
15 | # 1. Spartan2 has no HW multiplers. | ||
16 | # 2. MicroBlaze v3.x always uses them, except in Spartan 2 | ||
17 | # 3. All other FPGa/CPU ver combos, we can trust the CONFIG_ settings | ||
18 | ifeq (,$(findstring spartan2,$(CONFIG_XILINX_MICROBLAZE0_FAMILY))) | ||
19 | ifeq ($(CPU_MAJOR),3) | ||
20 | CPUFLAGS-1 += -mno-xl-soft-mul | ||
21 | else | ||
22 | # USE_HW_MUL can be 0, 1, or 2, defining a heirarchy of HW Mul support. | ||
23 | CPUFLAGS-$(subst 1,,$(CONFIG_XILINX_MICROBLAZE0_USE_HW_MUL)) += -mxl-multiply-high | ||
24 | CPUFLAGS-$(CONFIG_XILINX_MICROBLAZE0_USE_HW_MUL) += -mno-xl-soft-mul | ||
25 | endif | ||
26 | endif | ||
27 | CPUFLAGS-$(CONFIG_XILINX_MICROBLAZE0_USE_DIV) += -mno-xl-soft-div | ||
28 | CPUFLAGS-$(CONFIG_XILINX_MICROBLAZE0_USE_BARREL) += -mxl-barrel-shift | ||
29 | CPUFLAGS-$(CONFIG_XILINX_MICROBLAZE0_USE_PCMP) += -mxl-pattern-compare | ||
30 | |||
31 | CPUFLAGS-1 += $(call cc-option,-mcpu=v$(CPU_VER)) | ||
32 | |||
33 | # The various CONFIG_XILINX cpu features options are integers 0/1/2... | ||
34 | # rather than bools y/n | ||
35 | CFLAGS += $(CPUFLAGS-1) | ||
36 | CFLAGS += $(CPUFLAGS-2) | ||
37 | |||
38 | # r31 holds current when in kernel mode | ||
39 | CFLAGS += -ffixed-r31 | ||
40 | |||
41 | LDFLAGS_BLOB := --format binary --oformat elf32-microblaze | ||
42 | |||
43 | LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) | ||
44 | |||
45 | head-y := arch/microblaze/kernel/head.o | ||
46 | libs-y += arch/microblaze/lib/ $(LIBGCC) | ||
47 | core-y += arch/microblaze/kernel/ arch/microblaze/mm/ \ | ||
48 | arch/microblaze/platform/ | ||
49 | |||
50 | boot := arch/$(ARCH)/boot | ||
51 | |||
52 | # defines filename extension depending memory management type | ||
53 | ifeq ($(CONFIG_MMU),) | ||
54 | MMUEXT := -nommu | ||
55 | endif | ||
56 | export MMUEXT | ||
57 | |||
58 | all: linux.bin | ||
59 | |||
60 | archclean: | ||
61 | $(Q)$(MAKE) $(clean)=$(boot) | ||
62 | |||
63 | linux.bin linux.bin.gz: vmlinux | ||
64 | $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ | ||
65 | |||
66 | define archhelp | ||
67 | echo '* linux.bin - Create raw binary' | ||
68 | echo ' linux.bin.gz - Create compressed raw binary' | ||
69 | endef | ||
diff --git a/arch/microblaze/boot/Makefile b/arch/microblaze/boot/Makefile new file mode 100644 index 000000000000..844edf406d34 --- /dev/null +++ b/arch/microblaze/boot/Makefile | |||
@@ -0,0 +1,17 @@ | |||
1 | # | ||
2 | # arch/microblaze/boot/Makefile | ||
3 | # | ||
4 | |||
5 | targets := linux.bin linux.bin.gz | ||
6 | |||
7 | OBJCOPYFLAGS_linux.bin := -O binary | ||
8 | |||
9 | $(obj)/linux.bin: vmlinux FORCE | ||
10 | $(call if_changed,objcopy) | ||
11 | @echo 'Kernel: $@ is ready' ' (#'`cat .version`')' | ||
12 | |||
13 | $(obj)/linux.bin.gz: $(obj)/linux.bin FORCE | ||
14 | $(call if_changed,gzip) | ||
15 | @echo 'Kernel: $@ is ready' ' (#'`cat .version`')' | ||
16 | |||
17 | clean-kernel += linux.bin linux.bin.gz | ||
diff --git a/arch/microblaze/configs/nommu_defconfig b/arch/microblaze/configs/nommu_defconfig new file mode 100644 index 000000000000..beb7ecd72793 --- /dev/null +++ b/arch/microblaze/configs/nommu_defconfig | |||
@@ -0,0 +1,804 @@ | |||
1 | # | ||
2 | # Automatically generated make config: don't edit | ||
3 | # Linux kernel version: 2.6.29 | ||
4 | # Tue Mar 24 10:23:20 2009 | ||
5 | # | ||
6 | CONFIG_MICROBLAZE=y | ||
7 | # CONFIG_SWAP is not set | ||
8 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | ||
9 | # CONFIG_ARCH_HAS_ILOG2_U32 is not set | ||
10 | # CONFIG_ARCH_HAS_ILOG2_U64 is not set | ||
11 | CONFIG_GENERIC_FIND_NEXT_BIT=y | ||
12 | CONFIG_GENERIC_HWEIGHT=y | ||
13 | CONFIG_GENERIC_HARDIRQS=y | ||
14 | CONFIG_GENERIC_IRQ_PROBE=y | ||
15 | CONFIG_GENERIC_CALIBRATE_DELAY=y | ||
16 | CONFIG_GENERIC_TIME=y | ||
17 | # CONFIG_GENERIC_TIME_VSYSCALL is not set | ||
18 | CONFIG_GENERIC_CLOCKEVENTS=y | ||
19 | CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y | ||
20 | # CONFIG_PCI is not set | ||
21 | # CONFIG_NO_DMA is not set | ||
22 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" | ||
23 | |||
24 | # | ||
25 | # General setup | ||
26 | # | ||
27 | CONFIG_EXPERIMENTAL=y | ||
28 | CONFIG_BROKEN_ON_SMP=y | ||
29 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
30 | CONFIG_LOCALVERSION="" | ||
31 | CONFIG_LOCALVERSION_AUTO=y | ||
32 | CONFIG_SYSVIPC=y | ||
33 | CONFIG_SYSVIPC_SYSCTL=y | ||
34 | CONFIG_POSIX_MQUEUE=y | ||
35 | CONFIG_BSD_PROCESS_ACCT=y | ||
36 | CONFIG_BSD_PROCESS_ACCT_V3=y | ||
37 | # CONFIG_TASKSTATS is not set | ||
38 | # CONFIG_AUDIT is not set | ||
39 | |||
40 | # | ||
41 | # RCU Subsystem | ||
42 | # | ||
43 | CONFIG_CLASSIC_RCU=y | ||
44 | # CONFIG_TREE_RCU is not set | ||
45 | # CONFIG_PREEMPT_RCU is not set | ||
46 | # CONFIG_TREE_RCU_TRACE is not set | ||
47 | # CONFIG_PREEMPT_RCU_TRACE is not set | ||
48 | CONFIG_IKCONFIG=y | ||
49 | CONFIG_IKCONFIG_PROC=y | ||
50 | CONFIG_LOG_BUF_SHIFT=17 | ||
51 | # CONFIG_GROUP_SCHED is not set | ||
52 | # CONFIG_CGROUPS is not set | ||
53 | CONFIG_SYSFS_DEPRECATED=y | ||
54 | CONFIG_SYSFS_DEPRECATED_V2=y | ||
55 | # CONFIG_RELAY is not set | ||
56 | # CONFIG_NAMESPACES is not set | ||
57 | # CONFIG_BLK_DEV_INITRD is not set | ||
58 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | ||
59 | CONFIG_SYSCTL=y | ||
60 | CONFIG_ANON_INODES=y | ||
61 | CONFIG_EMBEDDED=y | ||
62 | CONFIG_SYSCTL_SYSCALL=y | ||
63 | CONFIG_KALLSYMS=y | ||
64 | CONFIG_KALLSYMS_ALL=y | ||
65 | CONFIG_KALLSYMS_EXTRA_PASS=y | ||
66 | # CONFIG_HOTPLUG is not set | ||
67 | CONFIG_PRINTK=y | ||
68 | CONFIG_BUG=y | ||
69 | CONFIG_ELF_CORE=y | ||
70 | # CONFIG_BASE_FULL is not set | ||
71 | CONFIG_FUTEX=y | ||
72 | CONFIG_EPOLL=y | ||
73 | CONFIG_SIGNALFD=y | ||
74 | CONFIG_TIMERFD=y | ||
75 | CONFIG_EVENTFD=y | ||
76 | CONFIG_AIO=y | ||
77 | CONFIG_VM_EVENT_COUNTERS=y | ||
78 | CONFIG_COMPAT_BRK=y | ||
79 | CONFIG_SLAB=y | ||
80 | # CONFIG_SLUB is not set | ||
81 | # CONFIG_SLOB is not set | ||
82 | # CONFIG_PROFILING is not set | ||
83 | # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set | ||
84 | CONFIG_SLABINFO=y | ||
85 | CONFIG_RT_MUTEXES=y | ||
86 | CONFIG_BASE_SMALL=1 | ||
87 | CONFIG_MODULES=y | ||
88 | # CONFIG_MODULE_FORCE_LOAD is not set | ||
89 | CONFIG_MODULE_UNLOAD=y | ||
90 | # CONFIG_MODULE_FORCE_UNLOAD is not set | ||
91 | # CONFIG_MODVERSIONS is not set | ||
92 | # CONFIG_MODULE_SRCVERSION_ALL is not set | ||
93 | CONFIG_BLOCK=y | ||
94 | # CONFIG_LBD is not set | ||
95 | # CONFIG_BLK_DEV_IO_TRACE is not set | ||
96 | # CONFIG_BLK_DEV_BSG is not set | ||
97 | # CONFIG_BLK_DEV_INTEGRITY is not set | ||
98 | |||
99 | # | ||
100 | # IO Schedulers | ||
101 | # | ||
102 | CONFIG_IOSCHED_NOOP=y | ||
103 | CONFIG_IOSCHED_AS=y | ||
104 | CONFIG_IOSCHED_DEADLINE=y | ||
105 | CONFIG_IOSCHED_CFQ=y | ||
106 | # CONFIG_DEFAULT_AS is not set | ||
107 | # CONFIG_DEFAULT_DEADLINE is not set | ||
108 | CONFIG_DEFAULT_CFQ=y | ||
109 | # CONFIG_DEFAULT_NOOP is not set | ||
110 | CONFIG_DEFAULT_IOSCHED="cfq" | ||
111 | # CONFIG_FREEZER is not set | ||
112 | |||
113 | # | ||
114 | # Platform options | ||
115 | # | ||
116 | CONFIG_PLATFORM_GENERIC=y | ||
117 | # CONFIG_SELFMOD is not set | ||
118 | # CONFIG_OPT_LIB_FUNCTION is not set | ||
119 | # CONFIG_ALLOW_EDIT_AUTO is not set | ||
120 | CONFIG_KERNEL_BASE_ADDR=0x90000000 | ||
121 | CONFIG_XILINX_MICROBLAZE0_FAMILY="virtex5" | ||
122 | CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR=1 | ||
123 | CONFIG_XILINX_MICROBLAZE0_USE_PCMP_INSTR=1 | ||
124 | CONFIG_XILINX_MICROBLAZE0_USE_BARREL=1 | ||
125 | CONFIG_XILINX_MICROBLAZE0_USE_DIV=1 | ||
126 | CONFIG_XILINX_MICROBLAZE0_USE_HW_MUL=2 | ||
127 | CONFIG_XILINX_MICROBLAZE0_USE_FPU=2 | ||
128 | CONFIG_XILINX_MICROBLAZE0_HW_VER="7.10.d" | ||
129 | |||
130 | # | ||
131 | # Processor type and features | ||
132 | # | ||
133 | CONFIG_TICK_ONESHOT=y | ||
134 | # CONFIG_NO_HZ is not set | ||
135 | CONFIG_HIGH_RES_TIMERS=y | ||
136 | CONFIG_GENERIC_CLOCKEVENTS_BUILD=y | ||
137 | CONFIG_PREEMPT_NONE=y | ||
138 | # CONFIG_PREEMPT_VOLUNTARY is not set | ||
139 | # CONFIG_PREEMPT is not set | ||
140 | CONFIG_HZ_100=y | ||
141 | # CONFIG_HZ_250 is not set | ||
142 | # CONFIG_HZ_300 is not set | ||
143 | # CONFIG_HZ_1000 is not set | ||
144 | CONFIG_HZ=100 | ||
145 | CONFIG_SCHED_HRTICK=y | ||
146 | # CONFIG_MMU is not set | ||
147 | CONFIG_NO_MMU=y | ||
148 | |||
149 | # | ||
150 | # Boot options | ||
151 | # | ||
152 | CONFIG_CMDLINE_BOOL=y | ||
153 | CONFIG_CMDLINE="console=ttyUL0,115200" | ||
154 | # CONFIG_CMDLINE_FORCE is not set | ||
155 | CONFIG_OF=y | ||
156 | CONFIG_OF_DEVICE=y | ||
157 | CONFIG_PROC_DEVICETREE=y | ||
158 | CONFIG_SELECT_MEMORY_MODEL=y | ||
159 | CONFIG_FLATMEM_MANUAL=y | ||
160 | # CONFIG_DISCONTIGMEM_MANUAL is not set | ||
161 | # CONFIG_SPARSEMEM_MANUAL is not set | ||
162 | CONFIG_FLATMEM=y | ||
163 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
164 | CONFIG_PAGEFLAGS_EXTENDED=y | ||
165 | CONFIG_SPLIT_PTLOCK_CPUS=4 | ||
166 | # CONFIG_PHYS_ADDR_T_64BIT is not set | ||
167 | CONFIG_ZONE_DMA_FLAG=0 | ||
168 | CONFIG_VIRT_TO_BUS=y | ||
169 | |||
170 | # | ||
171 | # Exectuable file formats | ||
172 | # | ||
173 | CONFIG_BINFMT_FLAT=y | ||
174 | # CONFIG_BINFMT_ZFLAT is not set | ||
175 | # CONFIG_BINFMT_SHARED_FLAT is not set | ||
176 | # CONFIG_HAVE_AOUT is not set | ||
177 | # CONFIG_BINFMT_MISC is not set | ||
178 | CONFIG_NET=y | ||
179 | |||
180 | # | ||
181 | # Networking options | ||
182 | # | ||
183 | CONFIG_COMPAT_NET_DEV_OPS=y | ||
184 | CONFIG_PACKET=y | ||
185 | # CONFIG_PACKET_MMAP is not set | ||
186 | CONFIG_UNIX=y | ||
187 | CONFIG_XFRM=y | ||
188 | # CONFIG_XFRM_USER is not set | ||
189 | # CONFIG_XFRM_SUB_POLICY is not set | ||
190 | # CONFIG_XFRM_MIGRATE is not set | ||
191 | # CONFIG_XFRM_STATISTICS is not set | ||
192 | # CONFIG_NET_KEY is not set | ||
193 | CONFIG_INET=y | ||
194 | # CONFIG_IP_MULTICAST is not set | ||
195 | # CONFIG_IP_ADVANCED_ROUTER is not set | ||
196 | CONFIG_IP_FIB_HASH=y | ||
197 | # CONFIG_IP_PNP is not set | ||
198 | # CONFIG_NET_IPIP is not set | ||
199 | # CONFIG_NET_IPGRE is not set | ||
200 | # CONFIG_ARPD is not set | ||
201 | # CONFIG_SYN_COOKIES is not set | ||
202 | # CONFIG_INET_AH is not set | ||
203 | # CONFIG_INET_ESP is not set | ||
204 | # CONFIG_INET_IPCOMP is not set | ||
205 | # CONFIG_INET_XFRM_TUNNEL is not set | ||
206 | # CONFIG_INET_TUNNEL is not set | ||
207 | CONFIG_INET_XFRM_MODE_TRANSPORT=y | ||
208 | CONFIG_INET_XFRM_MODE_TUNNEL=y | ||
209 | CONFIG_INET_XFRM_MODE_BEET=y | ||
210 | # CONFIG_INET_LRO is not set | ||
211 | CONFIG_INET_DIAG=y | ||
212 | CONFIG_INET_TCP_DIAG=y | ||
213 | # CONFIG_TCP_CONG_ADVANCED is not set | ||
214 | CONFIG_TCP_CONG_CUBIC=y | ||
215 | CONFIG_DEFAULT_TCP_CONG="cubic" | ||
216 | # CONFIG_TCP_MD5SIG is not set | ||
217 | # CONFIG_IPV6 is not set | ||
218 | # CONFIG_NETWORK_SECMARK is not set | ||
219 | # CONFIG_NETFILTER is not set | ||
220 | # CONFIG_IP_DCCP is not set | ||
221 | # CONFIG_IP_SCTP is not set | ||
222 | # CONFIG_TIPC is not set | ||
223 | # CONFIG_ATM is not set | ||
224 | # CONFIG_BRIDGE is not set | ||
225 | # CONFIG_NET_DSA is not set | ||
226 | # CONFIG_VLAN_8021Q is not set | ||
227 | # CONFIG_DECNET is not set | ||
228 | # CONFIG_LLC2 is not set | ||
229 | # CONFIG_IPX is not set | ||
230 | # CONFIG_ATALK is not set | ||
231 | # CONFIG_X25 is not set | ||
232 | # CONFIG_LAPB is not set | ||
233 | # CONFIG_ECONET is not set | ||
234 | # CONFIG_WAN_ROUTER is not set | ||
235 | # CONFIG_NET_SCHED is not set | ||
236 | # CONFIG_DCB is not set | ||
237 | |||
238 | # | ||
239 | # Network testing | ||
240 | # | ||
241 | # CONFIG_NET_PKTGEN is not set | ||
242 | # CONFIG_HAMRADIO is not set | ||
243 | # CONFIG_CAN is not set | ||
244 | # CONFIG_IRDA is not set | ||
245 | # CONFIG_BT is not set | ||
246 | # CONFIG_AF_RXRPC is not set | ||
247 | # CONFIG_PHONET is not set | ||
248 | CONFIG_WIRELESS=y | ||
249 | # CONFIG_CFG80211 is not set | ||
250 | CONFIG_WIRELESS_OLD_REGULATORY=y | ||
251 | # CONFIG_WIRELESS_EXT is not set | ||
252 | # CONFIG_LIB80211 is not set | ||
253 | # CONFIG_MAC80211 is not set | ||
254 | # CONFIG_WIMAX is not set | ||
255 | # CONFIG_RFKILL is not set | ||
256 | # CONFIG_NET_9P is not set | ||
257 | |||
258 | # | ||
259 | # Device Drivers | ||
260 | # | ||
261 | |||
262 | # | ||
263 | # Generic Driver Options | ||
264 | # | ||
265 | CONFIG_STANDALONE=y | ||
266 | # CONFIG_PREVENT_FIRMWARE_BUILD is not set | ||
267 | # CONFIG_DEBUG_DRIVER is not set | ||
268 | # CONFIG_DEBUG_DEVRES is not set | ||
269 | # CONFIG_SYS_HYPERVISOR is not set | ||
270 | # CONFIG_CONNECTOR is not set | ||
271 | CONFIG_MTD=y | ||
272 | # CONFIG_MTD_DEBUG is not set | ||
273 | CONFIG_MTD_CONCAT=y | ||
274 | CONFIG_MTD_PARTITIONS=y | ||
275 | # CONFIG_MTD_TESTS is not set | ||
276 | # CONFIG_MTD_REDBOOT_PARTS is not set | ||
277 | CONFIG_MTD_CMDLINE_PARTS=y | ||
278 | # CONFIG_MTD_AR7_PARTS is not set | ||
279 | |||
280 | # | ||
281 | # User Modules And Translation Layers | ||
282 | # | ||
283 | CONFIG_MTD_CHAR=y | ||
284 | CONFIG_MTD_BLKDEVS=y | ||
285 | CONFIG_MTD_BLOCK=y | ||
286 | # CONFIG_FTL is not set | ||
287 | # CONFIG_NFTL is not set | ||
288 | # CONFIG_INFTL is not set | ||
289 | # CONFIG_RFD_FTL is not set | ||
290 | # CONFIG_SSFDC is not set | ||
291 | # CONFIG_MTD_OOPS is not set | ||
292 | |||
293 | # | ||
294 | # RAM/ROM/Flash chip drivers | ||
295 | # | ||
296 | CONFIG_MTD_CFI=y | ||
297 | # CONFIG_MTD_JEDECPROBE is not set | ||
298 | CONFIG_MTD_GEN_PROBE=y | ||
299 | # CONFIG_MTD_CFI_ADV_OPTIONS is not set | ||
300 | CONFIG_MTD_MAP_BANK_WIDTH_1=y | ||
301 | CONFIG_MTD_MAP_BANK_WIDTH_2=y | ||
302 | CONFIG_MTD_MAP_BANK_WIDTH_4=y | ||
303 | # CONFIG_MTD_MAP_BANK_WIDTH_8 is not set | ||
304 | # CONFIG_MTD_MAP_BANK_WIDTH_16 is not set | ||
305 | # CONFIG_MTD_MAP_BANK_WIDTH_32 is not set | ||
306 | CONFIG_MTD_CFI_I1=y | ||
307 | CONFIG_MTD_CFI_I2=y | ||
308 | # CONFIG_MTD_CFI_I4 is not set | ||
309 | # CONFIG_MTD_CFI_I8 is not set | ||
310 | CONFIG_MTD_CFI_INTELEXT=y | ||
311 | CONFIG_MTD_CFI_AMDSTD=y | ||
312 | # CONFIG_MTD_CFI_STAA is not set | ||
313 | CONFIG_MTD_CFI_UTIL=y | ||
314 | CONFIG_MTD_RAM=y | ||
315 | # CONFIG_MTD_ROM is not set | ||
316 | # CONFIG_MTD_ABSENT is not set | ||
317 | |||
318 | # | ||
319 | # Mapping drivers for chip access | ||
320 | # | ||
321 | # CONFIG_MTD_COMPLEX_MAPPINGS is not set | ||
322 | # CONFIG_MTD_PHYSMAP is not set | ||
323 | CONFIG_MTD_UCLINUX=y | ||
324 | # CONFIG_MTD_PLATRAM is not set | ||
325 | |||
326 | # | ||
327 | # Self-contained MTD device drivers | ||
328 | # | ||
329 | # CONFIG_MTD_SLRAM is not set | ||
330 | # CONFIG_MTD_PHRAM is not set | ||
331 | # CONFIG_MTD_MTDRAM is not set | ||
332 | # CONFIG_MTD_BLOCK2MTD is not set | ||
333 | |||
334 | # | ||
335 | # Disk-On-Chip Device Drivers | ||
336 | # | ||
337 | # CONFIG_MTD_DOC2000 is not set | ||
338 | # CONFIG_MTD_DOC2001 is not set | ||
339 | # CONFIG_MTD_DOC2001PLUS is not set | ||
340 | # CONFIG_MTD_NAND is not set | ||
341 | # CONFIG_MTD_ONENAND is not set | ||
342 | |||
343 | # | ||
344 | # LPDDR flash memory drivers | ||
345 | # | ||
346 | # CONFIG_MTD_LPDDR is not set | ||
347 | |||
348 | # | ||
349 | # UBI - Unsorted block images | ||
350 | # | ||
351 | # CONFIG_MTD_UBI is not set | ||
352 | # CONFIG_PARPORT is not set | ||
353 | CONFIG_BLK_DEV=y | ||
354 | # CONFIG_BLK_DEV_COW_COMMON is not set | ||
355 | # CONFIG_BLK_DEV_LOOP is not set | ||
356 | CONFIG_BLK_DEV_NBD=y | ||
357 | CONFIG_BLK_DEV_RAM=y | ||
358 | CONFIG_BLK_DEV_RAM_COUNT=16 | ||
359 | CONFIG_BLK_DEV_RAM_SIZE=4096 | ||
360 | # CONFIG_BLK_DEV_XIP is not set | ||
361 | # CONFIG_CDROM_PKTCDVD is not set | ||
362 | # CONFIG_ATA_OVER_ETH is not set | ||
363 | CONFIG_MISC_DEVICES=y | ||
364 | # CONFIG_ENCLOSURE_SERVICES is not set | ||
365 | # CONFIG_C2PORT is not set | ||
366 | |||
367 | # | ||
368 | # EEPROM support | ||
369 | # | ||
370 | # CONFIG_EEPROM_93CX6 is not set | ||
371 | |||
372 | # | ||
373 | # SCSI device support | ||
374 | # | ||
375 | # CONFIG_RAID_ATTRS is not set | ||
376 | # CONFIG_SCSI is not set | ||
377 | # CONFIG_SCSI_DMA is not set | ||
378 | # CONFIG_SCSI_NETLINK is not set | ||
379 | # CONFIG_ATA is not set | ||
380 | # CONFIG_MD is not set | ||
381 | CONFIG_NETDEVICES=y | ||
382 | # CONFIG_DUMMY is not set | ||
383 | # CONFIG_BONDING is not set | ||
384 | # CONFIG_MACVLAN is not set | ||
385 | # CONFIG_EQUALIZER is not set | ||
386 | # CONFIG_TUN is not set | ||
387 | # CONFIG_VETH is not set | ||
388 | # CONFIG_PHYLIB is not set | ||
389 | CONFIG_NET_ETHERNET=y | ||
390 | # CONFIG_MII is not set | ||
391 | # CONFIG_DNET is not set | ||
392 | # CONFIG_IBM_NEW_EMAC_ZMII is not set | ||
393 | # CONFIG_IBM_NEW_EMAC_RGMII is not set | ||
394 | # CONFIG_IBM_NEW_EMAC_TAH is not set | ||
395 | # CONFIG_IBM_NEW_EMAC_EMAC4 is not set | ||
396 | # CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set | ||
397 | # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set | ||
398 | # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set | ||
399 | # CONFIG_B44 is not set | ||
400 | CONFIG_NETDEV_1000=y | ||
401 | CONFIG_NETDEV_10000=y | ||
402 | |||
403 | # | ||
404 | # Wireless LAN | ||
405 | # | ||
406 | # CONFIG_WLAN_PRE80211 is not set | ||
407 | # CONFIG_WLAN_80211 is not set | ||
408 | # CONFIG_IWLWIFI_LEDS is not set | ||
409 | |||
410 | # | ||
411 | # Enable WiMAX (Networking options) to see the WiMAX drivers | ||
412 | # | ||
413 | # CONFIG_WAN is not set | ||
414 | # CONFIG_PPP is not set | ||
415 | # CONFIG_SLIP is not set | ||
416 | # CONFIG_NETCONSOLE is not set | ||
417 | # CONFIG_NETPOLL is not set | ||
418 | # CONFIG_NET_POLL_CONTROLLER is not set | ||
419 | # CONFIG_ISDN is not set | ||
420 | # CONFIG_PHONE is not set | ||
421 | |||
422 | # | ||
423 | # Input device support | ||
424 | # | ||
425 | # CONFIG_INPUT is not set | ||
426 | |||
427 | # | ||
428 | # Hardware I/O ports | ||
429 | # | ||
430 | # CONFIG_SERIO is not set | ||
431 | # CONFIG_GAMEPORT is not set | ||
432 | |||
433 | # | ||
434 | # Character devices | ||
435 | # | ||
436 | # CONFIG_VT is not set | ||
437 | CONFIG_DEVKMEM=y | ||
438 | # CONFIG_SERIAL_NONSTANDARD is not set | ||
439 | |||
440 | # | ||
441 | # Serial drivers | ||
442 | # | ||
443 | # CONFIG_SERIAL_8250 is not set | ||
444 | |||
445 | # | ||
446 | # Non-8250 serial port support | ||
447 | # | ||
448 | CONFIG_SERIAL_UARTLITE=y | ||
449 | CONFIG_SERIAL_UARTLITE_CONSOLE=y | ||
450 | CONFIG_SERIAL_CORE=y | ||
451 | CONFIG_SERIAL_CORE_CONSOLE=y | ||
452 | CONFIG_UNIX98_PTYS=y | ||
453 | # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set | ||
454 | CONFIG_LEGACY_PTYS=y | ||
455 | CONFIG_LEGACY_PTY_COUNT=256 | ||
456 | # CONFIG_IPMI_HANDLER is not set | ||
457 | CONFIG_HW_RANDOM=y | ||
458 | # CONFIG_RTC is not set | ||
459 | # CONFIG_GEN_RTC is not set | ||
460 | # CONFIG_R3964 is not set | ||
461 | # CONFIG_RAW_DRIVER is not set | ||
462 | # CONFIG_TCG_TPM is not set | ||
463 | # CONFIG_I2C is not set | ||
464 | # CONFIG_SPI is not set | ||
465 | # CONFIG_W1 is not set | ||
466 | # CONFIG_POWER_SUPPLY is not set | ||
467 | # CONFIG_HWMON is not set | ||
468 | # CONFIG_THERMAL is not set | ||
469 | # CONFIG_THERMAL_HWMON is not set | ||
470 | # CONFIG_WATCHDOG is not set | ||
471 | CONFIG_SSB_POSSIBLE=y | ||
472 | |||
473 | # | ||
474 | # Sonics Silicon Backplane | ||
475 | # | ||
476 | # CONFIG_SSB is not set | ||
477 | |||
478 | # | ||
479 | # Multifunction device drivers | ||
480 | # | ||
481 | # CONFIG_MFD_CORE is not set | ||
482 | # CONFIG_MFD_SM501 is not set | ||
483 | # CONFIG_HTC_PASIC3 is not set | ||
484 | # CONFIG_MFD_TMIO is not set | ||
485 | # CONFIG_REGULATOR is not set | ||
486 | |||
487 | # | ||
488 | # Multimedia devices | ||
489 | # | ||
490 | |||
491 | # | ||
492 | # Multimedia core support | ||
493 | # | ||
494 | # CONFIG_VIDEO_DEV is not set | ||
495 | # CONFIG_DVB_CORE is not set | ||
496 | # CONFIG_VIDEO_MEDIA is not set | ||
497 | |||
498 | # | ||
499 | # Multimedia drivers | ||
500 | # | ||
501 | CONFIG_DAB=y | ||
502 | |||
503 | # | ||
504 | # Graphics support | ||
505 | # | ||
506 | # CONFIG_VGASTATE is not set | ||
507 | CONFIG_VIDEO_OUTPUT_CONTROL=y | ||
508 | # CONFIG_FB is not set | ||
509 | # CONFIG_BACKLIGHT_LCD_SUPPORT is not set | ||
510 | |||
511 | # | ||
512 | # Display device support | ||
513 | # | ||
514 | # CONFIG_DISPLAY_SUPPORT is not set | ||
515 | # CONFIG_SOUND is not set | ||
516 | CONFIG_USB_SUPPORT=y | ||
517 | # CONFIG_USB_ARCH_HAS_HCD is not set | ||
518 | # CONFIG_USB_ARCH_HAS_OHCI is not set | ||
519 | # CONFIG_USB_ARCH_HAS_EHCI is not set | ||
520 | # CONFIG_USB_OTG_WHITELIST is not set | ||
521 | # CONFIG_USB_OTG_BLACKLIST_HUB is not set | ||
522 | |||
523 | # | ||
524 | # Enable Host or Gadget support to see Inventra options | ||
525 | # | ||
526 | |||
527 | # | ||
528 | # NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; | ||
529 | # | ||
530 | # CONFIG_USB_GADGET is not set | ||
531 | |||
532 | # | ||
533 | # OTG and related infrastructure | ||
534 | # | ||
535 | # CONFIG_MMC is not set | ||
536 | # CONFIG_MEMSTICK is not set | ||
537 | # CONFIG_NEW_LEDS is not set | ||
538 | # CONFIG_ACCESSIBILITY is not set | ||
539 | # CONFIG_RTC_CLASS is not set | ||
540 | # CONFIG_DMADEVICES is not set | ||
541 | # CONFIG_UIO is not set | ||
542 | # CONFIG_STAGING is not set | ||
543 | |||
544 | # | ||
545 | # File systems | ||
546 | # | ||
547 | CONFIG_EXT2_FS=y | ||
548 | # CONFIG_EXT2_FS_XATTR is not set | ||
549 | # CONFIG_EXT3_FS is not set | ||
550 | # CONFIG_EXT4_FS is not set | ||
551 | # CONFIG_REISERFS_FS is not set | ||
552 | # CONFIG_JFS_FS is not set | ||
553 | CONFIG_FS_POSIX_ACL=y | ||
554 | CONFIG_FILE_LOCKING=y | ||
555 | # CONFIG_XFS_FS is not set | ||
556 | # CONFIG_OCFS2_FS is not set | ||
557 | # CONFIG_BTRFS_FS is not set | ||
558 | # CONFIG_DNOTIFY is not set | ||
559 | # CONFIG_INOTIFY is not set | ||
560 | # CONFIG_QUOTA is not set | ||
561 | # CONFIG_AUTOFS_FS is not set | ||
562 | # CONFIG_AUTOFS4_FS is not set | ||
563 | # CONFIG_FUSE_FS is not set | ||
564 | |||
565 | # | ||
566 | # CD-ROM/DVD Filesystems | ||
567 | # | ||
568 | # CONFIG_ISO9660_FS is not set | ||
569 | # CONFIG_UDF_FS is not set | ||
570 | |||
571 | # | ||
572 | # DOS/FAT/NT Filesystems | ||
573 | # | ||
574 | # CONFIG_MSDOS_FS is not set | ||
575 | # CONFIG_VFAT_FS is not set | ||
576 | # CONFIG_NTFS_FS is not set | ||
577 | |||
578 | # | ||
579 | # Pseudo filesystems | ||
580 | # | ||
581 | CONFIG_PROC_FS=y | ||
582 | CONFIG_PROC_SYSCTL=y | ||
583 | CONFIG_SYSFS=y | ||
584 | # CONFIG_TMPFS is not set | ||
585 | # CONFIG_HUGETLB_PAGE is not set | ||
586 | # CONFIG_CONFIGFS_FS is not set | ||
587 | CONFIG_MISC_FILESYSTEMS=y | ||
588 | # CONFIG_ADFS_FS is not set | ||
589 | # CONFIG_AFFS_FS is not set | ||
590 | # CONFIG_HFS_FS is not set | ||
591 | # CONFIG_HFSPLUS_FS is not set | ||
592 | # CONFIG_BEFS_FS is not set | ||
593 | # CONFIG_BFS_FS is not set | ||
594 | # CONFIG_EFS_FS is not set | ||
595 | # CONFIG_JFFS2_FS is not set | ||
596 | CONFIG_CRAMFS=y | ||
597 | # CONFIG_SQUASHFS is not set | ||
598 | # CONFIG_VXFS_FS is not set | ||
599 | # CONFIG_MINIX_FS is not set | ||
600 | # CONFIG_OMFS_FS is not set | ||
601 | # CONFIG_HPFS_FS is not set | ||
602 | # CONFIG_QNX4FS_FS is not set | ||
603 | CONFIG_ROMFS_FS=y | ||
604 | # CONFIG_SYSV_FS is not set | ||
605 | # CONFIG_UFS_FS is not set | ||
606 | CONFIG_NETWORK_FILESYSTEMS=y | ||
607 | CONFIG_NFS_FS=y | ||
608 | CONFIG_NFS_V3=y | ||
609 | CONFIG_NFS_V3_ACL=y | ||
610 | # CONFIG_NFS_V4 is not set | ||
611 | # CONFIG_NFSD is not set | ||
612 | CONFIG_LOCKD=y | ||
613 | CONFIG_LOCKD_V4=y | ||
614 | CONFIG_NFS_ACL_SUPPORT=y | ||
615 | CONFIG_NFS_COMMON=y | ||
616 | CONFIG_SUNRPC=y | ||
617 | # CONFIG_SUNRPC_REGISTER_V4 is not set | ||
618 | # CONFIG_RPCSEC_GSS_KRB5 is not set | ||
619 | # CONFIG_RPCSEC_GSS_SPKM3 is not set | ||
620 | # CONFIG_SMB_FS is not set | ||
621 | # CONFIG_CIFS is not set | ||
622 | # CONFIG_NCP_FS is not set | ||
623 | # CONFIG_CODA_FS is not set | ||
624 | # CONFIG_AFS_FS is not set | ||
625 | |||
626 | # | ||
627 | # Partition Types | ||
628 | # | ||
629 | # CONFIG_PARTITION_ADVANCED is not set | ||
630 | CONFIG_MSDOS_PARTITION=y | ||
631 | # CONFIG_NLS is not set | ||
632 | # CONFIG_DLM is not set | ||
633 | |||
634 | # | ||
635 | # Kernel hacking | ||
636 | # | ||
637 | # CONFIG_PRINTK_TIME is not set | ||
638 | CONFIG_ENABLE_WARN_DEPRECATED=y | ||
639 | CONFIG_ENABLE_MUST_CHECK=y | ||
640 | CONFIG_FRAME_WARN=1024 | ||
641 | # CONFIG_MAGIC_SYSRQ is not set | ||
642 | CONFIG_UNUSED_SYMBOLS=y | ||
643 | CONFIG_DEBUG_FS=y | ||
644 | # CONFIG_HEADERS_CHECK is not set | ||
645 | CONFIG_DEBUG_KERNEL=y | ||
646 | CONFIG_DEBUG_SHIRQ=y | ||
647 | CONFIG_DETECT_SOFTLOCKUP=y | ||
648 | CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y | ||
649 | CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=1 | ||
650 | CONFIG_SCHED_DEBUG=y | ||
651 | CONFIG_SCHEDSTATS=y | ||
652 | CONFIG_TIMER_STATS=y | ||
653 | CONFIG_DEBUG_OBJECTS=y | ||
654 | CONFIG_DEBUG_OBJECTS_SELFTEST=y | ||
655 | CONFIG_DEBUG_OBJECTS_FREE=y | ||
656 | CONFIG_DEBUG_OBJECTS_TIMERS=y | ||
657 | CONFIG_DEBUG_OBJECTS_ENABLE_DEFAULT=1 | ||
658 | # CONFIG_DEBUG_SLAB is not set | ||
659 | # CONFIG_DEBUG_RT_MUTEXES is not set | ||
660 | # CONFIG_RT_MUTEX_TESTER is not set | ||
661 | # CONFIG_DEBUG_SPINLOCK is not set | ||
662 | # CONFIG_DEBUG_MUTEXES is not set | ||
663 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set | ||
664 | # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set | ||
665 | # CONFIG_DEBUG_KOBJECT is not set | ||
666 | CONFIG_DEBUG_INFO=y | ||
667 | # CONFIG_DEBUG_VM is not set | ||
668 | # CONFIG_DEBUG_NOMMU_REGIONS is not set | ||
669 | # CONFIG_DEBUG_WRITECOUNT is not set | ||
670 | # CONFIG_DEBUG_MEMORY_INIT is not set | ||
671 | CONFIG_DEBUG_LIST=y | ||
672 | CONFIG_DEBUG_SG=y | ||
673 | # CONFIG_DEBUG_NOTIFIERS is not set | ||
674 | # CONFIG_BOOT_PRINTK_DELAY is not set | ||
675 | # CONFIG_RCU_TORTURE_TEST is not set | ||
676 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | ||
677 | # CONFIG_BACKTRACE_SELF_TEST is not set | ||
678 | # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set | ||
679 | # CONFIG_FAULT_INJECTION is not set | ||
680 | CONFIG_SYSCTL_SYSCALL_CHECK=y | ||
681 | |||
682 | # | ||
683 | # Tracers | ||
684 | # | ||
685 | # CONFIG_SCHED_TRACER is not set | ||
686 | # CONFIG_CONTEXT_SWITCH_TRACER is not set | ||
687 | # CONFIG_BOOT_TRACER is not set | ||
688 | # CONFIG_TRACE_BRANCH_PROFILING is not set | ||
689 | # CONFIG_DYNAMIC_PRINTK_DEBUG is not set | ||
690 | # CONFIG_SAMPLES is not set | ||
691 | CONFIG_EARLY_PRINTK=y | ||
692 | CONFIG_HEART_BEAT=y | ||
693 | # CONFIG_DEBUG_BOOTMEM is not set | ||
694 | |||
695 | # | ||
696 | # Security options | ||
697 | # | ||
698 | # CONFIG_KEYS is not set | ||
699 | # CONFIG_SECURITY is not set | ||
700 | # CONFIG_SECURITYFS is not set | ||
701 | # CONFIG_SECURITY_FILE_CAPABILITIES is not set | ||
702 | CONFIG_CRYPTO=y | ||
703 | |||
704 | # | ||
705 | # Crypto core or helper | ||
706 | # | ||
707 | # CONFIG_CRYPTO_FIPS is not set | ||
708 | # CONFIG_CRYPTO_MANAGER is not set | ||
709 | # CONFIG_CRYPTO_MANAGER2 is not set | ||
710 | # CONFIG_CRYPTO_GF128MUL is not set | ||
711 | # CONFIG_CRYPTO_NULL is not set | ||
712 | # CONFIG_CRYPTO_CRYPTD is not set | ||
713 | # CONFIG_CRYPTO_AUTHENC is not set | ||
714 | # CONFIG_CRYPTO_TEST is not set | ||
715 | |||
716 | # | ||
717 | # Authenticated Encryption with Associated Data | ||
718 | # | ||
719 | # CONFIG_CRYPTO_CCM is not set | ||
720 | # CONFIG_CRYPTO_GCM is not set | ||
721 | # CONFIG_CRYPTO_SEQIV is not set | ||
722 | |||
723 | # | ||
724 | # Block modes | ||
725 | # | ||
726 | # CONFIG_CRYPTO_CBC is not set | ||
727 | # CONFIG_CRYPTO_CTR is not set | ||
728 | # CONFIG_CRYPTO_CTS is not set | ||
729 | # CONFIG_CRYPTO_ECB is not set | ||
730 | # CONFIG_CRYPTO_LRW is not set | ||
731 | # CONFIG_CRYPTO_PCBC is not set | ||
732 | # CONFIG_CRYPTO_XTS is not set | ||
733 | |||
734 | # | ||
735 | # Hash modes | ||
736 | # | ||
737 | # CONFIG_CRYPTO_HMAC is not set | ||
738 | # CONFIG_CRYPTO_XCBC is not set | ||
739 | |||
740 | # | ||
741 | # Digest | ||
742 | # | ||
743 | # CONFIG_CRYPTO_CRC32C is not set | ||
744 | # CONFIG_CRYPTO_MD4 is not set | ||
745 | # CONFIG_CRYPTO_MD5 is not set | ||
746 | # CONFIG_CRYPTO_MICHAEL_MIC is not set | ||
747 | # CONFIG_CRYPTO_RMD128 is not set | ||
748 | # CONFIG_CRYPTO_RMD160 is not set | ||
749 | # CONFIG_CRYPTO_RMD256 is not set | ||
750 | # CONFIG_CRYPTO_RMD320 is not set | ||
751 | # CONFIG_CRYPTO_SHA1 is not set | ||
752 | # CONFIG_CRYPTO_SHA256 is not set | ||
753 | # CONFIG_CRYPTO_SHA512 is not set | ||
754 | # CONFIG_CRYPTO_TGR192 is not set | ||
755 | # CONFIG_CRYPTO_WP512 is not set | ||
756 | |||
757 | # | ||
758 | # Ciphers | ||
759 | # | ||
760 | # CONFIG_CRYPTO_AES is not set | ||
761 | # CONFIG_CRYPTO_ANUBIS is not set | ||
762 | # CONFIG_CRYPTO_ARC4 is not set | ||
763 | # CONFIG_CRYPTO_BLOWFISH is not set | ||
764 | # CONFIG_CRYPTO_CAMELLIA is not set | ||
765 | # CONFIG_CRYPTO_CAST5 is not set | ||
766 | # CONFIG_CRYPTO_CAST6 is not set | ||
767 | # CONFIG_CRYPTO_DES is not set | ||
768 | # CONFIG_CRYPTO_FCRYPT is not set | ||
769 | # CONFIG_CRYPTO_KHAZAD is not set | ||
770 | # CONFIG_CRYPTO_SALSA20 is not set | ||
771 | # CONFIG_CRYPTO_SEED is not set | ||
772 | # CONFIG_CRYPTO_SERPENT is not set | ||
773 | # CONFIG_CRYPTO_TEA is not set | ||
774 | # CONFIG_CRYPTO_TWOFISH is not set | ||
775 | |||
776 | # | ||
777 | # Compression | ||
778 | # | ||
779 | # CONFIG_CRYPTO_DEFLATE is not set | ||
780 | # CONFIG_CRYPTO_LZO is not set | ||
781 | |||
782 | # | ||
783 | # Random Number Generation | ||
784 | # | ||
785 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | ||
786 | CONFIG_CRYPTO_HW=y | ||
787 | |||
788 | # | ||
789 | # Library routines | ||
790 | # | ||
791 | CONFIG_GENERIC_FIND_LAST_BIT=y | ||
792 | # CONFIG_CRC_CCITT is not set | ||
793 | # CONFIG_CRC16 is not set | ||
794 | # CONFIG_CRC_T10DIF is not set | ||
795 | # CONFIG_CRC_ITU_T is not set | ||
796 | # CONFIG_CRC32 is not set | ||
797 | # CONFIG_CRC7 is not set | ||
798 | # CONFIG_LIBCRC32C is not set | ||
799 | CONFIG_ZLIB_INFLATE=y | ||
800 | CONFIG_PLIST=y | ||
801 | CONFIG_HAS_IOMEM=y | ||
802 | CONFIG_HAS_IOPORT=y | ||
803 | CONFIG_HAS_DMA=y | ||
804 | CONFIG_HAVE_LMB=y | ||
diff --git a/arch/microblaze/include/asm/Kbuild b/arch/microblaze/include/asm/Kbuild new file mode 100644 index 000000000000..31820dfef56b --- /dev/null +++ b/arch/microblaze/include/asm/Kbuild | |||
@@ -0,0 +1,26 @@ | |||
1 | include include/asm-generic/Kbuild.asm | ||
2 | |||
3 | header-y += auxvec.h | ||
4 | header-y += errno.h | ||
5 | header-y += fcntl.h | ||
6 | header-y += ioctl.h | ||
7 | header-y += ioctls.h | ||
8 | header-y += ipcbuf.h | ||
9 | header-y += linkage.h | ||
10 | header-y += msgbuf.h | ||
11 | header-y += poll.h | ||
12 | header-y += resource.h | ||
13 | header-y += sembuf.h | ||
14 | header-y += shmbuf.h | ||
15 | header-y += sigcontext.h | ||
16 | header-y += siginfo.h | ||
17 | header-y += socket.h | ||
18 | header-y += sockios.h | ||
19 | header-y += statfs.h | ||
20 | header-y += stat.h | ||
21 | header-y += termbits.h | ||
22 | header-y += ucontext.h | ||
23 | |||
24 | unifdef-y += cputable.h | ||
25 | unifdef-y += elf.h | ||
26 | unifdef-y += termios.h | ||
diff --git a/arch/microblaze/include/asm/atomic.h b/arch/microblaze/include/asm/atomic.h new file mode 100644 index 000000000000..a448d94ab721 --- /dev/null +++ b/arch/microblaze/include/asm/atomic.h | |||
@@ -0,0 +1,123 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_ATOMIC_H | ||
10 | #define _ASM_MICROBLAZE_ATOMIC_H | ||
11 | |||
12 | #include <linux/types.h> | ||
13 | #include <linux/compiler.h> /* likely */ | ||
14 | #include <asm/system.h> /* local_irq_XXX and friends */ | ||
15 | |||
16 | #define ATOMIC_INIT(i) { (i) } | ||
17 | #define atomic_read(v) ((v)->counter) | ||
18 | #define atomic_set(v, i) (((v)->counter) = (i)) | ||
19 | |||
20 | #define atomic_inc(v) (atomic_add_return(1, (v))) | ||
21 | #define atomic_dec(v) (atomic_sub_return(1, (v))) | ||
22 | |||
23 | #define atomic_add(i, v) (atomic_add_return(i, (v))) | ||
24 | #define atomic_sub(i, v) (atomic_sub_return(i, (v))) | ||
25 | |||
26 | #define atomic_inc_return(v) (atomic_add_return(1, (v))) | ||
27 | #define atomic_dec_return(v) (atomic_sub_return(1, (v))) | ||
28 | |||
29 | #define atomic_inc_and_test(v) (atomic_add_return(1, (v)) == 0) | ||
30 | #define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0) | ||
31 | |||
32 | #define atomic_inc_not_zero(v) (atomic_add_unless((v), 1, 0)) | ||
33 | |||
34 | #define atomic_sub_and_test(i, v) (atomic_sub_return((i), (v)) == 0) | ||
35 | |||
36 | static inline int atomic_cmpxchg(atomic_t *v, int old, int new) | ||
37 | { | ||
38 | int ret; | ||
39 | unsigned long flags; | ||
40 | |||
41 | local_irq_save(flags); | ||
42 | ret = v->counter; | ||
43 | if (likely(ret == old)) | ||
44 | v->counter = new; | ||
45 | local_irq_restore(flags); | ||
46 | |||
47 | return ret; | ||
48 | } | ||
49 | |||
50 | static inline int atomic_add_unless(atomic_t *v, int a, int u) | ||
51 | { | ||
52 | int c, old; | ||
53 | |||
54 | c = atomic_read(v); | ||
55 | while (c != u && (old = atomic_cmpxchg((v), c, c + a)) != c) | ||
56 | c = old; | ||
57 | return c != u; | ||
58 | } | ||
59 | |||
60 | static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr) | ||
61 | { | ||
62 | unsigned long flags; | ||
63 | |||
64 | local_irq_save(flags); | ||
65 | *addr &= ~mask; | ||
66 | local_irq_restore(flags); | ||
67 | } | ||
68 | |||
69 | /** | ||
70 | * atomic_add_return - add and return | ||
71 | * @i: integer value to add | ||
72 | * @v: pointer of type atomic_t | ||
73 | * | ||
74 | * Atomically adds @i to @v and returns @i + @v | ||
75 | */ | ||
76 | static inline int atomic_add_return(int i, atomic_t *v) | ||
77 | { | ||
78 | unsigned long flags; | ||
79 | int val; | ||
80 | |||
81 | local_irq_save(flags); | ||
82 | val = v->counter; | ||
83 | v->counter = val += i; | ||
84 | local_irq_restore(flags); | ||
85 | |||
86 | return val; | ||
87 | } | ||
88 | |||
89 | static inline int atomic_sub_return(int i, atomic_t *v) | ||
90 | { | ||
91 | return atomic_add_return(-i, v); | ||
92 | } | ||
93 | |||
94 | /* | ||
95 | * Atomically test *v and decrement if it is greater than 0. | ||
96 | * The function returns the old value of *v minus 1. | ||
97 | */ | ||
98 | static inline int atomic_dec_if_positive(atomic_t *v) | ||
99 | { | ||
100 | unsigned long flags; | ||
101 | int res; | ||
102 | |||
103 | local_irq_save(flags); | ||
104 | res = v->counter - 1; | ||
105 | if (res >= 0) | ||
106 | v->counter = res; | ||
107 | local_irq_restore(flags); | ||
108 | |||
109 | return res; | ||
110 | } | ||
111 | |||
112 | #define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0) | ||
113 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) | ||
114 | |||
115 | /* Atomic operations are already serializing */ | ||
116 | #define smp_mb__before_atomic_dec() barrier() | ||
117 | #define smp_mb__after_atomic_dec() barrier() | ||
118 | #define smp_mb__before_atomic_inc() barrier() | ||
119 | #define smp_mb__after_atomic_inc() barrier() | ||
120 | |||
121 | #include <asm-generic/atomic.h> | ||
122 | |||
123 | #endif /* _ASM_MICROBLAZE_ATOMIC_H */ | ||
diff --git a/arch/microblaze/include/asm/auxvec.h b/arch/microblaze/include/asm/auxvec.h new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/arch/microblaze/include/asm/auxvec.h | |||
diff --git a/arch/microblaze/include/asm/bitops.h b/arch/microblaze/include/asm/bitops.h new file mode 100644 index 000000000000..d6df1fd4e1e8 --- /dev/null +++ b/arch/microblaze/include/asm/bitops.h | |||
@@ -0,0 +1,27 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_BITOPS_H | ||
10 | #define _ASM_MICROBLAZE_BITOPS_H | ||
11 | |||
12 | /* | ||
13 | * Copyright 1992, Linus Torvalds. | ||
14 | */ | ||
15 | |||
16 | #include <asm/byteorder.h> /* swab32 */ | ||
17 | #include <asm/system.h> /* save_flags */ | ||
18 | |||
19 | /* | ||
20 | * clear_bit() doesn't provide any barrier for the compiler. | ||
21 | */ | ||
22 | #define smp_mb__before_clear_bit() barrier() | ||
23 | #define smp_mb__after_clear_bit() barrier() | ||
24 | #include <asm-generic/bitops.h> | ||
25 | #include <asm-generic/bitops/__fls.h> | ||
26 | |||
27 | #endif /* _ASM_MICROBLAZE_BITOPS_H */ | ||
diff --git a/arch/microblaze/include/asm/bug.h b/arch/microblaze/include/asm/bug.h new file mode 100644 index 000000000000..8eb2cdde11d7 --- /dev/null +++ b/arch/microblaze/include/asm/bug.h | |||
@@ -0,0 +1,15 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_BUG_H | ||
10 | #define _ASM_MICROBLAZE_BUG_H | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <asm-generic/bug.h> | ||
14 | |||
15 | #endif /* _ASM_MICROBLAZE_BUG_H */ | ||
diff --git a/arch/microblaze/include/asm/bugs.h b/arch/microblaze/include/asm/bugs.h new file mode 100644 index 000000000000..f2c6593653fb --- /dev/null +++ b/arch/microblaze/include/asm/bugs.h | |||
@@ -0,0 +1,17 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_BUGS_H | ||
10 | #define _ASM_MICROBLAZE_BUGS_H | ||
11 | |||
12 | static inline void check_bugs(void) | ||
13 | { | ||
14 | /* nothing to do */ | ||
15 | } | ||
16 | |||
17 | #endif /* _ASM_MICROBLAZE_BUGS_H */ | ||
diff --git a/arch/microblaze/include/asm/byteorder.h b/arch/microblaze/include/asm/byteorder.h new file mode 100644 index 000000000000..ce9c58732ffc --- /dev/null +++ b/arch/microblaze/include/asm/byteorder.h | |||
@@ -0,0 +1,6 @@ | |||
1 | #ifndef _ASM_MICROBLAZE_BYTEORDER_H | ||
2 | #define _ASM_MICROBLAZE_BYTEORDER_H | ||
3 | |||
4 | #include <linux/byteorder/big_endian.h> | ||
5 | |||
6 | #endif /* _ASM_MICROBLAZE_BYTEORDER_H */ | ||
diff --git a/arch/microblaze/include/asm/cache.h b/arch/microblaze/include/asm/cache.h new file mode 100644 index 000000000000..c4c64b43c074 --- /dev/null +++ b/arch/microblaze/include/asm/cache.h | |||
@@ -0,0 +1,45 @@ | |||
1 | /* | ||
2 | * Cache operations | ||
3 | * | ||
4 | * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> | ||
5 | * Copyright (C) 2007-2009 PetaLogix | ||
6 | * Copyright (C) 2003 John Williams <jwilliams@itee.uq.edu.au> | ||
7 | * | ||
8 | * This file is subject to the terms and conditions of the GNU General | ||
9 | * Public License. See the file COPYING in the main directory of this | ||
10 | * archive for more details. | ||
11 | */ | ||
12 | |||
13 | #ifndef _ASM_MICROBLAZE_CACHE_H | ||
14 | #define _ASM_MICROBLAZE_CACHE_H | ||
15 | |||
16 | #include <asm/registers.h> | ||
17 | |||
18 | #define L1_CACHE_SHIFT 2 | ||
19 | /* word-granular cache in microblaze */ | ||
20 | #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) | ||
21 | |||
22 | #define SMP_CACHE_BYTES L1_CACHE_BYTES | ||
23 | |||
24 | void _enable_icache(void); | ||
25 | void _disable_icache(void); | ||
26 | void _invalidate_icache(unsigned int addr); | ||
27 | |||
28 | #define __enable_icache() _enable_icache() | ||
29 | #define __disable_icache() _disable_icache() | ||
30 | #define __invalidate_icache(addr) _invalidate_icache(addr) | ||
31 | |||
32 | void _enable_dcache(void); | ||
33 | void _disable_dcache(void); | ||
34 | void _invalidate_dcache(unsigned int addr); | ||
35 | |||
36 | #define __enable_dcache() _enable_dcache() | ||
37 | #define __disable_dcache() _disable_dcache() | ||
38 | #define __invalidate_dcache(addr) _invalidate_dcache(addr) | ||
39 | |||
40 | /* FIXME - I don't think this is right */ | ||
41 | #ifdef CONFIG_XILINX_UNCACHED_SHADOW | ||
42 | #define UNCACHED_SHADOW_MASK (CONFIG_XILINX_ERAM_SIZE) | ||
43 | #endif | ||
44 | |||
45 | #endif /* _ASM_MICROBLAZE_CACHE_H */ | ||
diff --git a/arch/microblaze/include/asm/cacheflush.h b/arch/microblaze/include/asm/cacheflush.h new file mode 100644 index 000000000000..3300b785049b --- /dev/null +++ b/arch/microblaze/include/asm/cacheflush.h | |||
@@ -0,0 +1,85 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007 PetaLogix | ||
3 | * Copyright (C) 2007 John Williams <john.williams@petalogix.com> | ||
4 | * based on v850 version which was | ||
5 | * Copyright (C) 2001,02,03 NEC Electronics Corporation | ||
6 | * Copyright (C) 2001,02,03 Miles Bader <miles@gnu.org> | ||
7 | * | ||
8 | * This file is subject to the terms and conditions of the GNU General | ||
9 | * Public License. See the file COPYING in the main directory of this | ||
10 | * archive for more details. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #ifndef _ASM_MICROBLAZE_CACHEFLUSH_H | ||
15 | #define _ASM_MICROBLAZE_CACHEFLUSH_H | ||
16 | |||
17 | /* Somebody depends on this; sigh... */ | ||
18 | #include <linux/mm.h> | ||
19 | |||
20 | /* | ||
21 | * Cache handling functions. | ||
22 | * Microblaze has a write-through data cache, meaning that the data cache | ||
23 | * never needs to be flushed. The only flushing operations that are | ||
24 | * implemented are to invalidate the instruction cache. These are called | ||
25 | * after loading a user application into memory, we must invalidate the | ||
26 | * instruction cache to make sure we don't fetch old, bad code. | ||
27 | */ | ||
28 | |||
29 | /* FIXME for LL-temac driver */ | ||
30 | #define invalidate_dcache_range(start, end) \ | ||
31 | __invalidate_dcache_range(start, end) | ||
32 | |||
33 | #define flush_cache_all() __invalidate_cache_all() | ||
34 | #define flush_cache_mm(mm) do { } while (0) | ||
35 | #define flush_cache_range(vma, start, end) __invalidate_cache_all() | ||
36 | #define flush_cache_page(vma, vmaddr, pfn) do { } while (0) | ||
37 | |||
38 | #define flush_dcache_range(start, end) __invalidate_dcache_range(start, end) | ||
39 | #define flush_dcache_page(page) do { } while (0) | ||
40 | #define flush_dcache_mmap_lock(mapping) do { } while (0) | ||
41 | #define flush_dcache_mmap_unlock(mapping) do { } while (0) | ||
42 | |||
43 | #define flush_icache_range(start, len) __invalidate_icache_range(start, len) | ||
44 | #define flush_icache_page(vma, pg) do { } while (0) | ||
45 | |||
46 | #define flush_cache_vmap(start, end) do { } while (0) | ||
47 | #define flush_cache_vunmap(start, end) do { } while (0) | ||
48 | |||
49 | struct page; | ||
50 | struct mm_struct; | ||
51 | struct vm_area_struct; | ||
52 | |||
53 | /* see arch/microblaze/kernel/cache.c */ | ||
54 | extern void __invalidate_icache_all(void); | ||
55 | extern void __invalidate_icache_range(unsigned long start, unsigned long end); | ||
56 | extern void __invalidate_icache_page(struct vm_area_struct *vma, | ||
57 | struct page *page); | ||
58 | extern void __invalidate_icache_user_range(struct vm_area_struct *vma, | ||
59 | struct page *page, | ||
60 | unsigned long adr, int len); | ||
61 | extern void __invalidate_cache_sigtramp(unsigned long addr); | ||
62 | |||
63 | extern void __invalidate_dcache_all(void); | ||
64 | extern void __invalidate_dcache_range(unsigned long start, unsigned long end); | ||
65 | extern void __invalidate_dcache_page(struct vm_area_struct *vma, | ||
66 | struct page *page); | ||
67 | extern void __invalidate_dcache_user_range(struct vm_area_struct *vma, | ||
68 | struct page *page, | ||
69 | unsigned long adr, int len); | ||
70 | |||
71 | extern inline void __invalidate_cache_all(void) | ||
72 | { | ||
73 | __invalidate_icache_all(); | ||
74 | __invalidate_dcache_all(); | ||
75 | } | ||
76 | |||
77 | #define copy_to_user_page(vma, page, vaddr, dst, src, len) \ | ||
78 | do { memcpy((dst), (src), (len)); \ | ||
79 | flush_icache_range((unsigned) (dst), (unsigned) (dst) + (len)); \ | ||
80 | } while (0) | ||
81 | |||
82 | #define copy_from_user_page(vma, page, vaddr, dst, src, len) \ | ||
83 | memcpy((dst), (src), (len)) | ||
84 | |||
85 | #endif /* _ASM_MICROBLAZE_CACHEFLUSH_H */ | ||
diff --git a/arch/microblaze/include/asm/checksum.h b/arch/microblaze/include/asm/checksum.h new file mode 100644 index 000000000000..92b30762ce59 --- /dev/null +++ b/arch/microblaze/include/asm/checksum.h | |||
@@ -0,0 +1,98 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2008 Michal Simek <monstr@monstr.eu> | ||
3 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
4 | * | ||
5 | * This file is subject to the terms and conditions of the GNU General Public | ||
6 | * License. See the file "COPYING" in the main directory of this archive | ||
7 | * for more details. | ||
8 | */ | ||
9 | |||
10 | #ifndef _ASM_MICROBLAZE_CHECKSUM_H | ||
11 | #define _ASM_MICROBLAZE_CHECKSUM_H | ||
12 | |||
13 | #include <linux/in6.h> | ||
14 | |||
15 | /* | ||
16 | * computes the checksum of the TCP/UDP pseudo-header | ||
17 | * returns a 16-bit checksum, already complemented | ||
18 | */ | ||
19 | static inline __wsum | ||
20 | csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, | ||
21 | unsigned short proto, __wsum sum) | ||
22 | { | ||
23 | __asm__("add %0, %0, %1\n\t" | ||
24 | "addc %0, %0, %2\n\t" | ||
25 | "addc %0, %0, %3\n\t" | ||
26 | "addc %0, %0, r0\n\t" | ||
27 | : "+&d" (sum) | ||
28 | : "d" (saddr), "d" (daddr), "d" (len + proto)); | ||
29 | |||
30 | return sum; | ||
31 | } | ||
32 | |||
33 | /* | ||
34 | * computes the checksum of a memory block at buff, length len, | ||
35 | * and adds in "sum" (32-bit) | ||
36 | * | ||
37 | * returns a 32-bit number suitable for feeding into itself | ||
38 | * or csum_tcpudp_magic | ||
39 | * | ||
40 | * this function must be called with even lengths, except | ||
41 | * for the last fragment, which may be odd | ||
42 | * | ||
43 | * it's best to have buff aligned on a 32-bit boundary | ||
44 | */ | ||
45 | extern __wsum csum_partial(const void *buff, int len, __wsum sum); | ||
46 | |||
47 | /* | ||
48 | * the same as csum_partial, but copies from src while it | ||
49 | * checksums | ||
50 | * | ||
51 | * here even more important to align src and dst on a 32-bit (or even | ||
52 | * better 64-bit) boundary | ||
53 | */ | ||
54 | extern __wsum csum_partial_copy(const char *src, char *dst, int len, int sum); | ||
55 | |||
56 | /* | ||
57 | * the same as csum_partial_copy, but copies from user space. | ||
58 | * | ||
59 | * here even more important to align src and dst on a 32-bit (or even | ||
60 | * better 64-bit) boundary | ||
61 | */ | ||
62 | extern __wsum csum_partial_copy_from_user(const char *src, char *dst, | ||
63 | int len, int sum, int *csum_err); | ||
64 | |||
65 | #define csum_partial_copy_nocheck(src, dst, len, sum) \ | ||
66 | csum_partial_copy((src), (dst), (len), (sum)) | ||
67 | |||
68 | /* | ||
69 | * This is a version of ip_compute_csum() optimized for IP headers, | ||
70 | * which always checksum on 4 octet boundaries. | ||
71 | * | ||
72 | */ | ||
73 | extern __sum16 ip_fast_csum(const void *iph, unsigned int ihl); | ||
74 | |||
75 | /* | ||
76 | * Fold a partial checksum | ||
77 | */ | ||
78 | static inline __sum16 csum_fold(unsigned int sum) | ||
79 | { | ||
80 | sum = (sum & 0xffff) + (sum >> 16); | ||
81 | sum = (sum & 0xffff) + (sum >> 16); | ||
82 | return ~sum; | ||
83 | } | ||
84 | |||
85 | static inline __sum16 | ||
86 | csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len, | ||
87 | unsigned short proto, __wsum sum) | ||
88 | { | ||
89 | return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum)); | ||
90 | } | ||
91 | |||
92 | /* | ||
93 | * this routine is used for miscellaneous IP-like checksums, mainly | ||
94 | * in icmp.c | ||
95 | */ | ||
96 | extern __sum16 ip_compute_csum(const unsigned char *buff, int len); | ||
97 | |||
98 | #endif /* _ASM_MICROBLAZE_CHECKSUM_H */ | ||
diff --git a/arch/microblaze/include/asm/clinkage.h b/arch/microblaze/include/asm/clinkage.h new file mode 100644 index 000000000000..9e218435a55c --- /dev/null +++ b/arch/microblaze/include/asm/clinkage.h | |||
@@ -0,0 +1 @@ | |||
#include <linux/linkage.h> | |||
diff --git a/arch/microblaze/include/asm/cpuinfo.h b/arch/microblaze/include/asm/cpuinfo.h new file mode 100644 index 000000000000..52f28f6dc4eb --- /dev/null +++ b/arch/microblaze/include/asm/cpuinfo.h | |||
@@ -0,0 +1,102 @@ | |||
1 | /* | ||
2 | * Generic support for queying CPU info | ||
3 | * | ||
4 | * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> | ||
5 | * Copyright (C) 2007-2009 PetaLogix | ||
6 | * Copyright (C) 2007 John Williams <jwilliams@itee.uq.edu.au> | ||
7 | * | ||
8 | * This file is subject to the terms and conditions of the GNU General | ||
9 | * Public License. See the file COPYING in the main directory of this | ||
10 | * archive for more details. | ||
11 | */ | ||
12 | |||
13 | #ifndef _ASM_MICROBLAZE_CPUINFO_H | ||
14 | #define _ASM_MICROBLAZE_CPUINFO_H | ||
15 | |||
16 | #include <asm/prom.h> | ||
17 | |||
18 | /* CPU Version and FPGA Family code conversion table type */ | ||
19 | struct cpu_ver_key { | ||
20 | const char *s; | ||
21 | const unsigned k; | ||
22 | }; | ||
23 | |||
24 | extern const struct cpu_ver_key cpu_ver_lookup[]; | ||
25 | |||
26 | struct family_string_key { | ||
27 | const char *s; | ||
28 | const unsigned k; | ||
29 | }; | ||
30 | |||
31 | extern const struct family_string_key family_string_lookup[]; | ||
32 | |||
33 | struct cpuinfo { | ||
34 | /* Core CPU configuration */ | ||
35 | u32 use_instr; | ||
36 | u32 use_mult; | ||
37 | u32 use_fpu; | ||
38 | u32 use_exc; | ||
39 | u32 ver_code; | ||
40 | u32 mmu; | ||
41 | |||
42 | /* CPU caches */ | ||
43 | u32 use_icache; | ||
44 | u32 icache_tagbits; | ||
45 | u32 icache_write; | ||
46 | u32 icache_line; | ||
47 | u32 icache_size; | ||
48 | unsigned long icache_base; | ||
49 | unsigned long icache_high; | ||
50 | |||
51 | u32 use_dcache; | ||
52 | u32 dcache_tagbits; | ||
53 | u32 dcache_write; | ||
54 | u32 dcache_line; | ||
55 | u32 dcache_size; | ||
56 | unsigned long dcache_base; | ||
57 | unsigned long dcache_high; | ||
58 | |||
59 | /* Bus connections */ | ||
60 | u32 use_dopb; | ||
61 | u32 use_iopb; | ||
62 | u32 use_dlmb; | ||
63 | u32 use_ilmb; | ||
64 | u32 num_fsl; | ||
65 | |||
66 | /* CPU interrupt line info */ | ||
67 | u32 irq_edge; | ||
68 | u32 irq_positive; | ||
69 | |||
70 | u32 area_optimised; | ||
71 | |||
72 | /* HW debug support */ | ||
73 | u32 hw_debug; | ||
74 | u32 num_pc_brk; | ||
75 | u32 num_rd_brk; | ||
76 | u32 num_wr_brk; | ||
77 | u32 cpu_clock_freq; /* store real freq of cpu */ | ||
78 | u32 freq_div_hz; /* store freq/HZ */ | ||
79 | |||
80 | /* FPGA family */ | ||
81 | u32 fpga_family_code; | ||
82 | |||
83 | /* User define */ | ||
84 | u32 pvr_user1; | ||
85 | u32 pvr_user2; | ||
86 | }; | ||
87 | |||
88 | extern struct cpuinfo cpuinfo; | ||
89 | |||
90 | /* fwd declarations of the various CPUinfo populators */ | ||
91 | void setup_cpuinfo(void); | ||
92 | |||
93 | void set_cpuinfo_static(struct cpuinfo *ci, struct device_node *cpu); | ||
94 | void set_cpuinfo_pvr_full(struct cpuinfo *ci, struct device_node *cpu); | ||
95 | |||
96 | static inline unsigned int fcpu(struct device_node *cpu, char *n) | ||
97 | { | ||
98 | int *val; | ||
99 | return (val = (int *) of_get_property(cpu, n, NULL)) ? *val : 0; | ||
100 | } | ||
101 | |||
102 | #endif /* _ASM_MICROBLAZE_CPUINFO_H */ | ||
diff --git a/arch/microblaze/include/asm/cputable.h b/arch/microblaze/include/asm/cputable.h new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/arch/microblaze/include/asm/cputable.h | |||
diff --git a/arch/microblaze/include/asm/cputime.h b/arch/microblaze/include/asm/cputime.h new file mode 100644 index 000000000000..6d68ad7e0ea3 --- /dev/null +++ b/arch/microblaze/include/asm/cputime.h | |||
@@ -0,0 +1 @@ | |||
#include <asm-generic/cputime.h> | |||
diff --git a/arch/microblaze/include/asm/current.h b/arch/microblaze/include/asm/current.h new file mode 100644 index 000000000000..8375ea991e26 --- /dev/null +++ b/arch/microblaze/include/asm/current.h | |||
@@ -0,0 +1,21 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_CURRENT_H | ||
10 | #define _ASM_MICROBLAZE_CURRENT_H | ||
11 | |||
12 | # ifndef __ASSEMBLY__ | ||
13 | /* | ||
14 | * Dedicate r31 to keeping the current task pointer | ||
15 | */ | ||
16 | register struct task_struct *current asm("r31"); | ||
17 | |||
18 | # define get_current() current | ||
19 | # endif /* __ASSEMBLY__ */ | ||
20 | |||
21 | #endif /* _ASM_MICROBLAZE_CURRENT_H */ | ||
diff --git a/arch/microblaze/include/asm/delay.h b/arch/microblaze/include/asm/delay.h new file mode 100644 index 000000000000..05b7d39e4391 --- /dev/null +++ b/arch/microblaze/include/asm/delay.h | |||
@@ -0,0 +1,72 @@ | |||
1 | /* | ||
2 | * include/asm-microblaze/delay.h | ||
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 | * Copyright (C) 2008 Michal Simek | ||
9 | * Copyright (C) 2007 John Williams | ||
10 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
11 | */ | ||
12 | |||
13 | #ifndef _ASM_MICROBLAZE_DELAY_H | ||
14 | #define _ASM_MICROBLAZE_DELAY_H | ||
15 | |||
16 | extern inline void __delay(unsigned long loops) | ||
17 | { | ||
18 | asm volatile ("# __delay \n\t" \ | ||
19 | "1: addi %0, %0, -1\t\n" \ | ||
20 | "bneid %0, 1b \t\n" \ | ||
21 | "nop \t\n" | ||
22 | : "=r" (loops) | ||
23 | : "0" (loops)); | ||
24 | } | ||
25 | |||
26 | /* | ||
27 | * Note that 19 * 226 == 4294 ==~ 2^32 / 10^6, so | ||
28 | * loops = (4294 * usecs * loops_per_jiffy * HZ) / 2^32. | ||
29 | * | ||
30 | * The mul instruction gives us loops = (a * b) / 2^32. | ||
31 | * We choose a = usecs * 19 * HZ and b = loops_per_jiffy * 226 | ||
32 | * because this lets us support a wide range of HZ and | ||
33 | * loops_per_jiffy values without either a or b overflowing 2^32. | ||
34 | * Thus we need usecs * HZ <= (2^32 - 1) / 19 = 226050910 and | ||
35 | * loops_per_jiffy <= (2^32 - 1) / 226 = 19004280 | ||
36 | * (which corresponds to ~3800 bogomips at HZ = 100). | ||
37 | * -- paulus | ||
38 | */ | ||
39 | #define __MAX_UDELAY (226050910UL/HZ) /* maximum udelay argument */ | ||
40 | #define __MAX_NDELAY (4294967295UL/HZ) /* maximum ndelay argument */ | ||
41 | |||
42 | extern unsigned long loops_per_jiffy; | ||
43 | |||
44 | extern inline void __udelay(unsigned int x) | ||
45 | { | ||
46 | |||
47 | unsigned long long tmp = | ||
48 | (unsigned long long)x * (unsigned long long)loops_per_jiffy \ | ||
49 | * 226LL; | ||
50 | unsigned loops = tmp >> 32; | ||
51 | |||
52 | /* | ||
53 | __asm__("mulxuu %0,%1,%2" : "=r" (loops) : | ||
54 | "r" (x), "r" (loops_per_jiffy * 226)); | ||
55 | */ | ||
56 | __delay(loops); | ||
57 | } | ||
58 | |||
59 | extern void __bad_udelay(void); /* deliberately undefined */ | ||
60 | extern void __bad_ndelay(void); /* deliberately undefined */ | ||
61 | |||
62 | #define udelay(n) (__builtin_constant_p(n) ? \ | ||
63 | ((n) > __MAX_UDELAY ? __bad_udelay() : __udelay((n) * (19 * HZ))) : \ | ||
64 | __udelay((n) * (19 * HZ))) | ||
65 | |||
66 | #define ndelay(n) (__builtin_constant_p(n) ? \ | ||
67 | ((n) > __MAX_NDELAY ? __bad_ndelay() : __udelay((n) * HZ)) : \ | ||
68 | __udelay((n) * HZ)) | ||
69 | |||
70 | #define muldiv(a, b, c) (((a)*(b))/(c)) | ||
71 | |||
72 | #endif /* _ASM_MICROBLAZE_DELAY_H */ | ||
diff --git a/arch/microblaze/include/asm/device.h b/arch/microblaze/include/asm/device.h new file mode 100644 index 000000000000..c042830793ed --- /dev/null +++ b/arch/microblaze/include/asm/device.h | |||
@@ -0,0 +1,21 @@ | |||
1 | /* | ||
2 | * Arch specific extensions to struct device | ||
3 | * | ||
4 | * This file is subject to the terms and conditions of the GNU General Public | ||
5 | * License v2. See the file "COPYING" in the main directory of this archive | ||
6 | * for more details. | ||
7 | */ | ||
8 | |||
9 | #ifndef _ASM_MICROBLAZE_DEVICE_H | ||
10 | #define _ASM_MICROBLAZE_DEVICE_H | ||
11 | |||
12 | struct device_node; | ||
13 | |||
14 | struct dev_archdata { | ||
15 | /* Optional pointer to an OF device node */ | ||
16 | struct device_node *of_node; | ||
17 | }; | ||
18 | |||
19 | #endif /* _ASM_MICROBLAZE_DEVICE_H */ | ||
20 | |||
21 | |||
diff --git a/arch/microblaze/include/asm/div64.h b/arch/microblaze/include/asm/div64.h new file mode 100644 index 000000000000..6cd978cefb28 --- /dev/null +++ b/arch/microblaze/include/asm/div64.h | |||
@@ -0,0 +1 @@ | |||
#include <asm-generic/div64.h> | |||
diff --git a/arch/microblaze/include/asm/dma-mapping.h b/arch/microblaze/include/asm/dma-mapping.h new file mode 100644 index 000000000000..17336252a9b8 --- /dev/null +++ b/arch/microblaze/include/asm/dma-mapping.h | |||
@@ -0,0 +1,129 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_DMA_MAPPING_H | ||
10 | #define _ASM_MICROBLAZE_DMA_MAPPING_H | ||
11 | |||
12 | #include <asm/cacheflush.h> | ||
13 | #include <linux/io.h> | ||
14 | #include <linux/bug.h> | ||
15 | |||
16 | struct scatterlist; | ||
17 | |||
18 | #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) | ||
19 | #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) | ||
20 | |||
21 | /* FIXME */ | ||
22 | static inline int | ||
23 | dma_supported(struct device *dev, u64 mask) | ||
24 | { | ||
25 | return 1; | ||
26 | } | ||
27 | |||
28 | static inline dma_addr_t | ||
29 | dma_map_page(struct device *dev, struct page *page, | ||
30 | unsigned long offset, size_t size, | ||
31 | enum dma_data_direction direction) | ||
32 | { | ||
33 | BUG(); | ||
34 | return 0; | ||
35 | } | ||
36 | |||
37 | static inline void | ||
38 | dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size, | ||
39 | enum dma_data_direction direction) | ||
40 | { | ||
41 | BUG(); | ||
42 | } | ||
43 | |||
44 | static inline int | ||
45 | dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, | ||
46 | enum dma_data_direction direction) | ||
47 | { | ||
48 | BUG(); | ||
49 | return 0; | ||
50 | } | ||
51 | |||
52 | static inline void | ||
53 | dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries, | ||
54 | enum dma_data_direction direction) | ||
55 | { | ||
56 | BUG(); | ||
57 | } | ||
58 | |||
59 | static inline void | ||
60 | dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, | ||
61 | enum dma_data_direction direction) | ||
62 | { | ||
63 | BUG(); | ||
64 | } | ||
65 | |||
66 | static inline void | ||
67 | dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, | ||
68 | size_t size, enum dma_data_direction direction) | ||
69 | { | ||
70 | BUG(); | ||
71 | } | ||
72 | |||
73 | static inline void | ||
74 | dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems, | ||
75 | enum dma_data_direction direction) | ||
76 | { | ||
77 | BUG(); | ||
78 | } | ||
79 | |||
80 | static inline void | ||
81 | dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems, | ||
82 | enum dma_data_direction direction) | ||
83 | { | ||
84 | BUG(); | ||
85 | } | ||
86 | |||
87 | static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) | ||
88 | { | ||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | static inline void *dma_alloc_coherent(struct device *dev, size_t size, | ||
93 | dma_addr_t *dma_handle, int flag) | ||
94 | { | ||
95 | return NULL; /* consistent_alloc(flag, size, dma_handle); */ | ||
96 | } | ||
97 | |||
98 | static inline void dma_free_coherent(struct device *dev, size_t size, | ||
99 | void *vaddr, dma_addr_t dma_handle) | ||
100 | { | ||
101 | BUG(); | ||
102 | } | ||
103 | |||
104 | static inline dma_addr_t | ||
105 | dma_map_single(struct device *dev, void *ptr, size_t size, | ||
106 | enum dma_data_direction direction) | ||
107 | { | ||
108 | BUG_ON(direction == DMA_NONE); | ||
109 | |||
110 | return virt_to_bus(ptr); | ||
111 | } | ||
112 | |||
113 | static inline void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, | ||
114 | size_t size, | ||
115 | enum dma_data_direction direction) | ||
116 | { | ||
117 | switch (direction) { | ||
118 | case DMA_FROM_DEVICE: | ||
119 | flush_dcache_range((unsigned)dma_addr, | ||
120 | (unsigned)dma_addr + size); | ||
121 | /* Fall through */ | ||
122 | case DMA_TO_DEVICE: | ||
123 | break; | ||
124 | default: | ||
125 | BUG(); | ||
126 | } | ||
127 | } | ||
128 | |||
129 | #endif /* _ASM_MICROBLAZE_DMA_MAPPING_H */ | ||
diff --git a/arch/microblaze/include/asm/dma.h b/arch/microblaze/include/asm/dma.h new file mode 100644 index 000000000000..0967fa04fc5e --- /dev/null +++ b/arch/microblaze/include/asm/dma.h | |||
@@ -0,0 +1,16 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_DMA_H | ||
10 | #define _ASM_MICROBLAZE_DMA_H | ||
11 | |||
12 | /* we don't have dma address limit. define it as zero to be | ||
13 | * unlimited. */ | ||
14 | #define MAX_DMA_ADDRESS (0) | ||
15 | |||
16 | #endif /* _ASM_MICROBLAZE_DMA_H */ | ||
diff --git a/arch/microblaze/include/asm/elf.h b/arch/microblaze/include/asm/elf.h new file mode 100644 index 000000000000..81337f241347 --- /dev/null +++ b/arch/microblaze/include/asm/elf.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_ELF_H | ||
10 | #define _ASM_MICROBLAZE_ELF_H | ||
11 | |||
12 | /* | ||
13 | * Note there is no "official" ELF designation for Microblaze. | ||
14 | * I've snaffled the value from the microblaze binutils source code | ||
15 | * /binutils/microblaze/include/elf/microblaze.h | ||
16 | */ | ||
17 | #define EM_XILINX_MICROBLAZE 0xbaab | ||
18 | #define ELF_ARCH EM_XILINX_MICROBLAZE | ||
19 | |||
20 | /* | ||
21 | * This is used to ensure we don't load something for the wrong architecture. | ||
22 | */ | ||
23 | #define elf_check_arch(x) ((x)->e_machine == EM_XILINX_MICROBLAZE) | ||
24 | |||
25 | /* | ||
26 | * These are used to set parameters in the core dumps. | ||
27 | */ | ||
28 | #define ELF_CLASS ELFCLASS32 | ||
29 | |||
30 | #endif /* _ASM_MICROBLAZE_ELF_H */ | ||
diff --git a/arch/microblaze/include/asm/emergency-restart.h b/arch/microblaze/include/asm/emergency-restart.h new file mode 100644 index 000000000000..3711bd9d50bd --- /dev/null +++ b/arch/microblaze/include/asm/emergency-restart.h | |||
@@ -0,0 +1 @@ | |||
#include <asm-generic/emergency-restart.h> | |||
diff --git a/arch/microblaze/include/asm/entry.h b/arch/microblaze/include/asm/entry.h new file mode 100644 index 000000000000..7f57e42ee467 --- /dev/null +++ b/arch/microblaze/include/asm/entry.h | |||
@@ -0,0 +1,35 @@ | |||
1 | /* | ||
2 | * Definitions used by low-level trap handlers | ||
3 | * | ||
4 | * Copyright (C) 2008 Michal Simek | ||
5 | * Copyright (C) 2007 - 2008 PetaLogix | ||
6 | * Copyright (C) 2007 John Williams <john.williams@petalogix.com> | ||
7 | * | ||
8 | * This file is subject to the terms and conditions of the GNU General | ||
9 | * Public License. See the file COPYING in the main directory of this | ||
10 | * archive for more details. | ||
11 | */ | ||
12 | |||
13 | #ifndef _ASM_MICROBLAZE_ENTRY_H | ||
14 | #define _ASM_MICROBLAZE_ENTRY_H | ||
15 | |||
16 | #include <asm/percpu.h> | ||
17 | #include <asm/ptrace.h> | ||
18 | |||
19 | /* | ||
20 | * These are per-cpu variables required in entry.S, among other | ||
21 | * places | ||
22 | */ | ||
23 | |||
24 | #define PER_CPU(var) per_cpu__##var | ||
25 | |||
26 | # ifndef __ASSEMBLY__ | ||
27 | DECLARE_PER_CPU(unsigned int, KSP); /* Saved kernel stack pointer */ | ||
28 | DECLARE_PER_CPU(unsigned int, KM); /* Kernel/user mode */ | ||
29 | DECLARE_PER_CPU(unsigned int, ENTRY_SP); /* Saved SP on kernel entry */ | ||
30 | DECLARE_PER_CPU(unsigned int, R11_SAVE); /* Temp variable for entry */ | ||
31 | DECLARE_PER_CPU(unsigned int, CURRENT_SAVE); /* Saved current pointer */ | ||
32 | DECLARE_PER_CPU(unsigned int, SYSCALL_SAVE); /* Saved syscall number */ | ||
33 | # endif /* __ASSEMBLY__ */ | ||
34 | |||
35 | #endif /* _ASM_MICROBLAZE_ENTRY_H */ | ||
diff --git a/arch/microblaze/include/asm/errno.h b/arch/microblaze/include/asm/errno.h new file mode 100644 index 000000000000..4c82b503d92f --- /dev/null +++ b/arch/microblaze/include/asm/errno.h | |||
@@ -0,0 +1 @@ | |||
#include <asm-generic/errno.h> | |||
diff --git a/arch/microblaze/include/asm/exceptions.h b/arch/microblaze/include/asm/exceptions.h new file mode 100644 index 000000000000..4cdd2159f470 --- /dev/null +++ b/arch/microblaze/include/asm/exceptions.h | |||
@@ -0,0 +1,96 @@ | |||
1 | /* | ||
2 | * Preliminary support for HW exception handing for Microblaze | ||
3 | * | ||
4 | * Copyright (C) 2008 Michal Simek | ||
5 | * Copyright (C) 2008 PetaLogix | ||
6 | * Copyright (C) 2005 John Williams <jwilliams@itee.uq.edu.au> | ||
7 | * | ||
8 | * This file is subject to the terms and conditions of the GNU General | ||
9 | * Public License. See the file COPYING in the main directory of this | ||
10 | * archive for more details. | ||
11 | */ | ||
12 | |||
13 | #ifndef _ASM_MICROBLAZE_EXCEPTIONS_H | ||
14 | #define _ASM_MICROBLAZE_EXCEPTIONS_H | ||
15 | |||
16 | #ifdef __KERNEL__ | ||
17 | #ifndef __ASSEMBLY__ | ||
18 | |||
19 | /* Macros to enable and disable HW exceptions in the MSR */ | ||
20 | /* Define MSR enable bit for HW exceptions */ | ||
21 | #define HWEX_MSR_BIT (1 << 8) | ||
22 | |||
23 | #if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR | ||
24 | #define __enable_hw_exceptions() \ | ||
25 | __asm__ __volatile__ (" msrset r0, %0; \ | ||
26 | nop;" \ | ||
27 | : \ | ||
28 | : "i" (HWEX_MSR_BIT) \ | ||
29 | : "memory") | ||
30 | |||
31 | #define __disable_hw_exceptions() \ | ||
32 | __asm__ __volatile__ (" msrclr r0, %0; \ | ||
33 | nop;" \ | ||
34 | : \ | ||
35 | : "i" (HWEX_MSR_BIT) \ | ||
36 | : "memory") | ||
37 | #else /* !CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR */ | ||
38 | #define __enable_hw_exceptions() \ | ||
39 | __asm__ __volatile__ (" \ | ||
40 | mfs r12, rmsr; \ | ||
41 | nop; \ | ||
42 | ori r12, r12, %0; \ | ||
43 | mts rmsr, r12; \ | ||
44 | nop;" \ | ||
45 | : \ | ||
46 | : "i" (HWEX_MSR_BIT) \ | ||
47 | : "memory", "r12") | ||
48 | |||
49 | #define __disable_hw_exceptions() \ | ||
50 | __asm__ __volatile__ (" \ | ||
51 | mfs r12, rmsr; \ | ||
52 | nop; \ | ||
53 | andi r12, r12, ~%0; \ | ||
54 | mts rmsr, r12; \ | ||
55 | nop;" \ | ||
56 | : \ | ||
57 | : "i" (HWEX_MSR_BIT) \ | ||
58 | : "memory", "r12") | ||
59 | #endif /* CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR */ | ||
60 | |||
61 | asmlinkage void full_exception(struct pt_regs *regs, unsigned int type, | ||
62 | int fsr, int addr); | ||
63 | |||
64 | #if defined(CONFIG_XMON) | ||
65 | extern void xmon(struct pt_regs *regs); | ||
66 | extern int xmon_bpt(struct pt_regs *regs); | ||
67 | extern int xmon_sstep(struct pt_regs *regs); | ||
68 | extern int xmon_iabr_match(struct pt_regs *regs); | ||
69 | extern int xmon_dabr_match(struct pt_regs *regs); | ||
70 | extern void (*xmon_fault_handler)(struct pt_regs *regs); | ||
71 | |||
72 | void (*debugger)(struct pt_regs *regs) = xmon; | ||
73 | int (*debugger_bpt)(struct pt_regs *regs) = xmon_bpt; | ||
74 | int (*debugger_sstep)(struct pt_regs *regs) = xmon_sstep; | ||
75 | int (*debugger_iabr_match)(struct pt_regs *regs) = xmon_iabr_match; | ||
76 | int (*debugger_dabr_match)(struct pt_regs *regs) = xmon_dabr_match; | ||
77 | void (*debugger_fault_handler)(struct pt_regs *regs); | ||
78 | #elif defined(CONFIG_KGDB) | ||
79 | void (*debugger)(struct pt_regs *regs); | ||
80 | int (*debugger_bpt)(struct pt_regs *regs); | ||
81 | int (*debugger_sstep)(struct pt_regs *regs); | ||
82 | int (*debugger_iabr_match)(struct pt_regs *regs); | ||
83 | int (*debugger_dabr_match)(struct pt_regs *regs); | ||
84 | void (*debugger_fault_handler)(struct pt_regs *regs); | ||
85 | #else | ||
86 | #define debugger(regs) do { } while (0) | ||
87 | #define debugger_bpt(regs) 0 | ||
88 | #define debugger_sstep(regs) 0 | ||
89 | #define debugger_iabr_match(regs) 0 | ||
90 | #define debugger_dabr_match(regs) 0 | ||
91 | #define debugger_fault_handler ((void (*)(struct pt_regs *))0) | ||
92 | #endif | ||
93 | |||
94 | #endif /*__ASSEMBLY__ */ | ||
95 | #endif /* __KERNEL__ */ | ||
96 | #endif /* _ASM_MICROBLAZE_EXCEPTIONS_H */ | ||
diff --git a/arch/microblaze/include/asm/fcntl.h b/arch/microblaze/include/asm/fcntl.h new file mode 100644 index 000000000000..46ab12db5739 --- /dev/null +++ b/arch/microblaze/include/asm/fcntl.h | |||
@@ -0,0 +1 @@ | |||
#include <asm-generic/fcntl.h> | |||
diff --git a/arch/microblaze/include/asm/flat.h b/arch/microblaze/include/asm/flat.h new file mode 100644 index 000000000000..acf0da543ef1 --- /dev/null +++ b/arch/microblaze/include/asm/flat.h | |||
@@ -0,0 +1,90 @@ | |||
1 | /* | ||
2 | * uClinux flat-format executables | ||
3 | * | ||
4 | * Copyright (C) 2005 John Williams <jwilliams@itee.uq.edu.au> | ||
5 | * | ||
6 | * This file is subject to the terms and conditions of the GNU General | ||
7 | * Public License. See the file COPYING in the main directory of this | ||
8 | * archive for more details. | ||
9 | */ | ||
10 | |||
11 | #ifndef _ASM_MICROBLAZE_FLAT_H | ||
12 | #define _ASM_MICROBLAZE_FLAT_H | ||
13 | |||
14 | #include <asm/unaligned.h> | ||
15 | |||
16 | #define flat_stack_align(sp) /* nothing needed */ | ||
17 | #define flat_argvp_envp_on_stack() 0 | ||
18 | #define flat_old_ram_flag(flags) (flags) | ||
19 | #define flat_reloc_valid(reloc, size) ((reloc) <= (size)) | ||
20 | #define flat_set_persistent(relval, p) 0 | ||
21 | |||
22 | /* | ||
23 | * Microblaze works a little differently from other arches, because | ||
24 | * of the MICROBLAZE_64 reloc type. Here, a 32 bit address is split | ||
25 | * over two instructions, an 'imm' instruction which provides the top | ||
26 | * 16 bits, then the instruction "proper" which provides the low 16 | ||
27 | * bits. | ||
28 | */ | ||
29 | |||
30 | /* | ||
31 | * Crack open a symbol reference and extract the address to be | ||
32 | * relocated. rp is a potentially unaligned pointer to the | ||
33 | * reference | ||
34 | */ | ||
35 | |||
36 | static inline unsigned long | ||
37 | flat_get_addr_from_rp(unsigned long *rp, unsigned long relval, | ||
38 | unsigned long flags, unsigned long *persistent) | ||
39 | { | ||
40 | unsigned long addr; | ||
41 | (void)flags; | ||
42 | |||
43 | /* Is it a split 64/32 reference? */ | ||
44 | if (relval & 0x80000000) { | ||
45 | /* Grab the two halves of the reference */ | ||
46 | unsigned long val_hi, val_lo; | ||
47 | |||
48 | val_hi = get_unaligned(rp); | ||
49 | val_lo = get_unaligned(rp+1); | ||
50 | |||
51 | /* Crack the address out */ | ||
52 | addr = ((val_hi & 0xffff) << 16) + (val_lo & 0xffff); | ||
53 | } else { | ||
54 | /* Get the address straight out */ | ||
55 | addr = get_unaligned(rp); | ||
56 | } | ||
57 | |||
58 | return addr; | ||
59 | } | ||
60 | |||
61 | /* | ||
62 | * Insert an address into the symbol reference at rp. rp is potentially | ||
63 | * unaligned. | ||
64 | */ | ||
65 | |||
66 | static inline void | ||
67 | flat_put_addr_at_rp(unsigned long *rp, unsigned long addr, unsigned long relval) | ||
68 | { | ||
69 | /* Is this a split 64/32 reloc? */ | ||
70 | if (relval & 0x80000000) { | ||
71 | /* Get the two "halves" */ | ||
72 | unsigned long val_hi = get_unaligned(rp); | ||
73 | unsigned long val_lo = get_unaligned(rp + 1); | ||
74 | |||
75 | /* insert the address */ | ||
76 | val_hi = (val_hi & 0xffff0000) | addr >> 16; | ||
77 | val_lo = (val_lo & 0xffff0000) | (addr & 0xffff); | ||
78 | |||
79 | /* store the two halves back into memory */ | ||
80 | put_unaligned(val_hi, rp); | ||
81 | put_unaligned(val_lo, rp+1); | ||
82 | } else { | ||
83 | /* Put it straight in, no messing around */ | ||
84 | put_unaligned(addr, rp); | ||
85 | } | ||
86 | } | ||
87 | |||
88 | #define flat_get_relocate_addr(rel) (rel & 0x7fffffff) | ||
89 | |||
90 | #endif /* _ASM_MICROBLAZE_FLAT_H */ | ||
diff --git a/arch/microblaze/include/asm/futex.h b/arch/microblaze/include/asm/futex.h new file mode 100644 index 000000000000..0b745828f42b --- /dev/null +++ b/arch/microblaze/include/asm/futex.h | |||
@@ -0,0 +1 @@ | |||
#include <asm-generic/futex.h> | |||
diff --git a/arch/microblaze/include/asm/gpio.h b/arch/microblaze/include/asm/gpio.h new file mode 100644 index 000000000000..ea04632399d8 --- /dev/null +++ b/arch/microblaze/include/asm/gpio.h | |||
@@ -0,0 +1,56 @@ | |||
1 | /* | ||
2 | * Generic GPIO API implementation for PowerPC. | ||
3 | * | ||
4 | * Copyright (c) 2007-2008 MontaVista Software, Inc. | ||
5 | * | ||
6 | * Author: Anton Vorontsov <avorontsov@ru.mvista.com> | ||
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 | |||
14 | #ifndef __ASM_POWERPC_GPIO_H | ||
15 | #define __ASM_POWERPC_GPIO_H | ||
16 | |||
17 | #include <linux/errno.h> | ||
18 | #include <asm-generic/gpio.h> | ||
19 | |||
20 | #ifdef CONFIG_GPIOLIB | ||
21 | |||
22 | /* | ||
23 | * We don't (yet) implement inlined/rapid versions for on-chip gpios. | ||
24 | * Just call gpiolib. | ||
25 | */ | ||
26 | static inline int gpio_get_value(unsigned int gpio) | ||
27 | { | ||
28 | return __gpio_get_value(gpio); | ||
29 | } | ||
30 | |||
31 | static inline void gpio_set_value(unsigned int gpio, int value) | ||
32 | { | ||
33 | __gpio_set_value(gpio, value); | ||
34 | } | ||
35 | |||
36 | static inline int gpio_cansleep(unsigned int gpio) | ||
37 | { | ||
38 | return __gpio_cansleep(gpio); | ||
39 | } | ||
40 | |||
41 | /* | ||
42 | * Not implemented, yet. | ||
43 | */ | ||
44 | static inline int gpio_to_irq(unsigned int gpio) | ||
45 | { | ||
46 | return -ENOSYS; | ||
47 | } | ||
48 | |||
49 | static inline int irq_to_gpio(unsigned int irq) | ||
50 | { | ||
51 | return -EINVAL; | ||
52 | } | ||
53 | |||
54 | #endif /* CONFIG_GPIOLIB */ | ||
55 | |||
56 | #endif /* __ASM_POWERPC_GPIO_H */ | ||
diff --git a/arch/microblaze/include/asm/hardirq.h b/arch/microblaze/include/asm/hardirq.h new file mode 100644 index 000000000000..0f2d6b013e11 --- /dev/null +++ b/arch/microblaze/include/asm/hardirq.h | |||
@@ -0,0 +1,29 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_HARDIRQ_H | ||
10 | #define _ASM_MICROBLAZE_HARDIRQ_H | ||
11 | |||
12 | #include <linux/cache.h> | ||
13 | #include <linux/irq.h> | ||
14 | #include <asm/irq.h> | ||
15 | #include <asm/current.h> | ||
16 | #include <linux/ptrace.h> | ||
17 | |||
18 | /* should be defined in each interrupt controller driver */ | ||
19 | extern unsigned int get_irq(struct pt_regs *regs); | ||
20 | |||
21 | typedef struct { | ||
22 | unsigned int __softirq_pending; | ||
23 | } ____cacheline_aligned irq_cpustat_t; | ||
24 | |||
25 | void ack_bad_irq(unsigned int irq); | ||
26 | |||
27 | #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ | ||
28 | |||
29 | #endif /* _ASM_MICROBLAZE_HARDIRQ_H */ | ||
diff --git a/arch/microblaze/include/asm/hw_irq.h b/arch/microblaze/include/asm/hw_irq.h new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/arch/microblaze/include/asm/hw_irq.h | |||
diff --git a/arch/microblaze/include/asm/io.h b/arch/microblaze/include/asm/io.h new file mode 100644 index 000000000000..cfab0342588d --- /dev/null +++ b/arch/microblaze/include/asm/io.h | |||
@@ -0,0 +1,209 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_IO_H | ||
10 | #define _ASM_MICROBLAZE_IO_H | ||
11 | |||
12 | #include <asm/byteorder.h> | ||
13 | #include <asm/page.h> | ||
14 | #include <linux/types.h> | ||
15 | #include <asm/page.h> | ||
16 | |||
17 | #define IO_SPACE_LIMIT (0xFFFFFFFF) | ||
18 | |||
19 | static inline unsigned char __raw_readb(const volatile void __iomem *addr) | ||
20 | { | ||
21 | return *(volatile unsigned char __force *)addr; | ||
22 | } | ||
23 | static inline unsigned short __raw_readw(const volatile void __iomem *addr) | ||
24 | { | ||
25 | return *(volatile unsigned short __force *)addr; | ||
26 | } | ||
27 | static inline unsigned int __raw_readl(const volatile void __iomem *addr) | ||
28 | { | ||
29 | return *(volatile unsigned int __force *)addr; | ||
30 | } | ||
31 | static inline unsigned long __raw_readq(const volatile void __iomem *addr) | ||
32 | { | ||
33 | return *(volatile unsigned long __force *)addr; | ||
34 | } | ||
35 | static inline void __raw_writeb(unsigned char v, volatile void __iomem *addr) | ||
36 | { | ||
37 | *(volatile unsigned char __force *)addr = v; | ||
38 | } | ||
39 | static inline void __raw_writew(unsigned short v, volatile void __iomem *addr) | ||
40 | { | ||
41 | *(volatile unsigned short __force *)addr = v; | ||
42 | } | ||
43 | static inline void __raw_writel(unsigned int v, volatile void __iomem *addr) | ||
44 | { | ||
45 | *(volatile unsigned int __force *)addr = v; | ||
46 | } | ||
47 | static inline void __raw_writeq(unsigned long v, volatile void __iomem *addr) | ||
48 | { | ||
49 | *(volatile unsigned long __force *)addr = v; | ||
50 | } | ||
51 | |||
52 | /* | ||
53 | * read (readb, readw, readl, readq) and write (writeb, writew, | ||
54 | * writel, writeq) accessors are for PCI and thus littel endian. | ||
55 | * Linux 2.4 for Microblaze had this wrong. | ||
56 | */ | ||
57 | static inline unsigned char readb(const volatile void __iomem *addr) | ||
58 | { | ||
59 | return *(volatile unsigned char __force *)addr; | ||
60 | } | ||
61 | static inline unsigned short readw(const volatile void __iomem *addr) | ||
62 | { | ||
63 | return le16_to_cpu(*(volatile unsigned short __force *)addr); | ||
64 | } | ||
65 | static inline unsigned int readl(const volatile void __iomem *addr) | ||
66 | { | ||
67 | return le32_to_cpu(*(volatile unsigned int __force *)addr); | ||
68 | } | ||
69 | static inline void writeb(unsigned char v, volatile void __iomem *addr) | ||
70 | { | ||
71 | *(volatile unsigned char __force *)addr = v; | ||
72 | } | ||
73 | static inline void writew(unsigned short v, volatile void __iomem *addr) | ||
74 | { | ||
75 | *(volatile unsigned short __force *)addr = cpu_to_le16(v); | ||
76 | } | ||
77 | static inline void writel(unsigned int v, volatile void __iomem *addr) | ||
78 | { | ||
79 | *(volatile unsigned int __force *)addr = cpu_to_le32(v); | ||
80 | } | ||
81 | |||
82 | /* ioread and iowrite variants. thease are for now same as __raw_ | ||
83 | * variants of accessors. we might check for endianess in the feature | ||
84 | */ | ||
85 | #define ioread8(addr) __raw_readb((u8 *)(addr)) | ||
86 | #define ioread16(addr) __raw_readw((u16 *)(addr)) | ||
87 | #define ioread32(addr) __raw_readl((u32 *)(addr)) | ||
88 | #define iowrite8(v, addr) __raw_writeb((u8)(v), (u8 *)(addr)) | ||
89 | #define iowrite16(v, addr) __raw_writew((u16)(v), (u16 *)(addr)) | ||
90 | #define iowrite32(v, addr) __raw_writel((u32)(v), (u32 *)(addr)) | ||
91 | |||
92 | /* These are the definitions for the x86 IO instructions | ||
93 | * inb/inw/inl/outb/outw/outl, the "string" versions | ||
94 | * insb/insw/insl/outsb/outsw/outsl, and the "pausing" versions | ||
95 | * inb_p/inw_p/... | ||
96 | * The macros don't do byte-swapping. | ||
97 | */ | ||
98 | #define inb(port) readb((u8 *)((port))) | ||
99 | #define outb(val, port) writeb((val), (u8 *)((unsigned long)(port))) | ||
100 | #define inw(port) readw((u16 *)((port))) | ||
101 | #define outw(val, port) writew((val), (u16 *)((unsigned long)(port))) | ||
102 | #define inl(port) readl((u32 *)((port))) | ||
103 | #define outl(val, port) writel((val), (u32 *)((unsigned long)(port))) | ||
104 | |||
105 | #define inb_p(port) inb((port)) | ||
106 | #define outb_p(val, port) outb((val), (port)) | ||
107 | #define inw_p(port) inw((port)) | ||
108 | #define outw_p(val, port) outw((val), (port)) | ||
109 | #define inl_p(port) inl((port)) | ||
110 | #define outl_p(val, port) outl((val), (port)) | ||
111 | |||
112 | #define memset_io(a, b, c) memset((void *)(a), (b), (c)) | ||
113 | #define memcpy_fromio(a, b, c) memcpy((a), (void *)(b), (c)) | ||
114 | #define memcpy_toio(a, b, c) memcpy((void *)(a), (b), (c)) | ||
115 | |||
116 | /** | ||
117 | * virt_to_phys - map virtual addresses to physical | ||
118 | * @address: address to remap | ||
119 | * | ||
120 | * The returned physical address is the physical (CPU) mapping for | ||
121 | * the memory address given. It is only valid to use this function on | ||
122 | * addresses directly mapped or allocated via kmalloc. | ||
123 | * | ||
124 | * This function does not give bus mappings for DMA transfers. In | ||
125 | * almost all conceivable cases a device driver should not be using | ||
126 | * this function | ||
127 | */ | ||
128 | static inline unsigned long __iomem virt_to_phys(volatile void *address) | ||
129 | { | ||
130 | return __pa((unsigned long)address); | ||
131 | } | ||
132 | |||
133 | #define virt_to_bus virt_to_phys | ||
134 | |||
135 | /** | ||
136 | * phys_to_virt - map physical address to virtual | ||
137 | * @address: address to remap | ||
138 | * | ||
139 | * The returned virtual address is a current CPU mapping for | ||
140 | * the memory address given. It is only valid to use this function on | ||
141 | * addresses that have a kernel mapping | ||
142 | * | ||
143 | * This function does not handle bus mappings for DMA transfers. In | ||
144 | * almost all conceivable cases a device driver should not be using | ||
145 | * this function | ||
146 | */ | ||
147 | static inline void *phys_to_virt(unsigned long address) | ||
148 | { | ||
149 | return (void *)__va(address); | ||
150 | } | ||
151 | |||
152 | #define bus_to_virt(a) phys_to_virt(a) | ||
153 | |||
154 | static inline void __iomem *__ioremap(phys_addr_t address, unsigned long size, | ||
155 | unsigned long flags) | ||
156 | { | ||
157 | return (void *)address; | ||
158 | } | ||
159 | |||
160 | #define ioremap(physaddr, size) ((void __iomem *)(unsigned long)(physaddr)) | ||
161 | #define iounmap(addr) ((void)0) | ||
162 | #define ioremap_nocache(physaddr, size) ioremap(physaddr, size) | ||
163 | |||
164 | /* | ||
165 | * Convert a physical pointer to a virtual kernel pointer for /dev/mem | ||
166 | * access | ||
167 | */ | ||
168 | #define xlate_dev_mem_ptr(p) __va(p) | ||
169 | |||
170 | /* | ||
171 | * Convert a virtual cached pointer to an uncached pointer | ||
172 | */ | ||
173 | #define xlate_dev_kmem_ptr(p) p | ||
174 | |||
175 | /* | ||
176 | * Big Endian | ||
177 | */ | ||
178 | #define out_be32(a, v) __raw_writel((v), (void __iomem __force *)(a)) | ||
179 | #define out_be16(a, v) __raw_writew((v), (a)) | ||
180 | |||
181 | #define in_be32(a) __raw_readl((const void __iomem __force *)(a)) | ||
182 | #define in_be16(a) __raw_readw(a) | ||
183 | |||
184 | /* | ||
185 | * Little endian | ||
186 | */ | ||
187 | |||
188 | #define out_le32(a, v) __raw_writel(__cpu_to_le32(v), (a)); | ||
189 | #define out_le16(a, v) __raw_writew(__cpu_to_le16(v), (a)) | ||
190 | |||
191 | #define in_le32(a) __le32_to_cpu(__raw_readl(a)) | ||
192 | #define in_le16(a) __le16_to_cpu(__raw_readw(a)) | ||
193 | |||
194 | /* Byte ops */ | ||
195 | #define out_8(a, v) __raw_writeb((v), (a)) | ||
196 | #define in_8(a) __raw_readb(a) | ||
197 | |||
198 | /* FIXME */ | ||
199 | static inline void __iomem *ioport_map(unsigned long port, unsigned int len) | ||
200 | { | ||
201 | return (void __iomem *) (port); | ||
202 | } | ||
203 | |||
204 | static inline void ioport_unmap(void __iomem *addr) | ||
205 | { | ||
206 | /* Nothing to do */ | ||
207 | } | ||
208 | |||
209 | #endif /* _ASM_MICROBLAZE_IO_H */ | ||
diff --git a/arch/microblaze/include/asm/ioctl.h b/arch/microblaze/include/asm/ioctl.h new file mode 100644 index 000000000000..b279fe06dfe5 --- /dev/null +++ b/arch/microblaze/include/asm/ioctl.h | |||
@@ -0,0 +1 @@ | |||
#include <asm-generic/ioctl.h> | |||
diff --git a/arch/microblaze/include/asm/ioctls.h b/arch/microblaze/include/asm/ioctls.h new file mode 100644 index 000000000000..03582b249204 --- /dev/null +++ b/arch/microblaze/include/asm/ioctls.h | |||
@@ -0,0 +1,91 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_IOCTLS_H | ||
10 | #define _ASM_MICROBLAZE_IOCTLS_H | ||
11 | |||
12 | #include <linux/ioctl.h> | ||
13 | |||
14 | /* 0x54 is just a magic number to make these relatively unique ('T') */ | ||
15 | |||
16 | #define TCGETS 0x5401 | ||
17 | #define TCSETS 0x5402 | ||
18 | #define TCSETSW 0x5403 | ||
19 | #define TCSETSF 0x5404 | ||
20 | #define TCGETA 0x5405 | ||
21 | #define TCSETA 0x5406 | ||
22 | #define TCSETAW 0x5407 | ||
23 | #define TCSETAF 0x5408 | ||
24 | #define TCSBRK 0x5409 | ||
25 | #define TCXONC 0x540A | ||
26 | #define TCFLSH 0x540B | ||
27 | #define TIOCEXCL 0x540C | ||
28 | #define TIOCNXCL 0x540D | ||
29 | #define TIOCSCTTY 0x540E | ||
30 | #define TIOCGPGRP 0x540F | ||
31 | #define TIOCSPGRP 0x5410 | ||
32 | #define TIOCOUTQ 0x5411 | ||
33 | #define TIOCSTI 0x5412 | ||
34 | #define TIOCGWINSZ 0x5413 | ||
35 | #define TIOCSWINSZ 0x5414 | ||
36 | #define TIOCMGET 0x5415 | ||
37 | #define TIOCMBIS 0x5416 | ||
38 | #define TIOCMBIC 0x5417 | ||
39 | #define TIOCMSET 0x5418 | ||
40 | #define TIOCGSOFTCAR 0x5419 | ||
41 | #define TIOCSSOFTCAR 0x541A | ||
42 | #define FIONREAD 0x541B | ||
43 | #define TIOCINQ FIONREAD | ||
44 | #define TIOCLINUX 0x541C | ||
45 | #define TIOCCONS 0x541D | ||
46 | #define TIOCGSERIAL 0x541E | ||
47 | #define TIOCSSERIAL 0x541F | ||
48 | #define TIOCPKT 0x5420 | ||
49 | #define FIONBIO 0x5421 | ||
50 | #define TIOCNOTTY 0x5422 | ||
51 | #define TIOCSETD 0x5423 | ||
52 | #define TIOCGETD 0x5424 | ||
53 | #define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ | ||
54 | #define TIOCTTYGSTRUCT 0x5426 /* For debugging only */ | ||
55 | #define TIOCSBRK 0x5427 /* BSD compatibility */ | ||
56 | #define TIOCCBRK 0x5428 /* BSD compatibility */ | ||
57 | #define TIOCGSID 0x5429 /* Return the session ID of FD */ | ||
58 | /* Get Pty Number (of pty-mux device) */ | ||
59 | #define TIOCGPTN _IOR('T', 0x30, unsigned int) | ||
60 | #define TIOCSPTLCK _IOW('T', 0x31, int) /* Lock/unlock Pty */ | ||
61 | |||
62 | #define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ | ||
63 | #define FIOCLEX 0x5451 | ||
64 | #define FIOASYNC 0x5452 | ||
65 | #define TIOCSERCONFIG 0x5453 | ||
66 | #define TIOCSERGWILD 0x5454 | ||
67 | #define TIOCSERSWILD 0x5455 | ||
68 | #define TIOCGLCKTRMIOS 0x5456 | ||
69 | #define TIOCSLCKTRMIOS 0x5457 | ||
70 | #define TIOCSERGSTRUCT 0x5458 /* For debugging only */ | ||
71 | #define TIOCSERGETLSR 0x5459 /* Get line status register */ | ||
72 | #define TIOCSERGETMULTI 0x545A /* Get multiport config */ | ||
73 | #define TIOCSERSETMULTI 0x545B /* Set multiport config */ | ||
74 | |||
75 | #define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ | ||
76 | #define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ | ||
77 | |||
78 | #define FIOQSIZE 0x545E | ||
79 | |||
80 | /* Used for packet mode */ | ||
81 | #define TIOCPKT_DATA 0 | ||
82 | #define TIOCPKT_FLUSHREAD 1 | ||
83 | #define TIOCPKT_FLUSHWRITE 2 | ||
84 | #define TIOCPKT_STOP 4 | ||
85 | #define TIOCPKT_START 8 | ||
86 | #define TIOCPKT_NOSTOP 16 | ||
87 | #define TIOCPKT_DOSTOP 32 | ||
88 | |||
89 | #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ | ||
90 | |||
91 | #endif /* _ASM_MICROBLAZE_IOCTLS_H */ | ||
diff --git a/arch/microblaze/include/asm/ipc.h b/arch/microblaze/include/asm/ipc.h new file mode 100644 index 000000000000..a46e3d9c2a3f --- /dev/null +++ b/arch/microblaze/include/asm/ipc.h | |||
@@ -0,0 +1 @@ | |||
#include <asm-generic/ipc.h> | |||
diff --git a/arch/microblaze/include/asm/ipcbuf.h b/arch/microblaze/include/asm/ipcbuf.h new file mode 100644 index 000000000000..b056fa420654 --- /dev/null +++ b/arch/microblaze/include/asm/ipcbuf.h | |||
@@ -0,0 +1,36 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_IPCBUF_H | ||
10 | #define _ASM_MICROBLAZE_IPCBUF_H | ||
11 | |||
12 | /* | ||
13 | * The user_ipc_perm structure for microblaze architecture. | ||
14 | * Note extra padding because this structure is passed back and forth | ||
15 | * between kernel and user space. | ||
16 | * | ||
17 | * Pad space is left for: | ||
18 | * - 32-bit mode_t and seq | ||
19 | * - 2 miscellaneous 32-bit values | ||
20 | */ | ||
21 | |||
22 | struct ipc64_perm { | ||
23 | __kernel_key_t key; | ||
24 | __kernel_uid32_t uid; | ||
25 | __kernel_gid32_t gid; | ||
26 | __kernel_uid32_t cuid; | ||
27 | __kernel_gid32_t cgid; | ||
28 | __kernel_mode_t mode; | ||
29 | unsigned short __pad1; | ||
30 | unsigned short seq; | ||
31 | unsigned short __pad2; | ||
32 | unsigned long __unused1; | ||
33 | unsigned long __unused2; | ||
34 | }; | ||
35 | |||
36 | #endif /* _ASM_MICROBLAZE_IPCBUF_H */ | ||
diff --git a/arch/microblaze/include/asm/irq.h b/arch/microblaze/include/asm/irq.h new file mode 100644 index 000000000000..db515deaa720 --- /dev/null +++ b/arch/microblaze/include/asm/irq.h | |||
@@ -0,0 +1,47 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_IRQ_H | ||
10 | #define _ASM_MICROBLAZE_IRQ_H | ||
11 | |||
12 | #define NR_IRQS 32 | ||
13 | |||
14 | #include <linux/interrupt.h> | ||
15 | |||
16 | extern unsigned int nr_irq; | ||
17 | |||
18 | #define NO_IRQ (-1) | ||
19 | |||
20 | static inline int irq_canonicalize(int irq) | ||
21 | { | ||
22 | return irq; | ||
23 | } | ||
24 | |||
25 | struct pt_regs; | ||
26 | extern void do_IRQ(struct pt_regs *regs); | ||
27 | |||
28 | /* irq_of_parse_and_map - Parse and Map an interrupt into linux virq space | ||
29 | * @device: Device node of the device whose interrupt is to be mapped | ||
30 | * @index: Index of the interrupt to map | ||
31 | * | ||
32 | * This function is a wrapper that chains of_irq_map_one() and | ||
33 | * irq_create_of_mapping() to make things easier to callers | ||
34 | */ | ||
35 | struct device_node; | ||
36 | extern unsigned int irq_of_parse_and_map(struct device_node *dev, int index); | ||
37 | |||
38 | /** FIXME - not implement | ||
39 | * irq_dispose_mapping - Unmap an interrupt | ||
40 | * @virq: linux virq number of the interrupt to unmap | ||
41 | */ | ||
42 | static inline void irq_dispose_mapping(unsigned int virq) | ||
43 | { | ||
44 | return; | ||
45 | } | ||
46 | |||
47 | #endif /* _ASM_MICROBLAZE_IRQ_H */ | ||
diff --git a/arch/microblaze/include/asm/irq_regs.h b/arch/microblaze/include/asm/irq_regs.h new file mode 100644 index 000000000000..3dd9c0b70270 --- /dev/null +++ b/arch/microblaze/include/asm/irq_regs.h | |||
@@ -0,0 +1 @@ | |||
#include <asm-generic/irq_regs.h> | |||
diff --git a/arch/microblaze/include/asm/irqflags.h b/arch/microblaze/include/asm/irqflags.h new file mode 100644 index 000000000000..dea65645a4f8 --- /dev/null +++ b/arch/microblaze/include/asm/irqflags.h | |||
@@ -0,0 +1,123 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_IRQFLAGS_H | ||
10 | #define _ASM_MICROBLAZE_IRQFLAGS_H | ||
11 | |||
12 | #include <linux/irqflags.h> | ||
13 | |||
14 | # if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR | ||
15 | |||
16 | # define local_irq_save(flags) \ | ||
17 | do { \ | ||
18 | asm volatile ("# local_irq_save \n\t" \ | ||
19 | "msrclr %0, %1 \n\t" \ | ||
20 | "nop \n\t" \ | ||
21 | : "=r"(flags) \ | ||
22 | : "i"(MSR_IE) \ | ||
23 | : "memory"); \ | ||
24 | } while (0) | ||
25 | |||
26 | # define local_irq_disable() \ | ||
27 | do { \ | ||
28 | asm volatile ("# local_irq_disable \n\t" \ | ||
29 | "msrclr r0, %0 \n\t" \ | ||
30 | "nop \n\t" \ | ||
31 | : \ | ||
32 | : "i"(MSR_IE) \ | ||
33 | : "memory"); \ | ||
34 | } while (0) | ||
35 | |||
36 | # define local_irq_enable() \ | ||
37 | do { \ | ||
38 | asm volatile ("# local_irq_enable \n\t" \ | ||
39 | "msrset r0, %0 \n\t" \ | ||
40 | "nop \n\t" \ | ||
41 | : \ | ||
42 | : "i"(MSR_IE) \ | ||
43 | : "memory"); \ | ||
44 | } while (0) | ||
45 | |||
46 | # else /* CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR == 0 */ | ||
47 | |||
48 | # define local_irq_save(flags) \ | ||
49 | do { \ | ||
50 | register unsigned tmp; \ | ||
51 | asm volatile ("# local_irq_save \n\t" \ | ||
52 | "mfs %0, rmsr \n\t" \ | ||
53 | "nop \n\t" \ | ||
54 | "andi %1, %0, %2 \n\t" \ | ||
55 | "mts rmsr, %1 \n\t" \ | ||
56 | "nop \n\t" \ | ||
57 | : "=r"(flags), "=r" (tmp) \ | ||
58 | : "i"(~MSR_IE) \ | ||
59 | : "memory"); \ | ||
60 | } while (0) | ||
61 | |||
62 | # define local_irq_disable() \ | ||
63 | do { \ | ||
64 | register unsigned tmp; \ | ||
65 | asm volatile ("# local_irq_disable \n\t" \ | ||
66 | "mfs %0, rmsr \n\t" \ | ||
67 | "nop \n\t" \ | ||
68 | "andi %0, %0, %1 \n\t" \ | ||
69 | "mts rmsr, %0 \n\t" \ | ||
70 | "nop \n\t" \ | ||
71 | : "=r"(tmp) \ | ||
72 | : "i"(~MSR_IE) \ | ||
73 | : "memory"); \ | ||
74 | } while (0) | ||
75 | |||
76 | # define local_irq_enable() \ | ||
77 | do { \ | ||
78 | register unsigned tmp; \ | ||
79 | asm volatile ("# local_irq_enable \n\t" \ | ||
80 | "mfs %0, rmsr \n\t" \ | ||
81 | "nop \n\t" \ | ||
82 | "ori %0, %0, %1 \n\t" \ | ||
83 | "mts rmsr, %0 \n\t" \ | ||
84 | "nop \n\t" \ | ||
85 | : "=r"(tmp) \ | ||
86 | : "i"(MSR_IE) \ | ||
87 | : "memory"); \ | ||
88 | } while (0) | ||
89 | |||
90 | # endif /* CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR */ | ||
91 | |||
92 | #define local_save_flags(flags) \ | ||
93 | do { \ | ||
94 | asm volatile ("# local_save_flags \n\t" \ | ||
95 | "mfs %0, rmsr \n\t" \ | ||
96 | "nop \n\t" \ | ||
97 | : "=r"(flags) \ | ||
98 | : \ | ||
99 | : "memory"); \ | ||
100 | } while (0) | ||
101 | |||
102 | #define local_irq_restore(flags) \ | ||
103 | do { \ | ||
104 | asm volatile ("# local_irq_restore \n\t"\ | ||
105 | "mts rmsr, %0 \n\t" \ | ||
106 | "nop \n\t" \ | ||
107 | : \ | ||
108 | : "r"(flags) \ | ||
109 | : "memory"); \ | ||
110 | } while (0) | ||
111 | |||
112 | static inline int irqs_disabled(void) | ||
113 | { | ||
114 | unsigned long flags; | ||
115 | |||
116 | local_save_flags(flags); | ||
117 | return ((flags & MSR_IE) == 0); | ||
118 | } | ||
119 | |||
120 | #define raw_irqs_disabled irqs_disabled | ||
121 | #define raw_irqs_disabled_flags(flags) ((flags) == 0) | ||
122 | |||
123 | #endif /* _ASM_MICROBLAZE_IRQFLAGS_H */ | ||
diff --git a/arch/microblaze/include/asm/kdebug.h b/arch/microblaze/include/asm/kdebug.h new file mode 100644 index 000000000000..6ece1b037665 --- /dev/null +++ b/arch/microblaze/include/asm/kdebug.h | |||
@@ -0,0 +1 @@ | |||
#include <asm-generic/kdebug.h> | |||
diff --git a/arch/microblaze/include/asm/kmap_types.h b/arch/microblaze/include/asm/kmap_types.h new file mode 100644 index 000000000000..4d7e222f5dd7 --- /dev/null +++ b/arch/microblaze/include/asm/kmap_types.h | |||
@@ -0,0 +1,29 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_KMAP_TYPES_H | ||
10 | #define _ASM_MICROBLAZE_KMAP_TYPES_H | ||
11 | |||
12 | enum km_type { | ||
13 | KM_BOUNCE_READ, | ||
14 | KM_SKB_SUNRPC_DATA, | ||
15 | KM_SKB_DATA_SOFTIRQ, | ||
16 | KM_USER0, | ||
17 | KM_USER1, | ||
18 | KM_BIO_SRC_IRQ, | ||
19 | KM_BIO_DST_IRQ, | ||
20 | KM_PTE0, | ||
21 | KM_PTE1, | ||
22 | KM_IRQ0, | ||
23 | KM_IRQ1, | ||
24 | KM_SOFTIRQ0, | ||
25 | KM_SOFTIRQ1, | ||
26 | KM_TYPE_NR, | ||
27 | }; | ||
28 | |||
29 | #endif /* _ASM_MICROBLAZE_KMAP_TYPES_H */ | ||
diff --git a/arch/microblaze/include/asm/linkage.h b/arch/microblaze/include/asm/linkage.h new file mode 100644 index 000000000000..3a8e36d057eb --- /dev/null +++ b/arch/microblaze/include/asm/linkage.h | |||
@@ -0,0 +1,15 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_LINKAGE_H | ||
10 | #define _ASM_MICROBLAZE_LINKAGE_H | ||
11 | |||
12 | #define __ALIGN .align 4 | ||
13 | #define __ALIGN_STR ".align 4" | ||
14 | |||
15 | #endif /* _ASM_MICROBLAZE_LINKAGE_H */ | ||
diff --git a/arch/microblaze/include/asm/lmb.h b/arch/microblaze/include/asm/lmb.h new file mode 100644 index 000000000000..a0a0a929c293 --- /dev/null +++ b/arch/microblaze/include/asm/lmb.h | |||
@@ -0,0 +1,17 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2008 Michal Simek <monstr@monstr.eu> | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_LMB_H | ||
10 | #define _ASM_MICROBLAZE_LMB_H | ||
11 | |||
12 | /* LMB limit is OFF */ | ||
13 | #define LMB_REAL_LIMIT 0xFFFFFFFF | ||
14 | |||
15 | #endif /* _ASM_MICROBLAZE_LMB_H */ | ||
16 | |||
17 | |||
diff --git a/arch/microblaze/include/asm/local.h b/arch/microblaze/include/asm/local.h new file mode 100644 index 000000000000..c11c530f74d0 --- /dev/null +++ b/arch/microblaze/include/asm/local.h | |||
@@ -0,0 +1 @@ | |||
#include <asm-generic/local.h> | |||
diff --git a/arch/microblaze/include/asm/mman.h b/arch/microblaze/include/asm/mman.h new file mode 100644 index 000000000000..4914b1329445 --- /dev/null +++ b/arch/microblaze/include/asm/mman.h | |||
@@ -0,0 +1,25 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_MMAN_H | ||
10 | #define _ASM_MICROBLAZE_MMAN_H | ||
11 | |||
12 | #include <asm-generic/mman.h> | ||
13 | |||
14 | #define MAP_GROWSDOWN 0x0100 /* stack-like segment */ | ||
15 | #define MAP_DENYWRITE 0x0800 /* ETXTBSY */ | ||
16 | #define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ | ||
17 | #define MAP_LOCKED 0x2000 /* pages are locked */ | ||
18 | #define MAP_NORESERVE 0x4000 /* don't check for reservations */ | ||
19 | #define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ | ||
20 | #define MAP_NONBLOCK 0x10000 /* do not block on IO */ | ||
21 | |||
22 | #define MCL_CURRENT 1 /* lock all current mappings */ | ||
23 | #define MCL_FUTURE 2 /* lock all future mappings */ | ||
24 | |||
25 | #endif /* _ASM_MICROBLAZE_MMAN_H */ | ||
diff --git a/arch/microblaze/include/asm/mmu.h b/arch/microblaze/include/asm/mmu.h new file mode 100644 index 000000000000..0e0431d61635 --- /dev/null +++ b/arch/microblaze/include/asm/mmu.h | |||
@@ -0,0 +1,19 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_MMU_H | ||
10 | #define _ASM_MICROBLAZE_MMU_H | ||
11 | |||
12 | #ifndef __ASSEMBLY__ | ||
13 | typedef struct { | ||
14 | struct vm_list_struct *vmlist; | ||
15 | unsigned long end_brk; | ||
16 | } mm_context_t; | ||
17 | #endif /* __ASSEMBLY__ */ | ||
18 | |||
19 | #endif /* _ASM_MICROBLAZE_MMU_H */ | ||
diff --git a/arch/microblaze/include/asm/mmu_context.h b/arch/microblaze/include/asm/mmu_context.h new file mode 100644 index 000000000000..150ca01b74ba --- /dev/null +++ b/arch/microblaze/include/asm/mmu_context.h | |||
@@ -0,0 +1,21 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_MMU_CONTEXT_H | ||
10 | #define _ASM_MICROBLAZE_MMU_CONTEXT_H | ||
11 | |||
12 | # define init_new_context(tsk, mm) ({ 0; }) | ||
13 | |||
14 | # define enter_lazy_tlb(mm, tsk) do {} while (0) | ||
15 | # define change_mm_context(old, ctx, _pml4) do {} while (0) | ||
16 | # define destroy_context(mm) do {} while (0) | ||
17 | # define deactivate_mm(tsk, mm) do {} while (0) | ||
18 | # define switch_mm(prev, next, tsk) do {} while (0) | ||
19 | # define activate_mm(prev, next) do {} while (0) | ||
20 | |||
21 | #endif /* _ASM_MICROBLAZE_MMU_CONTEXT_H */ | ||
diff --git a/arch/microblaze/include/asm/module.h b/arch/microblaze/include/asm/module.h new file mode 100644 index 000000000000..914565a90315 --- /dev/null +++ b/arch/microblaze/include/asm/module.h | |||
@@ -0,0 +1,37 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_MODULE_H | ||
10 | #define _ASM_MICROBLAZE_MODULE_H | ||
11 | |||
12 | /* Microblaze Relocations */ | ||
13 | #define R_MICROBLAZE_NONE 0 | ||
14 | #define R_MICROBLAZE_32 1 | ||
15 | #define R_MICROBLAZE_32_PCREL 2 | ||
16 | #define R_MICROBLAZE_64_PCREL 3 | ||
17 | #define R_MICROBLAZE_32_PCREL_LO 4 | ||
18 | #define R_MICROBLAZE_64 5 | ||
19 | #define R_MICROBLAZE_32_LO 6 | ||
20 | #define R_MICROBLAZE_SRO32 7 | ||
21 | #define R_MICROBLAZE_SRW32 8 | ||
22 | #define R_MICROBLAZE_64_NONE 9 | ||
23 | #define R_MICROBLAZE_32_SYM_OP_SYM 10 | ||
24 | /* Keep this the last entry. */ | ||
25 | #define R_MICROBLAZE_NUM 11 | ||
26 | |||
27 | struct mod_arch_specific { | ||
28 | int foo; | ||
29 | }; | ||
30 | |||
31 | #define Elf_Shdr Elf32_Shdr | ||
32 | #define Elf_Sym Elf32_Sym | ||
33 | #define Elf_Ehdr Elf32_Ehdr | ||
34 | |||
35 | typedef struct { volatile int counter; } module_t; | ||
36 | |||
37 | #endif /* _ASM_MICROBLAZE_MODULE_H */ | ||
diff --git a/arch/microblaze/include/asm/msgbuf.h b/arch/microblaze/include/asm/msgbuf.h new file mode 100644 index 000000000000..09dd97097211 --- /dev/null +++ b/arch/microblaze/include/asm/msgbuf.h | |||
@@ -0,0 +1,31 @@ | |||
1 | #ifndef _ASM_MICROBLAZE_MSGBUF_H | ||
2 | #define _ASM_MICROBLAZE_MSGBUF_H | ||
3 | |||
4 | /* | ||
5 | * The msqid64_ds structure for microblaze architecture. | ||
6 | * Note extra padding because this structure is passed back and forth | ||
7 | * between kernel and user space. | ||
8 | * | ||
9 | * Pad space is left for: | ||
10 | * - 64-bit time_t to solve y2038 problem | ||
11 | * - 2 miscellaneous 32-bit values | ||
12 | */ | ||
13 | |||
14 | struct msqid64_ds { | ||
15 | struct ipc64_perm msg_perm; | ||
16 | __kernel_time_t msg_stime; /* last msgsnd time */ | ||
17 | unsigned long __unused1; | ||
18 | __kernel_time_t msg_rtime; /* last msgrcv time */ | ||
19 | unsigned long __unused2; | ||
20 | __kernel_time_t msg_ctime; /* last change time */ | ||
21 | unsigned long __unused3; | ||
22 | unsigned long msg_cbytes; /* current number of bytes on queue */ | ||
23 | unsigned long msg_qnum; /* number of messages in queue */ | ||
24 | unsigned long msg_qbytes; /* max number of bytes on queue */ | ||
25 | __kernel_pid_t msg_lspid; /* pid of last msgsnd */ | ||
26 | __kernel_pid_t msg_lrpid; /* last receive pid */ | ||
27 | unsigned long __unused4; | ||
28 | unsigned long __unused5; | ||
29 | }; | ||
30 | |||
31 | #endif /* _ASM_MICROBLAZE_MSGBUF_H */ | ||
diff --git a/arch/microblaze/include/asm/mutex.h b/arch/microblaze/include/asm/mutex.h new file mode 100644 index 000000000000..ff6101aa2c71 --- /dev/null +++ b/arch/microblaze/include/asm/mutex.h | |||
@@ -0,0 +1 @@ | |||
#include <asm-generic/mutex-dec.h> | |||
diff --git a/arch/microblaze/include/asm/namei.h b/arch/microblaze/include/asm/namei.h new file mode 100644 index 000000000000..61d60b8a07d5 --- /dev/null +++ b/arch/microblaze/include/asm/namei.h | |||
@@ -0,0 +1,22 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_NAMEI_H | ||
10 | #define _ASM_MICROBLAZE_NAMEI_H | ||
11 | |||
12 | #ifdef __KERNEL__ | ||
13 | |||
14 | /* This dummy routine maybe changed to something useful | ||
15 | * for /usr/gnemul/ emulation stuff. | ||
16 | * Look at asm-sparc/namei.h for details. | ||
17 | */ | ||
18 | #define __emul_prefix() NULL | ||
19 | |||
20 | #endif /* __KERNEL__ */ | ||
21 | |||
22 | #endif /* _ASM_MICROBLAZE_NAMEI_H */ | ||
diff --git a/arch/microblaze/include/asm/of_device.h b/arch/microblaze/include/asm/of_device.h new file mode 100644 index 000000000000..ba917cfaefe6 --- /dev/null +++ b/arch/microblaze/include/asm/of_device.h | |||
@@ -0,0 +1,45 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007-2008 Michal Simek <monstr@monstr.eu> | ||
3 | * | ||
4 | * based on PowerPC of_device.h | ||
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 | */ | ||
10 | |||
11 | #ifndef _ASM_MICROBLAZE_OF_DEVICE_H | ||
12 | #define _ASM_MICROBLAZE_OF_DEVICE_H | ||
13 | #ifdef __KERNEL__ | ||
14 | |||
15 | #include <linux/device.h> | ||
16 | #include <linux/of.h> | ||
17 | |||
18 | /* | ||
19 | * The of_device is a kind of "base class" that is a superset of | ||
20 | * struct device for use by devices attached to an OF node and | ||
21 | * probed using OF properties. | ||
22 | */ | ||
23 | struct of_device { | ||
24 | struct device_node *node; /* to be obsoleted */ | ||
25 | u64 dma_mask; /* DMA mask */ | ||
26 | struct device dev; /* Generic device interface */ | ||
27 | }; | ||
28 | |||
29 | extern ssize_t of_device_get_modalias(struct of_device *ofdev, | ||
30 | char *str, ssize_t len); | ||
31 | |||
32 | extern struct of_device *of_device_alloc(struct device_node *np, | ||
33 | const char *bus_id, | ||
34 | struct device *parent); | ||
35 | |||
36 | extern int of_device_uevent(struct device *dev, | ||
37 | struct kobj_uevent_env *env); | ||
38 | |||
39 | extern void of_device_make_bus_id(struct of_device *dev); | ||
40 | |||
41 | /* This is just here during the transition */ | ||
42 | #include <linux/of_device.h> | ||
43 | |||
44 | #endif /* __KERNEL__ */ | ||
45 | #endif /* _ASM_MICROBLAZE_OF_DEVICE_H */ | ||
diff --git a/arch/microblaze/include/asm/of_platform.h b/arch/microblaze/include/asm/of_platform.h new file mode 100644 index 000000000000..187c0eedaece --- /dev/null +++ b/arch/microblaze/include/asm/of_platform.h | |||
@@ -0,0 +1,64 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp. | ||
3 | * <benh@kernel.crashing.org> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License | ||
7 | * as published by the Free Software Foundation; either version | ||
8 | * 2 of the License, or (at your option) any later version. | ||
9 | */ | ||
10 | |||
11 | #ifndef _ASM_MICROBLAZE_OF_PLATFORM_H | ||
12 | #define _ASM_MICROBLAZE_OF_PLATFORM_H | ||
13 | |||
14 | /* This is just here during the transition */ | ||
15 | #include <linux/of_platform.h> | ||
16 | |||
17 | /* | ||
18 | * The list of OF IDs below is used for matching bus types in the | ||
19 | * system whose devices are to be exposed as of_platform_devices. | ||
20 | * | ||
21 | * This is the default list valid for most platforms. This file provides | ||
22 | * functions who can take an explicit list if necessary though | ||
23 | * | ||
24 | * The search is always performed recursively looking for children of | ||
25 | * the provided device_node and recursively if such a children matches | ||
26 | * a bus type in the list | ||
27 | */ | ||
28 | |||
29 | static const struct of_device_id of_default_bus_ids[] = { | ||
30 | { .type = "soc", }, | ||
31 | { .compatible = "soc", }, | ||
32 | { .type = "plb5", }, | ||
33 | { .type = "plb4", }, | ||
34 | { .type = "opb", }, | ||
35 | { .type = "simple", }, | ||
36 | {}, | ||
37 | }; | ||
38 | |||
39 | /* Platform drivers register/unregister */ | ||
40 | static inline int of_register_platform_driver(struct of_platform_driver *drv) | ||
41 | { | ||
42 | return of_register_driver(drv, &of_platform_bus_type); | ||
43 | } | ||
44 | static inline void of_unregister_platform_driver(struct of_platform_driver *drv) | ||
45 | { | ||
46 | of_unregister_driver(drv); | ||
47 | } | ||
48 | |||
49 | /* Platform devices and busses creation */ | ||
50 | extern struct of_device *of_platform_device_create(struct device_node *np, | ||
51 | const char *bus_id, | ||
52 | struct device *parent); | ||
53 | /* pseudo "matches" value to not do deep probe */ | ||
54 | #define OF_NO_DEEP_PROBE ((struct of_device_id *)-1) | ||
55 | |||
56 | extern int of_platform_bus_probe(struct device_node *root, | ||
57 | const struct of_device_id *matches, | ||
58 | struct device *parent); | ||
59 | |||
60 | extern struct of_device *of_find_device_by_phandle(phandle ph); | ||
61 | |||
62 | extern void of_instantiate_rtc(void); | ||
63 | |||
64 | #endif /* _ASM_MICROBLAZE_OF_PLATFORM_H */ | ||
diff --git a/arch/microblaze/include/asm/page.h b/arch/microblaze/include/asm/page.h new file mode 100644 index 000000000000..7238dcfcc517 --- /dev/null +++ b/arch/microblaze/include/asm/page.h | |||
@@ -0,0 +1,140 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2008 Michal Simek | ||
3 | * Copyright (C) 2008 PetaLogix | ||
4 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
5 | * Changes for MMU support: | ||
6 | * Copyright (C) 2007 Xilinx, Inc. All rights reserved. | ||
7 | * | ||
8 | * This file is subject to the terms and conditions of the GNU General Public | ||
9 | * License. See the file "COPYING" in the main directory of this archive | ||
10 | * for more details. | ||
11 | */ | ||
12 | |||
13 | #ifndef _ASM_MICROBLAZE_PAGE_H | ||
14 | #define _ASM_MICROBLAZE_PAGE_H | ||
15 | |||
16 | #include <linux/pfn.h> | ||
17 | #include <asm/setup.h> | ||
18 | |||
19 | /* PAGE_SHIFT determines the page size */ | ||
20 | #define PAGE_SHIFT (12) | ||
21 | #define PAGE_SIZE (1UL << PAGE_SHIFT) | ||
22 | #define PAGE_MASK (~(PAGE_SIZE-1)) | ||
23 | |||
24 | #ifdef __KERNEL__ | ||
25 | |||
26 | #ifndef __ASSEMBLY__ | ||
27 | |||
28 | #define PAGE_UP(addr) (((addr)+((PAGE_SIZE)-1))&(~((PAGE_SIZE)-1))) | ||
29 | #define PAGE_DOWN(addr) ((addr)&(~((PAGE_SIZE)-1))) | ||
30 | |||
31 | /* align addr on a size boundary - adjust address up/down if needed */ | ||
32 | #define _ALIGN_UP(addr, size) (((addr)+((size)-1))&(~((size)-1))) | ||
33 | #define _ALIGN_DOWN(addr, size) ((addr)&(~((size)-1))) | ||
34 | |||
35 | /* align addr on a size boundary - adjust address up if needed */ | ||
36 | #define _ALIGN(addr, size) _ALIGN_UP(addr, size) | ||
37 | |||
38 | /* | ||
39 | * PAGE_OFFSET -- the first address of the first page of memory. When not | ||
40 | * using MMU this corresponds to the first free page in physical memory (aligned | ||
41 | * on a page boundary). | ||
42 | */ | ||
43 | extern unsigned int __page_offset; | ||
44 | #define PAGE_OFFSET __page_offset | ||
45 | |||
46 | #define copy_page(to, from) memcpy((to), (from), PAGE_SIZE) | ||
47 | #define get_user_page(vaddr) __get_free_page(GFP_KERNEL) | ||
48 | #define free_user_page(page, addr) free_page(addr) | ||
49 | |||
50 | #define clear_page(pgaddr) memset((pgaddr), 0, PAGE_SIZE) | ||
51 | |||
52 | |||
53 | #define clear_user_page(pgaddr, vaddr, page) memset((pgaddr), 0, PAGE_SIZE) | ||
54 | #define copy_user_page(vto, vfrom, vaddr, topg) \ | ||
55 | memcpy((vto), (vfrom), PAGE_SIZE) | ||
56 | |||
57 | /* | ||
58 | * These are used to make use of C type-checking.. | ||
59 | */ | ||
60 | typedef struct page *pgtable_t; | ||
61 | typedef struct { unsigned long pte; } pte_t; | ||
62 | typedef struct { unsigned long pgprot; } pgprot_t; | ||
63 | typedef struct { unsigned long ste[64]; } pmd_t; | ||
64 | typedef struct { pmd_t pue[1]; } pud_t; | ||
65 | typedef struct { pud_t pge[1]; } pgd_t; | ||
66 | |||
67 | |||
68 | #define pte_val(x) ((x).pte) | ||
69 | #define pgprot_val(x) ((x).pgprot) | ||
70 | #define pmd_val(x) ((x).ste[0]) | ||
71 | #define pud_val(x) ((x).pue[0]) | ||
72 | #define pgd_val(x) ((x).pge[0]) | ||
73 | |||
74 | #define __pte(x) ((pte_t) { (x) }) | ||
75 | #define __pmd(x) ((pmd_t) { (x) }) | ||
76 | #define __pgd(x) ((pgd_t) { (x) }) | ||
77 | #define __pgprot(x) ((pgprot_t) { (x) }) | ||
78 | |||
79 | /** | ||
80 | * Conversions for virtual address, physical address, pfn, and struct | ||
81 | * page are defined in the following files. | ||
82 | * | ||
83 | * virt -+ | ||
84 | * | asm-microblaze/page.h | ||
85 | * phys -+ | ||
86 | * | linux/pfn.h | ||
87 | * pfn -+ | ||
88 | * | asm-generic/memory_model.h | ||
89 | * page -+ | ||
90 | * | ||
91 | */ | ||
92 | |||
93 | extern unsigned long max_low_pfn; | ||
94 | extern unsigned long min_low_pfn; | ||
95 | extern unsigned long max_pfn; | ||
96 | |||
97 | #define __pa(vaddr) ((unsigned long) (vaddr)) | ||
98 | #define __va(paddr) ((void *) (paddr)) | ||
99 | |||
100 | #define phys_to_pfn(phys) (PFN_DOWN(phys)) | ||
101 | #define pfn_to_phys(pfn) (PFN_PHYS(pfn)) | ||
102 | |||
103 | #define virt_to_pfn(vaddr) (phys_to_pfn((__pa(vaddr)))) | ||
104 | #define pfn_to_virt(pfn) __va(pfn_to_phys((pfn))) | ||
105 | |||
106 | #define virt_to_page(vaddr) (pfn_to_page(virt_to_pfn(vaddr))) | ||
107 | #define page_to_virt(page) (pfn_to_virt(page_to_pfn(page))) | ||
108 | |||
109 | #define page_to_phys(page) (pfn_to_phys(page_to_pfn(page))) | ||
110 | #define page_to_bus(page) (page_to_phys(page)) | ||
111 | #define phys_to_page(paddr) (pfn_to_page(phys_to_pfn(paddr))) | ||
112 | |||
113 | extern unsigned int memory_start; | ||
114 | extern unsigned int memory_end; | ||
115 | extern unsigned int memory_size; | ||
116 | |||
117 | #define pfn_valid(pfn) ((pfn) >= min_low_pfn && (pfn) < max_mapnr) | ||
118 | |||
119 | #define ARCH_PFN_OFFSET (PAGE_OFFSET >> PAGE_SHIFT) | ||
120 | |||
121 | #else | ||
122 | #define tophys(rd, rs) (addik rd, rs, 0) | ||
123 | #define tovirt(rd, rs) (addik rd, rs, 0) | ||
124 | #endif /* __ASSEMBLY__ */ | ||
125 | |||
126 | #define virt_addr_valid(vaddr) (pfn_valid(virt_to_pfn(vaddr))) | ||
127 | |||
128 | /* Convert between virtual and physical address for MMU. */ | ||
129 | /* Handle MicroBlaze processor with virtual memory. */ | ||
130 | #define __virt_to_phys(addr) addr | ||
131 | #define __phys_to_virt(addr) addr | ||
132 | |||
133 | #define TOPHYS(addr) __virt_to_phys(addr) | ||
134 | |||
135 | #endif /* __KERNEL__ */ | ||
136 | |||
137 | #include <asm-generic/memory_model.h> | ||
138 | #include <asm-generic/page.h> | ||
139 | |||
140 | #endif /* _ASM_MICROBLAZE_PAGE_H */ | ||
diff --git a/arch/microblaze/include/asm/param.h b/arch/microblaze/include/asm/param.h new file mode 100644 index 000000000000..8c538a49616d --- /dev/null +++ b/arch/microblaze/include/asm/param.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_PARAM_H | ||
10 | #define _ASM_MICROBLAZE_PARAM_H | ||
11 | |||
12 | #ifdef __KERNEL__ | ||
13 | #define HZ CONFIG_HZ /* internal kernel timer frequency */ | ||
14 | #define USER_HZ 100 /* for user interfaces in "ticks" */ | ||
15 | #define CLOCKS_PER_SEC (USER_HZ) /* frequency at which times() counts */ | ||
16 | #endif /* __KERNEL__ */ | ||
17 | |||
18 | #ifndef HZ | ||
19 | #define HZ 100 | ||
20 | #endif | ||
21 | |||
22 | #define EXEC_PAGESIZE 4096 | ||
23 | |||
24 | #ifndef NOGROUP | ||
25 | #define NOGROUP (-1) | ||
26 | #endif | ||
27 | |||
28 | #define MAXHOSTNAMELEN 64 /* max length of hostname */ | ||
29 | |||
30 | #endif /* _ASM_MICROBLAZE_PARAM_H */ | ||
diff --git a/arch/microblaze/include/asm/pci-bridge.h b/arch/microblaze/include/asm/pci-bridge.h new file mode 100644 index 000000000000..7ad28f6f5f1a --- /dev/null +++ b/arch/microblaze/include/asm/pci-bridge.h | |||
@@ -0,0 +1 @@ | |||
#include <linux/pci.h> | |||
diff --git a/arch/microblaze/include/asm/pci.h b/arch/microblaze/include/asm/pci.h new file mode 100644 index 000000000000..ca03794cf3f0 --- /dev/null +++ b/arch/microblaze/include/asm/pci.h | |||
@@ -0,0 +1 @@ | |||
#include <linux/io.h> | |||
diff --git a/arch/microblaze/include/asm/percpu.h b/arch/microblaze/include/asm/percpu.h new file mode 100644 index 000000000000..06a959d67234 --- /dev/null +++ b/arch/microblaze/include/asm/percpu.h | |||
@@ -0,0 +1 @@ | |||
#include <asm-generic/percpu.h> | |||
diff --git a/arch/microblaze/include/asm/pgalloc.h b/arch/microblaze/include/asm/pgalloc.h new file mode 100644 index 000000000000..2a4b35484010 --- /dev/null +++ b/arch/microblaze/include/asm/pgalloc.h | |||
@@ -0,0 +1,14 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_PGALLOC_H | ||
10 | #define _ASM_MICROBLAZE_PGALLOC_H | ||
11 | |||
12 | #define check_pgt_cache() do {} while (0) | ||
13 | |||
14 | #endif /* _ASM_MICROBLAZE_PGALLOC_H */ | ||
diff --git a/arch/microblaze/include/asm/pgtable.h b/arch/microblaze/include/asm/pgtable.h new file mode 100644 index 000000000000..4df31e46568e --- /dev/null +++ b/arch/microblaze/include/asm/pgtable.h | |||
@@ -0,0 +1,54 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_PGTABLE_H | ||
10 | #define _ASM_MICROBLAZE_PGTABLE_H | ||
11 | |||
12 | #include <asm/setup.h> | ||
13 | |||
14 | #define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ | ||
15 | remap_pfn_range(vma, vaddr, pfn, size, prot) | ||
16 | |||
17 | #define pgd_present(pgd) (1) /* pages are always present on non MMU */ | ||
18 | #define pgd_none(pgd) (0) | ||
19 | #define pgd_bad(pgd) (0) | ||
20 | #define pgd_clear(pgdp) | ||
21 | #define kern_addr_valid(addr) (1) | ||
22 | #define pmd_offset(a, b) ((void *) 0) | ||
23 | |||
24 | #define PAGE_NONE __pgprot(0) /* these mean nothing to non MMU */ | ||
25 | #define PAGE_SHARED __pgprot(0) /* these mean nothing to non MMU */ | ||
26 | #define PAGE_COPY __pgprot(0) /* these mean nothing to non MMU */ | ||
27 | #define PAGE_READONLY __pgprot(0) /* these mean nothing to non MMU */ | ||
28 | #define PAGE_KERNEL __pgprot(0) /* these mean nothing to non MMU */ | ||
29 | |||
30 | #define __swp_type(x) (0) | ||
31 | #define __swp_offset(x) (0) | ||
32 | #define __swp_entry(typ, off) ((swp_entry_t) { ((typ) | ((off) << 7)) }) | ||
33 | #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) | ||
34 | #define __swp_entry_to_pte(x) ((pte_t) { (x).val }) | ||
35 | |||
36 | #ifndef __ASSEMBLY__ | ||
37 | static inline int pte_file(pte_t pte) { return 0; } | ||
38 | #endif /* __ASSEMBLY__ */ | ||
39 | |||
40 | #define ZERO_PAGE(vaddr) ({ BUG(); NULL; }) | ||
41 | |||
42 | #define swapper_pg_dir ((pgd_t *) NULL) | ||
43 | |||
44 | #define pgtable_cache_init() do {} while (0) | ||
45 | |||
46 | #define arch_enter_lazy_cpu_mode() do {} while (0) | ||
47 | |||
48 | #ifndef __ASSEMBLY__ | ||
49 | #include <asm-generic/pgtable.h> | ||
50 | |||
51 | void setup_memory(void); | ||
52 | #endif /* __ASSEMBLY__ */ | ||
53 | |||
54 | #endif /* _ASM_MICROBLAZE_PGTABLE_H */ | ||
diff --git a/arch/microblaze/include/asm/poll.h b/arch/microblaze/include/asm/poll.h new file mode 100644 index 000000000000..c98509d3149e --- /dev/null +++ b/arch/microblaze/include/asm/poll.h | |||
@@ -0,0 +1 @@ | |||
#include <asm-generic/poll.h> | |||
diff --git a/arch/microblaze/include/asm/posix_types.h b/arch/microblaze/include/asm/posix_types.h new file mode 100644 index 000000000000..b4df41c5dde2 --- /dev/null +++ b/arch/microblaze/include/asm/posix_types.h | |||
@@ -0,0 +1,73 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_POSIX_TYPES_H | ||
10 | #define _ASM_MICROBLAZE_POSIX_TYPES_H | ||
11 | |||
12 | /* | ||
13 | * This file is generally used by user-level software, so you need to | ||
14 | * be a little careful about namespace pollution etc. Also, we cannot | ||
15 | * assume GCC is being used. | ||
16 | */ | ||
17 | |||
18 | typedef unsigned long __kernel_ino_t; | ||
19 | typedef unsigned int __kernel_mode_t; | ||
20 | typedef unsigned int __kernel_nlink_t; | ||
21 | typedef long __kernel_off_t; | ||
22 | typedef int __kernel_pid_t; | ||
23 | typedef unsigned int __kernel_ipc_pid_t; | ||
24 | typedef unsigned int __kernel_uid_t; | ||
25 | typedef unsigned int __kernel_gid_t; | ||
26 | typedef unsigned long __kernel_size_t; | ||
27 | typedef long __kernel_ssize_t; | ||
28 | typedef int __kernel_ptrdiff_t; | ||
29 | typedef long __kernel_time_t; | ||
30 | typedef long __kernel_suseconds_t; | ||
31 | typedef long __kernel_clock_t; | ||
32 | typedef int __kernel_timer_t; | ||
33 | typedef int __kernel_clockid_t; | ||
34 | typedef int __kernel_daddr_t; | ||
35 | typedef char *__kernel_caddr_t; | ||
36 | typedef unsigned short __kernel_uid16_t; | ||
37 | typedef unsigned short __kernel_gid16_t; | ||
38 | typedef unsigned int __kernel_uid32_t; | ||
39 | typedef unsigned int __kernel_gid32_t; | ||
40 | |||
41 | typedef unsigned int __kernel_old_uid_t; | ||
42 | typedef unsigned int __kernel_old_gid_t; | ||
43 | typedef unsigned int __kernel_old_dev_t; | ||
44 | |||
45 | #ifdef __GNUC__ | ||
46 | typedef long long __kernel_loff_t; | ||
47 | #endif | ||
48 | |||
49 | typedef struct { | ||
50 | #if defined(__KERNEL__) || defined(__USE_ALL) | ||
51 | int val[2]; | ||
52 | #else /* !defined(__KERNEL__) && !defined(__USE_ALL) */ | ||
53 | int __val[2]; | ||
54 | #endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */ | ||
55 | } __kernel_fsid_t; | ||
56 | |||
57 | #if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) | ||
58 | |||
59 | #undef __FD_SET | ||
60 | #define __FD_SET(d, set) ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d)) | ||
61 | |||
62 | #undef __FD_CLR | ||
63 | #define __FD_CLR(d, set) ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d)) | ||
64 | |||
65 | #undef __FD_ISSET | ||
66 | #define __FD_ISSET(d, set) (!!((set)->fds_bits[__FDELT(d)] & __FDMASK(d))) | ||
67 | |||
68 | #undef __FD_ZERO | ||
69 | #define __FD_ZERO(fdsetp) (memset(fdsetp, 0, sizeof(*(fd_set *)fdsetp))) | ||
70 | |||
71 | #endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */ | ||
72 | |||
73 | #endif /* _ASM_MICROBLAZE_POSIX_TYPES_H */ | ||
diff --git a/arch/microblaze/include/asm/processor.h b/arch/microblaze/include/asm/processor.h new file mode 100644 index 000000000000..d8e15434ba21 --- /dev/null +++ b/arch/microblaze/include/asm/processor.h | |||
@@ -0,0 +1,93 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2008 Michal Simek | ||
3 | * Copyright (C) 2008 PetaLogix | ||
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 | */ | ||
10 | |||
11 | #ifndef _ASM_MICROBLAZE_PROCESSOR_H | ||
12 | #define _ASM_MICROBLAZE_PROCESSOR_H | ||
13 | |||
14 | #include <asm/ptrace.h> | ||
15 | #include <asm/setup.h> | ||
16 | #include <asm/registers.h> | ||
17 | #include <asm/segment.h> | ||
18 | |||
19 | # ifndef __ASSEMBLY__ | ||
20 | /* from kernel/cpu/mb.c */ | ||
21 | extern const struct seq_operations cpuinfo_op; | ||
22 | |||
23 | # define cpu_relax() barrier() | ||
24 | # define cpu_sleep() do {} while (0) | ||
25 | # define prepare_to_copy(tsk) do {} while (0) | ||
26 | |||
27 | # endif /* __ASSEMBLY__ */ | ||
28 | |||
29 | /* | ||
30 | * User space process size: memory size | ||
31 | * | ||
32 | * TASK_SIZE on MMU cpu is usually 1GB. However, on no-MMU arch, both | ||
33 | * user processes and the kernel is on the same memory region. They | ||
34 | * both share the memory space and that is limited by the amount of | ||
35 | * physical memory. thus, we set TASK_SIZE == amount of total memory. | ||
36 | */ | ||
37 | # define TASK_SIZE (0x81000000 - 0x80000000) | ||
38 | |||
39 | /* | ||
40 | * Default implementation of macro that returns current | ||
41 | * instruction pointer ("program counter"). | ||
42 | */ | ||
43 | # define current_text_addr() ({ __label__ _l; _l: &&_l; }) | ||
44 | |||
45 | /* | ||
46 | * This decides where the kernel will search for a free chunk of vm | ||
47 | * space during mmap's. We won't be using it | ||
48 | */ | ||
49 | # define TASK_UNMAPPED_BASE 0 | ||
50 | |||
51 | /* definition in include/linux/sched.h */ | ||
52 | struct task_struct; | ||
53 | |||
54 | /* thread_struct is gone. use thread_info instead. */ | ||
55 | struct thread_struct { }; | ||
56 | # define INIT_THREAD { } | ||
57 | |||
58 | /* Do necessary setup to start up a newly executed thread. */ | ||
59 | static inline void start_thread(struct pt_regs *regs, | ||
60 | unsigned long pc, | ||
61 | unsigned long usp) | ||
62 | { | ||
63 | regs->pc = pc; | ||
64 | regs->r1 = usp; | ||
65 | regs->kernel_mode = 0; | ||
66 | } | ||
67 | |||
68 | /* Free all resources held by a thread. */ | ||
69 | static inline void release_thread(struct task_struct *dead_task) | ||
70 | { | ||
71 | } | ||
72 | |||
73 | /* Free all resources held by a thread. */ | ||
74 | static inline void exit_thread(void) | ||
75 | { | ||
76 | } | ||
77 | |||
78 | extern unsigned long thread_saved_pc(struct task_struct *t); | ||
79 | |||
80 | extern unsigned long get_wchan(struct task_struct *p); | ||
81 | |||
82 | /* | ||
83 | * create a kernel thread without removing it from tasklists | ||
84 | */ | ||
85 | extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); | ||
86 | |||
87 | # define task_pt_regs(tsk) \ | ||
88 | (((struct pt_regs *)(THREAD_SIZE + task_stack_page(tsk))) - 1) | ||
89 | |||
90 | # define KSTK_EIP(tsk) (0) | ||
91 | # define KSTK_ESP(tsk) (0) | ||
92 | |||
93 | #endif /* _ASM_MICROBLAZE_PROCESSOR_H */ | ||
diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h new file mode 100644 index 000000000000..20f7b3a926e8 --- /dev/null +++ b/arch/microblaze/include/asm/prom.h | |||
@@ -0,0 +1,313 @@ | |||
1 | /* | ||
2 | * Definitions for talking to the Open Firmware PROM on | ||
3 | * Power Macintosh computers. | ||
4 | * | ||
5 | * Copyright (C) 1996-2005 Paul Mackerras. | ||
6 | * | ||
7 | * Updates for PPC64 by Peter Bergner & David Engebretsen, IBM Corp. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License | ||
11 | * as published by the Free Software Foundation; either version | ||
12 | * 2 of the License, or (at your option) any later version. | ||
13 | */ | ||
14 | |||
15 | #ifndef _ASM_MICROBLAZE_PROM_H | ||
16 | #define _ASM_MICROBLAZE_PROM_H | ||
17 | #ifdef __KERNEL__ | ||
18 | |||
19 | #include <linux/types.h> | ||
20 | #include <linux/proc_fs.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <asm/irq.h> | ||
23 | #include <asm/atomic.h> | ||
24 | |||
25 | #define OF_ROOT_NODE_ADDR_CELLS_DEFAULT 1 | ||
26 | #define OF_ROOT_NODE_SIZE_CELLS_DEFAULT 1 | ||
27 | |||
28 | #define of_compat_cmp(s1, s2, l) strncasecmp((s1), (s2), (l)) | ||
29 | #define of_prop_cmp(s1, s2) strcmp((s1), (s2)) | ||
30 | #define of_node_cmp(s1, s2) strcasecmp((s1), (s2)) | ||
31 | |||
32 | /* Definitions used by the flattened device tree */ | ||
33 | #define OF_DT_HEADER 0xd00dfeed /* marker */ | ||
34 | #define OF_DT_BEGIN_NODE 0x1 /* Start of node, full name */ | ||
35 | #define OF_DT_END_NODE 0x2 /* End node */ | ||
36 | #define OF_DT_PROP 0x3 /* Property: name off, size, content */ | ||
37 | #define OF_DT_NOP 0x4 /* nop */ | ||
38 | #define OF_DT_END 0x9 | ||
39 | |||
40 | #define OF_DT_VERSION 0x10 | ||
41 | |||
42 | /* | ||
43 | * This is what gets passed to the kernel by prom_init or kexec | ||
44 | * | ||
45 | * The dt struct contains the device tree structure, full pathes and | ||
46 | * property contents. The dt strings contain a separate block with just | ||
47 | * the strings for the property names, and is fully page aligned and | ||
48 | * self contained in a page, so that it can be kept around by the kernel, | ||
49 | * each property name appears only once in this page (cheap compression) | ||
50 | * | ||
51 | * the mem_rsvmap contains a map of reserved ranges of physical memory, | ||
52 | * passing it here instead of in the device-tree itself greatly simplifies | ||
53 | * the job of everybody. It's just a list of u64 pairs (base/size) that | ||
54 | * ends when size is 0 | ||
55 | */ | ||
56 | struct boot_param_header { | ||
57 | u32 magic; /* magic word OF_DT_HEADER */ | ||
58 | u32 totalsize; /* total size of DT block */ | ||
59 | u32 off_dt_struct; /* offset to structure */ | ||
60 | u32 off_dt_strings; /* offset to strings */ | ||
61 | u32 off_mem_rsvmap; /* offset to memory reserve map */ | ||
62 | u32 version; /* format version */ | ||
63 | u32 last_comp_version; /* last compatible version */ | ||
64 | /* version 2 fields below */ | ||
65 | u32 boot_cpuid_phys; /* Physical CPU id we're booting on */ | ||
66 | /* version 3 fields below */ | ||
67 | u32 dt_strings_size; /* size of the DT strings block */ | ||
68 | /* version 17 fields below */ | ||
69 | u32 dt_struct_size; /* size of the DT structure block */ | ||
70 | }; | ||
71 | |||
72 | typedef u32 phandle; | ||
73 | typedef u32 ihandle; | ||
74 | |||
75 | struct property { | ||
76 | char *name; | ||
77 | int length; | ||
78 | void *value; | ||
79 | struct property *next; | ||
80 | }; | ||
81 | |||
82 | struct device_node { | ||
83 | const char *name; | ||
84 | const char *type; | ||
85 | phandle node; | ||
86 | phandle linux_phandle; | ||
87 | char *full_name; | ||
88 | |||
89 | struct property *properties; | ||
90 | struct property *deadprops; /* removed properties */ | ||
91 | struct device_node *parent; | ||
92 | struct device_node *child; | ||
93 | struct device_node *sibling; | ||
94 | struct device_node *next; /* next device of same type */ | ||
95 | struct device_node *allnext; /* next in list of all nodes */ | ||
96 | struct proc_dir_entry *pde; /* this node's proc directory */ | ||
97 | struct kref kref; | ||
98 | unsigned long _flags; | ||
99 | void *data; | ||
100 | }; | ||
101 | |||
102 | extern struct device_node *of_chosen; | ||
103 | |||
104 | static inline int of_node_check_flag(struct device_node *n, unsigned long flag) | ||
105 | { | ||
106 | return test_bit(flag, &n->_flags); | ||
107 | } | ||
108 | |||
109 | static inline void of_node_set_flag(struct device_node *n, unsigned long flag) | ||
110 | { | ||
111 | set_bit(flag, &n->_flags); | ||
112 | } | ||
113 | |||
114 | #define HAVE_ARCH_DEVTREE_FIXUPS | ||
115 | |||
116 | static inline void set_node_proc_entry(struct device_node *dn, | ||
117 | struct proc_dir_entry *de) | ||
118 | { | ||
119 | dn->pde = de; | ||
120 | } | ||
121 | |||
122 | extern struct device_node *allnodes; /* temporary while merging */ | ||
123 | extern rwlock_t devtree_lock; /* temporary while merging */ | ||
124 | |||
125 | extern struct device_node *of_find_all_nodes(struct device_node *prev); | ||
126 | extern struct device_node *of_node_get(struct device_node *node); | ||
127 | extern void of_node_put(struct device_node *node); | ||
128 | |||
129 | /* For scanning the flat device-tree at boot time */ | ||
130 | extern int __init of_scan_flat_dt(int (*it)(unsigned long node, | ||
131 | const char *uname, int depth, | ||
132 | void *data), | ||
133 | void *data); | ||
134 | extern void *__init of_get_flat_dt_prop(unsigned long node, const char *name, | ||
135 | unsigned long *size); | ||
136 | extern int __init | ||
137 | of_flat_dt_is_compatible(unsigned long node, const char *name); | ||
138 | extern unsigned long __init of_get_flat_dt_root(void); | ||
139 | |||
140 | /* For updating the device tree at runtime */ | ||
141 | extern void of_attach_node(struct device_node *); | ||
142 | extern void of_detach_node(struct device_node *); | ||
143 | |||
144 | /* Other Prototypes */ | ||
145 | extern void finish_device_tree(void); | ||
146 | extern void unflatten_device_tree(void); | ||
147 | extern int early_uartlite_console(void); | ||
148 | extern void early_init_devtree(void *); | ||
149 | extern int machine_is_compatible(const char *compat); | ||
150 | extern void print_properties(struct device_node *node); | ||
151 | extern int prom_n_intr_cells(struct device_node *np); | ||
152 | extern void prom_get_irq_senses(unsigned char *senses, int off, int max); | ||
153 | extern int prom_add_property(struct device_node *np, struct property *prop); | ||
154 | extern int prom_remove_property(struct device_node *np, struct property *prop); | ||
155 | extern int prom_update_property(struct device_node *np, | ||
156 | struct property *newprop, | ||
157 | struct property *oldprop); | ||
158 | |||
159 | extern struct resource *request_OF_resource(struct device_node *node, | ||
160 | int index, const char *name_postfix); | ||
161 | extern int release_OF_resource(struct device_node *node, int index); | ||
162 | |||
163 | /* | ||
164 | * OF address retreival & translation | ||
165 | */ | ||
166 | |||
167 | /* Helper to read a big number; size is in cells (not bytes) */ | ||
168 | static inline u64 of_read_number(const u32 *cell, int size) | ||
169 | { | ||
170 | u64 r = 0; | ||
171 | while (size--) | ||
172 | r = (r << 32) | *(cell++); | ||
173 | return r; | ||
174 | } | ||
175 | |||
176 | /* Like of_read_number, but we want an unsigned long result */ | ||
177 | #define of_read_ulong(cell, size) of_read_number(cell, size) | ||
178 | |||
179 | /* Translate an OF address block into a CPU physical address | ||
180 | */ | ||
181 | extern u64 of_translate_address(struct device_node *np, const u32 *addr); | ||
182 | |||
183 | /* Extract an address from a device, returns the region size and | ||
184 | * the address space flags too. The PCI version uses a BAR number | ||
185 | * instead of an absolute index | ||
186 | */ | ||
187 | extern const u32 *of_get_address(struct device_node *dev, int index, | ||
188 | u64 *size, unsigned int *flags); | ||
189 | extern const u32 *of_get_pci_address(struct device_node *dev, int bar_no, | ||
190 | u64 *size, unsigned int *flags); | ||
191 | |||
192 | /* Get an address as a resource. Note that if your address is | ||
193 | * a PIO address, the conversion will fail if the physical address | ||
194 | * can't be internally converted to an IO token with | ||
195 | * pci_address_to_pio(), that is because it's either called to early | ||
196 | * or it can't be matched to any host bridge IO space | ||
197 | */ | ||
198 | extern int of_address_to_resource(struct device_node *dev, int index, | ||
199 | struct resource *r); | ||
200 | extern int of_pci_address_to_resource(struct device_node *dev, int bar, | ||
201 | struct resource *r); | ||
202 | |||
203 | /* Parse the ibm,dma-window property of an OF node into the busno, phys and | ||
204 | * size parameters. | ||
205 | */ | ||
206 | void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, | ||
207 | unsigned long *busno, unsigned long *phys, unsigned long *size); | ||
208 | |||
209 | extern void kdump_move_device_tree(void); | ||
210 | |||
211 | /* CPU OF node matching */ | ||
212 | struct device_node *of_get_cpu_node(int cpu, unsigned int *thread); | ||
213 | |||
214 | /* Get the MAC address */ | ||
215 | extern const void *of_get_mac_address(struct device_node *np); | ||
216 | |||
217 | /* | ||
218 | * OF interrupt mapping | ||
219 | */ | ||
220 | |||
221 | /* This structure is returned when an interrupt is mapped. The controller | ||
222 | * field needs to be put() after use | ||
223 | */ | ||
224 | |||
225 | #define OF_MAX_IRQ_SPEC 4 /* We handle specifiers of at most 4 cells */ | ||
226 | |||
227 | struct of_irq { | ||
228 | struct device_node *controller; /* Interrupt controller node */ | ||
229 | u32 size; /* Specifier size */ | ||
230 | u32 specifier[OF_MAX_IRQ_SPEC]; /* Specifier copy */ | ||
231 | }; | ||
232 | |||
233 | /** | ||
234 | * of_irq_map_init - Initialize the irq remapper | ||
235 | * @flags: flags defining workarounds to enable | ||
236 | * | ||
237 | * Some machines have bugs in the device-tree which require certain workarounds | ||
238 | * to be applied. Call this before any interrupt mapping attempts to enable | ||
239 | * those workarounds. | ||
240 | */ | ||
241 | #define OF_IMAP_OLDWORLD_MAC 0x00000001 | ||
242 | #define OF_IMAP_NO_PHANDLE 0x00000002 | ||
243 | |||
244 | extern void of_irq_map_init(unsigned int flags); | ||
245 | |||
246 | /** | ||
247 | * of_irq_map_raw - Low level interrupt tree parsing | ||
248 | * @parent: the device interrupt parent | ||
249 | * @intspec: interrupt specifier ("interrupts" property of the device) | ||
250 | * @ointsize: size of the passed in interrupt specifier | ||
251 | * @addr: address specifier (start of "reg" property of the device) | ||
252 | * @out_irq: structure of_irq filled by this function | ||
253 | * | ||
254 | * Returns 0 on success and a negative number on error | ||
255 | * | ||
256 | * This function is a low-level interrupt tree walking function. It | ||
257 | * can be used to do a partial walk with synthetized reg and interrupts | ||
258 | * properties, for example when resolving PCI interrupts when no device | ||
259 | * node exist for the parent. | ||
260 | * | ||
261 | */ | ||
262 | |||
263 | extern int of_irq_map_raw(struct device_node *parent, const u32 *intspec, | ||
264 | u32 ointsize, const u32 *addr, | ||
265 | struct of_irq *out_irq); | ||
266 | |||
267 | /** | ||
268 | * of_irq_map_one - Resolve an interrupt for a device | ||
269 | * @device: the device whose interrupt is to be resolved | ||
270 | * @index: index of the interrupt to resolve | ||
271 | * @out_irq: structure of_irq filled by this function | ||
272 | * | ||
273 | * This function resolves an interrupt, walking the tree, for a given | ||
274 | * device-tree node. It's the high level pendant to of_irq_map_raw(). | ||
275 | * It also implements the workarounds for OldWolrd Macs. | ||
276 | */ | ||
277 | extern int of_irq_map_one(struct device_node *device, int index, | ||
278 | struct of_irq *out_irq); | ||
279 | |||
280 | /** | ||
281 | * of_irq_map_pci - Resolve the interrupt for a PCI device | ||
282 | * @pdev: the device whose interrupt is to be resolved | ||
283 | * @out_irq: structure of_irq filled by this function | ||
284 | * | ||
285 | * This function resolves the PCI interrupt for a given PCI device. If a | ||
286 | * device-node exists for a given pci_dev, it will use normal OF tree | ||
287 | * walking. If not, it will implement standard swizzling and walk up the | ||
288 | * PCI tree until an device-node is found, at which point it will finish | ||
289 | * resolving using the OF tree walking. | ||
290 | */ | ||
291 | struct pci_dev; | ||
292 | extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq); | ||
293 | |||
294 | extern int of_irq_to_resource(struct device_node *dev, int index, | ||
295 | struct resource *r); | ||
296 | |||
297 | /** | ||
298 | * of_iomap - Maps the memory mapped IO for a given device_node | ||
299 | * @device: the device whose io range will be mapped | ||
300 | * @index: index of the io range | ||
301 | * | ||
302 | * Returns a pointer to the mapped memory | ||
303 | */ | ||
304 | extern void __iomem *of_iomap(struct device_node *device, int index); | ||
305 | |||
306 | /* | ||
307 | * NB: This is here while we transition from using asm/prom.h | ||
308 | * to linux/of.h | ||
309 | */ | ||
310 | #include <linux/of.h> | ||
311 | |||
312 | #endif /* __KERNEL__ */ | ||
313 | #endif /* _ASM_MICROBLAZE_PROM_H */ | ||
diff --git a/arch/microblaze/include/asm/ptrace.h b/arch/microblaze/include/asm/ptrace.h new file mode 100644 index 000000000000..f1f03486428a --- /dev/null +++ b/arch/microblaze/include/asm/ptrace.h | |||
@@ -0,0 +1,68 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_PTRACE_H | ||
10 | #define _ASM_MICROBLAZE_PTRACE_H | ||
11 | |||
12 | #ifndef __ASSEMBLY__ | ||
13 | #include <linux/types.h> | ||
14 | |||
15 | typedef unsigned long microblaze_reg_t; | ||
16 | |||
17 | struct pt_regs { | ||
18 | microblaze_reg_t r0; | ||
19 | microblaze_reg_t r1; | ||
20 | microblaze_reg_t r2; | ||
21 | microblaze_reg_t r3; | ||
22 | microblaze_reg_t r4; | ||
23 | microblaze_reg_t r5; | ||
24 | microblaze_reg_t r6; | ||
25 | microblaze_reg_t r7; | ||
26 | microblaze_reg_t r8; | ||
27 | microblaze_reg_t r9; | ||
28 | microblaze_reg_t r10; | ||
29 | microblaze_reg_t r11; | ||
30 | microblaze_reg_t r12; | ||
31 | microblaze_reg_t r13; | ||
32 | microblaze_reg_t r14; | ||
33 | microblaze_reg_t r15; | ||
34 | microblaze_reg_t r16; | ||
35 | microblaze_reg_t r17; | ||
36 | microblaze_reg_t r18; | ||
37 | microblaze_reg_t r19; | ||
38 | microblaze_reg_t r20; | ||
39 | microblaze_reg_t r21; | ||
40 | microblaze_reg_t r22; | ||
41 | microblaze_reg_t r23; | ||
42 | microblaze_reg_t r24; | ||
43 | microblaze_reg_t r25; | ||
44 | microblaze_reg_t r26; | ||
45 | microblaze_reg_t r27; | ||
46 | microblaze_reg_t r28; | ||
47 | microblaze_reg_t r29; | ||
48 | microblaze_reg_t r30; | ||
49 | microblaze_reg_t r31; | ||
50 | microblaze_reg_t pc; | ||
51 | microblaze_reg_t msr; | ||
52 | microblaze_reg_t ear; | ||
53 | microblaze_reg_t esr; | ||
54 | microblaze_reg_t fsr; | ||
55 | int kernel_mode; | ||
56 | }; | ||
57 | |||
58 | #define kernel_mode(regs) ((regs)->kernel_mode) | ||
59 | #define user_mode(regs) (!kernel_mode(regs)) | ||
60 | |||
61 | #define instruction_pointer(regs) ((regs)->pc) | ||
62 | #define profile_pc(regs) instruction_pointer(regs) | ||
63 | |||
64 | void show_regs(struct pt_regs *); | ||
65 | |||
66 | #endif /* __ASSEMBLY__ */ | ||
67 | |||
68 | #endif /* _ASM_MICROBLAZE_PTRACE_H */ | ||
diff --git a/arch/microblaze/include/asm/pvr.h b/arch/microblaze/include/asm/pvr.h new file mode 100644 index 000000000000..66f1b30dd097 --- /dev/null +++ b/arch/microblaze/include/asm/pvr.h | |||
@@ -0,0 +1,209 @@ | |||
1 | /* | ||
2 | * Support for the MicroBlaze PVR (Processor Version Register) | ||
3 | * | ||
4 | * Copyright (C) 2009 Michal Simek <monstr@monstr.eu> | ||
5 | * Copyright (C) 2007 John Williams <john.williams@petalogix.com> | ||
6 | * Copyright (C) 2007 - 2009 PetaLogix | ||
7 | * | ||
8 | * This file is subject to the terms and conditions of the GNU General | ||
9 | * Public License. See the file COPYING in the main directory of this | ||
10 | * archive for more details. | ||
11 | */ | ||
12 | |||
13 | #ifndef _ASM_MICROBLAZE_PVR_H | ||
14 | #define _ASM_MICROBLAZE_PVR_H | ||
15 | |||
16 | #define PVR_MSR_BIT 0x400 | ||
17 | |||
18 | struct pvr_s { | ||
19 | unsigned pvr[16]; | ||
20 | }; | ||
21 | |||
22 | /* The following taken from Xilinx's standalone BSP pvr.h */ | ||
23 | |||
24 | /* Basic PVR mask */ | ||
25 | #define PVR0_PVR_FULL_MASK 0x80000000 | ||
26 | #define PVR0_USE_BARREL_MASK 0x40000000 | ||
27 | #define PVR0_USE_DIV_MASK 0x20000000 | ||
28 | #define PVR0_USE_HW_MUL_MASK 0x10000000 | ||
29 | #define PVR0_USE_FPU_MASK 0x08000000 | ||
30 | #define PVR0_USE_EXC_MASK 0x04000000 | ||
31 | #define PVR0_USE_ICACHE_MASK 0x02000000 | ||
32 | #define PVR0_USE_DCACHE_MASK 0x01000000 | ||
33 | #define PVR0_USE_MMU 0x00800000 /* new */ | ||
34 | #define PVR0_VERSION_MASK 0x0000FF00 | ||
35 | #define PVR0_USER1_MASK 0x000000FF | ||
36 | |||
37 | /* User 2 PVR mask */ | ||
38 | #define PVR1_USER2_MASK 0xFFFFFFFF | ||
39 | |||
40 | /* Configuration PVR masks */ | ||
41 | #define PVR2_D_OPB_MASK 0x80000000 | ||
42 | #define PVR2_D_LMB_MASK 0x40000000 | ||
43 | #define PVR2_I_OPB_MASK 0x20000000 | ||
44 | #define PVR2_I_LMB_MASK 0x10000000 | ||
45 | #define PVR2_INTERRUPT_IS_EDGE_MASK 0x08000000 | ||
46 | #define PVR2_EDGE_IS_POSITIVE_MASK 0x04000000 | ||
47 | #define PVR2_D_PLB_MASK 0x02000000 /* new */ | ||
48 | #define PVR2_I_PLB_MASK 0x01000000 /* new */ | ||
49 | #define PVR2_INTERCONNECT 0x00800000 /* new */ | ||
50 | #define PVR2_USE_EXTEND_FSL 0x00080000 /* new */ | ||
51 | #define PVR2_USE_FSL_EXC 0x00040000 /* new */ | ||
52 | #define PVR2_USE_MSR_INSTR 0x00020000 | ||
53 | #define PVR2_USE_PCMP_INSTR 0x00010000 | ||
54 | #define PVR2_AREA_OPTIMISED 0x00008000 | ||
55 | #define PVR2_USE_BARREL_MASK 0x00004000 | ||
56 | #define PVR2_USE_DIV_MASK 0x00002000 | ||
57 | #define PVR2_USE_HW_MUL_MASK 0x00001000 | ||
58 | #define PVR2_USE_FPU_MASK 0x00000800 | ||
59 | #define PVR2_USE_MUL64_MASK 0x00000400 | ||
60 | #define PVR2_USE_FPU2_MASK 0x00000200 /* new */ | ||
61 | #define PVR2_USE_IPLBEXC 0x00000100 | ||
62 | #define PVR2_USE_DPLBEXC 0x00000080 | ||
63 | #define PVR2_OPCODE_0x0_ILL_MASK 0x00000040 | ||
64 | #define PVR2_UNALIGNED_EXC_MASK 0x00000020 | ||
65 | #define PVR2_ILL_OPCODE_EXC_MASK 0x00000010 | ||
66 | #define PVR2_IOPB_BUS_EXC_MASK 0x00000008 | ||
67 | #define PVR2_DOPB_BUS_EXC_MASK 0x00000004 | ||
68 | #define PVR2_DIV_ZERO_EXC_MASK 0x00000002 | ||
69 | #define PVR2_FPU_EXC_MASK 0x00000001 | ||
70 | |||
71 | /* Debug and exception PVR masks */ | ||
72 | #define PVR3_DEBUG_ENABLED_MASK 0x80000000 | ||
73 | #define PVR3_NUMBER_OF_PC_BRK_MASK 0x1E000000 | ||
74 | #define PVR3_NUMBER_OF_RD_ADDR_BRK_MASK 0x00380000 | ||
75 | #define PVR3_NUMBER_OF_WR_ADDR_BRK_MASK 0x0000E000 | ||
76 | #define PVR3_FSL_LINKS_MASK 0x00000380 | ||
77 | |||
78 | /* ICache config PVR masks */ | ||
79 | #define PVR4_USE_ICACHE_MASK 0x80000000 | ||
80 | #define PVR4_ICACHE_ADDR_TAG_BITS_MASK 0x7C000000 | ||
81 | #define PVR4_ICACHE_USE_FSL_MASK 0x02000000 | ||
82 | #define PVR4_ICACHE_ALLOW_WR_MASK 0x01000000 | ||
83 | #define PVR4_ICACHE_LINE_LEN_MASK 0x00E00000 | ||
84 | #define PVR4_ICACHE_BYTE_SIZE_MASK 0x001F0000 | ||
85 | |||
86 | /* DCache config PVR masks */ | ||
87 | #define PVR5_USE_DCACHE_MASK 0x80000000 | ||
88 | #define PVR5_DCACHE_ADDR_TAG_BITS_MASK 0x7C000000 | ||
89 | #define PVR5_DCACHE_USE_FSL_MASK 0x02000000 | ||
90 | #define PVR5_DCACHE_ALLOW_WR_MASK 0x01000000 | ||
91 | #define PVR5_DCACHE_LINE_LEN_MASK 0x00E00000 | ||
92 | #define PVR5_DCACHE_BYTE_SIZE_MASK 0x001F0000 | ||
93 | |||
94 | /* ICache base address PVR mask */ | ||
95 | #define PVR6_ICACHE_BASEADDR_MASK 0xFFFFFFFF | ||
96 | |||
97 | /* ICache high address PVR mask */ | ||
98 | #define PVR7_ICACHE_HIGHADDR_MASK 0xFFFFFFFF | ||
99 | |||
100 | /* DCache base address PVR mask */ | ||
101 | #define PVR8_DCACHE_BASEADDR_MASK 0xFFFFFFFF | ||
102 | |||
103 | /* DCache high address PVR mask */ | ||
104 | #define PVR9_DCACHE_HIGHADDR_MASK 0xFFFFFFFF | ||
105 | |||
106 | /* Target family PVR mask */ | ||
107 | #define PVR10_TARGET_FAMILY_MASK 0xFF000000 | ||
108 | |||
109 | /* MMU descrtiption */ | ||
110 | #define PVR11_USE_MMU 0xC0000000 | ||
111 | #define PVR11_MMU_ITLB_SIZE 0x38000000 | ||
112 | #define PVR11_MMU_DTLB_SIZE 0x07000000 | ||
113 | #define PVR11_MMU_TLB_ACCESS 0x00C00000 | ||
114 | #define PVR11_MMU_ZONES 0x003C0000 | ||
115 | /* MSR Reset value PVR mask */ | ||
116 | #define PVR11_MSR_RESET_VALUE_MASK 0x000007FF | ||
117 | |||
118 | |||
119 | /* PVR access macros */ | ||
120 | #define PVR_IS_FULL(pvr) (pvr.pvr[0] & PVR0_PVR_FULL_MASK) | ||
121 | #define PVR_USE_BARREL(pvr) (pvr.pvr[0] & PVR0_USE_BARREL_MASK) | ||
122 | #define PVR_USE_DIV(pvr) (pvr.pvr[0] & PVR0_USE_DIV_MASK) | ||
123 | #define PVR_USE_HW_MUL(pvr) (pvr.pvr[0] & PVR0_USE_HW_MUL_MASK) | ||
124 | #define PVR_USE_FPU(pvr) (pvr.pvr[0] & PVR0_USE_FPU_MASK) | ||
125 | #define PVR_USE_FPU2(pvr) (pvr.pvr[2] & PVR2_USE_FPU2_MASK) | ||
126 | #define PVR_USE_ICACHE(pvr) (pvr.pvr[0] & PVR0_USE_ICACHE_MASK) | ||
127 | #define PVR_USE_DCACHE(pvr) (pvr.pvr[0] & PVR0_USE_DCACHE_MASK) | ||
128 | #define PVR_VERSION(pvr) ((pvr.pvr[0] & PVR0_VERSION_MASK) >> 8) | ||
129 | #define PVR_USER1(pvr) (pvr.pvr[0] & PVR0_USER1_MASK) | ||
130 | #define PVR_USER2(pvr) (pvr.pvr[1] & PVR1_USER2_MASK) | ||
131 | |||
132 | #define PVR_D_OPB(pvr) (pvr.pvr[2] & PVR2_D_OPB_MASK) | ||
133 | #define PVR_D_LMB(pvr) (pvr.pvr[2] & PVR2_D_LMB_MASK) | ||
134 | #define PVR_I_OPB(pvr) (pvr.pvr[2] & PVR2_I_OPB_MASK) | ||
135 | #define PVR_I_LMB(pvr) (pvr.pvr[2] & PVR2_I_LMB_MASK) | ||
136 | #define PVR_INTERRUPT_IS_EDGE(pvr) \ | ||
137 | (pvr.pvr[2] & PVR2_INTERRUPT_IS_EDGE_MASK) | ||
138 | #define PVR_EDGE_IS_POSITIVE(pvr) \ | ||
139 | (pvr.pvr[2] & PVR2_EDGE_IS_POSITIVE_MASK) | ||
140 | #define PVR_USE_MSR_INSTR(pvr) (pvr.pvr[2] & PVR2_USE_MSR_INSTR) | ||
141 | #define PVR_USE_PCMP_INSTR(pvr) (pvr.pvr[2] & PVR2_USE_PCMP_INSTR) | ||
142 | #define PVR_AREA_OPTIMISED(pvr) (pvr.pvr[2] & PVR2_AREA_OPTIMISED) | ||
143 | #define PVR_USE_MUL64(pvr) (pvr.pvr[2] & PVR2_USE_MUL64_MASK) | ||
144 | #define PVR_OPCODE_0x0_ILLEGAL(pvr) \ | ||
145 | (pvr.pvr[2] & PVR2_OPCODE_0x0_ILL_MASK) | ||
146 | #define PVR_UNALIGNED_EXCEPTION(pvr) \ | ||
147 | (pvr.pvr[2] & PVR2_UNALIGNED_EXC_MASK) | ||
148 | #define PVR_ILL_OPCODE_EXCEPTION(pvr) \ | ||
149 | (pvr.pvr[2] & PVR2_ILL_OPCODE_EXC_MASK) | ||
150 | #define PVR_IOPB_BUS_EXCEPTION(pvr) \ | ||
151 | (pvr.pvr[2] & PVR2_IOPB_BUS_EXC_MASK) | ||
152 | #define PVR_DOPB_BUS_EXCEPTION(pvr) \ | ||
153 | (pvr.pvr[2] & PVR2_DOPB_BUS_EXC_MASK) | ||
154 | #define PVR_DIV_ZERO_EXCEPTION(pvr) \ | ||
155 | (pvr.pvr[2] & PVR2_DIV_ZERO_EXC_MASK) | ||
156 | #define PVR_FPU_EXCEPTION(pvr) (pvr.pvr[2] & PVR2_FPU_EXC_MASK) | ||
157 | #define PVR_FSL_EXCEPTION(pvr) (pvr.pvr[2] & PVR2_USE_EXTEND_FSL) | ||
158 | |||
159 | #define PVR_DEBUG_ENABLED(pvr) (pvr.pvr[3] & PVR3_DEBUG_ENABLED_MASK) | ||
160 | #define PVR_NUMBER_OF_PC_BRK(pvr) \ | ||
161 | ((pvr.pvr[3] & PVR3_NUMBER_OF_PC_BRK_MASK) >> 25) | ||
162 | #define PVR_NUMBER_OF_RD_ADDR_BRK(pvr) \ | ||
163 | ((pvr.pvr[3] & PVR3_NUMBER_OF_RD_ADDR_BRK_MASK) >> 19) | ||
164 | #define PVR_NUMBER_OF_WR_ADDR_BRK(pvr) \ | ||
165 | ((pvr.pvr[3] & PVR3_NUMBER_OF_WR_ADDR_BRK_MASK) >> 13) | ||
166 | #define PVR_FSL_LINKS(pvr) ((pvr.pvr[3] & PVR3_FSL_LINKS_MASK) >> 7) | ||
167 | |||
168 | #define PVR_ICACHE_ADDR_TAG_BITS(pvr) \ | ||
169 | ((pvr.pvr[4] & PVR4_ICACHE_ADDR_TAG_BITS_MASK) >> 26) | ||
170 | #define PVR_ICACHE_USE_FSL(pvr) (pvr.pvr[4] & PVR4_ICACHE_USE_FSL_MASK) | ||
171 | #define PVR_ICACHE_ALLOW_WR(pvr) (pvr.pvr[4] & PVR4_ICACHE_ALLOW_WR_MASK) | ||
172 | #define PVR_ICACHE_LINE_LEN(pvr) \ | ||
173 | (1 << ((pvr.pvr[4] & PVR4_ICACHE_LINE_LEN_MASK) >> 21)) | ||
174 | #define PVR_ICACHE_BYTE_SIZE(pvr) \ | ||
175 | (1 << ((pvr.pvr[4] & PVR4_ICACHE_BYTE_SIZE_MASK) >> 16)) | ||
176 | |||
177 | #define PVR_DCACHE_ADDR_TAG_BITS(pvr) \ | ||
178 | ((pvr.pvr[5] & PVR5_DCACHE_ADDR_TAG_BITS_MASK) >> 26) | ||
179 | #define PVR_DCACHE_USE_FSL(pvr) (pvr.pvr[5] & PVR5_DCACHE_USE_FSL_MASK) | ||
180 | #define PVR_DCACHE_ALLOW_WR(pvr) (pvr.pvr[5] & PVR5_DCACHE_ALLOW_WR_MASK) | ||
181 | #define PVR_DCACHE_LINE_LEN(pvr) \ | ||
182 | (1 << ((pvr.pvr[5] & PVR5_DCACHE_LINE_LEN_MASK) >> 21)) | ||
183 | #define PVR_DCACHE_BYTE_SIZE(pvr) \ | ||
184 | (1 << ((pvr.pvr[5] & PVR5_DCACHE_BYTE_SIZE_MASK) >> 16)) | ||
185 | |||
186 | |||
187 | #define PVR_ICACHE_BASEADDR(pvr) (pvr.pvr[6] & PVR6_ICACHE_BASEADDR_MASK) | ||
188 | #define PVR_ICACHE_HIGHADDR(pvr) (pvr.pvr[7] & PVR7_ICACHE_HIGHADDR_MASK) | ||
189 | |||
190 | #define PVR_DCACHE_BASEADDR(pvr) (pvr.pvr[8] & PVR8_DCACHE_BASEADDR_MASK) | ||
191 | #define PVR_DCACHE_HIGHADDR(pvr) (pvr.pvr[9] & PVR9_DCACHE_HIGHADDR_MASK) | ||
192 | |||
193 | #define PVR_TARGET_FAMILY(pvr) ((pvr.pvr[10] & PVR10_TARGET_FAMILY_MASK) >> 24) | ||
194 | |||
195 | #define PVR_MSR_RESET_VALUE(pvr) \ | ||
196 | (pvr.pvr[11] & PVR11_MSR_RESET_VALUE_MASK) | ||
197 | |||
198 | /* mmu */ | ||
199 | #define PVR_USE_MMU(pvr) ((pvr.pvr[11] & PVR11_USE_MMU) >> 30) | ||
200 | #define PVR_MMU_ITLB_SIZE(pvr) (pvr.pvr[11] & PVR11_MMU_ITLB_SIZE) | ||
201 | #define PVR_MMU_DTLB_SIZE(pvr) (pvr.pvr[11] & PVR11_MMU_DTLB_SIZE) | ||
202 | #define PVR_MMU_TLB_ACCESS(pvr) (pvr.pvr[11] & PVR11_MMU_TLB_ACCESS) | ||
203 | #define PVR_MMU_ZONES(pvr) (pvr.pvr[11] & PVR11_MMU_ZONES) | ||
204 | |||
205 | |||
206 | int cpu_has_pvr(void); | ||
207 | void get_pvr(struct pvr_s *pvr); | ||
208 | |||
209 | #endif /* _ASM_MICROBLAZE_PVR_H */ | ||
diff --git a/arch/microblaze/include/asm/registers.h b/arch/microblaze/include/asm/registers.h new file mode 100644 index 000000000000..834142d9356f --- /dev/null +++ b/arch/microblaze/include/asm/registers.h | |||
@@ -0,0 +1,33 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2008 Michal Simek | ||
3 | * Copyright (C) 2008 PetaLogix | ||
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 | */ | ||
10 | |||
11 | #ifndef _ASM_MICROBLAZE_REGISTERS_H | ||
12 | #define _ASM_MICROBLAZE_REGISTERS_H | ||
13 | |||
14 | #define MSR_BE (1<<0) /* 0x001 */ | ||
15 | #define MSR_IE (1<<1) /* 0x002 */ | ||
16 | #define MSR_C (1<<2) /* 0x004 */ | ||
17 | #define MSR_BIP (1<<3) /* 0x008 */ | ||
18 | #define MSR_FSL (1<<4) /* 0x010 */ | ||
19 | #define MSR_ICE (1<<5) /* 0x020 */ | ||
20 | #define MSR_DZ (1<<6) /* 0x040 */ | ||
21 | #define MSR_DCE (1<<7) /* 0x080 */ | ||
22 | #define MSR_EE (1<<8) /* 0x100 */ | ||
23 | #define MSR_EIP (1<<9) /* 0x200 */ | ||
24 | #define MSR_CC (1<<31) | ||
25 | |||
26 | /* Floating Point Status Register (FSR) Bits */ | ||
27 | #define FSR_IO (1<<4) /* Invalid operation */ | ||
28 | #define FSR_DZ (1<<3) /* Divide-by-zero */ | ||
29 | #define FSR_OF (1<<2) /* Overflow */ | ||
30 | #define FSR_UF (1<<1) /* Underflow */ | ||
31 | #define FSR_DO (1<<0) /* Denormalized operand error */ | ||
32 | |||
33 | #endif /* _ASM_MICROBLAZE_REGISTERS_H */ | ||
diff --git a/arch/microblaze/include/asm/resource.h b/arch/microblaze/include/asm/resource.h new file mode 100644 index 000000000000..04bc4db8921b --- /dev/null +++ b/arch/microblaze/include/asm/resource.h | |||
@@ -0,0 +1 @@ | |||
#include <asm-generic/resource.h> | |||
diff --git a/arch/microblaze/include/asm/scatterlist.h b/arch/microblaze/include/asm/scatterlist.h new file mode 100644 index 000000000000..08ff1d049b42 --- /dev/null +++ b/arch/microblaze/include/asm/scatterlist.h | |||
@@ -0,0 +1,28 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2008 Michal Simek <monstr@monstr.eu> | ||
3 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
4 | * | ||
5 | * This file is subject to the terms and conditions of the GNU General Public | ||
6 | * License. See the file "COPYING" in the main directory of this archive | ||
7 | * for more details. | ||
8 | */ | ||
9 | |||
10 | #ifndef _ASM_MICROBLAZE_SCATTERLIST_H | ||
11 | #define _ASM_MICROBLAZE_SCATTERLIST_H | ||
12 | |||
13 | struct scatterlist { | ||
14 | #ifdef CONFIG_DEBUG_SG | ||
15 | unsigned long sg_magic; | ||
16 | #endif | ||
17 | unsigned long page_link; | ||
18 | dma_addr_t dma_address; | ||
19 | unsigned int offset; | ||
20 | unsigned int length; | ||
21 | }; | ||
22 | |||
23 | #define sg_dma_address(sg) ((sg)->dma_address) | ||
24 | #define sg_dma_len(sg) ((sg)->length) | ||
25 | |||
26 | #define ISA_DMA_THRESHOLD (~0UL) | ||
27 | |||
28 | #endif /* _ASM_MICROBLAZE_SCATTERLIST_H */ | ||
diff --git a/arch/microblaze/include/asm/sections.h b/arch/microblaze/include/asm/sections.h new file mode 100644 index 000000000000..8434a43e5421 --- /dev/null +++ b/arch/microblaze/include/asm/sections.h | |||
@@ -0,0 +1,25 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_SECTIONS_H | ||
10 | #define _ASM_MICROBLAZE_SECTIONS_H | ||
11 | |||
12 | #include <asm-generic/sections.h> | ||
13 | |||
14 | # ifndef __ASSEMBLY__ | ||
15 | extern char _ssbss[], _esbss[]; | ||
16 | extern unsigned long __ivt_start[], __ivt_end[]; | ||
17 | |||
18 | # ifdef CONFIG_MTD_UCLINUX | ||
19 | extern char *_ebss; | ||
20 | # endif | ||
21 | |||
22 | extern u32 _fdt_start[], _fdt_end[]; | ||
23 | |||
24 | # endif /* !__ASSEMBLY__ */ | ||
25 | #endif /* _ASM_MICROBLAZE_SECTIONS_H */ | ||
diff --git a/arch/microblaze/include/asm/segment.h b/arch/microblaze/include/asm/segment.h new file mode 100644 index 000000000000..7f5dcc56eea1 --- /dev/null +++ b/arch/microblaze/include/asm/segment.h | |||
@@ -0,0 +1,43 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2008 Michal Simek | ||
3 | * Copyright (C) 2008 PetaLogix | ||
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 | */ | ||
10 | |||
11 | #ifndef _ASM_MICROBLAZE_SEGMENT_H | ||
12 | #define _ASM_MICROBLAZE_SEGMENT_H | ||
13 | |||
14 | #ifndef __ASSEMBLY__ | ||
15 | |||
16 | typedef struct { | ||
17 | unsigned long seg; | ||
18 | } mm_segment_t; | ||
19 | |||
20 | /* | ||
21 | * On Microblaze the fs value is actually the top of the corresponding | ||
22 | * address space. | ||
23 | * | ||
24 | * The fs value determines whether argument validity checking should be | ||
25 | * performed or not. If get_fs() == USER_DS, checking is performed, with | ||
26 | * get_fs() == KERNEL_DS, checking is bypassed. | ||
27 | * | ||
28 | * For historical reasons, these macros are grossly misnamed. | ||
29 | * | ||
30 | * For non-MMU arch like Microblaze, KERNEL_DS and USER_DS is equal. | ||
31 | */ | ||
32 | # define KERNEL_DS ((mm_segment_t){0}) | ||
33 | # define USER_DS KERNEL_DS | ||
34 | |||
35 | # define get_ds() (KERNEL_DS) | ||
36 | # define get_fs() (current_thread_info()->addr_limit) | ||
37 | # define set_fs(x) \ | ||
38 | do { current_thread_info()->addr_limit = (x); } while (0) | ||
39 | |||
40 | # define segment_eq(a, b) ((a).seg == (b).seg) | ||
41 | |||
42 | # endif /* __ASSEMBLY__ */ | ||
43 | #endif /* _ASM_MICROBLAZE_SEGMENT_H */ | ||
diff --git a/arch/microblaze/include/asm/selfmod.h b/arch/microblaze/include/asm/selfmod.h new file mode 100644 index 000000000000..c42aff2e6cd0 --- /dev/null +++ b/arch/microblaze/include/asm/selfmod.h | |||
@@ -0,0 +1,24 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007-2008 Michal Simek <monstr@monstr.eu> | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_SELFMOD_H | ||
10 | #define _ASM_MICROBLAZE_SELFMOD_H | ||
11 | |||
12 | /* | ||
13 | * BARRIER_BASE_ADDR is constant address for selfmod function. | ||
14 | * do not change this value - selfmod function is in | ||
15 | * arch/microblaze/kernel/selfmod.c: selfmod_function() | ||
16 | * | ||
17 | * last 16 bits is used for storing register offset | ||
18 | */ | ||
19 | |||
20 | #define BARRIER_BASE_ADDR 0x1234ff00 | ||
21 | |||
22 | void selfmod_function(const int *arr_fce, const unsigned int base); | ||
23 | |||
24 | #endif /* _ASM_MICROBLAZE_SELFMOD_H */ | ||
diff --git a/arch/microblaze/include/asm/sembuf.h b/arch/microblaze/include/asm/sembuf.h new file mode 100644 index 000000000000..b804ed71a57e --- /dev/null +++ b/arch/microblaze/include/asm/sembuf.h | |||
@@ -0,0 +1,34 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_SEMBUF_H | ||
10 | #define _ASM_MICROBLAZE_SEMBUF_H | ||
11 | |||
12 | /* | ||
13 | * The semid64_ds structure for microblaze architecture. | ||
14 | * Note extra padding because this structure is passed back and forth | ||
15 | * between kernel and user space. | ||
16 | * | ||
17 | * Pad space is left for: | ||
18 | * - 64-bit time_t to solve y2038 problem | ||
19 | * - 2 miscellaneous 32-bit values | ||
20 | */ | ||
21 | |||
22 | struct semid64_ds { | ||
23 | struct ipc64_perm sem_perm; /* permissions .. see ipc.h */ | ||
24 | __kernel_time_t sem_otime; /* last semop time */ | ||
25 | unsigned long __unused1; | ||
26 | __kernel_time_t sem_ctime; /* last change time */ | ||
27 | unsigned long __unused2; | ||
28 | unsigned long sem_nsems; /* no. of semaphores in array */ | ||
29 | unsigned long __unused3; | ||
30 | unsigned long __unused4; | ||
31 | }; | ||
32 | |||
33 | |||
34 | #endif /* _ASM_MICROBLAZE_SEMBUF_H */ | ||
diff --git a/arch/microblaze/include/asm/serial.h b/arch/microblaze/include/asm/serial.h new file mode 100644 index 000000000000..39bfc8ce6af5 --- /dev/null +++ b/arch/microblaze/include/asm/serial.h | |||
@@ -0,0 +1,14 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2009 Michal Simek <monstr@monstr.eu> | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_SERIAL_H | ||
10 | #define _ASM_MICROBLAZE_SERIAL_H | ||
11 | |||
12 | # define BASE_BAUD (1843200 / 16) | ||
13 | |||
14 | #endif /* _ASM_MICROBLAZE_SERIAL_H */ | ||
diff --git a/arch/microblaze/include/asm/setup.h b/arch/microblaze/include/asm/setup.h new file mode 100644 index 000000000000..9b98e8e6abae --- /dev/null +++ b/arch/microblaze/include/asm/setup.h | |||
@@ -0,0 +1,44 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007-2008 Michal Simek <monstr@monstr.eu> | ||
3 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
4 | * | ||
5 | * This file is subject to the terms and conditions of the GNU General Public | ||
6 | * License. See the file "COPYING" in the main directory of this archive | ||
7 | * for more details. | ||
8 | */ | ||
9 | |||
10 | #ifndef _ASM_MICROBLAZE_SETUP_H | ||
11 | #define _ASM_MICROBLAZE_SETUP_H | ||
12 | |||
13 | #define COMMAND_LINE_SIZE 256 | ||
14 | |||
15 | # ifndef __ASSEMBLY__ | ||
16 | |||
17 | # ifdef __KERNEL__ | ||
18 | extern unsigned int boot_cpuid; /* move to smp.h */ | ||
19 | |||
20 | extern char cmd_line[COMMAND_LINE_SIZE]; | ||
21 | # endif/* __KERNEL__ */ | ||
22 | |||
23 | void early_printk(const char *fmt, ...); | ||
24 | |||
25 | int setup_early_printk(char *opt); | ||
26 | void disable_early_printk(void); | ||
27 | |||
28 | void heartbeat(void); | ||
29 | void setup_heartbeat(void); | ||
30 | |||
31 | unsigned long long sched_clock(void); | ||
32 | |||
33 | void time_init(void); | ||
34 | void init_IRQ(void); | ||
35 | void machine_early_init(const char *cmdline, unsigned int ram, | ||
36 | unsigned int fdt); | ||
37 | |||
38 | void machine_restart(char *cmd); | ||
39 | void machine_shutdown(void); | ||
40 | void machine_halt(void); | ||
41 | void machine_power_off(void); | ||
42 | |||
43 | # endif /* __ASSEMBLY__ */ | ||
44 | #endif /* _ASM_MICROBLAZE_SETUP_H */ | ||
diff --git a/arch/microblaze/include/asm/shmbuf.h b/arch/microblaze/include/asm/shmbuf.h new file mode 100644 index 000000000000..f829c5843618 --- /dev/null +++ b/arch/microblaze/include/asm/shmbuf.h | |||
@@ -0,0 +1,42 @@ | |||
1 | #ifndef _ASM_MICROBLAZE_SHMBUF_H | ||
2 | #define _ASM_MICROBLAZE_SHMBUF_H | ||
3 | |||
4 | /* | ||
5 | * The shmid64_ds structure for microblaze architecture. | ||
6 | * Note extra padding because this structure is passed back and forth | ||
7 | * between kernel and user space. | ||
8 | * | ||
9 | * Pad space is left for: | ||
10 | * - 64-bit time_t to solve y2038 problem | ||
11 | * - 2 miscellaneous 32-bit values | ||
12 | */ | ||
13 | |||
14 | struct shmid64_ds { | ||
15 | struct ipc64_perm shm_perm; /* operation perms */ | ||
16 | size_t shm_segsz; /* size of segment (bytes) */ | ||
17 | __kernel_time_t shm_atime; /* last attach time */ | ||
18 | unsigned long __unused1; | ||
19 | __kernel_time_t shm_dtime; /* last detach time */ | ||
20 | unsigned long __unused2; | ||
21 | __kernel_time_t shm_ctime; /* last change time */ | ||
22 | unsigned long __unused3; | ||
23 | __kernel_pid_t shm_cpid; /* pid of creator */ | ||
24 | __kernel_pid_t shm_lpid; /* pid of last operator */ | ||
25 | unsigned long shm_nattch; /* no. of current attaches */ | ||
26 | unsigned long __unused4; | ||
27 | unsigned long __unused5; | ||
28 | }; | ||
29 | |||
30 | struct shminfo64 { | ||
31 | unsigned long shmmax; | ||
32 | unsigned long shmmin; | ||
33 | unsigned long shmmni; | ||
34 | unsigned long shmseg; | ||
35 | unsigned long shmall; | ||
36 | unsigned long __unused1; | ||
37 | unsigned long __unused2; | ||
38 | unsigned long __unused3; | ||
39 | unsigned long __unused4; | ||
40 | }; | ||
41 | |||
42 | #endif /* _ASM_MICROBLAZE_SHMBUF_H */ | ||
diff --git a/arch/microblaze/include/asm/shmparam.h b/arch/microblaze/include/asm/shmparam.h new file mode 100644 index 000000000000..9f5fc2b3b6a3 --- /dev/null +++ b/arch/microblaze/include/asm/shmparam.h | |||
@@ -0,0 +1,6 @@ | |||
1 | #ifndef _ASM_MICROBLAZE_SHMPARAM_H | ||
2 | #define _ASM_MICROBLAZE_SHMPARAM_H | ||
3 | |||
4 | #define SHMLBA PAGE_SIZE /* attach addr a multiple of this */ | ||
5 | |||
6 | #endif /* _ASM_MICROBLAZE_SHMPARAM_H */ | ||
diff --git a/arch/microblaze/include/asm/sigcontext.h b/arch/microblaze/include/asm/sigcontext.h new file mode 100644 index 000000000000..55873c80c917 --- /dev/null +++ b/arch/microblaze/include/asm/sigcontext.h | |||
@@ -0,0 +1,20 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_SIGCONTEXT_H | ||
10 | #define _ASM_MICROBLAZE_SIGCONTEXT_H | ||
11 | |||
12 | /* FIXME should be linux/ptrace.h */ | ||
13 | #include <asm/ptrace.h> | ||
14 | |||
15 | struct sigcontext { | ||
16 | struct pt_regs regs; | ||
17 | unsigned long oldmask; | ||
18 | }; | ||
19 | |||
20 | #endif /* _ASM_MICROBLAZE_SIGCONTEXT_H */ | ||
diff --git a/arch/microblaze/include/asm/siginfo.h b/arch/microblaze/include/asm/siginfo.h new file mode 100644 index 000000000000..f162911a8f50 --- /dev/null +++ b/arch/microblaze/include/asm/siginfo.h | |||
@@ -0,0 +1,15 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_SIGINFO_H | ||
10 | #define _ASM_MICROBLAZE_SIGINFO_H | ||
11 | |||
12 | #include <linux/types.h> | ||
13 | #include <asm-generic/siginfo.h> | ||
14 | |||
15 | #endif /* _ASM_MICROBLAZE_SIGINFO_H */ | ||
diff --git a/arch/microblaze/include/asm/signal.h b/arch/microblaze/include/asm/signal.h new file mode 100644 index 000000000000..9676fad3486c --- /dev/null +++ b/arch/microblaze/include/asm/signal.h | |||
@@ -0,0 +1,165 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
3 | * Yasushi SHOJI <yashi@atmark-techno.com> | ||
4 | * Tetsuya OHKAWA <tetsuya@atmark-techno.com> | ||
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 | */ | ||
10 | |||
11 | #ifndef _ASM_MICROBLAZE_SIGNAL_H | ||
12 | #define _ASM_MICROBLAZE_SIGNAL_H | ||
13 | |||
14 | #define SIGHUP 1 | ||
15 | #define SIGINT 2 | ||
16 | #define SIGQUIT 3 | ||
17 | #define SIGILL 4 | ||
18 | #define SIGTRAP 5 | ||
19 | #define SIGABRT 6 | ||
20 | #define SIGIOT 6 | ||
21 | #define SIGBUS 7 | ||
22 | #define SIGFPE 8 | ||
23 | #define SIGKILL 9 | ||
24 | #define SIGUSR1 10 | ||
25 | #define SIGSEGV 11 | ||
26 | #define SIGUSR2 12 | ||
27 | #define SIGPIPE 13 | ||
28 | #define SIGALRM 14 | ||
29 | #define SIGTERM 15 | ||
30 | #define SIGSTKFLT 16 | ||
31 | #define SIGCHLD 17 | ||
32 | #define SIGCONT 18 | ||
33 | #define SIGSTOP 19 | ||
34 | #define SIGTSTP 20 | ||
35 | #define SIGTTIN 21 | ||
36 | #define SIGTTOU 22 | ||
37 | #define SIGURG 23 | ||
38 | #define SIGXCPU 24 | ||
39 | #define SIGXFSZ 25 | ||
40 | #define SIGVTALRM 26 | ||
41 | #define SIGPROF 27 | ||
42 | #define SIGWINCH 28 | ||
43 | #define SIGIO 29 | ||
44 | #define SIGPOLL SIGIO | ||
45 | /* | ||
46 | #define SIGLOST 29 | ||
47 | */ | ||
48 | #define SIGPWR 30 | ||
49 | #define SIGSYS 31 | ||
50 | #define SIGUNUSED 31 | ||
51 | |||
52 | /* These should not be considered constants from userland. */ | ||
53 | #define SIGRTMIN 32 | ||
54 | #define SIGRTMAX _NSIG | ||
55 | |||
56 | /* | ||
57 | * SA_FLAGS values: | ||
58 | * | ||
59 | * SA_ONSTACK indicates that a registered stack_t will be used. | ||
60 | * SA_RESTART flag to get restarting signals (which were the default long ago) | ||
61 | * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop. | ||
62 | * SA_RESETHAND clears the handler when the signal is delivered. | ||
63 | * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies. | ||
64 | * SA_NODEFER prevents the current signal from being masked in the handler. | ||
65 | * | ||
66 | * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single | ||
67 | * Unix names RESETHAND and NODEFER respectively. | ||
68 | */ | ||
69 | #define SA_NOCLDSTOP 0x00000001 | ||
70 | #define SA_NOCLDWAIT 0x00000002 | ||
71 | #define SA_SIGINFO 0x00000004 | ||
72 | #define SA_ONSTACK 0x08000000 | ||
73 | #define SA_RESTART 0x10000000 | ||
74 | #define SA_NODEFER 0x40000000 | ||
75 | #define SA_RESETHAND 0x80000000 | ||
76 | |||
77 | #define SA_NOMASK SA_NODEFER | ||
78 | #define SA_ONESHOT SA_RESETHAND | ||
79 | |||
80 | #define SA_RESTORER 0x04000000 | ||
81 | |||
82 | /* | ||
83 | * sigaltstack controls | ||
84 | */ | ||
85 | #define SS_ONSTACK 1 | ||
86 | #define SS_DISABLE 2 | ||
87 | |||
88 | #define MINSIGSTKSZ 2048 | ||
89 | #define SIGSTKSZ 8192 | ||
90 | |||
91 | # ifndef __ASSEMBLY__ | ||
92 | # include <linux/types.h> | ||
93 | # include <asm-generic/signal.h> | ||
94 | |||
95 | /* Avoid too many header ordering problems. */ | ||
96 | struct siginfo; | ||
97 | |||
98 | # ifdef __KERNEL__ | ||
99 | /* | ||
100 | * Most things should be clean enough to redefine this at will, if care | ||
101 | * is taken to make libc match. | ||
102 | */ | ||
103 | # define _NSIG 64 | ||
104 | # define _NSIG_BPW 32 | ||
105 | # define _NSIG_WORDS (_NSIG / _NSIG_BPW) | ||
106 | |||
107 | typedef unsigned long old_sigset_t; /* at least 32 bits */ | ||
108 | |||
109 | typedef struct { | ||
110 | unsigned long sig[_NSIG_WORDS]; | ||
111 | } sigset_t; | ||
112 | |||
113 | struct old_sigaction { | ||
114 | __sighandler_t sa_handler; | ||
115 | old_sigset_t sa_mask; | ||
116 | unsigned long sa_flags; | ||
117 | void (*sa_restorer)(void); | ||
118 | }; | ||
119 | |||
120 | struct sigaction { | ||
121 | __sighandler_t sa_handler; | ||
122 | unsigned long sa_flags; | ||
123 | void (*sa_restorer)(void); | ||
124 | sigset_t sa_mask; /* mask last for extensibility */ | ||
125 | }; | ||
126 | |||
127 | struct k_sigaction { | ||
128 | struct sigaction sa; | ||
129 | }; | ||
130 | |||
131 | # include <asm/sigcontext.h> | ||
132 | # undef __HAVE_ARCH_SIG_BITOPS | ||
133 | |||
134 | # define ptrace_signal_deliver(regs, cookie) do { } while (0) | ||
135 | |||
136 | # else /* !__KERNEL__ */ | ||
137 | |||
138 | /* Here we must cater to libcs that poke about in kernel headers. */ | ||
139 | |||
140 | # define NSIG 32 | ||
141 | typedef unsigned long sigset_t; | ||
142 | |||
143 | struct sigaction { | ||
144 | union { | ||
145 | __sighandler_t _sa_handler; | ||
146 | void (*_sa_sigaction)(int, struct siginfo *, void *); | ||
147 | } _u; | ||
148 | sigset_t sa_mask; | ||
149 | unsigned long sa_flags; | ||
150 | void (*sa_restorer)(void); | ||
151 | }; | ||
152 | |||
153 | # define sa_handler _u._sa_handler | ||
154 | # define sa_sigaction _u._sa_sigaction | ||
155 | |||
156 | # endif /* __KERNEL__ */ | ||
157 | |||
158 | typedef struct sigaltstack { | ||
159 | void *ss_sp; | ||
160 | int ss_flags; | ||
161 | size_t ss_size; | ||
162 | } stack_t; | ||
163 | |||
164 | # endif /* __ASSEMBLY__ */ | ||
165 | #endif /* _ASM_MICROBLAZE_SIGNAL_H */ | ||
diff --git a/arch/microblaze/include/asm/socket.h b/arch/microblaze/include/asm/socket.h new file mode 100644 index 000000000000..f919b6b540ac --- /dev/null +++ b/arch/microblaze/include/asm/socket.h | |||
@@ -0,0 +1,66 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_SOCKET_H | ||
10 | #define _ASM_MICROBLAZE_SOCKET_H | ||
11 | |||
12 | #include <asm/sockios.h> | ||
13 | |||
14 | /* For setsockoptions(2) */ | ||
15 | #define SOL_SOCKET 1 | ||
16 | |||
17 | #define SO_DEBUG 1 | ||
18 | #define SO_REUSEADDR 2 | ||
19 | #define SO_TYPE 3 | ||
20 | #define SO_ERROR 4 | ||
21 | #define SO_DONTROUTE 5 | ||
22 | #define SO_BROADCAST 6 | ||
23 | #define SO_SNDBUF 7 | ||
24 | #define SO_RCVBUF 8 | ||
25 | #define SO_SNDBUFFORCE 32 | ||
26 | #define SO_RCVBUFFORCE 33 | ||
27 | #define SO_KEEPALIVE 9 | ||
28 | #define SO_OOBINLINE 10 | ||
29 | #define SO_NO_CHECK 11 | ||
30 | #define SO_PRIORITY 12 | ||
31 | #define SO_LINGER 13 | ||
32 | #define SO_BSDCOMPAT 14 | ||
33 | /* To add :#define SO_REUSEPORT 15 */ | ||
34 | #define SO_PASSCRED 16 | ||
35 | #define SO_PEERCRED 17 | ||
36 | #define SO_RCVLOWAT 18 | ||
37 | #define SO_SNDLOWAT 19 | ||
38 | #define SO_RCVTIMEO 20 | ||
39 | #define SO_SNDTIMEO 21 | ||
40 | |||
41 | /* Security levels - as per NRL IPv6 - don't actually do anything */ | ||
42 | #define SO_SECURITY_AUTHENTICATION 22 | ||
43 | #define SO_SECURITY_ENCRYPTION_TRANSPORT 23 | ||
44 | #define SO_SECURITY_ENCRYPTION_NETWORK 24 | ||
45 | |||
46 | #define SO_BINDTODEVICE 25 | ||
47 | |||
48 | /* Socket filtering */ | ||
49 | #define SO_ATTACH_FILTER 26 | ||
50 | #define SO_DETACH_FILTER 27 | ||
51 | |||
52 | #define SO_PEERNAME 28 | ||
53 | #define SO_TIMESTAMP 29 | ||
54 | #define SCM_TIMESTAMP SO_TIMESTAMP | ||
55 | |||
56 | #define SO_ACCEPTCONN 30 | ||
57 | |||
58 | #define SO_PEERSEC 31 | ||
59 | #define SO_PASSSEC 34 | ||
60 | |||
61 | #define SO_TIMESTAMPNS 35 | ||
62 | #define SCM_TIMESTAMPNS SO_TIMESTAMPNS | ||
63 | |||
64 | #define SO_MARK 36 | ||
65 | |||
66 | #endif /* _ASM_MICROBLAZE_SOCKET_H */ | ||
diff --git a/arch/microblaze/include/asm/sockios.h b/arch/microblaze/include/asm/sockios.h new file mode 100644 index 000000000000..9fff57a701e1 --- /dev/null +++ b/arch/microblaze/include/asm/sockios.h | |||
@@ -0,0 +1,23 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_SOCKIOS_H | ||
10 | #define _ASM_MICROBLAZE_SOCKIOS_H | ||
11 | |||
12 | #include <linux/ioctl.h> | ||
13 | |||
14 | /* Socket-level I/O control calls. */ | ||
15 | #define FIOSETOWN 0x8901 | ||
16 | #define SIOCSPGRP 0x8902 | ||
17 | #define FIOGETOWN 0x8903 | ||
18 | #define SIOCGPGRP 0x8904 | ||
19 | #define SIOCATMARK 0x8905 | ||
20 | #define SIOCGSTAMP 0x8906 /* Get stamp (timeval) */ | ||
21 | #define SIOCGSTAMPNS 0x8907 /* Get stamp (timespec) */ | ||
22 | |||
23 | #endif /* _ASM_MICROBLAZE_SOCKIOS_H */ | ||
diff --git a/arch/microblaze/include/asm/stat.h b/arch/microblaze/include/asm/stat.h new file mode 100644 index 000000000000..5f18b8aed220 --- /dev/null +++ b/arch/microblaze/include/asm/stat.h | |||
@@ -0,0 +1,73 @@ | |||
1 | /* | ||
2 | * Microblaze stat structure | ||
3 | * | ||
4 | * Copyright (C) 2001,02,03 NEC Electronics Corporation | ||
5 | * Copyright (C) 2001,02,03 Miles Bader <miles@gnu.org> | ||
6 | * | ||
7 | * This file is subject to the terms and conditions of the GNU General | ||
8 | * Public License. See the file COPYING in the main directory of this | ||
9 | * archive for more details. | ||
10 | * | ||
11 | * Written by Miles Bader <miles@gnu.org> | ||
12 | */ | ||
13 | |||
14 | #ifndef _ASM_MICROBLAZE_STAT_H | ||
15 | #define _ASM_MICROBLAZE_STAT_H | ||
16 | |||
17 | #include <linux/posix_types.h> | ||
18 | |||
19 | struct stat { | ||
20 | unsigned int st_dev; | ||
21 | unsigned long st_ino; | ||
22 | unsigned int st_mode; | ||
23 | unsigned int st_nlink; | ||
24 | unsigned int st_uid; | ||
25 | unsigned int st_gid; | ||
26 | unsigned int st_rdev; | ||
27 | unsigned long st_size; | ||
28 | unsigned long st_blksize; | ||
29 | unsigned long st_blocks; | ||
30 | unsigned long st_atime; | ||
31 | unsigned long __unused1; /* unsigned long st_atime_nsec */ | ||
32 | unsigned long st_mtime; | ||
33 | unsigned long __unused2; /* unsigned long st_mtime_nsec */ | ||
34 | unsigned long st_ctime; | ||
35 | unsigned long __unused3; /* unsigned long st_ctime_nsec */ | ||
36 | unsigned long __unused4; | ||
37 | unsigned long __unused5; | ||
38 | }; | ||
39 | |||
40 | struct stat64 { | ||
41 | unsigned long long st_dev; | ||
42 | unsigned long __unused1; | ||
43 | |||
44 | unsigned long long st_ino; | ||
45 | |||
46 | unsigned int st_mode; | ||
47 | unsigned int st_nlink; | ||
48 | |||
49 | unsigned int st_uid; | ||
50 | unsigned int st_gid; | ||
51 | |||
52 | unsigned long long st_rdev; | ||
53 | unsigned long __unused3; | ||
54 | |||
55 | long long st_size; | ||
56 | unsigned long st_blksize; | ||
57 | |||
58 | unsigned long st_blocks; /* No. of 512-byte blocks allocated */ | ||
59 | unsigned long __unused4; /* future possible st_blocks high bits */ | ||
60 | |||
61 | unsigned long st_atime; | ||
62 | unsigned long st_atime_nsec; | ||
63 | |||
64 | unsigned long st_mtime; | ||
65 | unsigned long st_mtime_nsec; | ||
66 | |||
67 | unsigned long st_ctime; | ||
68 | unsigned long st_ctime_nsec; | ||
69 | |||
70 | unsigned long __unused8; | ||
71 | }; | ||
72 | |||
73 | #endif /* _ASM_MICROBLAZE_STAT_H */ | ||
diff --git a/arch/microblaze/include/asm/statfs.h b/arch/microblaze/include/asm/statfs.h new file mode 100644 index 000000000000..0b91fe198c20 --- /dev/null +++ b/arch/microblaze/include/asm/statfs.h | |||
@@ -0,0 +1 @@ | |||
#include <asm-generic/statfs.h> | |||
diff --git a/arch/microblaze/include/asm/string.h b/arch/microblaze/include/asm/string.h new file mode 100644 index 000000000000..f7728c90fc18 --- /dev/null +++ b/arch/microblaze/include/asm/string.h | |||
@@ -0,0 +1,24 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_STRING_H | ||
10 | #define _ASM_MICROBLAZE_STRING_H | ||
11 | |||
12 | #ifndef __KERNEL__ | ||
13 | |||
14 | #define __HAVE_ARCH_MEMSET | ||
15 | #define __HAVE_ARCH_MEMCPY | ||
16 | #define __HAVE_ARCH_MEMMOVE | ||
17 | |||
18 | extern void *memset(void *, int, __kernel_size_t); | ||
19 | extern void *memcpy(void *, const void *, __kernel_size_t); | ||
20 | extern void *memmove(void *, const void *, __kernel_size_t); | ||
21 | |||
22 | #endif /* __KERNEL__ */ | ||
23 | |||
24 | #endif /* _ASM_MICROBLAZE_STRING_H */ | ||
diff --git a/arch/microblaze/include/asm/swab.h b/arch/microblaze/include/asm/swab.h new file mode 100644 index 000000000000..b375d7b65ad7 --- /dev/null +++ b/arch/microblaze/include/asm/swab.h | |||
@@ -0,0 +1,8 @@ | |||
1 | #ifndef _ASM_MICROBLAZE_SWAB_H | ||
2 | #define _ASM_MICROBLAZE_SWAB_H | ||
3 | |||
4 | #if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__) | ||
5 | #define __SWAB_64_THRU_32__ | ||
6 | #endif | ||
7 | |||
8 | #endif /* _ASM_MICROBLAZE_SWAB_H */ | ||
diff --git a/arch/microblaze/include/asm/syscalls.h b/arch/microblaze/include/asm/syscalls.h new file mode 100644 index 000000000000..9cb4ff0edeb2 --- /dev/null +++ b/arch/microblaze/include/asm/syscalls.h | |||
@@ -0,0 +1,45 @@ | |||
1 | #ifndef __ASM_MICROBLAZE_SYSCALLS_H | ||
2 | #define __ASM_MICROBLAZE_SYSCALLS_H | ||
3 | #ifdef __KERNEL__ | ||
4 | |||
5 | #include <linux/compiler.h> | ||
6 | #include <linux/linkage.h> | ||
7 | #include <linux/types.h> | ||
8 | #include <linux/signal.h> | ||
9 | |||
10 | /* FIXME will be removed */ | ||
11 | asmlinkage int sys_ipc(uint call, int first, int second, | ||
12 | int third, void *ptr, long fifth); | ||
13 | |||
14 | struct pt_regs; | ||
15 | asmlinkage int sys_vfork(struct pt_regs *regs); | ||
16 | asmlinkage int sys_clone(int flags, unsigned long stack, struct pt_regs *regs); | ||
17 | asmlinkage int sys_execve(char __user *filenamei, char __user *__user *argv, | ||
18 | char __user *__user *envp, struct pt_regs *regs); | ||
19 | |||
20 | asmlinkage unsigned long sys_mmap2(unsigned long addr, size_t len, | ||
21 | unsigned long prot, unsigned long flags, | ||
22 | unsigned long fd, unsigned long pgoff); | ||
23 | |||
24 | asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len, | ||
25 | unsigned long prot, unsigned long flags, | ||
26 | unsigned long fd, off_t offset); | ||
27 | |||
28 | /* from signal.c */ | ||
29 | asmlinkage int sys_sigsuspend(old_sigset_t mask, struct pt_regs *regs); | ||
30 | |||
31 | asmlinkage int sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, | ||
32 | struct pt_regs *regs); | ||
33 | |||
34 | asmlinkage int sys_sigaction(int sig, const struct old_sigaction *act, | ||
35 | struct old_sigaction *oact); | ||
36 | |||
37 | asmlinkage int sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, | ||
38 | struct pt_regs *regs); | ||
39 | |||
40 | asmlinkage int sys_sigreturn(struct pt_regs *regs); | ||
41 | |||
42 | asmlinkage int sys_rt_sigreturn(struct pt_regs *regs); | ||
43 | |||
44 | #endif /* __KERNEL__ */ | ||
45 | #endif /* __ASM_MICROBLAZE_SYSCALLS_H */ | ||
diff --git a/arch/microblaze/include/asm/system.h b/arch/microblaze/include/asm/system.h new file mode 100644 index 000000000000..c4e308850b5d --- /dev/null +++ b/arch/microblaze/include/asm/system.h | |||
@@ -0,0 +1,91 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_SYSTEM_H | ||
10 | #define _ASM_MICROBLAZE_SYSTEM_H | ||
11 | |||
12 | #include <asm/registers.h> | ||
13 | #include <asm/setup.h> | ||
14 | #include <asm/irqflags.h> | ||
15 | |||
16 | struct task_struct; | ||
17 | struct thread_info; | ||
18 | |||
19 | extern struct task_struct *_switch_to(struct thread_info *prev, | ||
20 | struct thread_info *next); | ||
21 | |||
22 | #define switch_to(prev, next, last) \ | ||
23 | do { \ | ||
24 | (last) = _switch_to(task_thread_info(prev), \ | ||
25 | task_thread_info(next)); \ | ||
26 | } while (0) | ||
27 | |||
28 | #define smp_read_barrier_depends() do {} while (0) | ||
29 | #define read_barrier_depends() do {} while (0) | ||
30 | |||
31 | #define nop() asm volatile ("nop") | ||
32 | #define mb() barrier() | ||
33 | #define rmb() mb() | ||
34 | #define wmb() mb() | ||
35 | #define set_mb(var, value) do { var = value; mb(); } while (0) | ||
36 | #define set_wmb(var, value) do { var = value; wmb(); } while (0) | ||
37 | |||
38 | #define smp_mb() mb() | ||
39 | #define smp_rmb() rmb() | ||
40 | #define smp_wmb() wmb() | ||
41 | |||
42 | void show_trace(struct task_struct *task, unsigned long *stack); | ||
43 | void __bad_xchg(volatile void *ptr, int size); | ||
44 | |||
45 | static inline unsigned long __xchg(unsigned long x, volatile void *ptr, | ||
46 | int size) | ||
47 | { | ||
48 | unsigned long ret; | ||
49 | unsigned long flags; | ||
50 | |||
51 | switch (size) { | ||
52 | case 1: | ||
53 | local_irq_save(flags); | ||
54 | ret = *(volatile unsigned char *)ptr; | ||
55 | *(volatile unsigned char *)ptr = x; | ||
56 | local_irq_restore(flags); | ||
57 | break; | ||
58 | |||
59 | case 4: | ||
60 | local_irq_save(flags); | ||
61 | ret = *(volatile unsigned long *)ptr; | ||
62 | *(volatile unsigned long *)ptr = x; | ||
63 | local_irq_restore(flags); | ||
64 | break; | ||
65 | default: | ||
66 | __bad_xchg(ptr, size), ret = 0; | ||
67 | break; | ||
68 | } | ||
69 | |||
70 | return ret; | ||
71 | } | ||
72 | |||
73 | void disable_hlt(void); | ||
74 | void enable_hlt(void); | ||
75 | void default_idle(void); | ||
76 | |||
77 | #define xchg(ptr, x) \ | ||
78 | ((__typeof__(*(ptr))) __xchg((unsigned long)(x), (ptr), sizeof(*(ptr)))) | ||
79 | |||
80 | void free_init_pages(char *what, unsigned long begin, unsigned long end); | ||
81 | void free_initmem(void); | ||
82 | extern char *klimit; | ||
83 | extern void ret_from_fork(void); | ||
84 | |||
85 | #ifdef CONFIG_DEBUG_FS | ||
86 | extern struct dentry *of_debugfs_root; | ||
87 | #endif | ||
88 | |||
89 | #define arch_align_stack(x) (x) | ||
90 | |||
91 | #endif /* _ASM_MICROBLAZE_SYSTEM_H */ | ||
diff --git a/arch/microblaze/include/asm/termbits.h b/arch/microblaze/include/asm/termbits.h new file mode 100644 index 000000000000..a1b64bc4724a --- /dev/null +++ b/arch/microblaze/include/asm/termbits.h | |||
@@ -0,0 +1,203 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_TERMBITS_H | ||
10 | #define _ASM_MICROBLAZE_TERMBITS_H | ||
11 | |||
12 | #include <linux/posix_types.h> | ||
13 | |||
14 | typedef unsigned char cc_t; | ||
15 | typedef unsigned int speed_t; | ||
16 | typedef unsigned int tcflag_t; | ||
17 | |||
18 | #define NCCS 19 | ||
19 | struct termios { | ||
20 | tcflag_t c_iflag; /* input mode flags */ | ||
21 | tcflag_t c_oflag; /* output mode flags */ | ||
22 | tcflag_t c_cflag; /* control mode flags */ | ||
23 | tcflag_t c_lflag; /* local mode flags */ | ||
24 | cc_t c_line; /* line discipline */ | ||
25 | cc_t c_cc[NCCS]; /* control characters */ | ||
26 | }; | ||
27 | |||
28 | struct ktermios { | ||
29 | tcflag_t c_iflag; /* input mode flags */ | ||
30 | tcflag_t c_oflag; /* output mode flags */ | ||
31 | tcflag_t c_cflag; /* control mode flags */ | ||
32 | tcflag_t c_lflag; /* local mode flags */ | ||
33 | cc_t c_line; /* line discipline */ | ||
34 | cc_t c_cc[NCCS]; /* control characters */ | ||
35 | speed_t c_ispeed; /* input speed */ | ||
36 | speed_t c_ospeed; /* output speed */ | ||
37 | }; | ||
38 | |||
39 | /* c_cc characters */ | ||
40 | |||
41 | #define VINTR 0 | ||
42 | #define VQUIT 1 | ||
43 | #define VERASE 2 | ||
44 | #define VKILL 3 | ||
45 | #define VEOF 4 | ||
46 | #define VTIME 5 | ||
47 | #define VMIN 6 | ||
48 | #define VSWTC 7 | ||
49 | #define VSTART 8 | ||
50 | #define VSTOP 9 | ||
51 | #define VSUSP 10 | ||
52 | #define VEOL 11 | ||
53 | #define VREPRINT 12 | ||
54 | #define VDISCARD 13 | ||
55 | #define VWERASE 14 | ||
56 | #define VLNEXT 15 | ||
57 | #define VEOL2 16 | ||
58 | |||
59 | /* c_iflag bits */ | ||
60 | |||
61 | #define IGNBRK 0000001 | ||
62 | #define BRKINT 0000002 | ||
63 | #define IGNPAR 0000004 | ||
64 | #define PARMRK 0000010 | ||
65 | #define INPCK 0000020 | ||
66 | #define ISTRIP 0000040 | ||
67 | #define INLCR 0000100 | ||
68 | #define IGNCR 0000200 | ||
69 | #define ICRNL 0000400 | ||
70 | #define IUCLC 0001000 | ||
71 | #define IXON 0002000 | ||
72 | #define IXANY 0004000 | ||
73 | #define IXOFF 0010000 | ||
74 | #define IMAXBEL 0020000 | ||
75 | #define IUTF8 0040000 | ||
76 | |||
77 | /* c_oflag bits */ | ||
78 | |||
79 | #define OPOST 0000001 | ||
80 | #define OLCUC 0000002 | ||
81 | #define ONLCR 0000004 | ||
82 | #define OCRNL 0000010 | ||
83 | #define ONOCR 0000020 | ||
84 | #define ONLRET 0000040 | ||
85 | #define OFILL 0000100 | ||
86 | #define OFDEL 0000200 | ||
87 | #define NLDLY 0000400 | ||
88 | #define NL0 0000000 | ||
89 | #define NL1 0000400 | ||
90 | #define CRDLY 0003000 | ||
91 | #define CR0 0000000 | ||
92 | #define CR1 0001000 | ||
93 | #define CR2 0002000 | ||
94 | #define CR3 0003000 | ||
95 | #define TABDLY 0014000 | ||
96 | #define TAB0 0000000 | ||
97 | #define TAB1 0004000 | ||
98 | #define TAB2 0010000 | ||
99 | #define TAB3 0014000 | ||
100 | #define XTABS 0014000 | ||
101 | #define BSDLY 0020000 | ||
102 | #define BS0 0000000 | ||
103 | #define BS1 0020000 | ||
104 | #define VTDLY 0040000 | ||
105 | #define VT0 0000000 | ||
106 | #define VT1 0040000 | ||
107 | #define FFDLY 0100000 | ||
108 | #define FF0 0000000 | ||
109 | #define FF1 0100000 | ||
110 | |||
111 | /* c_cflag bit meaning */ | ||
112 | |||
113 | #define CBAUD 0010017 | ||
114 | #define B0 0000000 /* hang up */ | ||
115 | #define B50 0000001 | ||
116 | #define B75 0000002 | ||
117 | #define B110 0000003 | ||
118 | #define B134 0000004 | ||
119 | #define B150 0000005 | ||
120 | #define B200 0000006 | ||
121 | #define B300 0000007 | ||
122 | #define B600 0000010 | ||
123 | #define B1200 0000011 | ||
124 | #define B1800 0000012 | ||
125 | #define B2400 0000013 | ||
126 | #define B4800 0000014 | ||
127 | #define B9600 0000015 | ||
128 | #define B19200 0000016 | ||
129 | #define B38400 0000017 | ||
130 | #define EXTA B19200 | ||
131 | #define EXTB B38400 | ||
132 | #define CSIZE 0000060 | ||
133 | #define CS5 0000000 | ||
134 | #define CS6 0000020 | ||
135 | #define CS7 0000040 | ||
136 | #define CS8 0000060 | ||
137 | #define CSTOPB 0000100 | ||
138 | #define CREAD 0000200 | ||
139 | #define PARENB 0000400 | ||
140 | #define PARODD 0001000 | ||
141 | #define HUPCL 0002000 | ||
142 | #define CLOCAL 0004000 | ||
143 | #define CBAUDEX 0010000 | ||
144 | #define B57600 0010001 | ||
145 | #define B115200 0010002 | ||
146 | #define B230400 0010003 | ||
147 | #define B460800 0010004 | ||
148 | #define B500000 0010005 | ||
149 | #define B576000 0010006 | ||
150 | #define B921600 0010007 | ||
151 | #define BOTHER 0010000 | ||
152 | #define B1000000 0010010 | ||
153 | #define B1152000 0010011 | ||
154 | #define B1500000 0010012 | ||
155 | #define B2000000 0010013 | ||
156 | #define B2500000 0010014 | ||
157 | #define B3000000 0010015 | ||
158 | #define B3500000 0010016 | ||
159 | #define B4000000 0010017 | ||
160 | #define CIBAUD 002003600000 /* input baud rate (not used) */ | ||
161 | #define CMSPAR 010000000000 /* mark or space (stick) parity */ | ||
162 | #define CRTSCTS 020000000000 /* flow control */ | ||
163 | |||
164 | #define IBSHIFT 16 /* Shift from CBAUD to CIBAUD */ | ||
165 | |||
166 | /* c_lflag bits */ | ||
167 | |||
168 | #define ISIG 0000001 | ||
169 | #define ICANON 0000002 | ||
170 | #define XCASE 0000004 | ||
171 | #define ECHO 0000010 | ||
172 | #define ECHOE 0000020 | ||
173 | #define ECHOK 0000040 | ||
174 | #define ECHONL 0000100 | ||
175 | #define NOFLSH 0000200 | ||
176 | #define TOSTOP 0000400 | ||
177 | #define ECHOCTL 0001000 | ||
178 | #define ECHOPRT 0002000 | ||
179 | #define ECHOKE 0004000 | ||
180 | #define FLUSHO 0010000 | ||
181 | #define PENDIN 0040000 | ||
182 | #define IEXTEN 0100000 | ||
183 | |||
184 | /* tcflow() and TCXONC use these */ | ||
185 | |||
186 | #define TCOOFF 0 | ||
187 | #define TCOON 1 | ||
188 | #define TCIOFF 2 | ||
189 | #define TCION 3 | ||
190 | |||
191 | /* tcflush() and TCFLSH use these */ | ||
192 | |||
193 | #define TCIFLUSH 0 | ||
194 | #define TCOFLUSH 1 | ||
195 | #define TCIOFLUSH 2 | ||
196 | |||
197 | /* tcsetattr uses these */ | ||
198 | |||
199 | #define TCSANOW 0 | ||
200 | #define TCSADRAIN 1 | ||
201 | #define TCSAFLUSH 2 | ||
202 | |||
203 | #endif /* _ASM_MICROBLAZE_TERMBITS_H */ | ||
diff --git a/arch/microblaze/include/asm/termios.h b/arch/microblaze/include/asm/termios.h new file mode 100644 index 000000000000..102d77258668 --- /dev/null +++ b/arch/microblaze/include/asm/termios.h | |||
@@ -0,0 +1,88 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_TERMIOS_H | ||
10 | #define _ASM_MICROBLAZE_TERMIOS_H | ||
11 | |||
12 | #include <linux/string.h> | ||
13 | #include <asm/termbits.h> | ||
14 | #include <asm/ioctls.h> | ||
15 | |||
16 | struct winsize { | ||
17 | unsigned short ws_row; | ||
18 | unsigned short ws_col; | ||
19 | unsigned short ws_xpixel; | ||
20 | unsigned short ws_ypixel; | ||
21 | }; | ||
22 | |||
23 | #define NCC 8 | ||
24 | struct termio { | ||
25 | unsigned short c_iflag; /* input mode flags */ | ||
26 | unsigned short c_oflag; /* output mode flags */ | ||
27 | unsigned short c_cflag; /* control mode flags */ | ||
28 | unsigned short c_lflag; /* local mode flags */ | ||
29 | unsigned char c_line; /* line discipline */ | ||
30 | unsigned char c_cc[NCC]; /* control characters */ | ||
31 | }; | ||
32 | |||
33 | #ifdef __KERNEL__ | ||
34 | /* intr=^C quit=^| erase=del kill=^U | ||
35 | eof=^D vtime=\0 vmin=\1 sxtc=\0 | ||
36 | start=^Q stop=^S susp=^Z eol=\0 | ||
37 | reprint=^R discard=^U werase=^W lnext=^V | ||
38 | eol2=\0 | ||
39 | */ | ||
40 | #define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0" | ||
41 | #endif | ||
42 | |||
43 | /* Modem lines */ | ||
44 | |||
45 | #define TIOCM_LE 0x001 | ||
46 | #define TIOCM_DTR 0x002 | ||
47 | #define TIOCM_RTS 0x004 | ||
48 | #define TIOCM_ST 0x008 | ||
49 | #define TIOCM_SR 0x010 | ||
50 | #define TIOCM_CTS 0x020 | ||
51 | #define TIOCM_CAR 0x040 | ||
52 | #define TIOCM_RNG 0x080 | ||
53 | #define TIOCM_DSR 0x100 | ||
54 | #define TIOCM_CD TIOCM_CAR | ||
55 | #define TIOCM_RI TIOCM_RNG | ||
56 | #define TIOCM_OUT1 0x2000 | ||
57 | #define TIOCM_OUT2 0x4000 | ||
58 | #define TIOCM_LOOP 0x8000 | ||
59 | |||
60 | /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ | ||
61 | |||
62 | /* Line disciplines */ | ||
63 | |||
64 | #define N_TTY 0 | ||
65 | #define N_SLIP 1 | ||
66 | #define N_MOUSE 2 | ||
67 | #define N_PPP 3 | ||
68 | #define N_STRIP 4 | ||
69 | #define N_AX25 5 | ||
70 | #define N_X25 6 /* X.25 async */ | ||
71 | #define N_6PACK 7 | ||
72 | #define N_MASC 8 /* Reserved for Mobitex module <kaz@cafe.net> */ | ||
73 | #define N_R3964 9 /* Reserved for Simatic R3964 module */ | ||
74 | #define N_PROFIBUS_FDL 10 /* Reserved for Profibus <Dave@mvhi.com> */ | ||
75 | #define N_IRDA 11 /* Linux IR - http://irda.sourceforge.net/ */ | ||
76 | #define N_SMSBLOCK 12 /* SMS block mode - for talking to GSM data cards | ||
77 | about SMS messages */ | ||
78 | #define N_HDLC 13 /* synchronous HDLC */ | ||
79 | #define N_SYNC_PPP 14 | ||
80 | #define N_HCI 15 /* Bluetooth HCI UART */ | ||
81 | |||
82 | #ifdef __KERNEL__ | ||
83 | |||
84 | #include <asm-generic/termios.h> | ||
85 | |||
86 | #endif /* __KERNEL__ */ | ||
87 | |||
88 | #endif /* _ASM_MICROBLAZE_TERMIOS_H */ | ||
diff --git a/arch/microblaze/include/asm/thread_info.h b/arch/microblaze/include/asm/thread_info.h new file mode 100644 index 000000000000..4c3943e3f403 --- /dev/null +++ b/arch/microblaze/include/asm/thread_info.h | |||
@@ -0,0 +1,159 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_THREAD_INFO_H | ||
10 | #define _ASM_MICROBLAZE_THREAD_INFO_H | ||
11 | |||
12 | #ifdef __KERNEL__ | ||
13 | |||
14 | /* we have 8k stack */ | ||
15 | #define THREAD_SHIFT 13 | ||
16 | #define THREAD_SIZE (1 << THREAD_SHIFT) | ||
17 | #define THREAD_SIZE_ORDER 1 | ||
18 | |||
19 | #ifndef __ASSEMBLY__ | ||
20 | # include <linux/types.h> | ||
21 | # include <asm/processor.h> | ||
22 | # include <asm/segment.h> | ||
23 | |||
24 | /* | ||
25 | * low level task data that entry.S needs immediate access to | ||
26 | * - this struct should fit entirely inside of one cache line | ||
27 | * - this struct shares the supervisor stack pages | ||
28 | * - if the contents of this structure are changed, the assembly constants | ||
29 | * must also be changed | ||
30 | */ | ||
31 | |||
32 | struct cpu_context { | ||
33 | __u32 r1; /* stack pointer */ | ||
34 | __u32 r2; | ||
35 | /* dedicated registers */ | ||
36 | __u32 r13; | ||
37 | __u32 r14; | ||
38 | __u32 r15; | ||
39 | __u32 r16; | ||
40 | __u32 r17; | ||
41 | __u32 r18; | ||
42 | /* non-volatile registers */ | ||
43 | __u32 r19; | ||
44 | __u32 r20; | ||
45 | __u32 r21; | ||
46 | __u32 r22; | ||
47 | __u32 r23; | ||
48 | __u32 r24; | ||
49 | __u32 r25; | ||
50 | __u32 r26; | ||
51 | __u32 r27; | ||
52 | __u32 r28; | ||
53 | __u32 r29; | ||
54 | __u32 r30; | ||
55 | /* r31 is used as current task pointer */ | ||
56 | /* special purpose registers */ | ||
57 | __u32 msr; | ||
58 | __u32 ear; | ||
59 | __u32 esr; | ||
60 | __u32 fsr; | ||
61 | }; | ||
62 | |||
63 | struct thread_info { | ||
64 | struct task_struct *task; /* main task structure */ | ||
65 | struct exec_domain *exec_domain; /* execution domain */ | ||
66 | unsigned long flags; /* low level flags */ | ||
67 | unsigned long status; /* thread-synchronous flags */ | ||
68 | __u32 cpu; /* current CPU */ | ||
69 | __s32 preempt_count; /* 0 => preemptable,< 0 => BUG*/ | ||
70 | mm_segment_t addr_limit; /* thread address space */ | ||
71 | struct restart_block restart_block; | ||
72 | |||
73 | struct cpu_context cpu_context; | ||
74 | }; | ||
75 | |||
76 | /* | ||
77 | * macros/functions for gaining access to the thread information structure | ||
78 | * | ||
79 | * preempt_count needs to be 1 initially, until the scheduler is functional. | ||
80 | */ | ||
81 | #define INIT_THREAD_INFO(tsk) \ | ||
82 | { \ | ||
83 | .task = &tsk, \ | ||
84 | .exec_domain = &default_exec_domain, \ | ||
85 | .flags = 0, \ | ||
86 | .cpu = 0, \ | ||
87 | .preempt_count = 1, \ | ||
88 | .addr_limit = KERNEL_DS, \ | ||
89 | .restart_block = { \ | ||
90 | .fn = do_no_restart_syscall, \ | ||
91 | }, \ | ||
92 | } | ||
93 | |||
94 | #define init_thread_info (init_thread_union.thread_info) | ||
95 | #define init_stack (init_thread_union.stack) | ||
96 | |||
97 | /* how to get the thread information struct from C */ | ||
98 | static inline struct thread_info *current_thread_info(void) | ||
99 | { | ||
100 | register unsigned long sp asm("r1"); | ||
101 | |||
102 | return (struct thread_info *)(sp & ~(THREAD_SIZE-1)); | ||
103 | } | ||
104 | |||
105 | /* thread information allocation */ | ||
106 | #endif /* __ASSEMBLY__ */ | ||
107 | |||
108 | #define PREEMPT_ACTIVE 0x10000000 | ||
109 | |||
110 | /* | ||
111 | * thread information flags | ||
112 | * - these are process state flags that various assembly files may | ||
113 | * need to access | ||
114 | * - pending work-to-be-done flags are in LSW | ||
115 | * - other flags in MSW | ||
116 | */ | ||
117 | #define TIF_SYSCALL_TRACE 0 /* syscall trace active */ | ||
118 | #define TIF_NOTIFY_RESUME 1 /* resumption notification requested */ | ||
119 | #define TIF_SIGPENDING 2 /* signal pending */ | ||
120 | #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ | ||
121 | /* restore singlestep on return to user mode */ | ||
122 | #define TIF_SINGLESTEP 4 | ||
123 | #define TIF_IRET 5 /* return with iret */ | ||
124 | #define TIF_MEMDIE 6 | ||
125 | #define TIF_FREEZE 14 /* Freezing for suspend */ | ||
126 | |||
127 | /* FIXME change in entry.S */ | ||
128 | #define TIF_KERNEL_TRACE 8 /* kernel trace active */ | ||
129 | |||
130 | /* true if poll_idle() is polling TIF_NEED_RESCHED */ | ||
131 | #define TIF_POLLING_NRFLAG 16 | ||
132 | |||
133 | #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) | ||
134 | #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) | ||
135 | #define _TIF_SIGPENDING (1<<TIF_SIGPENDING) | ||
136 | #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) | ||
137 | #define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP) | ||
138 | #define _TIF_IRET (1<<TIF_IRET) | ||
139 | #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) | ||
140 | #define _TIF_FREEZE (1<<TIF_FREEZE) | ||
141 | #define _TIF_KERNEL_TRACE (1 << TIF_KERNEL_TRACE) | ||
142 | |||
143 | /* work to do on interrupt/exception return */ | ||
144 | #define _TIF_WORK_MASK 0x0000FFFE | ||
145 | /* work to do on any return to u-space */ | ||
146 | #define _TIF_ALLWORK_MASK 0x0000FFFF | ||
147 | |||
148 | /* | ||
149 | * Thread-synchronous status. | ||
150 | * | ||
151 | * This is different from the flags in that nobody else | ||
152 | * ever touches our thread-synchronous status, so we don't | ||
153 | * have to worry about atomic accesses. | ||
154 | */ | ||
155 | /* FPU was used by this task this quantum (SMP) */ | ||
156 | #define TS_USEDFPU 0x0001 | ||
157 | |||
158 | #endif /* __KERNEL__ */ | ||
159 | #endif /* _ASM_MICROBLAZE_THREAD_INFO_H */ | ||
diff --git a/arch/microblaze/include/asm/timex.h b/arch/microblaze/include/asm/timex.h new file mode 100644 index 000000000000..678525dc6d0b --- /dev/null +++ b/arch/microblaze/include/asm/timex.h | |||
@@ -0,0 +1,18 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_TIMEX_H | ||
10 | #define _ASM_MICROBLAZE_TIMEX_H | ||
11 | |||
12 | #define CLOCK_TICK_RATE 1000 /* Timer input freq. */ | ||
13 | |||
14 | typedef unsigned long cycles_t; | ||
15 | |||
16 | #define get_cycles() (0) | ||
17 | |||
18 | #endif /* _ASM_TIMEX_H */ | ||
diff --git a/arch/microblaze/include/asm/tlb.h b/arch/microblaze/include/asm/tlb.h new file mode 100644 index 000000000000..d1dfe3791127 --- /dev/null +++ b/arch/microblaze/include/asm/tlb.h | |||
@@ -0,0 +1,16 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_TLB_H | ||
10 | #define _ASM_MICROBLAZE_TLB_H | ||
11 | |||
12 | #define tlb_flush(tlb) do {} while (0) | ||
13 | |||
14 | #include <asm-generic/tlb.h> | ||
15 | |||
16 | #endif /* _ASM_MICROBLAZE_TLB_H */ | ||
diff --git a/arch/microblaze/include/asm/tlbflush.h b/arch/microblaze/include/asm/tlbflush.h new file mode 100644 index 000000000000..d7fe7629001b --- /dev/null +++ b/arch/microblaze/include/asm/tlbflush.h | |||
@@ -0,0 +1,20 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_TLBFLUSH_H | ||
10 | #define _ASM_MICROBLAZE_TLBFLUSH_H | ||
11 | |||
12 | #define flush_tlb() BUG() | ||
13 | #define flush_tlb_all() BUG() | ||
14 | #define flush_tlb_mm(mm) BUG() | ||
15 | #define flush_tlb_page(vma, addr) BUG() | ||
16 | #define flush_tlb_range(mm, start, end) BUG() | ||
17 | #define flush_tlb_pgtables(mm, start, end) BUG() | ||
18 | #define flush_tlb_kernel_range(start, end) BUG() | ||
19 | |||
20 | #endif /* _ASM_MICROBLAZE_TLBFLUSH_H */ | ||
diff --git a/arch/microblaze/include/asm/topology.h b/arch/microblaze/include/asm/topology.h new file mode 100644 index 000000000000..96bcea5a9920 --- /dev/null +++ b/arch/microblaze/include/asm/topology.h | |||
@@ -0,0 +1,11 @@ | |||
1 | #include <asm-generic/topology.h> | ||
2 | |||
3 | #ifndef _ASM_MICROBLAZE_TOPOLOGY_H | ||
4 | #define _ASM_MICROBLAZE_TOPOLOGY_H | ||
5 | |||
6 | struct device_node; | ||
7 | static inline int of_node_to_nid(struct device_node *device) | ||
8 | { | ||
9 | return 0; | ||
10 | } | ||
11 | #endif /* _ASM_MICROBLAZE_TOPOLOGY_H */ | ||
diff --git a/arch/microblaze/include/asm/types.h b/arch/microblaze/include/asm/types.h new file mode 100644 index 000000000000..bebc018318f5 --- /dev/null +++ b/arch/microblaze/include/asm/types.h | |||
@@ -0,0 +1,38 @@ | |||
1 | /* | ||
2 | * Copyright (C) Atmark Techno, Inc. | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_TYPES_H | ||
10 | #define _ASM_MICROBLAZE_TYPES_H | ||
11 | |||
12 | /* | ||
13 | * This file is never included by application software unless | ||
14 | * explicitly requested (e.g., via linux/types.h) in which case the | ||
15 | * application is Linux specific so (user-) name space pollution is | ||
16 | * not a major issue. However, for interoperability, libraries still | ||
17 | * need to be careful to avoid a name clashes. | ||
18 | */ | ||
19 | |||
20 | #include <asm-generic/int-ll64.h> | ||
21 | |||
22 | # ifndef __ASSEMBLY__ | ||
23 | |||
24 | typedef unsigned short umode_t; | ||
25 | |||
26 | /* | ||
27 | * These aren't exported outside the kernel to avoid name space clashes | ||
28 | */ | ||
29 | # ifdef __KERNEL__ | ||
30 | # define BITS_PER_LONG 32 | ||
31 | |||
32 | /* Dma addresses are 32-bits wide. */ | ||
33 | |||
34 | typedef u32 dma_addr_t; | ||
35 | |||
36 | # endif/* __KERNEL__ */ | ||
37 | # endif /* __ASSEMBLY__ */ | ||
38 | #endif /* _ASM_MICROBLAZE_TYPES_H */ | ||
diff --git a/arch/microblaze/include/asm/uaccess.h b/arch/microblaze/include/asm/uaccess.h new file mode 100644 index 000000000000..5a3ffc308e12 --- /dev/null +++ b/arch/microblaze/include/asm/uaccess.h | |||
@@ -0,0 +1,134 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_UACCESS_H | ||
10 | #define _ASM_MICROBLAZE_UACCESS_H | ||
11 | |||
12 | #ifdef __KERNEL__ | ||
13 | #ifndef __ASSEMBLY__ | ||
14 | |||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/errno.h> | ||
17 | #include <linux/sched.h> /* RLIMIT_FSIZE */ | ||
18 | #include <linux/mm.h> | ||
19 | |||
20 | #include <asm/mmu.h> | ||
21 | #include <asm/page.h> | ||
22 | #include <asm/pgtable.h> | ||
23 | #include <asm/segment.h> | ||
24 | #include <linux/string.h> | ||
25 | |||
26 | #define VERIFY_READ 0 | ||
27 | #define VERIFY_WRITE 1 | ||
28 | |||
29 | extern int ___range_ok(unsigned long addr, unsigned long size); | ||
30 | |||
31 | #define __range_ok(addr, size) \ | ||
32 | ___range_ok((unsigned long)(addr), (unsigned long)(size)) | ||
33 | |||
34 | #define access_ok(type, addr, size) (__range_ok((addr), (size)) == 0) | ||
35 | #define __access_ok(add, size) (__range_ok((addr), (size)) == 0) | ||
36 | |||
37 | extern inline int bad_user_access_length(void) | ||
38 | { | ||
39 | return 0; | ||
40 | } | ||
41 | /* FIXME this is function for optimalization -> memcpy */ | ||
42 | #define __get_user(var, ptr) \ | ||
43 | ({ \ | ||
44 | int __gu_err = 0; \ | ||
45 | switch (sizeof(*(ptr))) { \ | ||
46 | case 1: \ | ||
47 | case 2: \ | ||
48 | case 4: \ | ||
49 | (var) = *(ptr); \ | ||
50 | break; \ | ||
51 | case 8: \ | ||
52 | memcpy((void *) &(var), (ptr), 8); \ | ||
53 | break; \ | ||
54 | default: \ | ||
55 | (var) = 0; \ | ||
56 | __gu_err = __get_user_bad(); \ | ||
57 | break; \ | ||
58 | } \ | ||
59 | __gu_err; \ | ||
60 | }) | ||
61 | |||
62 | #define __get_user_bad() (bad_user_access_length(), (-EFAULT)) | ||
63 | |||
64 | #define __put_user(var, ptr) \ | ||
65 | ({ \ | ||
66 | int __pu_err = 0; \ | ||
67 | switch (sizeof(*(ptr))) { \ | ||
68 | case 1: \ | ||
69 | case 2: \ | ||
70 | case 4: \ | ||
71 | *(ptr) = (var); \ | ||
72 | break; \ | ||
73 | case 8: { \ | ||
74 | typeof(*(ptr)) __pu_val = var; \ | ||
75 | memcpy(ptr, &__pu_val, sizeof(__pu_val));\ | ||
76 | } \ | ||
77 | break; \ | ||
78 | default: \ | ||
79 | __pu_err = __put_user_bad(); \ | ||
80 | break; \ | ||
81 | } \ | ||
82 | __pu_err; \ | ||
83 | }) | ||
84 | |||
85 | #define __put_user_bad() (bad_user_access_length(), (-EFAULT)) | ||
86 | |||
87 | #define put_user(x, ptr) __put_user(x, ptr) | ||
88 | #define get_user(x, ptr) __get_user(x, ptr) | ||
89 | |||
90 | #define copy_to_user(to, from, n) (memcpy(to, from, n), 0) | ||
91 | #define copy_from_user(to, from, n) (memcpy(to, from, n), 0) | ||
92 | |||
93 | #define __copy_to_user(to, from, n) (copy_to_user(to, from, n)) | ||
94 | #define __copy_from_user(to, from, n) (copy_from_user(to, from, n)) | ||
95 | #define __copy_to_user_inatomic(to, from, n) (__copy_to_user(to, from, n)) | ||
96 | #define __copy_from_user_inatomic(to, from, n) (__copy_from_user(to, from, n)) | ||
97 | |||
98 | #define __clear_user(addr, n) (memset((void *)addr, 0, n), 0) | ||
99 | |||
100 | static inline unsigned long clear_user(void *addr, unsigned long size) | ||
101 | { | ||
102 | if (access_ok(VERIFY_WRITE, addr, size)) | ||
103 | size = __clear_user(addr, size); | ||
104 | return size; | ||
105 | } | ||
106 | |||
107 | /* Returns 0 if exception not found and fixup otherwise. */ | ||
108 | extern unsigned long search_exception_table(unsigned long); | ||
109 | |||
110 | |||
111 | extern long strncpy_from_user(char *dst, const char __user *src, long count); | ||
112 | extern long strnlen_user(const char __user *src, long count); | ||
113 | extern long __strncpy_from_user(char *dst, const char __user *src, long count); | ||
114 | |||
115 | /* | ||
116 | * The exception table consists of pairs of addresses: the first is the | ||
117 | * address of an instruction that is allowed to fault, and the second is | ||
118 | * the address at which the program should continue. No registers are | ||
119 | * modified, so it is entirely up to the continuation code to figure out | ||
120 | * what to do. | ||
121 | * | ||
122 | * All the routines below use bits of fixup code that are out of line | ||
123 | * with the main instruction path. This means when everything is well, | ||
124 | * we don't even have to jump over them. Further, they do not intrude | ||
125 | * on our cache or tlb entries. | ||
126 | */ | ||
127 | struct exception_table_entry { | ||
128 | unsigned long insn, fixup; | ||
129 | }; | ||
130 | |||
131 | #endif /* __ASSEMBLY__ */ | ||
132 | #endif /* __KERNEL__ */ | ||
133 | |||
134 | #endif /* _ASM_MICROBLAZE_UACCESS_H */ | ||
diff --git a/arch/microblaze/include/asm/ucontext.h b/arch/microblaze/include/asm/ucontext.h new file mode 100644 index 000000000000..11f6bb3ae3a4 --- /dev/null +++ b/arch/microblaze/include/asm/ucontext.h | |||
@@ -0,0 +1,22 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
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 | |||
9 | #ifndef _ASM_MICROBLAZE_UCONTEXT_H | ||
10 | #define _ASM_MICROBLAZE_UCONTEXT_H | ||
11 | |||
12 | #include <asm/sigcontext.h> | ||
13 | |||
14 | struct ucontext { | ||
15 | unsigned long uc_flags; | ||
16 | struct ucontext *uc_link; | ||
17 | stack_t uc_stack; | ||
18 | struct sigcontext uc_mcontext; | ||
19 | sigset_t uc_sigmask; /* mask last for extensibility */ | ||
20 | }; | ||
21 | |||
22 | #endif /* _ASM_MICROBLAZE_UCONTEXT_H */ | ||
diff --git a/arch/microblaze/include/asm/unaligned.h b/arch/microblaze/include/asm/unaligned.h new file mode 100644 index 000000000000..9d66b640c910 --- /dev/null +++ b/arch/microblaze/include/asm/unaligned.h | |||
@@ -0,0 +1,22 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2008 Michal Simek <monstr@monstr.eu> | ||
3 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
4 | * | ||
5 | * This file is subject to the terms and conditions of the GNU General Public | ||
6 | * License. See the file "COPYING" in the main directory of this archive | ||
7 | * for more details. | ||
8 | */ | ||
9 | |||
10 | #ifndef _ASM_MICROBLAZE_UNALIGNED_H | ||
11 | #define _ASM_MICROBLAZE_UNALIGNED_H | ||
12 | |||
13 | # ifdef __KERNEL__ | ||
14 | |||
15 | # include <linux/unaligned/access_ok.h> | ||
16 | # include <linux/unaligned/generic.h> | ||
17 | |||
18 | # define get_unaligned __get_unaligned_be | ||
19 | # define put_unaligned __put_unaligned_be | ||
20 | |||
21 | # endif /* __KERNEL__ */ | ||
22 | #endif /* _ASM_MICROBLAZE_UNALIGNED_H */ | ||
diff --git a/arch/microblaze/include/asm/unistd.h b/arch/microblaze/include/asm/unistd.h new file mode 100644 index 000000000000..d9d3903fde3f --- /dev/null +++ b/arch/microblaze/include/asm/unistd.h | |||
@@ -0,0 +1,421 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007-2008 Michal Simek <monstr@monstr.eu> | ||
3 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
4 | * | ||
5 | * This file is subject to the terms and conditions of the GNU General Public | ||
6 | * License. See the file "COPYING" in the main directory of this archive | ||
7 | * for more details. | ||
8 | */ | ||
9 | |||
10 | #ifndef _ASM_MICROBLAZE_UNISTD_H | ||
11 | #define _ASM_MICROBLAZE_UNISTD_H | ||
12 | |||
13 | #define __NR_restart_syscall 0 /* ok */ | ||
14 | #define __NR_exit 1 /* ok */ | ||
15 | #define __NR_fork 2 /* not for no MMU - weird */ | ||
16 | #define __NR_read 3 /* ok */ | ||
17 | #define __NR_write 4 /* ok */ | ||
18 | #define __NR_open 5 /* openat */ | ||
19 | #define __NR_close 6 /* ok */ | ||
20 | #define __NR_waitpid 7 /* waitid */ | ||
21 | #define __NR_creat 8 /* openat */ | ||
22 | #define __NR_link 9 /* linkat */ | ||
23 | #define __NR_unlink 10 /* unlinkat */ | ||
24 | #define __NR_execve 11 /* ok */ | ||
25 | #define __NR_chdir 12 /* ok */ | ||
26 | #define __NR_time 13 /* obsolete -> sys_gettimeofday */ | ||
27 | #define __NR_mknod 14 /* mknodat */ | ||
28 | #define __NR_chmod 15 /* fchmodat */ | ||
29 | #define __NR_lchown 16 /* ok */ | ||
30 | #define __NR_break 17 /* don't know */ | ||
31 | #define __NR_oldstat 18 /* remove */ | ||
32 | #define __NR_lseek 19 /* ok */ | ||
33 | #define __NR_getpid 20 /* ok */ | ||
34 | #define __NR_mount 21 /* ok */ | ||
35 | #define __NR_umount 22 /* ok */ /* use only umount2 */ | ||
36 | #define __NR_setuid 23 /* ok */ | ||
37 | #define __NR_getuid 24 /* ok */ | ||
38 | #define __NR_stime 25 /* obsolete -> sys_settimeofday */ | ||
39 | #define __NR_ptrace 26 /* ok */ | ||
40 | #define __NR_alarm 27 /* obsolete -> sys_setitimer */ | ||
41 | #define __NR_oldfstat 28 /* remove */ | ||
42 | #define __NR_pause 29 /* obsolete -> sys_rt_sigtimedwait */ | ||
43 | #define __NR_utime 30 /* obsolete -> sys_utimesat */ | ||
44 | #define __NR_stty 31 /* remove */ | ||
45 | #define __NR_gtty 32 /* remove */ | ||
46 | #define __NR_access 33 /* faccessat */ | ||
47 | /* can be implemented by sys_setpriority */ | ||
48 | #define __NR_nice 34 | ||
49 | #define __NR_ftime 35 /* remove */ | ||
50 | #define __NR_sync 36 /* ok */ | ||
51 | #define __NR_kill 37 /* ok */ | ||
52 | #define __NR_rename 38 /* renameat */ | ||
53 | #define __NR_mkdir 39 /* mkdirat */ | ||
54 | #define __NR_rmdir 40 /* unlinkat */ | ||
55 | #define __NR_dup 41 /* ok */ | ||
56 | #define __NR_pipe 42 /* ok */ | ||
57 | #define __NR_times 43 /* ok */ | ||
58 | #define __NR_prof 44 /* remove */ | ||
59 | #define __NR_brk 45 /* ok -mmu, nommu specific */ | ||
60 | #define __NR_setgid 46 /* ok */ | ||
61 | #define __NR_getgid 47 /* ok */ | ||
62 | #define __NR_signal 48 /* obsolete -> sys_rt_sigaction */ | ||
63 | #define __NR_geteuid 49 /* ok */ | ||
64 | #define __NR_getegid 50 /* ok */ | ||
65 | #define __NR_acct 51 /* add it and then I can disable it */ | ||
66 | #define __NR_umount2 52 /* remove */ | ||
67 | #define __NR_lock 53 /* remove */ | ||
68 | #define __NR_ioctl 54 /* ok */ | ||
69 | #define __NR_fcntl 55 /* ok -> 64bit version*/ | ||
70 | #define __NR_mpx 56 /* remove */ | ||
71 | #define __NR_setpgid 57 /* ok */ | ||
72 | #define __NR_ulimit 58 /* remove */ | ||
73 | #define __NR_oldolduname 59 /* remove */ | ||
74 | #define __NR_umask 60 /* ok */ | ||
75 | #define __NR_chroot 61 /* ok */ | ||
76 | #define __NR_ustat 62 /* obsolete -> statfs64 */ | ||
77 | #define __NR_dup2 63 /* ok */ | ||
78 | #define __NR_getppid 64 /* ok */ | ||
79 | #define __NR_getpgrp 65 /* obsolete -> sys_getpgid */ | ||
80 | #define __NR_setsid 66 /* ok */ | ||
81 | #define __NR_sigaction 67 /* obsolete -> rt_sigaction */ | ||
82 | #define __NR_sgetmask 68 /* obsolete -> sys_rt_sigprocmask */ | ||
83 | #define __NR_ssetmask 69 /* obsolete ->sys_rt_sigprocmask */ | ||
84 | #define __NR_setreuid 70 /* ok */ | ||
85 | #define __NR_setregid 71 /* ok */ | ||
86 | #define __NR_sigsuspend 72 /* obsolete -> rt_sigsuspend */ | ||
87 | #define __NR_sigpending 73 /* obsolete -> sys_rt_sigpending */ | ||
88 | #define __NR_sethostname 74 /* ok */ | ||
89 | #define __NR_setrlimit 75 /* ok */ | ||
90 | #define __NR_getrlimit 76 /* ok Back compatible 2G limited rlimit */ | ||
91 | #define __NR_getrusage 77 /* ok */ | ||
92 | #define __NR_gettimeofday 78 /* ok */ | ||
93 | #define __NR_settimeofday 79 /* ok */ | ||
94 | #define __NR_getgroups 80 /* ok */ | ||
95 | #define __NR_setgroups 81 /* ok */ | ||
96 | #define __NR_select 82 /* obsolete -> sys_pselect7 */ | ||
97 | #define __NR_symlink 83 /* symlinkat */ | ||
98 | #define __NR_oldlstat 84 /* remove */ | ||
99 | #define __NR_readlink 85 /* obsolete -> sys_readlinkat */ | ||
100 | #define __NR_uselib 86 /* remove */ | ||
101 | #define __NR_swapon 87 /* ok */ | ||
102 | #define __NR_reboot 88 /* ok */ | ||
103 | #define __NR_readdir 89 /* remove ? */ | ||
104 | #define __NR_mmap 90 /* obsolete -> sys_mmap2 */ | ||
105 | #define __NR_munmap 91 /* ok - mmu and nommu */ | ||
106 | #define __NR_truncate 92 /* ok or truncate64 */ | ||
107 | #define __NR_ftruncate 93 /* ok or ftruncate64 */ | ||
108 | #define __NR_fchmod 94 /* ok */ | ||
109 | #define __NR_fchown 95 /* ok */ | ||
110 | #define __NR_getpriority 96 /* ok */ | ||
111 | #define __NR_setpriority 97 /* ok */ | ||
112 | #define __NR_profil 98 /* remove */ | ||
113 | #define __NR_statfs 99 /* ok or statfs64 */ | ||
114 | #define __NR_fstatfs 100 /* ok or fstatfs64 */ | ||
115 | #define __NR_ioperm 101 /* remove */ | ||
116 | #define __NR_socketcall 102 /* remove */ | ||
117 | #define __NR_syslog 103 /* ok */ | ||
118 | #define __NR_setitimer 104 /* ok */ | ||
119 | #define __NR_getitimer 105 /* ok */ | ||
120 | #define __NR_stat 106 /* remove */ | ||
121 | #define __NR_lstat 107 /* remove */ | ||
122 | #define __NR_fstat 108 /* remove */ | ||
123 | #define __NR_olduname 109 /* remove */ | ||
124 | #define __NR_iopl 110 /* remove */ | ||
125 | #define __NR_vhangup 111 /* ok */ | ||
126 | #define __NR_idle 112 /* remove */ | ||
127 | #define __NR_vm86old 113 /* remove */ | ||
128 | #define __NR_wait4 114 /* obsolete -> waitid */ | ||
129 | #define __NR_swapoff 115 /* ok */ | ||
130 | #define __NR_sysinfo 116 /* ok */ | ||
131 | #define __NR_ipc 117 /* remove - direct call */ | ||
132 | #define __NR_fsync 118 /* ok */ | ||
133 | #define __NR_sigreturn 119 /* obsolete -> sys_rt_sigreturn */ | ||
134 | #define __NR_clone 120 /* ok */ | ||
135 | #define __NR_setdomainname 121 /* ok */ | ||
136 | #define __NR_uname 122 /* remove */ | ||
137 | #define __NR_modify_ldt 123 /* remove */ | ||
138 | #define __NR_adjtimex 124 /* ok */ | ||
139 | #define __NR_mprotect 125 /* remove */ | ||
140 | #define __NR_sigprocmask 126 /* obsolete -> sys_rt_sigprocmask */ | ||
141 | #define __NR_create_module 127 /* remove */ | ||
142 | #define __NR_init_module 128 /* ok */ | ||
143 | #define __NR_delete_module 129 /* ok */ | ||
144 | #define __NR_get_kernel_syms 130 /* remove */ | ||
145 | #define __NR_quotactl 131 /* ok */ | ||
146 | #define __NR_getpgid 132 /* ok */ | ||
147 | #define __NR_fchdir 133 /* ok */ | ||
148 | #define __NR_bdflush 134 /* remove */ | ||
149 | #define __NR_sysfs 135 /* needed for busybox */ | ||
150 | #define __NR_personality 136 /* ok */ | ||
151 | #define __NR_afs_syscall 137 /* Syscall for Andrew File System */ | ||
152 | #define __NR_setfsuid 138 /* ok */ | ||
153 | #define __NR_setfsgid 139 /* ok */ | ||
154 | #define __NR__llseek 140 /* remove only lseek */ | ||
155 | #define __NR_getdents 141 /* ok or getdents64 */ | ||
156 | #define __NR__newselect 142 /* remove */ | ||
157 | #define __NR_flock 143 /* ok */ | ||
158 | #define __NR_msync 144 /* remove */ | ||
159 | #define __NR_readv 145 /* ok */ | ||
160 | #define __NR_writev 146 /* ok */ | ||
161 | #define __NR_getsid 147 /* ok */ | ||
162 | #define __NR_fdatasync 148 /* ok */ | ||
163 | #define __NR__sysctl 149 /* remove */ | ||
164 | #define __NR_mlock 150 /* ok - nommu or mmu */ | ||
165 | #define __NR_munlock 151 /* ok - nommu or mmu */ | ||
166 | #define __NR_mlockall 152 /* ok - nommu or mmu */ | ||
167 | #define __NR_munlockall 153 /* ok - nommu or mmu */ | ||
168 | #define __NR_sched_setparam 154 /* ok */ | ||
169 | #define __NR_sched_getparam 155 /* ok */ | ||
170 | #define __NR_sched_setscheduler 156 /* ok */ | ||
171 | #define __NR_sched_getscheduler 157 /* ok */ | ||
172 | #define __NR_sched_yield 158 /* ok */ | ||
173 | #define __NR_sched_get_priority_max 159 /* ok */ | ||
174 | #define __NR_sched_get_priority_min 160 /* ok */ | ||
175 | #define __NR_sched_rr_get_interval 161 /* ok */ | ||
176 | #define __NR_nanosleep 162 /* ok */ | ||
177 | #define __NR_mremap 163 /* ok - nommu or mmu */ | ||
178 | #define __NR_setresuid 164 /* ok */ | ||
179 | #define __NR_getresuid 165 /* ok */ | ||
180 | #define __NR_vm86 166 /* remove */ | ||
181 | #define __NR_query_module 167 /* ok */ | ||
182 | #define __NR_poll 168 /* obsolete -> sys_ppoll */ | ||
183 | #define __NR_nfsservctl 169 /* ok */ | ||
184 | #define __NR_setresgid 170 /* ok */ | ||
185 | #define __NR_getresgid 171 /* ok */ | ||
186 | #define __NR_prctl 172 /* ok */ | ||
187 | #define __NR_rt_sigreturn 173 /* ok */ | ||
188 | #define __NR_rt_sigaction 174 /* ok */ | ||
189 | #define __NR_rt_sigprocmask 175 /* ok */ | ||
190 | #define __NR_rt_sigpending 176 /* ok */ | ||
191 | #define __NR_rt_sigtimedwait 177 /* ok */ | ||
192 | #define __NR_rt_sigqueueinfo 178 /* ok */ | ||
193 | #define __NR_rt_sigsuspend 179 /* ok */ | ||
194 | #define __NR_pread64 180 /* ok */ | ||
195 | #define __NR_pwrite64 181 /* ok */ | ||
196 | #define __NR_chown 182 /* obsolete -> fchownat */ | ||
197 | #define __NR_getcwd 183 /* ok */ | ||
198 | #define __NR_capget 184 /* ok */ | ||
199 | #define __NR_capset 185 /* ok */ | ||
200 | #define __NR_sigaltstack 186 /* remove */ | ||
201 | #define __NR_sendfile 187 /* ok -> exist 64bit version*/ | ||
202 | #define __NR_getpmsg 188 /* remove */ | ||
203 | /* remove - some people actually want streams */ | ||
204 | #define __NR_putpmsg 189 | ||
205 | /* for noMMU - group with clone -> maybe remove */ | ||
206 | #define __NR_vfork 190 | ||
207 | #define __NR_ugetrlimit 191 /* remove - SuS compliant getrlimit */ | ||
208 | #define __NR_mmap2 192 /* ok */ | ||
209 | #define __NR_truncate64 193 /* ok */ | ||
210 | #define __NR_ftruncate64 194 /* ok */ | ||
211 | #define __NR_stat64 195 /* remove _ARCH_WANT_STAT64 */ | ||
212 | #define __NR_lstat64 196 /* remove _ARCH_WANT_STAT64 */ | ||
213 | #define __NR_fstat64 197 /* remove _ARCH_WANT_STAT64 */ | ||
214 | #define __NR_lchown32 198 /* ok - without 32 */ | ||
215 | #define __NR_getuid32 199 /* ok - without 32 */ | ||
216 | #define __NR_getgid32 200 /* ok - without 32 */ | ||
217 | #define __NR_geteuid32 201 /* ok - without 32 */ | ||
218 | #define __NR_getegid32 202 /* ok - without 32 */ | ||
219 | #define __NR_setreuid32 203 /* ok - without 32 */ | ||
220 | #define __NR_setregid32 204 /* ok - without 32 */ | ||
221 | #define __NR_getgroups32 205 /* ok - without 32 */ | ||
222 | #define __NR_setgroups32 206 /* ok - without 32 */ | ||
223 | #define __NR_fchown32 207 /* ok - without 32 */ | ||
224 | #define __NR_setresuid32 208 /* ok - without 32 */ | ||
225 | #define __NR_getresuid32 209 /* ok - without 32 */ | ||
226 | #define __NR_setresgid32 210 /* ok - without 32 */ | ||
227 | #define __NR_getresgid32 211 /* ok - without 32 */ | ||
228 | #define __NR_chown32 212 /* ok - without 32 -obsolete -> fchownat */ | ||
229 | #define __NR_setuid32 213 /* ok - without 32 */ | ||
230 | #define __NR_setgid32 214 /* ok - without 32 */ | ||
231 | #define __NR_setfsuid32 215 /* ok - without 32 */ | ||
232 | #define __NR_setfsgid32 216 /* ok - without 32 */ | ||
233 | #define __NR_pivot_root 217 /* ok */ | ||
234 | #define __NR_mincore 218 /* ok */ | ||
235 | #define __NR_madvise 219 /* ok */ | ||
236 | #define __NR_getdents64 220 /* ok */ | ||
237 | #define __NR_fcntl64 221 /* ok */ | ||
238 | /* 223 is unused */ | ||
239 | #define __NR_gettid 224 /* ok */ | ||
240 | #define __NR_readahead 225 /* ok */ | ||
241 | #define __NR_setxattr 226 /* ok */ | ||
242 | #define __NR_lsetxattr 227 /* ok */ | ||
243 | #define __NR_fsetxattr 228 /* ok */ | ||
244 | #define __NR_getxattr 229 /* ok */ | ||
245 | #define __NR_lgetxattr 230 /* ok */ | ||
246 | #define __NR_fgetxattr 231 /* ok */ | ||
247 | #define __NR_listxattr 232 /* ok */ | ||
248 | #define __NR_llistxattr 233 /* ok */ | ||
249 | #define __NR_flistxattr 234 /* ok */ | ||
250 | #define __NR_removexattr 235 /* ok */ | ||
251 | #define __NR_lremovexattr 236 /* ok */ | ||
252 | #define __NR_fremovexattr 237 /* ok */ | ||
253 | #define __NR_tkill 238 /* ok */ | ||
254 | #define __NR_sendfile64 239 /* ok */ | ||
255 | #define __NR_futex 240 /* ok */ | ||
256 | #define __NR_sched_setaffinity 241 /* ok */ | ||
257 | #define __NR_sched_getaffinity 242 /* ok */ | ||
258 | #define __NR_set_thread_area 243 /* remove */ | ||
259 | #define __NR_get_thread_area 244 /* remove */ | ||
260 | #define __NR_io_setup 245 /* ok */ | ||
261 | #define __NR_io_destroy 246 /* ok */ | ||
262 | #define __NR_io_getevents 247 /* ok */ | ||
263 | #define __NR_io_submit 248 /* ok */ | ||
264 | #define __NR_io_cancel 249 /* ok */ | ||
265 | #define __NR_fadvise64 250 /* remove -> sys_fadvise64_64 */ | ||
266 | /* 251 is available for reuse (was briefly sys_set_zone_reclaim) */ | ||
267 | #define __NR_exit_group 252 /* ok */ | ||
268 | #define __NR_lookup_dcookie 253 /* ok */ | ||
269 | #define __NR_epoll_create 254 /* ok */ | ||
270 | #define __NR_epoll_ctl 255 /* ok */ | ||
271 | #define __NR_epoll_wait 256 /* obsolete -> sys_epoll_pwait */ | ||
272 | #define __NR_remap_file_pages 257 /* only for mmu */ | ||
273 | #define __NR_set_tid_address 258 /* ok */ | ||
274 | #define __NR_timer_create 259 /* ok */ | ||
275 | #define __NR_timer_settime (__NR_timer_create+1) /* 260 */ /* ok */ | ||
276 | #define __NR_timer_gettime (__NR_timer_create+2) /* 261 */ /* ok */ | ||
277 | #define __NR_timer_getoverrun (__NR_timer_create+3) /* 262 */ /* ok */ | ||
278 | #define __NR_timer_delete (__NR_timer_create+4) /* 263 */ /* ok */ | ||
279 | #define __NR_clock_settime (__NR_timer_create+5) /* 264 */ /* ok */ | ||
280 | #define __NR_clock_gettime (__NR_timer_create+6) /* 265 */ /* ok */ | ||
281 | #define __NR_clock_getres (__NR_timer_create+7) /* 266 */ /* ok */ | ||
282 | #define __NR_clock_nanosleep (__NR_timer_create+8) /* 267 */ /* ok */ | ||
283 | #define __NR_statfs64 268 /* ok */ | ||
284 | #define __NR_fstatfs64 269 /* ok */ | ||
285 | #define __NR_tgkill 270 /* ok */ | ||
286 | #define __NR_utimes 271 /* obsolete -> sys_futimesat */ | ||
287 | #define __NR_fadvise64_64 272 /* ok */ | ||
288 | #define __NR_vserver 273 /* ok */ | ||
289 | #define __NR_mbind 274 /* only for mmu */ | ||
290 | #define __NR_get_mempolicy 275 /* only for mmu */ | ||
291 | #define __NR_set_mempolicy 276 /* only for mmu */ | ||
292 | #define __NR_mq_open 277 /* ok */ | ||
293 | #define __NR_mq_unlink (__NR_mq_open+1) /* 278 */ /* ok */ | ||
294 | #define __NR_mq_timedsend (__NR_mq_open+2) /* 279 */ /* ok */ | ||
295 | #define __NR_mq_timedreceive (__NR_mq_open+3) /* 280 */ /* ok */ | ||
296 | #define __NR_mq_notify (__NR_mq_open+4) /* 281 */ /* ok */ | ||
297 | #define __NR_mq_getsetattr (__NR_mq_open+5) /* 282 */ /* ok */ | ||
298 | #define __NR_kexec_load 283 /* ok */ | ||
299 | #define __NR_waitid 284 /* ok */ | ||
300 | /* #define __NR_sys_setaltroot 285 */ | ||
301 | #define __NR_add_key 286 /* ok */ | ||
302 | #define __NR_request_key 287 /* ok */ | ||
303 | #define __NR_keyctl 288 /* ok */ | ||
304 | #define __NR_ioprio_set 289 /* ok */ | ||
305 | #define __NR_ioprio_get 290 /* ok */ | ||
306 | #define __NR_inotify_init 291 /* ok */ | ||
307 | #define __NR_inotify_add_watch 292 /* ok */ | ||
308 | #define __NR_inotify_rm_watch 293 /* ok */ | ||
309 | #define __NR_migrate_pages 294 /* mmu */ | ||
310 | #define __NR_openat 295 /* ok */ | ||
311 | #define __NR_mkdirat 296 /* ok */ | ||
312 | #define __NR_mknodat 297 /* ok */ | ||
313 | #define __NR_fchownat 298 /* ok */ | ||
314 | #define __NR_futimesat 299 /* obsolete -> sys_utimesat */ | ||
315 | #define __NR_fstatat64 300 /* stat64 */ | ||
316 | #define __NR_unlinkat 301 /* ok */ | ||
317 | #define __NR_renameat 302 /* ok */ | ||
318 | #define __NR_linkat 303 /* ok */ | ||
319 | #define __NR_symlinkat 304 /* ok */ | ||
320 | #define __NR_readlinkat 305 /* ok */ | ||
321 | #define __NR_fchmodat 306 /* ok */ | ||
322 | #define __NR_faccessat 307 /* ok */ | ||
323 | #define __NR_pselect6 308 /* obsolete -> sys_pselect7 */ | ||
324 | #define __NR_ppoll 309 /* ok */ | ||
325 | #define __NR_unshare 310 /* ok */ | ||
326 | #define __NR_set_robust_list 311 /* ok */ | ||
327 | #define __NR_get_robust_list 312 /* ok */ | ||
328 | #define __NR_splice 313 /* ok */ | ||
329 | #define __NR_sync_file_range 314 /* ok */ | ||
330 | #define __NR_tee 315 /* ok */ | ||
331 | #define __NR_vmsplice 316 /* ok */ | ||
332 | #define __NR_move_pages 317 /* mmu */ | ||
333 | #define __NR_getcpu 318 /* ok */ | ||
334 | #define __NR_epoll_pwait 319 /* ok */ | ||
335 | #define __NR_utimensat 320 /* ok */ | ||
336 | #define __NR_signalfd 321 /* ok */ | ||
337 | #define __NR_timerfd_create 322 /* ok */ | ||
338 | #define __NR_eventfd 323 /* ok */ | ||
339 | #define __NR_fallocate 324 /* ok */ | ||
340 | #define __NR_semtimedop 325 /* ok - semaphore group */ | ||
341 | #define __NR_timerfd_settime 326 /* ok */ | ||
342 | #define __NR_timerfd_gettime 327 /* ok */ | ||
343 | /* sysv ipc syscalls */ | ||
344 | #define __NR_semctl 328 /* ok */ | ||
345 | #define __NR_semget 329 /* ok */ | ||
346 | #define __NR_semop 330 /* ok */ | ||
347 | #define __NR_msgctl 331 /* ok */ | ||
348 | #define __NR_msgget 332 /* ok */ | ||
349 | #define __NR_msgrcv 333 /* ok */ | ||
350 | #define __NR_msgsnd 334 /* ok */ | ||
351 | #define __NR_shmat 335 /* ok */ | ||
352 | #define __NR_shmctl 336 /* ok */ | ||
353 | #define __NR_shmdt 337 /* ok */ | ||
354 | #define __NR_shmget 338 /* ok */ | ||
355 | |||
356 | |||
357 | #define __NR_signalfd4 339 /* new */ | ||
358 | #define __NR_eventfd2 340 /* new */ | ||
359 | #define __NR_epoll_create1 341 /* new */ | ||
360 | #define __NR_dup3 342 /* new */ | ||
361 | #define __NR_pipe2 343 /* new */ | ||
362 | #define __NR_inotify_init1 344 /* new */ | ||
363 | #define __NR_socket 345 /* new */ | ||
364 | #define __NR_socketpair 346 /* new */ | ||
365 | #define __NR_bind 347 /* new */ | ||
366 | #define __NR_listen 348 /* new */ | ||
367 | #define __NR_accept 349 /* new */ | ||
368 | #define __NR_connect 350 /* new */ | ||
369 | #define __NR_getsockname 351 /* new */ | ||
370 | #define __NR_getpeername 352 /* new */ | ||
371 | #define __NR_sendto 353 /* new */ | ||
372 | #define __NR_send 354 /* new */ | ||
373 | #define __NR_recvfrom 355 /* new */ | ||
374 | #define __NR_recv 356 /* new */ | ||
375 | #define __NR_setsockopt 357 /* new */ | ||
376 | #define __NR_getsockopt 358 /* new */ | ||
377 | #define __NR_shutdown 359 /* new */ | ||
378 | #define __NR_sendmsg 360 /* new */ | ||
379 | #define __NR_recvmsg 361 /* new */ | ||
380 | #define __NR_accept04 362 /* new */ | ||
381 | |||
382 | #define __NR_syscalls 363 | ||
383 | |||
384 | #ifdef __KERNEL__ | ||
385 | #ifndef __ASSEMBLY__ | ||
386 | |||
387 | #define __ARCH_WANT_IPC_PARSE_VERSION | ||
388 | /* #define __ARCH_WANT_OLD_READDIR */ | ||
389 | /* #define __ARCH_WANT_OLD_STAT */ | ||
390 | #define __ARCH_WANT_STAT64 | ||
391 | #define __ARCH_WANT_SYS_ALARM | ||
392 | #define __ARCH_WANT_SYS_GETHOSTNAME | ||
393 | #define __ARCH_WANT_SYS_PAUSE | ||
394 | #define __ARCH_WANT_SYS_SGETMASK | ||
395 | #define __ARCH_WANT_SYS_SIGNAL | ||
396 | #define __ARCH_WANT_SYS_TIME | ||
397 | #define __ARCH_WANT_SYS_UTIME | ||
398 | #define __ARCH_WANT_SYS_WAITPID | ||
399 | #define __ARCH_WANT_SYS_SOCKETCALL | ||
400 | #define __ARCH_WANT_SYS_FADVISE64 | ||
401 | #define __ARCH_WANT_SYS_GETPGRP | ||
402 | #define __ARCH_WANT_SYS_LLSEEK | ||
403 | #define __ARCH_WANT_SYS_NICE | ||
404 | /* #define __ARCH_WANT_SYS_OLD_GETRLIMIT */ | ||
405 | #define __ARCH_WANT_SYS_OLDUMOUNT | ||
406 | #define __ARCH_WANT_SYS_SIGPENDING | ||
407 | #define __ARCH_WANT_SYS_SIGPROCMASK | ||
408 | #define __ARCH_WANT_SYS_RT_SIGACTION | ||
409 | /* #define __ARCH_WANT_SYS_RT_SIGSUSPEND */ | ||
410 | |||
411 | /* | ||
412 | * "Conditional" syscalls | ||
413 | * | ||
414 | * What we want is __attribute__((weak,alias("sys_ni_syscall"))), | ||
415 | * but it doesn't work on all toolchains, so we just do it by hand | ||
416 | */ | ||
417 | #define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall"); | ||
418 | |||
419 | #endif /* __ASSEMBLY__ */ | ||
420 | #endif /* __KERNEL__ */ | ||
421 | #endif /* _ASM_MICROBLAZE_UNISTD_H */ | ||
diff --git a/arch/microblaze/include/asm/user.h b/arch/microblaze/include/asm/user.h new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/arch/microblaze/include/asm/user.h | |||
diff --git a/arch/microblaze/include/asm/vga.h b/arch/microblaze/include/asm/vga.h new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/arch/microblaze/include/asm/vga.h | |||
diff --git a/arch/microblaze/include/asm/xor.h b/arch/microblaze/include/asm/xor.h new file mode 100644 index 000000000000..c82eb12a5b18 --- /dev/null +++ b/arch/microblaze/include/asm/xor.h | |||
@@ -0,0 +1 @@ | |||
#include <asm-generic/xor.h> | |||
diff --git a/arch/microblaze/kernel/Makefile b/arch/microblaze/kernel/Makefile new file mode 100644 index 000000000000..da94bec4ecba --- /dev/null +++ b/arch/microblaze/kernel/Makefile | |||
@@ -0,0 +1,19 @@ | |||
1 | # | ||
2 | # Makefile | ||
3 | # | ||
4 | |||
5 | extra-y := head.o vmlinux.lds | ||
6 | |||
7 | obj-y += exceptions.o \ | ||
8 | hw_exception_handler.o init_task.o intc.o irq.o of_device.o \ | ||
9 | of_platform.o process.o prom.o prom_parse.o ptrace.o \ | ||
10 | setup.o signal.o sys_microblaze.o timer.o traps.o | ||
11 | |||
12 | obj-y += cpu/ | ||
13 | |||
14 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o | ||
15 | obj-$(CONFIG_SELFMOD) += selfmod.o | ||
16 | obj-$(CONFIG_HEART_BEAT) += heartbeat.o | ||
17 | obj-$(CONFIG_MODULES) += microblaze_ksyms.o module.o | ||
18 | |||
19 | obj-y += entry$(MMUEXT).o | ||
diff --git a/arch/microblaze/kernel/asm-offsets.c b/arch/microblaze/kernel/asm-offsets.c new file mode 100644 index 000000000000..38e1a2e8ad0c --- /dev/null +++ b/arch/microblaze/kernel/asm-offsets.c | |||
@@ -0,0 +1,115 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007-2009 PetaLogix | ||
3 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
4 | * | ||
5 | * This file is subject to the terms and conditions of the GNU General Public | ||
6 | * License. See the file "COPYING" in the main directory of this archive | ||
7 | * for more details. | ||
8 | */ | ||
9 | |||
10 | #include <linux/init.h> | ||
11 | #include <linux/stddef.h> | ||
12 | #include <linux/sched.h> | ||
13 | #include <linux/kernel_stat.h> | ||
14 | #include <linux/ptrace.h> | ||
15 | #include <linux/hardirq.h> | ||
16 | #include <linux/thread_info.h> | ||
17 | #include <linux/kbuild.h> | ||
18 | |||
19 | int main(int argc, char *argv[]) | ||
20 | { | ||
21 | /* struct pt_regs */ | ||
22 | DEFINE(PT_SIZE, sizeof(struct pt_regs)); | ||
23 | DEFINE(PT_MSR, offsetof(struct pt_regs, msr)); | ||
24 | DEFINE(PT_EAR, offsetof(struct pt_regs, ear)); | ||
25 | DEFINE(PT_ESR, offsetof(struct pt_regs, esr)); | ||
26 | DEFINE(PT_FSR, offsetof(struct pt_regs, fsr)); | ||
27 | DEFINE(PT_PC, offsetof(struct pt_regs, pc)); | ||
28 | DEFINE(PT_R0, offsetof(struct pt_regs, r0)); | ||
29 | DEFINE(PT_R1, offsetof(struct pt_regs, r1)); | ||
30 | DEFINE(PT_R2, offsetof(struct pt_regs, r2)); | ||
31 | DEFINE(PT_R3, offsetof(struct pt_regs, r3)); | ||
32 | DEFINE(PT_R4, offsetof(struct pt_regs, r4)); | ||
33 | DEFINE(PT_R5, offsetof(struct pt_regs, r5)); | ||
34 | DEFINE(PT_R6, offsetof(struct pt_regs, r6)); | ||
35 | DEFINE(PT_R7, offsetof(struct pt_regs, r7)); | ||
36 | DEFINE(PT_R8, offsetof(struct pt_regs, r8)); | ||
37 | DEFINE(PT_R9, offsetof(struct pt_regs, r9)); | ||
38 | DEFINE(PT_R10, offsetof(struct pt_regs, r10)); | ||
39 | DEFINE(PT_R11, offsetof(struct pt_regs, r11)); | ||
40 | DEFINE(PT_R12, offsetof(struct pt_regs, r12)); | ||
41 | DEFINE(PT_R13, offsetof(struct pt_regs, r13)); | ||
42 | DEFINE(PT_R14, offsetof(struct pt_regs, r14)); | ||
43 | DEFINE(PT_R15, offsetof(struct pt_regs, r15)); | ||
44 | DEFINE(PT_R16, offsetof(struct pt_regs, r16)); | ||
45 | DEFINE(PT_R17, offsetof(struct pt_regs, r17)); | ||
46 | DEFINE(PT_R18, offsetof(struct pt_regs, r18)); | ||
47 | DEFINE(PT_R19, offsetof(struct pt_regs, r19)); | ||
48 | DEFINE(PT_R20, offsetof(struct pt_regs, r20)); | ||
49 | DEFINE(PT_R21, offsetof(struct pt_regs, r21)); | ||
50 | DEFINE(PT_R22, offsetof(struct pt_regs, r22)); | ||
51 | DEFINE(PT_R23, offsetof(struct pt_regs, r23)); | ||
52 | DEFINE(PT_R24, offsetof(struct pt_regs, r24)); | ||
53 | DEFINE(PT_R25, offsetof(struct pt_regs, r25)); | ||
54 | DEFINE(PT_R26, offsetof(struct pt_regs, r26)); | ||
55 | DEFINE(PT_R27, offsetof(struct pt_regs, r27)); | ||
56 | DEFINE(PT_R28, offsetof(struct pt_regs, r28)); | ||
57 | DEFINE(PT_R29, offsetof(struct pt_regs, r29)); | ||
58 | DEFINE(PT_R30, offsetof(struct pt_regs, r30)); | ||
59 | DEFINE(PT_R31, offsetof(struct pt_regs, r31)); | ||
60 | DEFINE(PT_MODE, offsetof(struct pt_regs, kernel_mode)); | ||
61 | BLANK(); | ||
62 | |||
63 | /* Magic offsets for PTRACE PEEK/POKE etc */ | ||
64 | DEFINE(PT_TEXT_ADDR, sizeof(struct pt_regs) + 1); | ||
65 | DEFINE(PT_TEXT_LEN, sizeof(struct pt_regs) + 2); | ||
66 | DEFINE(PT_DATA_ADDR, sizeof(struct pt_regs) + 3); | ||
67 | BLANK(); | ||
68 | |||
69 | /* struct task_struct */ | ||
70 | DEFINE(TS_THREAD_INFO, offsetof(struct task_struct, stack)); | ||
71 | |||
72 | /* struct thread_info */ | ||
73 | DEFINE(TI_TASK, offsetof(struct thread_info, task)); | ||
74 | DEFINE(TI_EXEC_DOMAIN, offsetof(struct thread_info, exec_domain)); | ||
75 | DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); | ||
76 | DEFINE(TI_STATUS, offsetof(struct thread_info, status)); | ||
77 | DEFINE(TI_CPU, offsetof(struct thread_info, cpu)); | ||
78 | DEFINE(TI_PRE_COUNT, offsetof(struct thread_info, preempt_count)); | ||
79 | DEFINE(TI_ADDR_LIMIT, offsetof(struct thread_info, addr_limit)); | ||
80 | DEFINE(TI_RESTART_BLOCK, offsetof(struct thread_info, restart_block)); | ||
81 | DEFINE(TI_CPU_CONTEXT, offsetof(struct thread_info, cpu_context)); | ||
82 | BLANK(); | ||
83 | |||
84 | /* struct cpu_context */ | ||
85 | DEFINE(CC_R1, offsetof(struct cpu_context, r1)); /* r1 */ | ||
86 | DEFINE(CC_R2, offsetof(struct cpu_context, r2)); | ||
87 | /* dedicated registers */ | ||
88 | DEFINE(CC_R13, offsetof(struct cpu_context, r13)); | ||
89 | DEFINE(CC_R14, offsetof(struct cpu_context, r14)); | ||
90 | DEFINE(CC_R15, offsetof(struct cpu_context, r15)); | ||
91 | DEFINE(CC_R16, offsetof(struct cpu_context, r16)); | ||
92 | DEFINE(CC_R17, offsetof(struct cpu_context, r17)); | ||
93 | DEFINE(CC_R18, offsetof(struct cpu_context, r18)); | ||
94 | /* non-volatile registers */ | ||
95 | DEFINE(CC_R19, offsetof(struct cpu_context, r19)); | ||
96 | DEFINE(CC_R20, offsetof(struct cpu_context, r20)); | ||
97 | DEFINE(CC_R21, offsetof(struct cpu_context, r21)); | ||
98 | DEFINE(CC_R22, offsetof(struct cpu_context, r22)); | ||
99 | DEFINE(CC_R23, offsetof(struct cpu_context, r23)); | ||
100 | DEFINE(CC_R24, offsetof(struct cpu_context, r24)); | ||
101 | DEFINE(CC_R25, offsetof(struct cpu_context, r25)); | ||
102 | DEFINE(CC_R26, offsetof(struct cpu_context, r26)); | ||
103 | DEFINE(CC_R27, offsetof(struct cpu_context, r27)); | ||
104 | DEFINE(CC_R28, offsetof(struct cpu_context, r28)); | ||
105 | DEFINE(CC_R29, offsetof(struct cpu_context, r29)); | ||
106 | DEFINE(CC_R30, offsetof(struct cpu_context, r30)); | ||
107 | /* special purpose registers */ | ||
108 | DEFINE(CC_MSR, offsetof(struct cpu_context, msr)); | ||
109 | DEFINE(CC_EAR, offsetof(struct cpu_context, ear)); | ||
110 | DEFINE(CC_ESR, offsetof(struct cpu_context, esr)); | ||
111 | DEFINE(CC_FSR, offsetof(struct cpu_context, fsr)); | ||
112 | BLANK(); | ||
113 | |||
114 | return 0; | ||
115 | } | ||
diff --git a/arch/microblaze/kernel/cpu/Makefile b/arch/microblaze/kernel/cpu/Makefile new file mode 100644 index 000000000000..20646e549271 --- /dev/null +++ b/arch/microblaze/kernel/cpu/Makefile | |||
@@ -0,0 +1,8 @@ | |||
1 | # | ||
2 | # Build the appropriate CPU version support | ||
3 | # | ||
4 | |||
5 | EXTRA_CFLAGS += -DCPU_MAJOR=$(CPU_MAJOR) -DCPU_MINOR=$(CPU_MINOR) \ | ||
6 | -DCPU_REV=$(CPU_REV) | ||
7 | |||
8 | obj-y += cache.o cpuinfo.o cpuinfo-pvr-full.o cpuinfo-static.o mb.o pvr.o | ||
diff --git a/arch/microblaze/kernel/cpu/cache.c b/arch/microblaze/kernel/cpu/cache.c new file mode 100644 index 000000000000..be9fecca4f91 --- /dev/null +++ b/arch/microblaze/kernel/cpu/cache.c | |||
@@ -0,0 +1,258 @@ | |||
1 | /* | ||
2 | * Cache control for MicroBlaze cache memories | ||
3 | * | ||
4 | * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> | ||
5 | * Copyright (C) 2007-2009 PetaLogix | ||
6 | * Copyright (C) 2007 John Williams <john.williams@petalogix.com> | ||
7 | * | ||
8 | * This file is subject to the terms and conditions of the GNU General | ||
9 | * Public License. See the file COPYING in the main directory of this | ||
10 | * archive for more details. | ||
11 | */ | ||
12 | |||
13 | #include <asm/cacheflush.h> | ||
14 | #include <linux/cache.h> | ||
15 | #include <asm/cpuinfo.h> | ||
16 | |||
17 | /* Exported functions */ | ||
18 | |||
19 | void _enable_icache(void) | ||
20 | { | ||
21 | if (cpuinfo.use_icache) { | ||
22 | #if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR | ||
23 | __asm__ __volatile__ (" \ | ||
24 | msrset r0, %0; \ | ||
25 | nop; " \ | ||
26 | : \ | ||
27 | : "i" (MSR_ICE) \ | ||
28 | : "memory"); | ||
29 | #else | ||
30 | __asm__ __volatile__ (" \ | ||
31 | mfs r12, rmsr; \ | ||
32 | nop; \ | ||
33 | ori r12, r12, %0; \ | ||
34 | mts rmsr, r12; \ | ||
35 | nop; " \ | ||
36 | : \ | ||
37 | : "i" (MSR_ICE) \ | ||
38 | : "memory", "r12"); | ||
39 | #endif | ||
40 | } | ||
41 | } | ||
42 | |||
43 | void _disable_icache(void) | ||
44 | { | ||
45 | if (cpuinfo.use_icache) { | ||
46 | #if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR | ||
47 | __asm__ __volatile__ (" \ | ||
48 | msrclr r0, %0; \ | ||
49 | nop; " \ | ||
50 | : \ | ||
51 | : "i" (MSR_ICE) \ | ||
52 | : "memory"); | ||
53 | #else | ||
54 | __asm__ __volatile__ (" \ | ||
55 | mfs r12, rmsr; \ | ||
56 | nop; \ | ||
57 | andi r12, r12, ~%0; \ | ||
58 | mts rmsr, r12; \ | ||
59 | nop; " \ | ||
60 | : \ | ||
61 | : "i" (MSR_ICE) \ | ||
62 | : "memory", "r12"); | ||
63 | #endif | ||
64 | } | ||
65 | } | ||
66 | |||
67 | void _invalidate_icache(unsigned int addr) | ||
68 | { | ||
69 | if (cpuinfo.use_icache) { | ||
70 | __asm__ __volatile__ (" \ | ||
71 | wic %0, r0" \ | ||
72 | : \ | ||
73 | : "r" (addr)); | ||
74 | } | ||
75 | } | ||
76 | |||
77 | void _enable_dcache(void) | ||
78 | { | ||
79 | if (cpuinfo.use_dcache) { | ||
80 | #if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR | ||
81 | __asm__ __volatile__ (" \ | ||
82 | msrset r0, %0; \ | ||
83 | nop; " \ | ||
84 | : \ | ||
85 | : "i" (MSR_DCE) \ | ||
86 | : "memory"); | ||
87 | #else | ||
88 | __asm__ __volatile__ (" \ | ||
89 | mfs r12, rmsr; \ | ||
90 | nop; \ | ||
91 | ori r12, r12, %0; \ | ||
92 | mts rmsr, r12; \ | ||
93 | nop; " \ | ||
94 | : \ | ||
95 | : "i" (MSR_DCE) \ | ||
96 | : "memory", "r12"); | ||
97 | #endif | ||
98 | } | ||
99 | } | ||
100 | |||
101 | void _disable_dcache(void) | ||
102 | { | ||
103 | if (cpuinfo.use_dcache) { | ||
104 | #if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR | ||
105 | __asm__ __volatile__ (" \ | ||
106 | msrclr r0, %0; \ | ||
107 | nop; " \ | ||
108 | : \ | ||
109 | : "i" (MSR_DCE) \ | ||
110 | : "memory"); | ||
111 | #else | ||
112 | __asm__ __volatile__ (" \ | ||
113 | mfs r12, rmsr; \ | ||
114 | nop; \ | ||
115 | andi r12, r12, ~%0; \ | ||
116 | mts rmsr, r12; \ | ||
117 | nop; " \ | ||
118 | : \ | ||
119 | : "i" (MSR_DCE) \ | ||
120 | : "memory", "r12"); | ||
121 | #endif | ||
122 | } | ||
123 | } | ||
124 | |||
125 | void _invalidate_dcache(unsigned int addr) | ||
126 | { | ||
127 | if (cpuinfo.use_dcache) | ||
128 | __asm__ __volatile__ (" \ | ||
129 | wdc %0, r0" \ | ||
130 | : \ | ||
131 | : "r" (addr)); | ||
132 | } | ||
133 | |||
134 | void __invalidate_icache_all(void) | ||
135 | { | ||
136 | unsigned int i; | ||
137 | unsigned flags; | ||
138 | |||
139 | if (cpuinfo.use_icache) { | ||
140 | local_irq_save(flags); | ||
141 | __disable_icache(); | ||
142 | |||
143 | /* Just loop through cache size and invalidate, no need to add | ||
144 | CACHE_BASE address */ | ||
145 | for (i = 0; i < cpuinfo.icache_size; | ||
146 | i += cpuinfo.icache_line) | ||
147 | __invalidate_icache(i); | ||
148 | |||
149 | __enable_icache(); | ||
150 | local_irq_restore(flags); | ||
151 | } | ||
152 | } | ||
153 | |||
154 | void __invalidate_icache_range(unsigned long start, unsigned long end) | ||
155 | { | ||
156 | unsigned int i; | ||
157 | unsigned flags; | ||
158 | unsigned int align; | ||
159 | |||
160 | if (cpuinfo.use_icache) { | ||
161 | /* | ||
162 | * No need to cover entire cache range, | ||
163 | * just cover cache footprint | ||
164 | */ | ||
165 | end = min(start + cpuinfo.icache_size, end); | ||
166 | align = ~(cpuinfo.icache_line - 1); | ||
167 | start &= align; /* Make sure we are aligned */ | ||
168 | /* Push end up to the next cache line */ | ||
169 | end = ((end & align) + cpuinfo.icache_line); | ||
170 | |||
171 | local_irq_save(flags); | ||
172 | __disable_icache(); | ||
173 | |||
174 | for (i = start; i < end; i += cpuinfo.icache_line) | ||
175 | __invalidate_icache(i); | ||
176 | |||
177 | __enable_icache(); | ||
178 | local_irq_restore(flags); | ||
179 | } | ||
180 | } | ||
181 | |||
182 | void __invalidate_icache_page(struct vm_area_struct *vma, struct page *page) | ||
183 | { | ||
184 | __invalidate_icache_all(); | ||
185 | } | ||
186 | |||
187 | void __invalidate_icache_user_range(struct vm_area_struct *vma, | ||
188 | struct page *page, unsigned long adr, | ||
189 | int len) | ||
190 | { | ||
191 | __invalidate_icache_all(); | ||
192 | } | ||
193 | |||
194 | void __invalidate_cache_sigtramp(unsigned long addr) | ||
195 | { | ||
196 | __invalidate_icache_range(addr, addr + 8); | ||
197 | } | ||
198 | |||
199 | void __invalidate_dcache_all(void) | ||
200 | { | ||
201 | unsigned int i; | ||
202 | unsigned flags; | ||
203 | |||
204 | if (cpuinfo.use_dcache) { | ||
205 | local_irq_save(flags); | ||
206 | __disable_dcache(); | ||
207 | |||
208 | /* | ||
209 | * Just loop through cache size and invalidate, | ||
210 | * no need to add CACHE_BASE address | ||
211 | */ | ||
212 | for (i = 0; i < cpuinfo.dcache_size; | ||
213 | i += cpuinfo.dcache_line) | ||
214 | __invalidate_dcache(i); | ||
215 | |||
216 | __enable_dcache(); | ||
217 | local_irq_restore(flags); | ||
218 | } | ||
219 | } | ||
220 | |||
221 | void __invalidate_dcache_range(unsigned long start, unsigned long end) | ||
222 | { | ||
223 | unsigned int i; | ||
224 | unsigned flags; | ||
225 | unsigned int align; | ||
226 | |||
227 | if (cpuinfo.use_dcache) { | ||
228 | /* | ||
229 | * No need to cover entire cache range, | ||
230 | * just cover cache footprint | ||
231 | */ | ||
232 | end = min(start + cpuinfo.dcache_size, end); | ||
233 | align = ~(cpuinfo.dcache_line - 1); | ||
234 | start &= align; /* Make sure we are aligned */ | ||
235 | /* Push end up to the next cache line */ | ||
236 | end = ((end & align) + cpuinfo.dcache_line); | ||
237 | local_irq_save(flags); | ||
238 | __disable_dcache(); | ||
239 | |||
240 | for (i = start; i < end; i += cpuinfo.dcache_line) | ||
241 | __invalidate_dcache(i); | ||
242 | |||
243 | __enable_dcache(); | ||
244 | local_irq_restore(flags); | ||
245 | } | ||
246 | } | ||
247 | |||
248 | void __invalidate_dcache_page(struct vm_area_struct *vma, struct page *page) | ||
249 | { | ||
250 | __invalidate_dcache_all(); | ||
251 | } | ||
252 | |||
253 | void __invalidate_dcache_user_range(struct vm_area_struct *vma, | ||
254 | struct page *page, unsigned long adr, | ||
255 | int len) | ||
256 | { | ||
257 | __invalidate_dcache_all(); | ||
258 | } | ||
diff --git a/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c b/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c new file mode 100644 index 000000000000..cf7424a6bb87 --- /dev/null +++ b/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c | |||
@@ -0,0 +1,101 @@ | |||
1 | /* | ||
2 | * Support for MicroBlaze PVR (processor version register) | ||
3 | * | ||
4 | * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> | ||
5 | * Copyright (C) 2007-2009 PetaLogix | ||
6 | * Copyright (C) 2007 John Williams <john.williams@petalogix.com> | ||
7 | * | ||
8 | * This file is subject to the terms and conditions of the GNU General Public | ||
9 | * License. See the file "COPYING" in the main directory of this archive | ||
10 | * for more details. | ||
11 | */ | ||
12 | |||
13 | #include <linux/init.h> | ||
14 | #include <linux/string.h> | ||
15 | #include <asm/pvr.h> | ||
16 | #include <asm/cpuinfo.h> | ||
17 | |||
18 | /* | ||
19 | * Helper macro to map between fields in our struct cpuinfo, and | ||
20 | * the PVR macros in pvr.h. | ||
21 | */ | ||
22 | |||
23 | #define CI(c, p) { ci->c = PVR_##p(pvr); } | ||
24 | #define err_printk(x) \ | ||
25 | early_printk("ERROR: Microblaze " x " - different for PVR and DTS\n"); | ||
26 | |||
27 | void set_cpuinfo_pvr_full(struct cpuinfo *ci, struct device_node *cpu) | ||
28 | { | ||
29 | struct pvr_s pvr; | ||
30 | int temp; /* for saving temp value */ | ||
31 | get_pvr(&pvr); | ||
32 | |||
33 | temp = PVR_USE_BARREL(pvr) | PVR_USE_MSR_INSTR(pvr) |\ | ||
34 | PVR_USE_PCMP_INSTR(pvr) | PVR_USE_DIV(pvr); | ||
35 | if (ci->use_instr != temp) | ||
36 | err_printk("BARREL, MSR, PCMP or DIV"); | ||
37 | ci->use_instr = temp; | ||
38 | |||
39 | temp = PVR_USE_HW_MUL(pvr) | PVR_USE_MUL64(pvr); | ||
40 | if (ci->use_mult != temp) | ||
41 | err_printk("HW_MUL"); | ||
42 | ci->use_mult = temp; | ||
43 | |||
44 | temp = PVR_USE_FPU(pvr) | PVR_USE_FPU2(pvr); | ||
45 | if (ci->use_fpu != temp) | ||
46 | err_printk("HW_FPU"); | ||
47 | ci->use_fpu = temp; | ||
48 | |||
49 | ci->use_exc = PVR_OPCODE_0x0_ILLEGAL(pvr) |\ | ||
50 | PVR_UNALIGNED_EXCEPTION(pvr) |\ | ||
51 | PVR_ILL_OPCODE_EXCEPTION(pvr) |\ | ||
52 | PVR_IOPB_BUS_EXCEPTION(pvr) |\ | ||
53 | PVR_DOPB_BUS_EXCEPTION(pvr) |\ | ||
54 | PVR_DIV_ZERO_EXCEPTION(pvr) |\ | ||
55 | PVR_FPU_EXCEPTION(pvr) |\ | ||
56 | PVR_FSL_EXCEPTION(pvr); | ||
57 | |||
58 | CI(pvr_user1, USER1); | ||
59 | CI(pvr_user2, USER2); | ||
60 | |||
61 | CI(mmu, USE_MMU); | ||
62 | |||
63 | CI(ver_code, VERSION); | ||
64 | |||
65 | CI(use_icache, USE_ICACHE); | ||
66 | CI(icache_tagbits, ICACHE_ADDR_TAG_BITS); | ||
67 | CI(icache_write, ICACHE_ALLOW_WR); | ||
68 | CI(icache_line, ICACHE_LINE_LEN); | ||
69 | CI(icache_size, ICACHE_BYTE_SIZE); | ||
70 | CI(icache_base, ICACHE_BASEADDR); | ||
71 | CI(icache_high, ICACHE_HIGHADDR); | ||
72 | |||
73 | CI(use_dcache, USE_DCACHE); | ||
74 | CI(dcache_tagbits, DCACHE_ADDR_TAG_BITS); | ||
75 | CI(dcache_write, DCACHE_ALLOW_WR); | ||
76 | CI(dcache_line, DCACHE_LINE_LEN); | ||
77 | CI(dcache_size, DCACHE_BYTE_SIZE); | ||
78 | CI(dcache_base, DCACHE_BASEADDR); | ||
79 | CI(dcache_high, DCACHE_HIGHADDR); | ||
80 | |||
81 | CI(use_dopb, D_OPB); | ||
82 | CI(use_iopb, I_OPB); | ||
83 | CI(use_dlmb, D_LMB); | ||
84 | CI(use_ilmb, I_LMB); | ||
85 | CI(num_fsl, FSL_LINKS); | ||
86 | |||
87 | CI(irq_edge, INTERRUPT_IS_EDGE); | ||
88 | CI(irq_positive, EDGE_IS_POSITIVE); | ||
89 | |||
90 | CI(area_optimised, AREA_OPTIMISED); | ||
91 | |||
92 | CI(hw_debug, DEBUG_ENABLED); | ||
93 | CI(num_pc_brk, NUMBER_OF_PC_BRK); | ||
94 | CI(num_rd_brk, NUMBER_OF_RD_ADDR_BRK); | ||
95 | CI(num_wr_brk, NUMBER_OF_WR_ADDR_BRK); | ||
96 | |||
97 | CI(fpga_family_code, TARGET_FAMILY); | ||
98 | |||
99 | /* take timebase-frequency from DTS */ | ||
100 | ci->cpu_clock_freq = fcpu(cpu, "timebase-frequency"); | ||
101 | } | ||
diff --git a/arch/microblaze/kernel/cpu/cpuinfo-static.c b/arch/microblaze/kernel/cpu/cpuinfo-static.c new file mode 100644 index 000000000000..cfe44effdb77 --- /dev/null +++ b/arch/microblaze/kernel/cpu/cpuinfo-static.c | |||
@@ -0,0 +1,144 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> | ||
3 | * Copyright (C) 2007-2009 PetaLogix | ||
4 | * Copyright (C) 2007 John Williams <john.williams@petalogix.com> | ||
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 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/string.h> | ||
14 | #include <asm/cpuinfo.h> | ||
15 | #include <asm/pvr.h> | ||
16 | |||
17 | const static char family_string[] = CONFIG_XILINX_MICROBLAZE0_FAMILY; | ||
18 | const static char cpu_ver_string[] = CONFIG_XILINX_MICROBLAZE0_HW_VER; | ||
19 | |||
20 | #define err_printk(x) \ | ||
21 | early_printk("ERROR: Microblaze " x "- different for kernel and DTS\n"); | ||
22 | |||
23 | void __init set_cpuinfo_static(struct cpuinfo *ci, struct device_node *cpu) | ||
24 | { | ||
25 | int i = 0; | ||
26 | |||
27 | ci->use_instr = | ||
28 | (fcpu(cpu, "xlnx,use-barrel") ? PVR0_USE_BARREL_MASK : 0) | | ||
29 | (fcpu(cpu, "xlnx,use-msr-instr") ? PVR2_USE_MSR_INSTR : 0) | | ||
30 | (fcpu(cpu, "xlnx,use-pcmp-instr") ? PVR2_USE_PCMP_INSTR : 0) | | ||
31 | (fcpu(cpu, "xlnx,use-div") ? PVR0_USE_DIV_MASK : 0); | ||
32 | if (CONFIG_XILINX_MICROBLAZE0_USE_BARREL) | ||
33 | i |= PVR0_USE_BARREL_MASK; | ||
34 | if (CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR) | ||
35 | i |= PVR2_USE_MSR_INSTR; | ||
36 | if (CONFIG_XILINX_MICROBLAZE0_USE_PCMP_INSTR) | ||
37 | i |= PVR2_USE_PCMP_INSTR; | ||
38 | if (CONFIG_XILINX_MICROBLAZE0_USE_DIV) | ||
39 | i |= PVR0_USE_DIV_MASK; | ||
40 | if (ci->use_instr != i) | ||
41 | err_printk("BARREL, MSR, PCMP or DIV"); | ||
42 | |||
43 | ci->use_mult = fcpu(cpu, "xlnx,use-hw-mul"); | ||
44 | if (ci->use_mult != CONFIG_XILINX_MICROBLAZE0_USE_HW_MUL) | ||
45 | err_printk("HW_MUL"); | ||
46 | ci->use_mult = | ||
47 | (ci->use_mult > 1 ? | ||
48 | (PVR2_USE_MUL64_MASK | PVR0_USE_HW_MUL_MASK) : | ||
49 | (ci->use_mult == 1 ? PVR0_USE_HW_MUL_MASK : 0)); | ||
50 | |||
51 | ci->use_fpu = fcpu(cpu, "xlnx,use-fpu"); | ||
52 | if (ci->use_fpu != CONFIG_XILINX_MICROBLAZE0_USE_FPU) | ||
53 | err_printk("HW_FPU"); | ||
54 | ci->use_fpu = (ci->use_fpu > 1 ? | ||
55 | (PVR2_USE_FPU2_MASK | PVR0_USE_FPU_MASK) : | ||
56 | (ci->use_fpu == 1 ? PVR0_USE_FPU_MASK : 0)); | ||
57 | |||
58 | ci->use_exc = | ||
59 | (fcpu(cpu, "xlnx,unaligned-exceptions") ? | ||
60 | PVR2_UNALIGNED_EXC_MASK : 0) | | ||
61 | (fcpu(cpu, "xlnx,ill-opcode-exception") ? | ||
62 | PVR2_ILL_OPCODE_EXC_MASK : 0) | | ||
63 | (fcpu(cpu, "xlnx,iopb-bus-exception") ? | ||
64 | PVR2_IOPB_BUS_EXC_MASK : 0) | | ||
65 | (fcpu(cpu, "xlnx,dopb-bus-exception") ? | ||
66 | PVR2_DOPB_BUS_EXC_MASK : 0) | | ||
67 | (fcpu(cpu, "xlnx,div-zero-exception") ? | ||
68 | PVR2_DIV_ZERO_EXC_MASK : 0) | | ||
69 | (fcpu(cpu, "xlnx,fpu-exception") ? PVR2_FPU_EXC_MASK : 0) | | ||
70 | (fcpu(cpu, "xlnx,fsl-exception") ? PVR2_USE_EXTEND_FSL : 0); | ||
71 | |||
72 | ci->use_icache = fcpu(cpu, "xlnx,use-icache"); | ||
73 | ci->icache_tagbits = fcpu(cpu, "xlnx,addr-tag-bits"); | ||
74 | ci->icache_write = fcpu(cpu, "xlnx,allow-icache-wr"); | ||
75 | ci->icache_line = fcpu(cpu, "xlnx,icache-line-len") << 2; | ||
76 | if (!ci->icache_line) { | ||
77 | if (fcpu(cpu, "xlnx,icache-use-fsl")) | ||
78 | ci->icache_line = 4 << 2; | ||
79 | else | ||
80 | ci->icache_line = 1 << 2; | ||
81 | } | ||
82 | ci->icache_size = fcpu(cpu, "i-cache-size"); | ||
83 | ci->icache_base = fcpu(cpu, "i-cache-baseaddr"); | ||
84 | ci->icache_high = fcpu(cpu, "i-cache-highaddr"); | ||
85 | |||
86 | ci->use_dcache = fcpu(cpu, "xlnx,use-dcache"); | ||
87 | ci->dcache_tagbits = fcpu(cpu, "xlnx,dcache-addr-tag"); | ||
88 | ci->dcache_write = fcpu(cpu, "xlnx,allow-dcache-wr"); | ||
89 | ci->dcache_line = fcpu(cpu, "xlnx,dcache-line-len") << 2; | ||
90 | if (!ci->dcache_line) { | ||
91 | if (fcpu(cpu, "xlnx,dcache-use-fsl")) | ||
92 | ci->dcache_line = 4 << 2; | ||
93 | else | ||
94 | ci->dcache_line = 1 << 2; | ||
95 | } | ||
96 | ci->dcache_size = fcpu(cpu, "d-cache-size"); | ||
97 | ci->dcache_base = fcpu(cpu, "d-cache-baseaddr"); | ||
98 | ci->dcache_high = fcpu(cpu, "d-cache-highaddr"); | ||
99 | |||
100 | ci->use_dopb = fcpu(cpu, "xlnx,d-opb"); | ||
101 | ci->use_iopb = fcpu(cpu, "xlnx,i-opb"); | ||
102 | ci->use_dlmb = fcpu(cpu, "xlnx,d-lmb"); | ||
103 | ci->use_ilmb = fcpu(cpu, "xlnx,i-lmb"); | ||
104 | |||
105 | ci->num_fsl = fcpu(cpu, "xlnx,fsl-links"); | ||
106 | ci->irq_edge = fcpu(cpu, "xlnx,interrupt-is-edge"); | ||
107 | ci->irq_positive = fcpu(cpu, "xlnx,edge-is-positive"); | ||
108 | ci->area_optimised = 0; | ||
109 | |||
110 | ci->hw_debug = fcpu(cpu, "xlnx,debug-enabled"); | ||
111 | ci->num_pc_brk = fcpu(cpu, "xlnx,number-of-pc-brk"); | ||
112 | ci->num_rd_brk = fcpu(cpu, "xlnx,number-of-rd-addr-brk"); | ||
113 | ci->num_wr_brk = fcpu(cpu, "xlnx,number-of-wr-addr-brk"); | ||
114 | |||
115 | ci->cpu_clock_freq = fcpu(cpu, "timebase-frequency"); | ||
116 | |||
117 | ci->pvr_user1 = fcpu(cpu, "xlnx,pvr-user1"); | ||
118 | ci->pvr_user2 = fcpu(cpu, "xlnx,pvr-user2"); | ||
119 | |||
120 | ci->mmu = fcpu(cpu, "xlnx,use-mmu"); | ||
121 | |||
122 | ci->ver_code = 0; | ||
123 | ci->fpga_family_code = 0; | ||
124 | |||
125 | /* Do various fixups based on CPU version and FPGA family strings */ | ||
126 | |||
127 | /* Resolved the CPU version code */ | ||
128 | for (i = 0; cpu_ver_lookup[i].s != NULL; i++) { | ||
129 | if (strcmp(cpu_ver_lookup[i].s, cpu_ver_string) == 0) | ||
130 | ci->ver_code = cpu_ver_lookup[i].k; | ||
131 | } | ||
132 | |||
133 | /* Resolved the fpga family code */ | ||
134 | for (i = 0; family_string_lookup[i].s != NULL; i++) { | ||
135 | if (strcmp(family_string_lookup[i].s, family_string) == 0) | ||
136 | ci->fpga_family_code = family_string_lookup[i].k; | ||
137 | } | ||
138 | |||
139 | /* FIXME - mb3 and spartan2 do not exist in PVR */ | ||
140 | /* This is mb3 and on a non Spartan2 */ | ||
141 | if (ci->ver_code == 0x20 && ci->fpga_family_code != 0xf0) | ||
142 | /* Hardware Multiplier in use */ | ||
143 | ci->use_mult = 1; | ||
144 | } | ||
diff --git a/arch/microblaze/kernel/cpu/cpuinfo.c b/arch/microblaze/kernel/cpu/cpuinfo.c new file mode 100644 index 000000000000..4a740dfcf6da --- /dev/null +++ b/arch/microblaze/kernel/cpu/cpuinfo.c | |||
@@ -0,0 +1,86 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> | ||
3 | * Copyright (C) 2007-2009 PetaLogix | ||
4 | * Copyright (C) 2007 John Williams <john.williams@petalogix.com> | ||
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 | */ | ||
10 | |||
11 | #include <linux/init.h> | ||
12 | #include <linux/slab.h> | ||
13 | #include <asm/cpuinfo.h> | ||
14 | #include <asm/pvr.h> | ||
15 | |||
16 | const struct cpu_ver_key cpu_ver_lookup[] = { | ||
17 | /* These key value are as per MBV field in PVR0 */ | ||
18 | {"5.00.a", 0x01}, | ||
19 | {"5.00.b", 0x02}, | ||
20 | {"5.00.c", 0x03}, | ||
21 | {"6.00.a", 0x04}, | ||
22 | {"6.00.b", 0x06}, | ||
23 | {"7.00.a", 0x05}, | ||
24 | {"7.00.b", 0x07}, | ||
25 | {"7.10.a", 0x08}, | ||
26 | {"7.10.b", 0x09}, | ||
27 | {"7.10.c", 0x0a}, | ||
28 | {"7.10.d", 0x0b}, | ||
29 | /* FIXME There is no keycode defined in MBV for these versions */ | ||
30 | {"2.10.a", 0x10}, | ||
31 | {"3.00.a", 0x20}, | ||
32 | {"4.00.a", 0x30}, | ||
33 | {"4.00.b", 0x40}, | ||
34 | {NULL, 0}, | ||
35 | }; | ||
36 | |||
37 | /* | ||
38 | * FIXME Not sure if the actual key is defined by Xilinx in the PVR | ||
39 | */ | ||
40 | const struct family_string_key family_string_lookup[] = { | ||
41 | {"virtex2", 0x4}, | ||
42 | {"virtex2pro", 0x5}, | ||
43 | {"spartan3", 0x6}, | ||
44 | {"virtex4", 0x7}, | ||
45 | {"virtex5", 0x8}, | ||
46 | {"spartan3e", 0x9}, | ||
47 | {"spartan3a", 0xa}, | ||
48 | {"spartan3an", 0xb}, | ||
49 | {"spartan3adsp", 0xc}, | ||
50 | /* FIXME There is no key code defined for spartan2 */ | ||
51 | {"spartan2", 0xf0}, | ||
52 | {NULL, 0}, | ||
53 | }; | ||
54 | |||
55 | struct cpuinfo cpuinfo; | ||
56 | |||
57 | void __init setup_cpuinfo(void) | ||
58 | { | ||
59 | struct device_node *cpu = NULL; | ||
60 | |||
61 | cpu = (struct device_node *) of_find_node_by_type(NULL, "cpu"); | ||
62 | if (!cpu) | ||
63 | printk(KERN_ERR "You don't have cpu!!!\n"); | ||
64 | |||
65 | printk(KERN_INFO "%s: initialising\n", __func__); | ||
66 | |||
67 | switch (cpu_has_pvr()) { | ||
68 | case 0: | ||
69 | printk(KERN_WARNING | ||
70 | "%s: No PVR support. Using static CPU info from FDT\n", | ||
71 | __func__); | ||
72 | set_cpuinfo_static(&cpuinfo, cpu); | ||
73 | break; | ||
74 | /* FIXME I found weird behavior with MB 7.00.a/b | ||
75 | * please do not use FULL PVR with MMU */ | ||
76 | case 1: | ||
77 | printk(KERN_INFO "%s: Using full CPU PVR support\n", | ||
78 | __func__); | ||
79 | set_cpuinfo_static(&cpuinfo, cpu); | ||
80 | set_cpuinfo_pvr_full(&cpuinfo, cpu); | ||
81 | break; | ||
82 | default: | ||
83 | printk(KERN_WARNING "%s: Unsupported PVR setting\n", __func__); | ||
84 | set_cpuinfo_static(&cpuinfo, cpu); | ||
85 | } | ||
86 | } | ||
diff --git a/arch/microblaze/kernel/cpu/mb.c b/arch/microblaze/kernel/cpu/mb.c new file mode 100644 index 000000000000..3b6212bdc8dc --- /dev/null +++ b/arch/microblaze/kernel/cpu/mb.c | |||
@@ -0,0 +1,148 @@ | |||
1 | /* | ||
2 | * CPU-version specific code | ||
3 | * | ||
4 | * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> | ||
5 | * Copyright (C) 2006-2009 PetaLogix | ||
6 | * | ||
7 | * This file is subject to the terms and conditions of the GNU General Public | ||
8 | * License. See the file "COPYING" in the main directory of this archive | ||
9 | * for more details. | ||
10 | */ | ||
11 | |||
12 | #include <linux/init.h> | ||
13 | #include <linux/string.h> | ||
14 | #include <linux/seq_file.h> | ||
15 | #include <linux/cpu.h> | ||
16 | #include <linux/initrd.h> | ||
17 | |||
18 | #include <linux/bug.h> | ||
19 | #include <asm/cpuinfo.h> | ||
20 | #include <linux/delay.h> | ||
21 | #include <linux/io.h> | ||
22 | #include <asm/page.h> | ||
23 | #include <linux/param.h> | ||
24 | #include <asm/pvr.h> | ||
25 | #include <asm/sections.h> | ||
26 | #include <asm/setup.h> | ||
27 | |||
28 | static int show_cpuinfo(struct seq_file *m, void *v) | ||
29 | { | ||
30 | int count = 0; | ||
31 | char *fpga_family = "Unknown"; | ||
32 | char *cpu_ver = "Unknown"; | ||
33 | int i; | ||
34 | |||
35 | /* Denormalised to get the fpga family string */ | ||
36 | for (i = 0; family_string_lookup[i].s != NULL; i++) { | ||
37 | if (cpuinfo.fpga_family_code == family_string_lookup[i].k) { | ||
38 | fpga_family = (char *)family_string_lookup[i].s; | ||
39 | break; | ||
40 | } | ||
41 | } | ||
42 | |||
43 | /* Denormalised to get the hw version string */ | ||
44 | for (i = 0; cpu_ver_lookup[i].s != NULL; i++) { | ||
45 | if (cpuinfo.ver_code == cpu_ver_lookup[i].k) { | ||
46 | cpu_ver = (char *)cpu_ver_lookup[i].s; | ||
47 | break; | ||
48 | } | ||
49 | } | ||
50 | |||
51 | count = seq_printf(m, | ||
52 | "CPU-Family: MicroBlaze\n" | ||
53 | "FPGA-Arch: %s\n" | ||
54 | "CPU-Ver: %s\n" | ||
55 | "CPU-MHz: %d.%02d\n" | ||
56 | "BogoMips: %lu.%02lu\n", | ||
57 | fpga_family, | ||
58 | cpu_ver, | ||
59 | cpuinfo.cpu_clock_freq / | ||
60 | 1000000, | ||
61 | cpuinfo.cpu_clock_freq % | ||
62 | 1000000, | ||
63 | loops_per_jiffy / (500000 / HZ), | ||
64 | (loops_per_jiffy / (5000 / HZ)) % 100); | ||
65 | |||
66 | count += seq_printf(m, | ||
67 | "HW:\n Shift:\t\t%s\n" | ||
68 | " MSR:\t\t%s\n" | ||
69 | " PCMP:\t\t%s\n" | ||
70 | " DIV:\t\t%s\n", | ||
71 | (cpuinfo.use_instr & PVR0_USE_BARREL_MASK) ? "yes" : "no", | ||
72 | (cpuinfo.use_instr & PVR2_USE_MSR_INSTR) ? "yes" : "no", | ||
73 | (cpuinfo.use_instr & PVR2_USE_PCMP_INSTR) ? "yes" : "no", | ||
74 | (cpuinfo.use_instr & PVR0_USE_DIV_MASK) ? "yes" : "no"); | ||
75 | |||
76 | count += seq_printf(m, | ||
77 | " MMU:\t\t%x\n", | ||
78 | cpuinfo.mmu); | ||
79 | |||
80 | count += seq_printf(m, | ||
81 | " MUL:\t\t%s\n" | ||
82 | " FPU:\t\t%s\n", | ||
83 | (cpuinfo.use_mult & PVR2_USE_MUL64_MASK) ? "v2" : | ||
84 | (cpuinfo.use_mult & PVR0_USE_HW_MUL_MASK) ? "v1" : "no", | ||
85 | (cpuinfo.use_fpu & PVR2_USE_FPU2_MASK) ? "v2" : | ||
86 | (cpuinfo.use_fpu & PVR0_USE_FPU_MASK) ? "v1" : "no"); | ||
87 | |||
88 | count += seq_printf(m, | ||
89 | " Exc:\t\t%s%s%s%s%s%s%s%s\n", | ||
90 | (cpuinfo.use_exc & PVR2_OPCODE_0x0_ILL_MASK) ? "op0x0 " : "", | ||
91 | (cpuinfo.use_exc & PVR2_UNALIGNED_EXC_MASK) ? "unal " : "", | ||
92 | (cpuinfo.use_exc & PVR2_ILL_OPCODE_EXC_MASK) ? "ill " : "", | ||
93 | (cpuinfo.use_exc & PVR2_IOPB_BUS_EXC_MASK) ? "iopb " : "", | ||
94 | (cpuinfo.use_exc & PVR2_DOPB_BUS_EXC_MASK) ? "dopb " : "", | ||
95 | (cpuinfo.use_exc & PVR2_DIV_ZERO_EXC_MASK) ? "zero " : "", | ||
96 | (cpuinfo.use_exc & PVR2_FPU_EXC_MASK) ? "fpu " : "", | ||
97 | (cpuinfo.use_exc & PVR2_USE_FSL_EXC) ? "fsl " : ""); | ||
98 | |||
99 | if (cpuinfo.use_icache) | ||
100 | count += seq_printf(m, | ||
101 | "Icache:\t\t%ukB\n", | ||
102 | cpuinfo.icache_size >> 10); | ||
103 | else | ||
104 | count += seq_printf(m, "Icache:\t\tno\n"); | ||
105 | |||
106 | if (cpuinfo.use_dcache) | ||
107 | count += seq_printf(m, | ||
108 | "Dcache:\t\t%ukB\n", | ||
109 | cpuinfo.dcache_size >> 10); | ||
110 | else | ||
111 | count += seq_printf(m, "Dcache:\t\tno\n"); | ||
112 | |||
113 | count += seq_printf(m, | ||
114 | "HW-Debug:\t%s\n", | ||
115 | cpuinfo.hw_debug ? "yes" : "no"); | ||
116 | |||
117 | count += seq_printf(m, | ||
118 | "PVR-USR1:\t%x\n" | ||
119 | "PVR-USR2:\t%x\n", | ||
120 | cpuinfo.pvr_user1, | ||
121 | cpuinfo.pvr_user2); | ||
122 | |||
123 | return 0; | ||
124 | } | ||
125 | |||
126 | static void *c_start(struct seq_file *m, loff_t *pos) | ||
127 | { | ||
128 | int i = *pos; | ||
129 | |||
130 | return i < NR_CPUS ? (void *) (i + 1) : NULL; | ||
131 | } | ||
132 | |||
133 | static void *c_next(struct seq_file *m, void *v, loff_t *pos) | ||
134 | { | ||
135 | ++*pos; | ||
136 | return c_start(m, pos); | ||
137 | } | ||
138 | |||
139 | static void c_stop(struct seq_file *m, void *v) | ||
140 | { | ||
141 | } | ||
142 | |||
143 | const struct seq_operations cpuinfo_op = { | ||
144 | .start = c_start, | ||
145 | .next = c_next, | ||
146 | .stop = c_stop, | ||
147 | .show = show_cpuinfo, | ||
148 | }; | ||
diff --git a/arch/microblaze/kernel/cpu/pvr.c b/arch/microblaze/kernel/cpu/pvr.c new file mode 100644 index 000000000000..c9a4340ddd53 --- /dev/null +++ b/arch/microblaze/kernel/cpu/pvr.c | |||
@@ -0,0 +1,81 @@ | |||
1 | /* | ||
2 | * Support for MicroBlaze PVR (processor version register) | ||
3 | * | ||
4 | * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> | ||
5 | * Copyright (C) 2007-2009 PetaLogix | ||
6 | * Copyright (C) 2007 John Williams <john.williams@petalogix.com> | ||
7 | * | ||
8 | * This file is subject to the terms and conditions of the GNU General Public | ||
9 | * License. See the file "COPYING" in the main directory of this archive | ||
10 | * for more details. | ||
11 | */ | ||
12 | |||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/compiler.h> | ||
15 | #include <asm/system.h> | ||
16 | #include <asm/exceptions.h> | ||
17 | #include <asm/pvr.h> | ||
18 | |||
19 | /* | ||
20 | * Until we get an assembler that knows about the pvr registers, | ||
21 | * this horrible cruft will have to do. | ||
22 | * That hardcoded opcode is mfs r3, rpvrNN | ||
23 | */ | ||
24 | |||
25 | #define get_single_pvr(pvrid, val) \ | ||
26 | { \ | ||
27 | register unsigned tmp __asm__("r3"); \ | ||
28 | tmp = 0x0; /* Prevent warning about unused */ \ | ||
29 | __asm__ __volatile__ ( \ | ||
30 | ".byte 0x94,0x60,0xa0, " #pvrid "\n\t" \ | ||
31 | : "=r" (tmp) : : "memory"); \ | ||
32 | val = tmp; \ | ||
33 | } | ||
34 | |||
35 | /* | ||
36 | * Does the CPU support the PVR register? | ||
37 | * return value: | ||
38 | * 0: no PVR | ||
39 | * 1: simple PVR | ||
40 | * 2: full PVR | ||
41 | * | ||
42 | * This must work on all CPU versions, including those before the | ||
43 | * PVR was even an option. | ||
44 | */ | ||
45 | |||
46 | int cpu_has_pvr(void) | ||
47 | { | ||
48 | unsigned flags; | ||
49 | unsigned pvr0; | ||
50 | |||
51 | local_save_flags(flags); | ||
52 | |||
53 | /* PVR bit in MSR tells us if there is any support */ | ||
54 | if (!(flags & PVR_MSR_BIT)) | ||
55 | return 0; | ||
56 | |||
57 | get_single_pvr(0x00, pvr0); | ||
58 | pr_debug("%s: pvr0 is 0x%08x\n", __func__, pvr0); | ||
59 | |||
60 | if (pvr0 & PVR0_PVR_FULL_MASK) | ||
61 | return 1; | ||
62 | |||
63 | /* for partial PVR use static cpuinfo */ | ||
64 | return 2; | ||
65 | } | ||
66 | |||
67 | void get_pvr(struct pvr_s *p) | ||
68 | { | ||
69 | get_single_pvr(0, p->pvr[0]); | ||
70 | get_single_pvr(1, p->pvr[1]); | ||
71 | get_single_pvr(2, p->pvr[2]); | ||
72 | get_single_pvr(3, p->pvr[3]); | ||
73 | get_single_pvr(4, p->pvr[4]); | ||
74 | get_single_pvr(5, p->pvr[5]); | ||
75 | get_single_pvr(6, p->pvr[6]); | ||
76 | get_single_pvr(7, p->pvr[7]); | ||
77 | get_single_pvr(8, p->pvr[8]); | ||
78 | get_single_pvr(9, p->pvr[9]); | ||
79 | get_single_pvr(10, p->pvr[10]); | ||
80 | get_single_pvr(11, p->pvr[11]); | ||
81 | } | ||
diff --git a/arch/microblaze/kernel/early_printk.c b/arch/microblaze/kernel/early_printk.c new file mode 100644 index 000000000000..62cc78993f44 --- /dev/null +++ b/arch/microblaze/kernel/early_printk.c | |||
@@ -0,0 +1,107 @@ | |||
1 | /* | ||
2 | * Early printk support for Microblaze. | ||
3 | * | ||
4 | * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> | ||
5 | * Copyright (C) 2007-2009 PetaLogix | ||
6 | * Copyright (C) 2003-2006 Yasushi SHOJI <yashi@atmark-techno.com> | ||
7 | * | ||
8 | * This file is subject to the terms and conditions of the GNU General Public | ||
9 | * License. See the file "COPYING" in the main directory of this archive | ||
10 | * for more details. | ||
11 | */ | ||
12 | |||
13 | #include <linux/console.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/string.h> | ||
17 | #include <linux/tty.h> | ||
18 | #include <linux/io.h> | ||
19 | #include <asm/processor.h> | ||
20 | #include <linux/fcntl.h> | ||
21 | #include <asm/setup.h> | ||
22 | #include <asm/prom.h> | ||
23 | |||
24 | static u32 early_console_initialized; | ||
25 | static u32 base_addr; | ||
26 | |||
27 | static void early_printk_putc(char c) | ||
28 | { | ||
29 | /* | ||
30 | * Limit how many times we'll spin waiting for TX FIFO status. | ||
31 | * This will prevent lockups if the base address is incorrectly | ||
32 | * set, or any other issue on the UARTLITE. | ||
33 | * This limit is pretty arbitrary, unless we are at about 10 baud | ||
34 | * we'll never timeout on a working UART. | ||
35 | */ | ||
36 | |||
37 | unsigned retries = 10000; | ||
38 | /* read status bit - 0x8 offset */ | ||
39 | while (retries-- && (in_be32(base_addr + 8) & (1 << 3))) | ||
40 | ; | ||
41 | |||
42 | /* Only attempt the iowrite if we didn't timeout */ | ||
43 | /* write to TX_FIFO - 0x4 offset */ | ||
44 | if (retries) | ||
45 | out_be32(base_addr + 4, c & 0xff); | ||
46 | } | ||
47 | |||
48 | static void early_printk_write(struct console *unused, | ||
49 | const char *s, unsigned n) | ||
50 | { | ||
51 | while (*s && n-- > 0) { | ||
52 | early_printk_putc(*s); | ||
53 | if (*s == '\n') | ||
54 | early_printk_putc('\r'); | ||
55 | s++; | ||
56 | } | ||
57 | } | ||
58 | |||
59 | static struct console early_serial_console = { | ||
60 | .name = "earlyser", | ||
61 | .write = early_printk_write, | ||
62 | .flags = CON_PRINTBUFFER, | ||
63 | .index = -1, | ||
64 | }; | ||
65 | |||
66 | static struct console *early_console = &early_serial_console; | ||
67 | |||
68 | void early_printk(const char *fmt, ...) | ||
69 | { | ||
70 | char buf[512]; | ||
71 | int n; | ||
72 | va_list ap; | ||
73 | |||
74 | if (early_console_initialized) { | ||
75 | va_start(ap, fmt); | ||
76 | n = vscnprintf(buf, 512, fmt, ap); | ||
77 | early_console->write(early_console, buf, n); | ||
78 | va_end(ap); | ||
79 | } | ||
80 | } | ||
81 | |||
82 | int __init setup_early_printk(char *opt) | ||
83 | { | ||
84 | if (early_console_initialized) | ||
85 | return 1; | ||
86 | |||
87 | base_addr = early_uartlite_console(); | ||
88 | if (base_addr) { | ||
89 | early_console_initialized = 1; | ||
90 | early_printk("early_printk_console is enabled at 0x%08x\n", | ||
91 | base_addr); | ||
92 | |||
93 | /* register_console(early_console); */ | ||
94 | |||
95 | return 0; | ||
96 | } else | ||
97 | return 1; | ||
98 | } | ||
99 | |||
100 | void __init disable_early_printk(void) | ||
101 | { | ||
102 | if (!early_console_initialized || !early_console) | ||
103 | return; | ||
104 | printk(KERN_WARNING "disabling early console\n"); | ||
105 | unregister_console(early_console); | ||
106 | early_console_initialized = 0; | ||
107 | } | ||
diff --git a/arch/microblaze/kernel/entry-nommu.S b/arch/microblaze/kernel/entry-nommu.S new file mode 100644 index 000000000000..f24b1268baaf --- /dev/null +++ b/arch/microblaze/kernel/entry-nommu.S | |||
@@ -0,0 +1,596 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> | ||
3 | * Copyright (C) 2007-2009 PetaLogix | ||
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 | */ | ||
10 | |||
11 | #include <linux/linkage.h> | ||
12 | #include <asm/thread_info.h> | ||
13 | #include <asm/errno.h> | ||
14 | #include <asm/entry.h> | ||
15 | #include <asm/asm-offsets.h> | ||
16 | #include <asm/registers.h> | ||
17 | #include <asm/unistd.h> | ||
18 | #include <asm/percpu.h> | ||
19 | #include <asm/signal.h> | ||
20 | |||
21 | #if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR | ||
22 | .macro disable_irq | ||
23 | msrclr r0, MSR_IE | ||
24 | .endm | ||
25 | |||
26 | .macro enable_irq | ||
27 | msrset r0, MSR_IE | ||
28 | .endm | ||
29 | |||
30 | .macro clear_bip | ||
31 | msrclr r0, MSR_BIP | ||
32 | .endm | ||
33 | #else | ||
34 | .macro disable_irq | ||
35 | mfs r11, rmsr | ||
36 | andi r11, r11, ~MSR_IE | ||
37 | mts rmsr, r11 | ||
38 | .endm | ||
39 | |||
40 | .macro enable_irq | ||
41 | mfs r11, rmsr | ||
42 | ori r11, r11, MSR_IE | ||
43 | mts rmsr, r11 | ||
44 | .endm | ||
45 | |||
46 | .macro clear_bip | ||
47 | mfs r11, rmsr | ||
48 | andi r11, r11, ~MSR_BIP | ||
49 | mts rmsr, r11 | ||
50 | .endm | ||
51 | #endif | ||
52 | |||
53 | ENTRY(_interrupt) | ||
54 | swi r1, r0, PER_CPU(ENTRY_SP) /* save the current sp */ | ||
55 | swi r11, r0, PER_CPU(R11_SAVE) /* temporarily save r11 */ | ||
56 | lwi r11, r0, PER_CPU(KM) /* load mode indicator */ | ||
57 | beqid r11, 1f | ||
58 | nop | ||
59 | brid 2f /* jump over */ | ||
60 | addik r1, r1, (-PT_SIZE) /* room for pt_regs (delay slot) */ | ||
61 | 1: /* switch to kernel stack */ | ||
62 | lwi r1, r0, PER_CPU(CURRENT_SAVE) /* get the saved current */ | ||
63 | lwi r1, r1, TS_THREAD_INFO /* get the thread info */ | ||
64 | /* calculate kernel stack pointer */ | ||
65 | addik r1, r1, THREAD_SIZE - PT_SIZE | ||
66 | 2: | ||
67 | swi r11, r1, PT_MODE /* store the mode */ | ||
68 | lwi r11, r0, PER_CPU(R11_SAVE) /* reload r11 */ | ||
69 | swi r2, r1, PT_R2 | ||
70 | swi r3, r1, PT_R3 | ||
71 | swi r4, r1, PT_R4 | ||
72 | swi r5, r1, PT_R5 | ||
73 | swi r6, r1, PT_R6 | ||
74 | swi r7, r1, PT_R7 | ||
75 | swi r8, r1, PT_R8 | ||
76 | swi r9, r1, PT_R9 | ||
77 | swi r10, r1, PT_R10 | ||
78 | swi r11, r1, PT_R11 | ||
79 | swi r12, r1, PT_R12 | ||
80 | swi r13, r1, PT_R13 | ||
81 | swi r14, r1, PT_R14 | ||
82 | swi r14, r1, PT_PC | ||
83 | swi r15, r1, PT_R15 | ||
84 | swi r16, r1, PT_R16 | ||
85 | swi r17, r1, PT_R17 | ||
86 | swi r18, r1, PT_R18 | ||
87 | swi r19, r1, PT_R19 | ||
88 | swi r20, r1, PT_R20 | ||
89 | swi r21, r1, PT_R21 | ||
90 | swi r22, r1, PT_R22 | ||
91 | swi r23, r1, PT_R23 | ||
92 | swi r24, r1, PT_R24 | ||
93 | swi r25, r1, PT_R25 | ||
94 | swi r26, r1, PT_R26 | ||
95 | swi r27, r1, PT_R27 | ||
96 | swi r28, r1, PT_R28 | ||
97 | swi r29, r1, PT_R29 | ||
98 | swi r30, r1, PT_R30 | ||
99 | swi r31, r1, PT_R31 | ||
100 | /* special purpose registers */ | ||
101 | mfs r11, rmsr | ||
102 | swi r11, r1, PT_MSR | ||
103 | mfs r11, rear | ||
104 | swi r11, r1, PT_EAR | ||
105 | mfs r11, resr | ||
106 | swi r11, r1, PT_ESR | ||
107 | mfs r11, rfsr | ||
108 | swi r11, r1, PT_FSR | ||
109 | /* reload original stack pointer and save it */ | ||
110 | lwi r11, r0, PER_CPU(ENTRY_SP) | ||
111 | swi r11, r1, PT_R1 | ||
112 | /* update mode indicator we are in kernel mode */ | ||
113 | addik r11, r0, 1 | ||
114 | swi r11, r0, PER_CPU(KM) | ||
115 | /* restore r31 */ | ||
116 | lwi r31, r0, PER_CPU(CURRENT_SAVE) | ||
117 | /* prepare the link register, the argument and jump */ | ||
118 | la r15, r0, ret_from_intr - 8 | ||
119 | addk r6, r0, r15 | ||
120 | braid do_IRQ | ||
121 | add r5, r0, r1 | ||
122 | |||
123 | ret_from_intr: | ||
124 | lwi r11, r1, PT_MODE | ||
125 | bneid r11, 3f | ||
126 | |||
127 | lwi r6, r31, TS_THREAD_INFO /* get thread info */ | ||
128 | lwi r19, r6, TI_FLAGS /* get flags in thread info */ | ||
129 | /* do an extra work if any bits are set */ | ||
130 | |||
131 | andi r11, r19, _TIF_NEED_RESCHED | ||
132 | beqi r11, 1f | ||
133 | bralid r15, schedule | ||
134 | nop | ||
135 | 1: andi r11, r19, _TIF_SIGPENDING | ||
136 | beqid r11, no_intr_reshed | ||
137 | addk r5, r1, r0 | ||
138 | addk r7, r0, r0 | ||
139 | bralid r15, do_signal | ||
140 | addk r6, r0, r0 | ||
141 | |||
142 | no_intr_reshed: | ||
143 | /* save mode indicator */ | ||
144 | lwi r11, r1, PT_MODE | ||
145 | 3: | ||
146 | swi r11, r0, PER_CPU(KM) | ||
147 | |||
148 | /* save r31 */ | ||
149 | swi r31, r0, PER_CPU(CURRENT_SAVE) | ||
150 | restore_context: | ||
151 | /* special purpose registers */ | ||
152 | lwi r11, r1, PT_FSR | ||
153 | mts rfsr, r11 | ||
154 | lwi r11, r1, PT_ESR | ||
155 | mts resr, r11 | ||
156 | lwi r11, r1, PT_EAR | ||
157 | mts rear, r11 | ||
158 | lwi r11, r1, PT_MSR | ||
159 | mts rmsr, r11 | ||
160 | |||
161 | lwi r31, r1, PT_R31 | ||
162 | lwi r30, r1, PT_R30 | ||
163 | lwi r29, r1, PT_R29 | ||
164 | lwi r28, r1, PT_R28 | ||
165 | lwi r27, r1, PT_R27 | ||
166 | lwi r26, r1, PT_R26 | ||
167 | lwi r25, r1, PT_R25 | ||
168 | lwi r24, r1, PT_R24 | ||
169 | lwi r23, r1, PT_R23 | ||
170 | lwi r22, r1, PT_R22 | ||
171 | lwi r21, r1, PT_R21 | ||
172 | lwi r20, r1, PT_R20 | ||
173 | lwi r19, r1, PT_R19 | ||
174 | lwi r18, r1, PT_R18 | ||
175 | lwi r17, r1, PT_R17 | ||
176 | lwi r16, r1, PT_R16 | ||
177 | lwi r15, r1, PT_R15 | ||
178 | lwi r14, r1, PT_PC | ||
179 | lwi r13, r1, PT_R13 | ||
180 | lwi r12, r1, PT_R12 | ||
181 | lwi r11, r1, PT_R11 | ||
182 | lwi r10, r1, PT_R10 | ||
183 | lwi r9, r1, PT_R9 | ||
184 | lwi r8, r1, PT_R8 | ||
185 | lwi r7, r1, PT_R7 | ||
186 | lwi r6, r1, PT_R6 | ||
187 | lwi r5, r1, PT_R5 | ||
188 | lwi r4, r1, PT_R4 | ||
189 | lwi r3, r1, PT_R3 | ||
190 | lwi r2, r1, PT_R2 | ||
191 | lwi r1, r1, PT_R1 | ||
192 | rtid r14, 0 | ||
193 | nop | ||
194 | |||
195 | ENTRY(_reset) | ||
196 | brai 0; | ||
197 | |||
198 | ENTRY(_user_exception) | ||
199 | swi r1, r0, PER_CPU(ENTRY_SP) /* save the current sp */ | ||
200 | swi r11, r0, PER_CPU(R11_SAVE) /* temporarily save r11 */ | ||
201 | lwi r11, r0, PER_CPU(KM) /* load mode indicator */ | ||
202 | beqid r11, 1f /* Already in kernel mode? */ | ||
203 | nop | ||
204 | brid 2f /* jump over */ | ||
205 | addik r1, r1, (-PT_SIZE) /* Room for pt_regs (delay slot) */ | ||
206 | 1: /* Switch to kernel stack */ | ||
207 | lwi r1, r0, PER_CPU(CURRENT_SAVE) /* get the saved current */ | ||
208 | lwi r1, r1, TS_THREAD_INFO /* get the thread info */ | ||
209 | /* calculate kernel stack pointer */ | ||
210 | addik r1, r1, THREAD_SIZE - PT_SIZE | ||
211 | swi r11, r0, PER_CPU(R11_SAVE) /* temporarily save r11 */ | ||
212 | lwi r11, r0, PER_CPU(KM) /* load mode indicator */ | ||
213 | 2: | ||
214 | swi r11, r1, PT_MODE /* store the mode */ | ||
215 | lwi r11, r0, PER_CPU(R11_SAVE) /* reload r11 */ | ||
216 | /* save them on stack */ | ||
217 | swi r2, r1, PT_R2 | ||
218 | swi r3, r1, PT_R3 /* r3: _always_ in clobber list; see unistd.h */ | ||
219 | swi r4, r1, PT_R4 /* r4: _always_ in clobber list; see unistd.h */ | ||
220 | swi r5, r1, PT_R5 | ||
221 | swi r6, r1, PT_R6 | ||
222 | swi r7, r1, PT_R7 | ||
223 | swi r8, r1, PT_R8 | ||
224 | swi r9, r1, PT_R9 | ||
225 | swi r10, r1, PT_R10 | ||
226 | swi r11, r1, PT_R11 | ||
227 | /* r12: _always_ in clobber list; see unistd.h */ | ||
228 | swi r12, r1, PT_R12 | ||
229 | swi r13, r1, PT_R13 | ||
230 | /* r14: _always_ in clobber list; see unistd.h */ | ||
231 | swi r14, r1, PT_R14 | ||
232 | /* but we want to return to the next inst. */ | ||
233 | addik r14, r14, 0x4 | ||
234 | swi r14, r1, PT_PC /* increment by 4 and store in pc */ | ||
235 | swi r15, r1, PT_R15 | ||
236 | swi r16, r1, PT_R16 | ||
237 | swi r17, r1, PT_R17 | ||
238 | swi r18, r1, PT_R18 | ||
239 | swi r19, r1, PT_R19 | ||
240 | swi r20, r1, PT_R20 | ||
241 | swi r21, r1, PT_R21 | ||
242 | swi r22, r1, PT_R22 | ||
243 | swi r23, r1, PT_R23 | ||
244 | swi r24, r1, PT_R24 | ||
245 | swi r25, r1, PT_R25 | ||
246 | swi r26, r1, PT_R26 | ||
247 | swi r27, r1, PT_R27 | ||
248 | swi r28, r1, PT_R28 | ||
249 | swi r29, r1, PT_R29 | ||
250 | swi r30, r1, PT_R30 | ||
251 | swi r31, r1, PT_R31 | ||
252 | |||
253 | disable_irq | ||
254 | nop /* make sure IE bit is in effect */ | ||
255 | clear_bip /* once IE is in effect it is safe to clear BIP */ | ||
256 | nop | ||
257 | |||
258 | /* special purpose registers */ | ||
259 | mfs r11, rmsr | ||
260 | swi r11, r1, PT_MSR | ||
261 | mfs r11, rear | ||
262 | swi r11, r1, PT_EAR | ||
263 | mfs r11, resr | ||
264 | swi r11, r1, PT_ESR | ||
265 | mfs r11, rfsr | ||
266 | swi r11, r1, PT_FSR | ||
267 | /* reload original stack pointer and save it */ | ||
268 | lwi r11, r0, PER_CPU(ENTRY_SP) | ||
269 | swi r11, r1, PT_R1 | ||
270 | /* update mode indicator we are in kernel mode */ | ||
271 | addik r11, r0, 1 | ||
272 | swi r11, r0, PER_CPU(KM) | ||
273 | /* restore r31 */ | ||
274 | lwi r31, r0, PER_CPU(CURRENT_SAVE) | ||
275 | /* re-enable interrupts now we are in kernel mode */ | ||
276 | enable_irq | ||
277 | |||
278 | /* See if the system call number is valid. */ | ||
279 | addi r11, r12, -__NR_syscalls | ||
280 | bgei r11, 1f /* return to user if not valid */ | ||
281 | /* Figure out which function to use for this system call. */ | ||
282 | /* Note Microblaze barrel shift is optional, so don't rely on it */ | ||
283 | add r12, r12, r12 /* convert num -> ptr */ | ||
284 | add r12, r12, r12 | ||
285 | lwi r12, r12, sys_call_table /* Get function pointer */ | ||
286 | la r15, r0, ret_to_user-8 /* set return address */ | ||
287 | bra r12 /* Make the system call. */ | ||
288 | bri 0 /* won't reach here */ | ||
289 | 1: | ||
290 | brid ret_to_user /* jump to syscall epilogue */ | ||
291 | addi r3, r0, -ENOSYS /* set errno in delay slot */ | ||
292 | |||
293 | /* | ||
294 | * Debug traps are like a system call, but entered via brki r14, 0x60 | ||
295 | * All we need to do is send the SIGTRAP signal to current, ptrace and do_signal | ||
296 | * will handle the rest | ||
297 | */ | ||
298 | ENTRY(_debug_exception) | ||
299 | swi r1, r0, PER_CPU(ENTRY_SP) /* save the current sp */ | ||
300 | lwi r1, r0, PER_CPU(CURRENT_SAVE) /* get the saved current */ | ||
301 | lwi r1, r1, TS_THREAD_INFO /* get the thread info */ | ||
302 | addik r1, r1, THREAD_SIZE - PT_SIZE /* get the kernel stack */ | ||
303 | swi r11, r0, PER_CPU(R11_SAVE) /* temporarily save r11 */ | ||
304 | lwi r11, r0, PER_CPU(KM) /* load mode indicator */ | ||
305 | //save_context: | ||
306 | swi r11, r1, PT_MODE /* store the mode */ | ||
307 | lwi r11, r0, PER_CPU(R11_SAVE) /* reload r11 */ | ||
308 | /* save them on stack */ | ||
309 | swi r2, r1, PT_R2 | ||
310 | swi r3, r1, PT_R3 /* r3: _always_ in clobber list; see unistd.h */ | ||
311 | swi r4, r1, PT_R4 /* r4: _always_ in clobber list; see unistd.h */ | ||
312 | swi r5, r1, PT_R5 | ||
313 | swi r6, r1, PT_R6 | ||
314 | swi r7, r1, PT_R7 | ||
315 | swi r8, r1, PT_R8 | ||
316 | swi r9, r1, PT_R9 | ||
317 | swi r10, r1, PT_R10 | ||
318 | swi r11, r1, PT_R11 | ||
319 | /* r12: _always_ in clobber list; see unistd.h */ | ||
320 | swi r12, r1, PT_R12 | ||
321 | swi r13, r1, PT_R13 | ||
322 | /* r14: _always_ in clobber list; see unistd.h */ | ||
323 | swi r14, r1, PT_R14 | ||
324 | swi r14, r1, PT_PC /* Will return to interrupted instruction */ | ||
325 | swi r15, r1, PT_R15 | ||
326 | swi r16, r1, PT_R16 | ||
327 | swi r17, r1, PT_R17 | ||
328 | swi r18, r1, PT_R18 | ||
329 | swi r19, r1, PT_R19 | ||
330 | swi r20, r1, PT_R20 | ||
331 | swi r21, r1, PT_R21 | ||
332 | swi r22, r1, PT_R22 | ||
333 | swi r23, r1, PT_R23 | ||
334 | swi r24, r1, PT_R24 | ||
335 | swi r25, r1, PT_R25 | ||
336 | swi r26, r1, PT_R26 | ||
337 | swi r27, r1, PT_R27 | ||
338 | swi r28, r1, PT_R28 | ||
339 | swi r29, r1, PT_R29 | ||
340 | swi r30, r1, PT_R30 | ||
341 | swi r31, r1, PT_R31 | ||
342 | |||
343 | disable_irq | ||
344 | nop /* make sure IE bit is in effect */ | ||
345 | clear_bip /* once IE is in effect it is safe to clear BIP */ | ||
346 | nop | ||
347 | |||
348 | /* special purpose registers */ | ||
349 | mfs r11, rmsr | ||
350 | swi r11, r1, PT_MSR | ||
351 | mfs r11, rear | ||
352 | swi r11, r1, PT_EAR | ||
353 | mfs r11, resr | ||
354 | swi r11, r1, PT_ESR | ||
355 | mfs r11, rfsr | ||
356 | swi r11, r1, PT_FSR | ||
357 | /* reload original stack pointer and save it */ | ||
358 | lwi r11, r0, PER_CPU(ENTRY_SP) | ||
359 | swi r11, r1, PT_R1 | ||
360 | /* update mode indicator we are in kernel mode */ | ||
361 | addik r11, r0, 1 | ||
362 | swi r11, r0, PER_CPU(KM) | ||
363 | /* restore r31 */ | ||
364 | lwi r31, r0, PER_CPU(CURRENT_SAVE) | ||
365 | /* re-enable interrupts now we are in kernel mode */ | ||
366 | enable_irq | ||
367 | |||
368 | addi r5, r0, SIGTRAP /* sending the trap signal */ | ||
369 | add r6, r0, r31 /* to current */ | ||
370 | bralid r15, send_sig | ||
371 | add r7, r0, r0 /* 3rd param zero */ | ||
372 | |||
373 | /* Restore r3/r4 to work around how ret_to_user works */ | ||
374 | lwi r3, r1, PT_R3 | ||
375 | lwi r4, r1, PT_R4 | ||
376 | bri ret_to_user | ||
377 | |||
378 | ENTRY(_break) | ||
379 | bri 0 | ||
380 | |||
381 | /* struct task_struct *_switch_to(struct thread_info *prev, | ||
382 | struct thread_info *next); */ | ||
383 | ENTRY(_switch_to) | ||
384 | /* prepare return value */ | ||
385 | addk r3, r0, r31 | ||
386 | |||
387 | /* save registers in cpu_context */ | ||
388 | /* use r11 and r12, volatile registers, as temp register */ | ||
389 | addik r11, r5, TI_CPU_CONTEXT | ||
390 | swi r1, r11, CC_R1 | ||
391 | swi r2, r11, CC_R2 | ||
392 | /* skip volatile registers. | ||
393 | * they are saved on stack when we jumped to _switch_to() */ | ||
394 | /* dedicated registers */ | ||
395 | swi r13, r11, CC_R13 | ||
396 | swi r14, r11, CC_R14 | ||
397 | swi r15, r11, CC_R15 | ||
398 | swi r16, r11, CC_R16 | ||
399 | swi r17, r11, CC_R17 | ||
400 | swi r18, r11, CC_R18 | ||
401 | /* save non-volatile registers */ | ||
402 | swi r19, r11, CC_R19 | ||
403 | swi r20, r11, CC_R20 | ||
404 | swi r21, r11, CC_R21 | ||
405 | swi r22, r11, CC_R22 | ||
406 | swi r23, r11, CC_R23 | ||
407 | swi r24, r11, CC_R24 | ||
408 | swi r25, r11, CC_R25 | ||
409 | swi r26, r11, CC_R26 | ||
410 | swi r27, r11, CC_R27 | ||
411 | swi r28, r11, CC_R28 | ||
412 | swi r29, r11, CC_R29 | ||
413 | swi r30, r11, CC_R30 | ||
414 | /* special purpose registers */ | ||
415 | mfs r12, rmsr | ||
416 | swi r12, r11, CC_MSR | ||
417 | mfs r12, rear | ||
418 | swi r12, r11, CC_EAR | ||
419 | mfs r12, resr | ||
420 | swi r12, r11, CC_ESR | ||
421 | mfs r12, rfsr | ||
422 | swi r12, r11, CC_FSR | ||
423 | |||
424 | /* update r31, the current */ | ||
425 | lwi r31, r6, TI_TASK | ||
426 | swi r31, r0, PER_CPU(CURRENT_SAVE) | ||
427 | |||
428 | /* get new process' cpu context and restore */ | ||
429 | addik r11, r6, TI_CPU_CONTEXT | ||
430 | |||
431 | /* special purpose registers */ | ||
432 | lwi r12, r11, CC_FSR | ||
433 | mts rfsr, r12 | ||
434 | lwi r12, r11, CC_ESR | ||
435 | mts resr, r12 | ||
436 | lwi r12, r11, CC_EAR | ||
437 | mts rear, r12 | ||
438 | lwi r12, r11, CC_MSR | ||
439 | mts rmsr, r12 | ||
440 | /* non-volatile registers */ | ||
441 | lwi r30, r11, CC_R30 | ||
442 | lwi r29, r11, CC_R29 | ||
443 | lwi r28, r11, CC_R28 | ||
444 | lwi r27, r11, CC_R27 | ||
445 | lwi r26, r11, CC_R26 | ||
446 | lwi r25, r11, CC_R25 | ||
447 | lwi r24, r11, CC_R24 | ||
448 | lwi r23, r11, CC_R23 | ||
449 | lwi r22, r11, CC_R22 | ||
450 | lwi r21, r11, CC_R21 | ||
451 | lwi r20, r11, CC_R20 | ||
452 | lwi r19, r11, CC_R19 | ||
453 | /* dedicated registers */ | ||
454 | lwi r18, r11, CC_R18 | ||
455 | lwi r17, r11, CC_R17 | ||
456 | lwi r16, r11, CC_R16 | ||
457 | lwi r15, r11, CC_R15 | ||
458 | lwi r14, r11, CC_R14 | ||
459 | lwi r13, r11, CC_R13 | ||
460 | /* skip volatile registers */ | ||
461 | lwi r2, r11, CC_R2 | ||
462 | lwi r1, r11, CC_R1 | ||
463 | |||
464 | rtsd r15, 8 | ||
465 | nop | ||
466 | |||
467 | ENTRY(ret_from_fork) | ||
468 | addk r5, r0, r3 | ||
469 | addk r6, r0, r1 | ||
470 | brlid r15, schedule_tail | ||
471 | nop | ||
472 | swi r31, r1, PT_R31 /* save r31 in user context. */ | ||
473 | /* will soon be restored to r31 in ret_to_user */ | ||
474 | addk r3, r0, r0 | ||
475 | brid ret_to_user | ||
476 | nop | ||
477 | |||
478 | work_pending: | ||
479 | andi r11, r19, _TIF_NEED_RESCHED | ||
480 | beqi r11, 1f | ||
481 | bralid r15, schedule | ||
482 | nop | ||
483 | 1: andi r11, r19, _TIF_SIGPENDING | ||
484 | beqi r11, no_work_pending | ||
485 | addk r5, r1, r0 | ||
486 | addik r7, r0, 1 | ||
487 | bralid r15, do_signal | ||
488 | addk r6, r0, r0 | ||
489 | bri no_work_pending | ||
490 | |||
491 | ENTRY(ret_to_user) | ||
492 | disable_irq | ||
493 | |||
494 | swi r4, r1, PT_R4 /* return val */ | ||
495 | swi r3, r1, PT_R3 /* return val */ | ||
496 | |||
497 | lwi r6, r31, TS_THREAD_INFO /* get thread info */ | ||
498 | lwi r19, r6, TI_FLAGS /* get flags in thread info */ | ||
499 | bnei r19, work_pending /* do an extra work if any bits are set */ | ||
500 | no_work_pending: | ||
501 | disable_irq | ||
502 | |||
503 | /* save r31 */ | ||
504 | swi r31, r0, PER_CPU(CURRENT_SAVE) | ||
505 | /* save mode indicator */ | ||
506 | lwi r18, r1, PT_MODE | ||
507 | swi r18, r0, PER_CPU(KM) | ||
508 | //restore_context: | ||
509 | /* special purpose registers */ | ||
510 | lwi r18, r1, PT_FSR | ||
511 | mts rfsr, r18 | ||
512 | lwi r18, r1, PT_ESR | ||
513 | mts resr, r18 | ||
514 | lwi r18, r1, PT_EAR | ||
515 | mts rear, r18 | ||
516 | lwi r18, r1, PT_MSR | ||
517 | mts rmsr, r18 | ||
518 | |||
519 | lwi r31, r1, PT_R31 | ||
520 | lwi r30, r1, PT_R30 | ||
521 | lwi r29, r1, PT_R29 | ||
522 | lwi r28, r1, PT_R28 | ||
523 | lwi r27, r1, PT_R27 | ||
524 | lwi r26, r1, PT_R26 | ||
525 | lwi r25, r1, PT_R25 | ||
526 | lwi r24, r1, PT_R24 | ||
527 | lwi r23, r1, PT_R23 | ||
528 | lwi r22, r1, PT_R22 | ||
529 | lwi r21, r1, PT_R21 | ||
530 | lwi r20, r1, PT_R20 | ||
531 | lwi r19, r1, PT_R19 | ||
532 | lwi r18, r1, PT_R18 | ||
533 | lwi r17, r1, PT_R17 | ||
534 | lwi r16, r1, PT_R16 | ||
535 | lwi r15, r1, PT_R15 | ||
536 | lwi r14, r1, PT_PC | ||
537 | lwi r13, r1, PT_R13 | ||
538 | lwi r12, r1, PT_R12 | ||
539 | lwi r11, r1, PT_R11 | ||
540 | lwi r10, r1, PT_R10 | ||
541 | lwi r9, r1, PT_R9 | ||
542 | lwi r8, r1, PT_R8 | ||
543 | lwi r7, r1, PT_R7 | ||
544 | lwi r6, r1, PT_R6 | ||
545 | lwi r5, r1, PT_R5 | ||
546 | lwi r4, r1, PT_R4 /* return val */ | ||
547 | lwi r3, r1, PT_R3 /* return val */ | ||
548 | lwi r2, r1, PT_R2 | ||
549 | lwi r1, r1, PT_R1 | ||
550 | |||
551 | rtid r14, 0 | ||
552 | nop | ||
553 | |||
554 | sys_vfork_wrapper: | ||
555 | brid sys_vfork | ||
556 | addk r5, r1, r0 | ||
557 | |||
558 | sys_clone_wrapper: | ||
559 | brid sys_clone | ||
560 | addk r7, r1, r0 | ||
561 | |||
562 | sys_execve_wrapper: | ||
563 | brid sys_execve | ||
564 | addk r8, r1, r0 | ||
565 | |||
566 | sys_sigreturn_wrapper: | ||
567 | brid sys_sigreturn | ||
568 | addk r5, r1, r0 | ||
569 | |||
570 | sys_rt_sigreturn_wrapper: | ||
571 | brid sys_rt_sigreturn | ||
572 | addk r5, r1, r0 | ||
573 | |||
574 | sys_sigsuspend_wrapper: | ||
575 | brid sys_rt_sigsuspend | ||
576 | addk r6, r1, r0 | ||
577 | |||
578 | sys_rt_sigsuspend_wrapper: | ||
579 | brid sys_rt_sigsuspend | ||
580 | addk r7, r1, r0 | ||
581 | |||
582 | /* Interrupt vector table */ | ||
583 | .section .init.ivt, "ax" | ||
584 | .org 0x0 | ||
585 | brai _reset | ||
586 | brai _user_exception | ||
587 | brai _interrupt | ||
588 | brai _break | ||
589 | brai _hw_exception_handler | ||
590 | .org 0x60 | ||
591 | brai _debug_exception | ||
592 | |||
593 | .section .rodata,"a" | ||
594 | #include "syscall_table.S" | ||
595 | |||
596 | syscall_table_size=(.-sys_call_table) | ||
diff --git a/arch/microblaze/kernel/exceptions.c b/arch/microblaze/kernel/exceptions.c new file mode 100644 index 000000000000..4a8a4064c7ee --- /dev/null +++ b/arch/microblaze/kernel/exceptions.c | |||
@@ -0,0 +1,124 @@ | |||
1 | /* | ||
2 | * HW exception handling | ||
3 | * | ||
4 | * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu> | ||
5 | * Copyright (C) 2008 PetaLogix | ||
6 | * | ||
7 | * This file is subject to the terms and conditions of the GNU General | ||
8 | * Public License. See the file COPYING in the main directory of this | ||
9 | * archive for more details. | ||
10 | */ | ||
11 | |||
12 | /* | ||
13 | * This file handles the architecture-dependent parts of hardware exceptions | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/signal.h> | ||
18 | #include <linux/sched.h> | ||
19 | #include <linux/kallsyms.h> | ||
20 | #include <linux/module.h> | ||
21 | |||
22 | #include <asm/exceptions.h> | ||
23 | #include <asm/entry.h> /* For KM CPU var */ | ||
24 | #include <asm/uaccess.h> | ||
25 | #include <asm/errno.h> | ||
26 | #include <asm/ptrace.h> | ||
27 | #include <asm/current.h> | ||
28 | |||
29 | #define MICROBLAZE_ILL_OPCODE_EXCEPTION 0x02 | ||
30 | #define MICROBLAZE_IBUS_EXCEPTION 0x03 | ||
31 | #define MICROBLAZE_DBUS_EXCEPTION 0x04 | ||
32 | #define MICROBLAZE_DIV_ZERO_EXCEPTION 0x05 | ||
33 | #define MICROBLAZE_FPU_EXCEPTION 0x06 | ||
34 | #define MICROBLAZE_PRIVILEG_EXCEPTION 0x07 | ||
35 | |||
36 | static DEFINE_SPINLOCK(die_lock); | ||
37 | |||
38 | void die(const char *str, struct pt_regs *fp, long err) | ||
39 | { | ||
40 | console_verbose(); | ||
41 | spin_lock_irq(&die_lock); | ||
42 | printk(KERN_WARNING "Oops: %s, sig: %ld\n", str, err); | ||
43 | show_regs(fp); | ||
44 | spin_unlock_irq(&die_lock); | ||
45 | /* do_exit() should take care of panic'ing from an interrupt | ||
46 | * context so we don't handle it here | ||
47 | */ | ||
48 | do_exit(err); | ||
49 | } | ||
50 | |||
51 | void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr) | ||
52 | { | ||
53 | siginfo_t info; | ||
54 | |||
55 | if (kernel_mode(regs)) { | ||
56 | debugger(regs); | ||
57 | die("Exception in kernel mode", regs, signr); | ||
58 | } | ||
59 | info.si_signo = signr; | ||
60 | info.si_errno = 0; | ||
61 | info.si_code = code; | ||
62 | info.si_addr = (void __user *) addr; | ||
63 | force_sig_info(signr, &info, current); | ||
64 | } | ||
65 | |||
66 | asmlinkage void full_exception(struct pt_regs *regs, unsigned int type, | ||
67 | int fsr, int addr) | ||
68 | { | ||
69 | #if 0 | ||
70 | printk(KERN_WARNING "Exception %02x in %s mode, FSR=%08x PC=%08x ESR=%08x\n", | ||
71 | type, user_mode(regs) ? "user" : "kernel", fsr, | ||
72 | (unsigned int) regs->pc, (unsigned int) regs->esr); | ||
73 | #endif | ||
74 | |||
75 | switch (type & 0x1F) { | ||
76 | case MICROBLAZE_ILL_OPCODE_EXCEPTION: | ||
77 | _exception(SIGILL, regs, ILL_ILLOPC, addr); | ||
78 | break; | ||
79 | case MICROBLAZE_IBUS_EXCEPTION: | ||
80 | if (user_mode(regs)) { | ||
81 | printk(KERN_WARNING "Instruction bus error exception in user mode.\n"); | ||
82 | _exception(SIGBUS, regs, BUS_ADRERR, addr); | ||
83 | return; | ||
84 | } | ||
85 | printk(KERN_WARNING "Instruction bus error exception in kernel mode.\n"); | ||
86 | die("bus exception", regs, SIGBUS); | ||
87 | break; | ||
88 | case MICROBLAZE_DBUS_EXCEPTION: | ||
89 | if (user_mode(regs)) { | ||
90 | printk(KERN_WARNING "Data bus error exception in user mode.\n"); | ||
91 | _exception(SIGBUS, regs, BUS_ADRERR, addr); | ||
92 | return; | ||
93 | } | ||
94 | printk(KERN_WARNING "Data bus error exception in kernel mode.\n"); | ||
95 | die("bus exception", regs, SIGBUS); | ||
96 | break; | ||
97 | case MICROBLAZE_DIV_ZERO_EXCEPTION: | ||
98 | printk(KERN_WARNING "Divide by zero exception\n"); | ||
99 | _exception(SIGILL, regs, ILL_ILLOPC, addr); | ||
100 | break; | ||
101 | |||
102 | case MICROBLAZE_FPU_EXCEPTION: | ||
103 | /* IEEE FP exception */ | ||
104 | /* I removed fsr variable and use code var for storing fsr */ | ||
105 | if (fsr & FSR_IO) | ||
106 | fsr = FPE_FLTINV; | ||
107 | else if (fsr & FSR_OF) | ||
108 | fsr = FPE_FLTOVF; | ||
109 | else if (fsr & FSR_UF) | ||
110 | fsr = FPE_FLTUND; | ||
111 | else if (fsr & FSR_DZ) | ||
112 | fsr = FPE_FLTDIV; | ||
113 | else if (fsr & FSR_DO) | ||
114 | fsr = FPE_FLTRES; | ||
115 | _exception(SIGFPE, regs, fsr, addr); | ||
116 | break; | ||
117 | |||
118 | default: | ||
119 | printk(KERN_WARNING "Unexpected exception %02x " | ||
120 | "PC=%08x in %s mode\n", type, (unsigned int) addr, | ||
121 | kernel_mode(regs) ? "kernel" : "user"); | ||
122 | } | ||
123 | return; | ||
124 | } | ||
diff --git a/arch/microblaze/kernel/head.S b/arch/microblaze/kernel/head.S new file mode 100644 index 000000000000..319dc35fc922 --- /dev/null +++ b/arch/microblaze/kernel/head.S | |||
@@ -0,0 +1,56 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> | ||
3 | * Copyright (C) 2007-2009 PetaLogix | ||
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 | */ | ||
10 | |||
11 | #include <linux/linkage.h> | ||
12 | #include <asm/thread_info.h> | ||
13 | #include <asm/page.h> | ||
14 | |||
15 | .text | ||
16 | ENTRY(_start) | ||
17 | mfs r1, rmsr | ||
18 | andi r1, r1, ~2 | ||
19 | mts rmsr, r1 | ||
20 | |||
21 | /* save fdt to kernel location */ | ||
22 | /* r7 stores pointer to fdt blob */ | ||
23 | beqi r7, no_fdt_arg | ||
24 | or r11, r0, r0 /* incremment */ | ||
25 | ori r4, r0, TOPHYS(_fdt_start) /* save bram context */ | ||
26 | ori r3, r0, (0x4000 - 4) | ||
27 | _copy_fdt: | ||
28 | lw r12, r7, r11 /* r12 = r7 + r11 */ | ||
29 | sw r12, r4, r11 /* addr[r4 + r11] = r12 */ | ||
30 | addik r11, r11, 4 /* increment counting */ | ||
31 | bgtid r3, _copy_fdt /* loop for all entries */ | ||
32 | addik r3, r3, -4 /* descrement loop */ | ||
33 | no_fdt_arg: | ||
34 | |||
35 | /* Initialize small data anchors */ | ||
36 | la r13, r0, _KERNEL_SDA_BASE_ | ||
37 | la r2, r0, _KERNEL_SDA2_BASE_ | ||
38 | |||
39 | /* Initialize stack pointer */ | ||
40 | la r1, r0, init_thread_union + THREAD_SIZE - 4 | ||
41 | |||
42 | /* Initialize r31 with current task address */ | ||
43 | la r31, r0, init_task | ||
44 | |||
45 | /* | ||
46 | * Call platform dependent initialize function. | ||
47 | * Please see $(ARCH)/mach-$(SUBARCH)/setup.c for | ||
48 | * the function. | ||
49 | */ | ||
50 | la r8, r0, machine_early_init | ||
51 | brald r15, r8 | ||
52 | nop | ||
53 | |||
54 | la r15, r0, machine_halt | ||
55 | braid start_kernel | ||
56 | nop | ||
diff --git a/arch/microblaze/kernel/heartbeat.c b/arch/microblaze/kernel/heartbeat.c new file mode 100644 index 000000000000..1bdf20222b92 --- /dev/null +++ b/arch/microblaze/kernel/heartbeat.c | |||
@@ -0,0 +1,67 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> | ||
3 | * Copyright (C) 2007-2009 PetaLogix | ||
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 | */ | ||
10 | |||
11 | #include <linux/sched.h> | ||
12 | #include <linux/io.h> | ||
13 | |||
14 | #include <asm/setup.h> | ||
15 | #include <asm/page.h> | ||
16 | #include <asm/prom.h> | ||
17 | |||
18 | static unsigned int base_addr; | ||
19 | |||
20 | void heartbeat(void) | ||
21 | { | ||
22 | static unsigned int cnt, period, dist; | ||
23 | |||
24 | if (base_addr) { | ||
25 | if (cnt == 0 || cnt == dist) | ||
26 | out_be32(base_addr, 1); | ||
27 | else if (cnt == 7 || cnt == dist + 7) | ||
28 | out_be32(base_addr, 0); | ||
29 | |||
30 | if (++cnt > period) { | ||
31 | cnt = 0; | ||
32 | /* | ||
33 | * The hyperbolic function below modifies the heartbeat | ||
34 | * period length in dependency of the current (5min) | ||
35 | * load. It goes through the points f(0)=126, f(1)=86, | ||
36 | * f(5)=51, f(inf)->30. | ||
37 | */ | ||
38 | period = ((672 << FSHIFT) / (5 * avenrun[0] + | ||
39 | (7 << FSHIFT))) + 30; | ||
40 | dist = period / 4; | ||
41 | } | ||
42 | } | ||
43 | } | ||
44 | |||
45 | void setup_heartbeat(void) | ||
46 | { | ||
47 | struct device_node *gpio = NULL; | ||
48 | int j; | ||
49 | char *gpio_list[] = { | ||
50 | "xlnx,xps-gpio-1.00.a", | ||
51 | "xlnx,opb-gpio-1.00.a", | ||
52 | NULL | ||
53 | }; | ||
54 | |||
55 | for (j = 0; gpio_list[j] != NULL; j++) { | ||
56 | gpio = of_find_compatible_node(NULL, NULL, gpio_list[j]); | ||
57 | if (gpio) | ||
58 | break; | ||
59 | } | ||
60 | |||
61 | base_addr = *(int *) of_get_property(gpio, "reg", NULL); | ||
62 | base_addr = (unsigned long) ioremap(base_addr, PAGE_SIZE); | ||
63 | printk(KERN_NOTICE "Heartbeat GPIO at 0x%x\n", base_addr); | ||
64 | |||
65 | if (*(int *) of_get_property(gpio, "xlnx,is-bidir", NULL)) | ||
66 | out_be32(base_addr + 4, 0); /* GPIO is configured as output */ | ||
67 | } | ||
diff --git a/arch/microblaze/kernel/hw_exception_handler.S b/arch/microblaze/kernel/hw_exception_handler.S new file mode 100644 index 000000000000..cf9486d99838 --- /dev/null +++ b/arch/microblaze/kernel/hw_exception_handler.S | |||
@@ -0,0 +1,458 @@ | |||
1 | /* | ||
2 | * Exception handling for Microblaze | ||
3 | * | ||
4 | * Rewriten interrupt handling | ||
5 | * | ||
6 | * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu> | ||
7 | * Copyright (C) 2008-2009 PetaLogix | ||
8 | * | ||
9 | * uClinux customisation (C) 2005 John Williams | ||
10 | * | ||
11 | * MMU code derived from arch/ppc/kernel/head_4xx.S: | ||
12 | * Copyright (C) 1995-1996 Gary Thomas <gdt@linuxppc.org> | ||
13 | * Initial PowerPC version. | ||
14 | * Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu> | ||
15 | * Rewritten for PReP | ||
16 | * Copyright (C) 1996 Paul Mackerras <paulus@cs.anu.edu.au> | ||
17 | * Low-level exception handers, MMU support, and rewrite. | ||
18 | * Copyright (C) 1997 Dan Malek <dmalek@jlc.net> | ||
19 | * PowerPC 8xx modifications. | ||
20 | * Copyright (C) 1998-1999 TiVo, Inc. | ||
21 | * PowerPC 403GCX modifications. | ||
22 | * Copyright (C) 1999 Grant Erickson <grant@lcse.umn.edu> | ||
23 | * PowerPC 403GCX/405GP modifications. | ||
24 | * Copyright 2000 MontaVista Software Inc. | ||
25 | * PPC405 modifications | ||
26 | * PowerPC 403GCX/405GP modifications. | ||
27 | * Author: MontaVista Software, Inc. | ||
28 | * frank_rowand@mvista.com or source@mvista.com | ||
29 | * debbie_chu@mvista.com | ||
30 | * | ||
31 | * Original code | ||
32 | * Copyright (C) 2004 Xilinx, Inc. | ||
33 | * | ||
34 | * This program is free software; you can redistribute it and/or modify it | ||
35 | * under the terms of the GNU General Public License version 2 as published | ||
36 | * by the Free Software Foundation. | ||
37 | */ | ||
38 | |||
39 | /* | ||
40 | * Here are the handlers which don't require enabling translation | ||
41 | * and calling other kernel code thus we can keep their design very simple | ||
42 | * and do all processing in real mode. All what they need is a valid current | ||
43 | * (that is an issue for the CONFIG_REGISTER_TASK_PTR case) | ||
44 | * This handlers use r3,r4,r5,r6 and optionally r[current] to work therefore | ||
45 | * these registers are saved/restored | ||
46 | * The handlers which require translation are in entry.S --KAA | ||
47 | * | ||
48 | * Microblaze HW Exception Handler | ||
49 | * - Non self-modifying exception handler for the following exception conditions | ||
50 | * - Unalignment | ||
51 | * - Instruction bus error | ||
52 | * - Data bus error | ||
53 | * - Illegal instruction opcode | ||
54 | * - Divide-by-zero | ||
55 | * | ||
56 | * Note we disable interrupts during exception handling, otherwise we will | ||
57 | * possibly get multiple re-entrancy if interrupt handles themselves cause | ||
58 | * exceptions. JW | ||
59 | */ | ||
60 | |||
61 | #include <asm/exceptions.h> | ||
62 | #include <asm/unistd.h> | ||
63 | #include <asm/page.h> | ||
64 | |||
65 | #include <asm/entry.h> | ||
66 | #include <asm/current.h> | ||
67 | #include <linux/linkage.h> | ||
68 | |||
69 | #include <asm/mmu.h> | ||
70 | #include <asm/pgtable.h> | ||
71 | #include <asm/asm-offsets.h> | ||
72 | |||
73 | /* Helpful Macros */ | ||
74 | #define EX_HANDLER_STACK_SIZ (4*19) | ||
75 | #define NUM_TO_REG(num) r ## num | ||
76 | |||
77 | #define LWREG_NOP \ | ||
78 | bri ex_handler_unhandled; \ | ||
79 | nop; | ||
80 | |||
81 | #define SWREG_NOP \ | ||
82 | bri ex_handler_unhandled; \ | ||
83 | nop; | ||
84 | |||
85 | /* FIXME this is weird - for noMMU kernel is not possible to use brid | ||
86 | * instruction which can shorten executed time | ||
87 | */ | ||
88 | |||
89 | /* r3 is the source */ | ||
90 | #define R3_TO_LWREG_V(regnum) \ | ||
91 | swi r3, r1, 4 * regnum; \ | ||
92 | bri ex_handler_done; | ||
93 | |||
94 | /* r3 is the source */ | ||
95 | #define R3_TO_LWREG(regnum) \ | ||
96 | or NUM_TO_REG (regnum), r0, r3; \ | ||
97 | bri ex_handler_done; | ||
98 | |||
99 | /* r3 is the target */ | ||
100 | #define SWREG_TO_R3_V(regnum) \ | ||
101 | lwi r3, r1, 4 * regnum; \ | ||
102 | bri ex_sw_tail; | ||
103 | |||
104 | /* r3 is the target */ | ||
105 | #define SWREG_TO_R3(regnum) \ | ||
106 | or r3, r0, NUM_TO_REG (regnum); \ | ||
107 | bri ex_sw_tail; | ||
108 | |||
109 | .extern other_exception_handler /* Defined in exception.c */ | ||
110 | |||
111 | /* | ||
112 | * hw_exception_handler - Handler for exceptions | ||
113 | * | ||
114 | * Exception handler notes: | ||
115 | * - Handles all exceptions | ||
116 | * - Does not handle unaligned exceptions during load into r17, r1, r0. | ||
117 | * - Does not handle unaligned exceptions during store from r17 (cannot be | ||
118 | * done) and r1 (slows down common case) | ||
119 | * | ||
120 | * Relevant register structures | ||
121 | * | ||
122 | * EAR - |----|----|----|----|----|----|----|----| | ||
123 | * - < ## 32 bit faulting address ## > | ||
124 | * | ||
125 | * ESR - |----|----|----|----|----| - | - |-----|-----| | ||
126 | * - W S REG EXC | ||
127 | * | ||
128 | * | ||
129 | * STACK FRAME STRUCTURE (for NO_MMU) | ||
130 | * --------------------------------- | ||
131 | * | ||
132 | * +-------------+ + 0 | ||
133 | * | MSR | | ||
134 | * +-------------+ + 4 | ||
135 | * | r1 | | ||
136 | * | . | | ||
137 | * | . | | ||
138 | * | . | | ||
139 | * | . | | ||
140 | * | r18 | | ||
141 | * +-------------+ + 76 | ||
142 | * | . | | ||
143 | * | . | | ||
144 | * | ||
145 | * NO_MMU kernel use the same r0_ram pointed space - look to vmlinux.lds.S | ||
146 | * which is used for storing register values - old style was, that value were | ||
147 | * stored in stack but in case of failure you lost information about register. | ||
148 | * Currently you can see register value in memory in specific place. | ||
149 | * In compare to with previous solution the speed should be the same. | ||
150 | * | ||
151 | * MMU exception handler has different handling compare to no MMU kernel. | ||
152 | * Exception handler use jump table for directing of what happen. For MMU kernel | ||
153 | * is this approach better because MMU relate exception are handled by asm code | ||
154 | * in this file. In compare to with MMU expect of unaligned exception | ||
155 | * is everything handled by C code. | ||
156 | */ | ||
157 | |||
158 | /* | ||
159 | * every of these handlers is entered having R3/4/5/6/11/current saved on stack | ||
160 | * and clobbered so care should be taken to restore them if someone is going to | ||
161 | * return from exception | ||
162 | */ | ||
163 | |||
164 | /* wrappers to restore state before coming to entry.S */ | ||
165 | |||
166 | .global _hw_exception_handler | ||
167 | .section .text | ||
168 | .align 4 | ||
169 | .ent _hw_exception_handler | ||
170 | _hw_exception_handler: | ||
171 | addik r1, r1, -(EX_HANDLER_STACK_SIZ); /* Create stack frame */ | ||
172 | swi r3, r1, PT_R3 | ||
173 | swi r4, r1, PT_R4 | ||
174 | swi r5, r1, PT_R5 | ||
175 | swi r6, r1, PT_R6 | ||
176 | |||
177 | mfs r5, rmsr; | ||
178 | nop | ||
179 | swi r5, r1, 0; | ||
180 | mfs r4, rbtr /* Save BTR before jumping to handler */ | ||
181 | nop | ||
182 | mfs r3, resr | ||
183 | nop | ||
184 | |||
185 | andi r5, r3, 0x1000; /* Check ESR[DS] */ | ||
186 | beqi r5, not_in_delay_slot; /* Branch if ESR[DS] not set */ | ||
187 | mfs r17, rbtr; /* ESR[DS] set - return address in BTR */ | ||
188 | nop | ||
189 | not_in_delay_slot: | ||
190 | swi r17, r1, PT_R17 | ||
191 | |||
192 | andi r5, r3, 0x1F; /* Extract ESR[EXC] */ | ||
193 | |||
194 | /* Exceptions enabled here. This will allow nested exceptions */ | ||
195 | mfs r6, rmsr; | ||
196 | nop | ||
197 | swi r6, r1, 0; /* RMSR_OFFSET */ | ||
198 | ori r6, r6, 0x100; /* Turn ON the EE bit */ | ||
199 | andi r6, r6, ~2; /* Disable interrupts */ | ||
200 | mts rmsr, r6; | ||
201 | nop | ||
202 | |||
203 | xori r6, r5, 1; /* 00001 = Unaligned Exception */ | ||
204 | /* Jump to unalignment exception handler */ | ||
205 | beqi r6, handle_unaligned_ex; | ||
206 | |||
207 | handle_other_ex: /* Handle Other exceptions here */ | ||
208 | /* Save other volatiles before we make procedure calls below */ | ||
209 | swi r7, r1, PT_R7 | ||
210 | swi r8, r1, PT_R8 | ||
211 | swi r9, r1, PT_R9 | ||
212 | swi r10, r1, PT_R10 | ||
213 | swi r11, r1, PT_R11 | ||
214 | swi r12, r1, PT_R12 | ||
215 | swi r14, r1, PT_R14 | ||
216 | swi r15, r1, PT_R15 | ||
217 | swi r18, r1, PT_R18 | ||
218 | |||
219 | or r5, r1, r0 | ||
220 | andi r6, r3, 0x1F; /* Load ESR[EC] */ | ||
221 | lwi r7, r0, PER_CPU(KM) /* MS: saving current kernel mode to regs */ | ||
222 | swi r7, r1, PT_MODE | ||
223 | mfs r7, rfsr | ||
224 | nop | ||
225 | addk r8, r17, r0; /* Load exception address */ | ||
226 | bralid r15, full_exception; /* Branch to the handler */ | ||
227 | nop; | ||
228 | |||
229 | /* | ||
230 | * Trigger execution of the signal handler by enabling | ||
231 | * interrupts and calling an invalid syscall. | ||
232 | */ | ||
233 | mfs r5, rmsr; | ||
234 | nop | ||
235 | ori r5, r5, 2; | ||
236 | mts rmsr, r5; /* enable interrupt */ | ||
237 | nop | ||
238 | addi r12, r0, __NR_syscalls; | ||
239 | brki r14, 0x08; | ||
240 | mfs r5, rmsr; /* disable interrupt */ | ||
241 | nop | ||
242 | andi r5, r5, ~2; | ||
243 | mts rmsr, r5; | ||
244 | nop | ||
245 | |||
246 | lwi r7, r1, PT_R7 | ||
247 | lwi r8, r1, PT_R8 | ||
248 | lwi r9, r1, PT_R9 | ||
249 | lwi r10, r1, PT_R10 | ||
250 | lwi r11, r1, PT_R11 | ||
251 | lwi r12, r1, PT_R12 | ||
252 | lwi r14, r1, PT_R14 | ||
253 | lwi r15, r1, PT_R15 | ||
254 | lwi r18, r1, PT_R18 | ||
255 | |||
256 | bri ex_handler_done; /* Complete exception handling */ | ||
257 | |||
258 | /* 0x01 - Unaligned data access exception | ||
259 | * This occurs when a word access is not aligned on a word boundary, | ||
260 | * or when a 16-bit access is not aligned on a 16-bit boundary. | ||
261 | * This handler perform the access, and returns, except for MMU when | ||
262 | * the unaligned address is last on a 4k page or the physical address is | ||
263 | * not found in the page table, in which case unaligned_data_trap is called. | ||
264 | */ | ||
265 | handle_unaligned_ex: | ||
266 | /* Working registers already saved: R3, R4, R5, R6 | ||
267 | * R3 = ESR | ||
268 | * R4 = BTR | ||
269 | */ | ||
270 | mfs r4, rear; | ||
271 | nop | ||
272 | |||
273 | andi r6, r3, 0x3E0; /* Mask and extract the register operand */ | ||
274 | srl r6, r6; /* r6 >> 5 */ | ||
275 | srl r6, r6; | ||
276 | srl r6, r6; | ||
277 | srl r6, r6; | ||
278 | srl r6, r6; | ||
279 | /* Store the register operand in a temporary location */ | ||
280 | sbi r6, r0, TOPHYS(ex_reg_op); | ||
281 | |||
282 | andi r6, r3, 0x400; /* Extract ESR[S] */ | ||
283 | bnei r6, ex_sw; | ||
284 | ex_lw: | ||
285 | andi r6, r3, 0x800; /* Extract ESR[W] */ | ||
286 | beqi r6, ex_lhw; | ||
287 | lbui r5, r4, 0; /* Exception address in r4 */ | ||
288 | /* Load a word, byte-by-byte from destination address | ||
289 | and save it in tmp space */ | ||
290 | sbi r5, r0, TOPHYS(ex_tmp_data_loc_0); | ||
291 | lbui r5, r4, 1; | ||
292 | sbi r5, r0, TOPHYS(ex_tmp_data_loc_1); | ||
293 | lbui r5, r4, 2; | ||
294 | sbi r5, r0, TOPHYS(ex_tmp_data_loc_2); | ||
295 | lbui r5, r4, 3; | ||
296 | sbi r5, r0, TOPHYS(ex_tmp_data_loc_3); | ||
297 | /* Get the destination register value into r3 */ | ||
298 | lwi r3, r0, TOPHYS(ex_tmp_data_loc_0); | ||
299 | bri ex_lw_tail; | ||
300 | ex_lhw: | ||
301 | lbui r5, r4, 0; /* Exception address in r4 */ | ||
302 | /* Load a half-word, byte-by-byte from destination | ||
303 | address and save it in tmp space */ | ||
304 | sbi r5, r0, TOPHYS(ex_tmp_data_loc_0); | ||
305 | lbui r5, r4, 1; | ||
306 | sbi r5, r0, TOPHYS(ex_tmp_data_loc_1); | ||
307 | /* Get the destination register value into r3 */ | ||
308 | lhui r3, r0, TOPHYS(ex_tmp_data_loc_0); | ||
309 | ex_lw_tail: | ||
310 | /* Get the destination register number into r5 */ | ||
311 | lbui r5, r0, TOPHYS(ex_reg_op); | ||
312 | /* Form load_word jump table offset (lw_table + (8 * regnum)) */ | ||
313 | la r6, r0, TOPHYS(lw_table); | ||
314 | addk r5, r5, r5; | ||
315 | addk r5, r5, r5; | ||
316 | addk r5, r5, r5; | ||
317 | addk r5, r5, r6; | ||
318 | bra r5; | ||
319 | ex_lw_end: /* Exception handling of load word, ends */ | ||
320 | ex_sw: | ||
321 | /* Get the destination register number into r5 */ | ||
322 | lbui r5, r0, TOPHYS(ex_reg_op); | ||
323 | /* Form store_word jump table offset (sw_table + (8 * regnum)) */ | ||
324 | la r6, r0, TOPHYS(sw_table); | ||
325 | add r5, r5, r5; | ||
326 | add r5, r5, r5; | ||
327 | add r5, r5, r5; | ||
328 | add r5, r5, r6; | ||
329 | bra r5; | ||
330 | ex_sw_tail: | ||
331 | mfs r6, resr; | ||
332 | nop | ||
333 | andi r6, r6, 0x800; /* Extract ESR[W] */ | ||
334 | beqi r6, ex_shw; | ||
335 | /* Get the word - delay slot */ | ||
336 | swi r3, r0, TOPHYS(ex_tmp_data_loc_0); | ||
337 | /* Store the word, byte-by-byte into destination address */ | ||
338 | lbui r3, r0, TOPHYS(ex_tmp_data_loc_0); | ||
339 | sbi r3, r4, 0; | ||
340 | lbui r3, r0, TOPHYS(ex_tmp_data_loc_1); | ||
341 | sbi r3, r4, 1; | ||
342 | lbui r3, r0, TOPHYS(ex_tmp_data_loc_2); | ||
343 | sbi r3, r4, 2; | ||
344 | lbui r3, r0, TOPHYS(ex_tmp_data_loc_3); | ||
345 | sbi r3, r4, 3; | ||
346 | bri ex_handler_done; | ||
347 | |||
348 | ex_shw: | ||
349 | /* Store the lower half-word, byte-by-byte into destination address */ | ||
350 | swi r3, r0, TOPHYS(ex_tmp_data_loc_0); | ||
351 | lbui r3, r0, TOPHYS(ex_tmp_data_loc_2); | ||
352 | sbi r3, r4, 0; | ||
353 | lbui r3, r0, TOPHYS(ex_tmp_data_loc_3); | ||
354 | sbi r3, r4, 1; | ||
355 | ex_sw_end: /* Exception handling of store word, ends. */ | ||
356 | |||
357 | ex_handler_done: | ||
358 | lwi r5, r1, 0 /* RMSR */ | ||
359 | mts rmsr, r5 | ||
360 | nop | ||
361 | lwi r3, r1, PT_R3 | ||
362 | lwi r4, r1, PT_R4 | ||
363 | lwi r5, r1, PT_R5 | ||
364 | lwi r6, r1, PT_R6 | ||
365 | lwi r17, r1, PT_R17 | ||
366 | |||
367 | rted r17, 0 | ||
368 | addik r1, r1, (EX_HANDLER_STACK_SIZ); /* Restore stack frame */ | ||
369 | |||
370 | .end _hw_exception_handler | ||
371 | |||
372 | ex_handler_unhandled: | ||
373 | /* FIXME add handle function for unhandled exception - dump register */ | ||
374 | bri 0 | ||
375 | |||
376 | .section .text | ||
377 | .align 4 | ||
378 | lw_table: | ||
379 | lw_r0: R3_TO_LWREG (0); | ||
380 | lw_r1: LWREG_NOP; | ||
381 | lw_r2: R3_TO_LWREG (2); | ||
382 | lw_r3: R3_TO_LWREG_V (3); | ||
383 | lw_r4: R3_TO_LWREG_V (4); | ||
384 | lw_r5: R3_TO_LWREG_V (5); | ||
385 | lw_r6: R3_TO_LWREG_V (6); | ||
386 | lw_r7: R3_TO_LWREG (7); | ||
387 | lw_r8: R3_TO_LWREG (8); | ||
388 | lw_r9: R3_TO_LWREG (9); | ||
389 | lw_r10: R3_TO_LWREG (10); | ||
390 | lw_r11: R3_TO_LWREG (11); | ||
391 | lw_r12: R3_TO_LWREG (12); | ||
392 | lw_r13: R3_TO_LWREG (13); | ||
393 | lw_r14: R3_TO_LWREG (14); | ||
394 | lw_r15: R3_TO_LWREG (15); | ||
395 | lw_r16: R3_TO_LWREG (16); | ||
396 | lw_r17: LWREG_NOP; | ||
397 | lw_r18: R3_TO_LWREG (18); | ||
398 | lw_r19: R3_TO_LWREG (19); | ||
399 | lw_r20: R3_TO_LWREG (20); | ||
400 | lw_r21: R3_TO_LWREG (21); | ||
401 | lw_r22: R3_TO_LWREG (22); | ||
402 | lw_r23: R3_TO_LWREG (23); | ||
403 | lw_r24: R3_TO_LWREG (24); | ||
404 | lw_r25: R3_TO_LWREG (25); | ||
405 | lw_r26: R3_TO_LWREG (26); | ||
406 | lw_r27: R3_TO_LWREG (27); | ||
407 | lw_r28: R3_TO_LWREG (28); | ||
408 | lw_r29: R3_TO_LWREG (29); | ||
409 | lw_r30: R3_TO_LWREG (30); | ||
410 | lw_r31: R3_TO_LWREG (31); | ||
411 | |||
412 | sw_table: | ||
413 | sw_r0: SWREG_TO_R3 (0); | ||
414 | sw_r1: SWREG_NOP; | ||
415 | sw_r2: SWREG_TO_R3 (2); | ||
416 | sw_r3: SWREG_TO_R3_V (3); | ||
417 | sw_r4: SWREG_TO_R3_V (4); | ||
418 | sw_r5: SWREG_TO_R3_V (5); | ||
419 | sw_r6: SWREG_TO_R3_V (6); | ||
420 | sw_r7: SWREG_TO_R3 (7); | ||
421 | sw_r8: SWREG_TO_R3 (8); | ||
422 | sw_r9: SWREG_TO_R3 (9); | ||
423 | sw_r10: SWREG_TO_R3 (10); | ||
424 | sw_r11: SWREG_TO_R3 (11); | ||
425 | sw_r12: SWREG_TO_R3 (12); | ||
426 | sw_r13: SWREG_TO_R3 (13); | ||
427 | sw_r14: SWREG_TO_R3 (14); | ||
428 | sw_r15: SWREG_TO_R3 (15); | ||
429 | sw_r16: SWREG_TO_R3 (16); | ||
430 | sw_r17: SWREG_NOP; | ||
431 | sw_r18: SWREG_TO_R3 (18); | ||
432 | sw_r19: SWREG_TO_R3 (19); | ||
433 | sw_r20: SWREG_TO_R3 (20); | ||
434 | sw_r21: SWREG_TO_R3 (21); | ||
435 | sw_r22: SWREG_TO_R3 (22); | ||
436 | sw_r23: SWREG_TO_R3 (23); | ||
437 | sw_r24: SWREG_TO_R3 (24); | ||
438 | sw_r25: SWREG_TO_R3 (25); | ||
439 | sw_r26: SWREG_TO_R3 (26); | ||
440 | sw_r27: SWREG_TO_R3 (27); | ||
441 | sw_r28: SWREG_TO_R3 (28); | ||
442 | sw_r29: SWREG_TO_R3 (29); | ||
443 | sw_r30: SWREG_TO_R3 (30); | ||
444 | sw_r31: SWREG_TO_R3 (31); | ||
445 | |||
446 | /* Temporary data structures used in the handler */ | ||
447 | .section .data | ||
448 | .align 4 | ||
449 | ex_tmp_data_loc_0: | ||
450 | .byte 0 | ||
451 | ex_tmp_data_loc_1: | ||
452 | .byte 0 | ||
453 | ex_tmp_data_loc_2: | ||
454 | .byte 0 | ||
455 | ex_tmp_data_loc_3: | ||
456 | .byte 0 | ||
457 | ex_reg_op: | ||
458 | .byte 0 | ||
diff --git a/arch/microblaze/kernel/init_task.c b/arch/microblaze/kernel/init_task.c new file mode 100644 index 000000000000..48eb9fb255fa --- /dev/null +++ b/arch/microblaze/kernel/init_task.c | |||
@@ -0,0 +1,29 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2009 Michal Simek <monstr@monstr.eu> | ||
3 | * Copyright (C) 2009 PetaLogix | ||
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 | */ | ||
10 | |||
11 | #include <linux/module.h> | ||
12 | #include <linux/sched.h> | ||
13 | #include <linux/init_task.h> | ||
14 | #include <linux/fs.h> | ||
15 | #include <linux/mqueue.h> | ||
16 | |||
17 | #include <asm/pgtable.h> | ||
18 | |||
19 | static struct signal_struct init_signals = INIT_SIGNALS(init_signals); | ||
20 | static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); | ||
21 | struct mm_struct init_mm = INIT_MM(init_mm); | ||
22 | EXPORT_SYMBOL(init_mm); | ||
23 | |||
24 | union thread_union init_thread_union | ||
25 | __attribute__((__section__(".data.init_task"))) = | ||
26 | { INIT_THREAD_INFO(init_task) }; | ||
27 | |||
28 | struct task_struct init_task = INIT_TASK(init_task); | ||
29 | EXPORT_SYMBOL(init_task); | ||
diff --git a/arch/microblaze/kernel/intc.c b/arch/microblaze/kernel/intc.c new file mode 100644 index 000000000000..a69d3e3c2fd4 --- /dev/null +++ b/arch/microblaze/kernel/intc.c | |||
@@ -0,0 +1,172 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> | ||
3 | * Copyright (C) 2007-2009 PetaLogix | ||
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 | */ | ||
10 | |||
11 | #include <linux/init.h> | ||
12 | #include <linux/irq.h> | ||
13 | #include <asm/page.h> | ||
14 | #include <linux/io.h> | ||
15 | |||
16 | #include <asm/prom.h> | ||
17 | #include <asm/irq.h> | ||
18 | |||
19 | #ifdef CONFIG_SELFMOD_INTC | ||
20 | #include <asm/selfmod.h> | ||
21 | #define INTC_BASE BARRIER_BASE_ADDR | ||
22 | #else | ||
23 | static unsigned int intc_baseaddr; | ||
24 | #define INTC_BASE intc_baseaddr | ||
25 | #endif | ||
26 | |||
27 | unsigned int nr_irq; | ||
28 | |||
29 | /* No one else should require these constants, so define them locally here. */ | ||
30 | #define ISR 0x00 /* Interrupt Status Register */ | ||
31 | #define IPR 0x04 /* Interrupt Pending Register */ | ||
32 | #define IER 0x08 /* Interrupt Enable Register */ | ||
33 | #define IAR 0x0c /* Interrupt Acknowledge Register */ | ||
34 | #define SIE 0x10 /* Set Interrupt Enable bits */ | ||
35 | #define CIE 0x14 /* Clear Interrupt Enable bits */ | ||
36 | #define IVR 0x18 /* Interrupt Vector Register */ | ||
37 | #define MER 0x1c /* Master Enable Register */ | ||
38 | |||
39 | #define MER_ME (1<<0) | ||
40 | #define MER_HIE (1<<1) | ||
41 | |||
42 | static void intc_enable_or_unmask(unsigned int irq) | ||
43 | { | ||
44 | pr_debug("enable_or_unmask: %d\n", irq); | ||
45 | out_be32(INTC_BASE + SIE, 1 << irq); | ||
46 | } | ||
47 | |||
48 | static void intc_disable_or_mask(unsigned int irq) | ||
49 | { | ||
50 | pr_debug("disable: %d\n", irq); | ||
51 | out_be32(INTC_BASE + CIE, 1 << irq); | ||
52 | } | ||
53 | |||
54 | static void intc_ack(unsigned int irq) | ||
55 | { | ||
56 | pr_debug("ack: %d\n", irq); | ||
57 | out_be32(INTC_BASE + IAR, 1 << irq); | ||
58 | } | ||
59 | |||
60 | static void intc_mask_ack(unsigned int irq) | ||
61 | { | ||
62 | unsigned long mask = 1 << irq; | ||
63 | pr_debug("disable_and_ack: %d\n", irq); | ||
64 | out_be32(INTC_BASE + CIE, mask); | ||
65 | out_be32(INTC_BASE + IAR, mask); | ||
66 | } | ||
67 | |||
68 | static void intc_end(unsigned int irq) | ||
69 | { | ||
70 | unsigned long mask = 1 << irq; | ||
71 | pr_debug("end: %d\n", irq); | ||
72 | if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { | ||
73 | out_be32(INTC_BASE + SIE, mask); | ||
74 | /* ack level sensitive intr */ | ||
75 | if (irq_desc[irq].status & IRQ_LEVEL) | ||
76 | out_be32(INTC_BASE + IAR, mask); | ||
77 | } | ||
78 | } | ||
79 | |||
80 | static struct irq_chip intc_dev = { | ||
81 | .name = "Xilinx INTC", | ||
82 | .unmask = intc_enable_or_unmask, | ||
83 | .mask = intc_disable_or_mask, | ||
84 | .ack = intc_ack, | ||
85 | .mask_ack = intc_mask_ack, | ||
86 | .end = intc_end, | ||
87 | }; | ||
88 | |||
89 | unsigned int get_irq(struct pt_regs *regs) | ||
90 | { | ||
91 | int irq; | ||
92 | |||
93 | /* | ||
94 | * NOTE: This function is the one that needs to be improved in | ||
95 | * order to handle multiple interrupt controllers. It currently | ||
96 | * is hardcoded to check for interrupts only on the first INTC. | ||
97 | */ | ||
98 | irq = in_be32(INTC_BASE + IVR); | ||
99 | pr_debug("get_irq: %d\n", irq); | ||
100 | |||
101 | return irq; | ||
102 | } | ||
103 | |||
104 | void __init init_IRQ(void) | ||
105 | { | ||
106 | u32 i, j, intr_type; | ||
107 | struct device_node *intc = NULL; | ||
108 | #ifdef CONFIG_SELFMOD_INTC | ||
109 | unsigned int intc_baseaddr = 0; | ||
110 | static int arr_func[] = { | ||
111 | (int)&get_irq, | ||
112 | (int)&intc_enable_or_unmask, | ||
113 | (int)&intc_disable_or_mask, | ||
114 | (int)&intc_mask_ack, | ||
115 | (int)&intc_ack, | ||
116 | (int)&intc_end, | ||
117 | 0 | ||
118 | }; | ||
119 | #endif | ||
120 | static char *intc_list[] = { | ||
121 | "xlnx,xps-intc-1.00.a", | ||
122 | "xlnx,opb-intc-1.00.c", | ||
123 | "xlnx,opb-intc-1.00.b", | ||
124 | "xlnx,opb-intc-1.00.a", | ||
125 | NULL | ||
126 | }; | ||
127 | |||
128 | for (j = 0; intc_list[j] != NULL; j++) { | ||
129 | intc = of_find_compatible_node(NULL, NULL, intc_list[j]); | ||
130 | if (intc) | ||
131 | break; | ||
132 | } | ||
133 | |||
134 | intc_baseaddr = *(int *) of_get_property(intc, "reg", NULL); | ||
135 | intc_baseaddr = (unsigned long) ioremap(intc_baseaddr, PAGE_SIZE); | ||
136 | nr_irq = *(int *) of_get_property(intc, "xlnx,num-intr-inputs", NULL); | ||
137 | |||
138 | intr_type = | ||
139 | *(int *) of_get_property(intc, "xlnx,kind-of-intr", NULL); | ||
140 | if (intr_type >= (1 << nr_irq)) | ||
141 | printk(KERN_INFO " ERROR: Mishmash in king-of-intr param\n"); | ||
142 | |||
143 | #ifdef CONFIG_SELFMOD_INTC | ||
144 | selfmod_function((int *) arr_func, intc_baseaddr); | ||
145 | #endif | ||
146 | printk(KERN_INFO "%s #0 at 0x%08x, num_irq=%d, edge=0x%x\n", | ||
147 | intc_list[j], intc_baseaddr, nr_irq, intr_type); | ||
148 | |||
149 | /* | ||
150 | * Disable all external interrupts until they are | ||
151 | * explicity requested. | ||
152 | */ | ||
153 | out_be32(intc_baseaddr + IER, 0); | ||
154 | |||
155 | /* Acknowledge any pending interrupts just in case. */ | ||
156 | out_be32(intc_baseaddr + IAR, 0xffffffff); | ||
157 | |||
158 | /* Turn on the Master Enable. */ | ||
159 | out_be32(intc_baseaddr + MER, MER_HIE | MER_ME); | ||
160 | |||
161 | for (i = 0; i < nr_irq; ++i) { | ||
162 | if (intr_type & (0x00000001 << i)) { | ||
163 | set_irq_chip_and_handler_name(i, &intc_dev, | ||
164 | handle_edge_irq, intc_dev.name); | ||
165 | irq_desc[i].status &= ~IRQ_LEVEL; | ||
166 | } else { | ||
167 | set_irq_chip_and_handler_name(i, &intc_dev, | ||
168 | handle_level_irq, intc_dev.name); | ||
169 | irq_desc[i].status |= IRQ_LEVEL; | ||
170 | } | ||
171 | } | ||
172 | } | ||
diff --git a/arch/microblaze/kernel/irq.c b/arch/microblaze/kernel/irq.c new file mode 100644 index 000000000000..f688ee93e3b9 --- /dev/null +++ b/arch/microblaze/kernel/irq.c | |||
@@ -0,0 +1,104 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> | ||
3 | * Copyright (C) 2007-2009 PetaLogix | ||
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 | */ | ||
10 | |||
11 | #include <linux/init.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/hardirq.h> | ||
14 | #include <linux/interrupt.h> | ||
15 | #include <linux/irqflags.h> | ||
16 | #include <linux/seq_file.h> | ||
17 | #include <linux/kernel_stat.h> | ||
18 | #include <linux/irq.h> | ||
19 | |||
20 | #include <asm/prom.h> | ||
21 | |||
22 | unsigned int irq_of_parse_and_map(struct device_node *dev, int index) | ||
23 | { | ||
24 | struct of_irq oirq; | ||
25 | |||
26 | if (of_irq_map_one(dev, index, &oirq)) | ||
27 | return NO_IRQ; | ||
28 | |||
29 | return oirq.specifier[0]; | ||
30 | } | ||
31 | EXPORT_SYMBOL_GPL(irq_of_parse_and_map); | ||
32 | |||
33 | /* | ||
34 | * 'what should we do if we get a hw irq event on an illegal vector'. | ||
35 | * each architecture has to answer this themselves. | ||
36 | */ | ||
37 | void ack_bad_irq(unsigned int irq) | ||
38 | { | ||
39 | printk(KERN_WARNING "unexpected IRQ trap at vector %02x\n", irq); | ||
40 | } | ||
41 | |||
42 | static u32 concurrent_irq; | ||
43 | |||
44 | void do_IRQ(struct pt_regs *regs) | ||
45 | { | ||
46 | unsigned int irq; | ||
47 | struct pt_regs *old_regs = set_irq_regs(regs); | ||
48 | |||
49 | irq_enter(); | ||
50 | irq = get_irq(regs); | ||
51 | next_irq: | ||
52 | BUG_ON(irq == -1U); | ||
53 | generic_handle_irq(irq); | ||
54 | |||
55 | irq = get_irq(regs); | ||
56 | if (irq != -1U) { | ||
57 | pr_debug("next irq: %d\n", irq); | ||
58 | ++concurrent_irq; | ||
59 | goto next_irq; | ||
60 | } | ||
61 | |||
62 | irq_exit(); | ||
63 | set_irq_regs(old_regs); | ||
64 | } | ||
65 | |||
66 | int show_interrupts(struct seq_file *p, void *v) | ||
67 | { | ||
68 | int i = *(loff_t *) v, j; | ||
69 | struct irqaction *action; | ||
70 | unsigned long flags; | ||
71 | |||
72 | if (i == 0) { | ||
73 | seq_printf(p, " "); | ||
74 | for_each_online_cpu(j) | ||
75 | seq_printf(p, "CPU%-8d", j); | ||
76 | seq_putc(p, '\n'); | ||
77 | } | ||
78 | |||
79 | if (i < nr_irq) { | ||
80 | spin_lock_irqsave(&irq_desc[i].lock, flags); | ||
81 | action = irq_desc[i].action; | ||
82 | if (!action) | ||
83 | goto skip; | ||
84 | seq_printf(p, "%3d: ", i); | ||
85 | #ifndef CONFIG_SMP | ||
86 | seq_printf(p, "%10u ", kstat_irqs(i)); | ||
87 | #else | ||
88 | for_each_online_cpu(j) | ||
89 | seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); | ||
90 | #endif | ||
91 | seq_printf(p, " %8s", irq_desc[i].status & | ||
92 | IRQ_LEVEL ? "level" : "edge"); | ||
93 | seq_printf(p, " %8s", irq_desc[i].chip->name); | ||
94 | seq_printf(p, " %s", action->name); | ||
95 | |||
96 | for (action = action->next; action; action = action->next) | ||
97 | seq_printf(p, ", %s", action->name); | ||
98 | |||
99 | seq_putc(p, '\n'); | ||
100 | skip: | ||
101 | spin_unlock_irqrestore(&irq_desc[i].lock, flags); | ||
102 | } | ||
103 | return 0; | ||
104 | } | ||
diff --git a/arch/microblaze/kernel/microblaze_ksyms.c b/arch/microblaze/kernel/microblaze_ksyms.c new file mode 100644 index 000000000000..5f71790e3c3c --- /dev/null +++ b/arch/microblaze/kernel/microblaze_ksyms.c | |||
@@ -0,0 +1,47 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu> | ||
3 | * Copyright (C) 2008-2009 PetaLogix | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | */ | ||
9 | |||
10 | #include <linux/module.h> | ||
11 | #include <linux/string.h> | ||
12 | #include <linux/cryptohash.h> | ||
13 | #include <linux/delay.h> | ||
14 | #include <linux/in6.h> | ||
15 | #include <linux/syscalls.h> | ||
16 | |||
17 | #include <asm/checksum.h> | ||
18 | #include <linux/io.h> | ||
19 | #include <asm/page.h> | ||
20 | #include <asm/system.h> | ||
21 | #include <linux/uaccess.h> | ||
22 | |||
23 | /* | ||
24 | * libgcc functions - functions that are used internally by the | ||
25 | * compiler... (prototypes are not correct though, but that | ||
26 | * doesn't really matter since they're not versioned). | ||
27 | */ | ||
28 | extern void __ashldi3(void); | ||
29 | EXPORT_SYMBOL(__ashldi3); | ||
30 | extern void __ashrdi3(void); | ||
31 | EXPORT_SYMBOL(__ashrdi3); | ||
32 | extern void __divsi3(void); | ||
33 | EXPORT_SYMBOL(__divsi3); | ||
34 | extern void __lshrdi3(void); | ||
35 | EXPORT_SYMBOL(__lshrdi3); | ||
36 | extern void __modsi3(void); | ||
37 | EXPORT_SYMBOL(__modsi3); | ||
38 | extern void __mulsi3(void); | ||
39 | EXPORT_SYMBOL(__mulsi3); | ||
40 | extern void __muldi3(void); | ||
41 | EXPORT_SYMBOL(__muldi3); | ||
42 | extern void __ucmpdi2(void); | ||
43 | EXPORT_SYMBOL(__ucmpdi2); | ||
44 | extern void __udivsi3(void); | ||
45 | EXPORT_SYMBOL(__udivsi3); | ||
46 | extern void __umodsi3(void); | ||
47 | EXPORT_SYMBOL(__umodsi3); | ||
diff --git a/arch/microblaze/kernel/module.c b/arch/microblaze/kernel/module.c new file mode 100644 index 000000000000..51414171326f --- /dev/null +++ b/arch/microblaze/kernel/module.c | |||
@@ -0,0 +1,151 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> | ||
3 | * Copyright (C) 2007-2009 PetaLogix | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | */ | ||
9 | |||
10 | #include <linux/module.h> | ||
11 | #include <linux/moduleloader.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/elf.h> | ||
14 | #include <linux/vmalloc.h> | ||
15 | #include <linux/slab.h> | ||
16 | #include <linux/fs.h> | ||
17 | #include <linux/string.h> | ||
18 | |||
19 | #include <asm/pgtable.h> | ||
20 | |||
21 | void *module_alloc(unsigned long size) | ||
22 | { | ||
23 | void *ret; | ||
24 | ret = (size == 0) ? NULL : vmalloc(size); | ||
25 | pr_debug("module_alloc (%08lx@%08lx)\n", size, (unsigned long int)ret); | ||
26 | return ret; | ||
27 | } | ||
28 | |||
29 | void module_free(struct module *module, void *region) | ||
30 | { | ||
31 | pr_debug("module_free(%s,%08lx)\n", module->name, | ||
32 | (unsigned long)region); | ||
33 | vfree(region); | ||
34 | } | ||
35 | |||
36 | int module_frob_arch_sections(Elf_Ehdr *hdr, | ||
37 | Elf_Shdr *sechdrs, | ||
38 | char *secstrings, | ||
39 | struct module *mod) | ||
40 | { | ||
41 | return 0; | ||
42 | } | ||
43 | |||
44 | int apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, | ||
45 | unsigned int symindex, unsigned int relsec, struct module *module) | ||
46 | { | ||
47 | printk(KERN_ERR "module %s: ADD RELOCATION unsupported\n", | ||
48 | module->name); | ||
49 | return -ENOEXEC; | ||
50 | } | ||
51 | |||
52 | int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab, | ||
53 | unsigned int symindex, unsigned int relsec, struct module *module) | ||
54 | { | ||
55 | |||
56 | unsigned int i; | ||
57 | Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr; | ||
58 | Elf32_Sym *sym; | ||
59 | unsigned long int *location; | ||
60 | unsigned long int locoffs; | ||
61 | unsigned long int value; | ||
62 | #if __GNUC__ < 4 | ||
63 | unsigned long int old_value; | ||
64 | #endif | ||
65 | |||
66 | pr_debug("Applying add relocation section %u to %u\n", | ||
67 | relsec, sechdrs[relsec].sh_info); | ||
68 | |||
69 | for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rela); i++) { | ||
70 | |||
71 | location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + | ||
72 | rela[i].r_offset; | ||
73 | sym = (Elf32_Sym *)sechdrs[symindex].sh_addr + | ||
74 | ELF32_R_SYM(rela[i].r_info); | ||
75 | value = sym->st_value + rela[i].r_addend; | ||
76 | |||
77 | switch (ELF32_R_TYPE(rela[i].r_info)) { | ||
78 | |||
79 | /* | ||
80 | * Be careful! mb-gcc / mb-ld splits the relocs between the | ||
81 | * text and the reloc table. In general this means we must | ||
82 | * read the current contents of (*location), add any offset | ||
83 | * then store the result back in | ||
84 | */ | ||
85 | |||
86 | case R_MICROBLAZE_32: | ||
87 | #if __GNUC__ < 4 | ||
88 | old_value = *location; | ||
89 | *location = value + old_value; | ||
90 | |||
91 | pr_debug("R_MICROBLAZE_32 (%08lx->%08lx)\n", | ||
92 | old_value, value); | ||
93 | #else | ||
94 | *location = value; | ||
95 | #endif | ||
96 | break; | ||
97 | |||
98 | case R_MICROBLAZE_64: | ||
99 | #if __GNUC__ < 4 | ||
100 | /* Split relocs only required/used pre gcc4.1.1 */ | ||
101 | old_value = ((location[0] & 0x0000FFFF) << 16) | | ||
102 | (location[1] & 0x0000FFFF); | ||
103 | value += old_value; | ||
104 | #endif | ||
105 | location[0] = (location[0] & 0xFFFF0000) | | ||
106 | (value >> 16); | ||
107 | location[1] = (location[1] & 0xFFFF0000) | | ||
108 | (value & 0xFFFF); | ||
109 | #if __GNUC__ < 4 | ||
110 | pr_debug("R_MICROBLAZE_64 (%08lx->%08lx)\n", | ||
111 | old_value, value); | ||
112 | #endif | ||
113 | break; | ||
114 | |||
115 | case R_MICROBLAZE_64_PCREL: | ||
116 | locoffs = (location[0] & 0xFFFF) << 16 | | ||
117 | (location[1] & 0xFFFF); | ||
118 | value -= (unsigned long int)(location) + 4 + | ||
119 | locoffs; | ||
120 | location[0] = (location[0] & 0xFFFF0000) | | ||
121 | (value >> 16); | ||
122 | location[1] = (location[1] & 0xFFFF0000) | | ||
123 | (value & 0xFFFF); | ||
124 | pr_debug("R_MICROBLAZE_64_PCREL (%08lx)\n", | ||
125 | value); | ||
126 | break; | ||
127 | |||
128 | case R_MICROBLAZE_NONE: | ||
129 | pr_debug("R_MICROBLAZE_NONE\n"); | ||
130 | break; | ||
131 | |||
132 | default: | ||
133 | printk(KERN_ERR "module %s: " | ||
134 | "Unknown relocation: %u\n", | ||
135 | module->name, | ||
136 | ELF32_R_TYPE(rela->r_info)); | ||
137 | return -ENOEXEC; | ||
138 | } | ||
139 | } | ||
140 | return 0; | ||
141 | } | ||
142 | |||
143 | int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs, | ||
144 | struct module *module) | ||
145 | { | ||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | void module_arch_cleanup(struct module *mod) | ||
150 | { | ||
151 | } | ||
diff --git a/arch/microblaze/kernel/of_device.c b/arch/microblaze/kernel/of_device.c new file mode 100644 index 000000000000..717edf4ad0b4 --- /dev/null +++ b/arch/microblaze/kernel/of_device.c | |||
@@ -0,0 +1,115 @@ | |||
1 | #include <linux/string.h> | ||
2 | #include <linux/kernel.h> | ||
3 | #include <linux/of.h> | ||
4 | #include <linux/init.h> | ||
5 | #include <linux/module.h> | ||
6 | #include <linux/mod_devicetable.h> | ||
7 | #include <linux/slab.h> | ||
8 | #include <linux/of_device.h> | ||
9 | |||
10 | #include <linux/errno.h> | ||
11 | |||
12 | void of_device_make_bus_id(struct of_device *dev) | ||
13 | { | ||
14 | static atomic_t bus_no_reg_magic; | ||
15 | struct device_node *node = dev->node; | ||
16 | char *name = dev->dev.bus_id; | ||
17 | const u32 *reg; | ||
18 | u64 addr; | ||
19 | int magic; | ||
20 | |||
21 | /* | ||
22 | * For MMIO, get the physical address | ||
23 | */ | ||
24 | reg = of_get_property(node, "reg", NULL); | ||
25 | if (reg) { | ||
26 | addr = of_translate_address(node, reg); | ||
27 | if (addr != OF_BAD_ADDR) { | ||
28 | snprintf(name, BUS_ID_SIZE, | ||
29 | "%llx.%s", (unsigned long long)addr, | ||
30 | node->name); | ||
31 | return; | ||
32 | } | ||
33 | } | ||
34 | |||
35 | /* | ||
36 | * No BusID, use the node name and add a globally incremented | ||
37 | * counter (and pray...) | ||
38 | */ | ||
39 | magic = atomic_add_return(1, &bus_no_reg_magic); | ||
40 | snprintf(name, BUS_ID_SIZE, "%s.%d", node->name, magic - 1); | ||
41 | } | ||
42 | EXPORT_SYMBOL(of_device_make_bus_id); | ||
43 | |||
44 | struct of_device *of_device_alloc(struct device_node *np, | ||
45 | const char *bus_id, | ||
46 | struct device *parent) | ||
47 | { | ||
48 | struct of_device *dev; | ||
49 | |||
50 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
51 | if (!dev) | ||
52 | return NULL; | ||
53 | |||
54 | dev->node = of_node_get(np); | ||
55 | dev->dev.dma_mask = &dev->dma_mask; | ||
56 | dev->dev.parent = parent; | ||
57 | dev->dev.release = of_release_dev; | ||
58 | dev->dev.archdata.of_node = np; | ||
59 | |||
60 | if (bus_id) | ||
61 | strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE); | ||
62 | else | ||
63 | of_device_make_bus_id(dev); | ||
64 | |||
65 | return dev; | ||
66 | } | ||
67 | EXPORT_SYMBOL(of_device_alloc); | ||
68 | |||
69 | int of_device_uevent(struct device *dev, struct kobj_uevent_env *env) | ||
70 | { | ||
71 | struct of_device *ofdev; | ||
72 | const char *compat; | ||
73 | int seen = 0, cplen, sl; | ||
74 | |||
75 | if (!dev) | ||
76 | return -ENODEV; | ||
77 | |||
78 | ofdev = to_of_device(dev); | ||
79 | |||
80 | if (add_uevent_var(env, "OF_NAME=%s", ofdev->node->name)) | ||
81 | return -ENOMEM; | ||
82 | |||
83 | if (add_uevent_var(env, "OF_TYPE=%s", ofdev->node->type)) | ||
84 | return -ENOMEM; | ||
85 | |||
86 | /* Since the compatible field can contain pretty much anything | ||
87 | * it's not really legal to split it out with commas. We split it | ||
88 | * up using a number of environment variables instead. */ | ||
89 | |||
90 | compat = of_get_property(ofdev->node, "compatible", &cplen); | ||
91 | while (compat && *compat && cplen > 0) { | ||
92 | if (add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat)) | ||
93 | return -ENOMEM; | ||
94 | |||
95 | sl = strlen(compat) + 1; | ||
96 | compat += sl; | ||
97 | cplen -= sl; | ||
98 | seen++; | ||
99 | } | ||
100 | |||
101 | if (add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen)) | ||
102 | return -ENOMEM; | ||
103 | |||
104 | /* modalias is trickier, we add it in 2 steps */ | ||
105 | if (add_uevent_var(env, "MODALIAS=")) | ||
106 | return -ENOMEM; | ||
107 | sl = of_device_get_modalias(ofdev, &env->buf[env->buflen-1], | ||
108 | sizeof(env->buf) - env->buflen); | ||
109 | if (sl >= (sizeof(env->buf) - env->buflen)) | ||
110 | return -ENOMEM; | ||
111 | env->buflen += sl; | ||
112 | |||
113 | return 0; | ||
114 | } | ||
115 | EXPORT_SYMBOL(of_device_uevent); | ||
diff --git a/arch/microblaze/kernel/of_platform.c b/arch/microblaze/kernel/of_platform.c new file mode 100644 index 000000000000..acf4574d0f18 --- /dev/null +++ b/arch/microblaze/kernel/of_platform.c | |||
@@ -0,0 +1,201 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp. | ||
3 | * <benh@kernel.crashing.org> | ||
4 | * and Arnd Bergmann, IBM Corp. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | * | ||
11 | */ | ||
12 | |||
13 | #undef DEBUG | ||
14 | |||
15 | #include <linux/string.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/mod_devicetable.h> | ||
20 | #include <linux/slab.h> | ||
21 | #include <linux/pci.h> | ||
22 | #include <linux/of.h> | ||
23 | #include <linux/of_device.h> | ||
24 | #include <linux/of_platform.h> | ||
25 | |||
26 | #include <linux/errno.h> | ||
27 | #include <linux/topology.h> | ||
28 | #include <asm/atomic.h> | ||
29 | |||
30 | struct bus_type of_platform_bus_type = { | ||
31 | .uevent = of_device_uevent, | ||
32 | }; | ||
33 | EXPORT_SYMBOL(of_platform_bus_type); | ||
34 | |||
35 | static int __init of_bus_driver_init(void) | ||
36 | { | ||
37 | return of_bus_type_init(&of_platform_bus_type, "of_platform"); | ||
38 | } | ||
39 | postcore_initcall(of_bus_driver_init); | ||
40 | |||
41 | struct of_device *of_platform_device_create(struct device_node *np, | ||
42 | const char *bus_id, | ||
43 | struct device *parent) | ||
44 | { | ||
45 | struct of_device *dev; | ||
46 | |||
47 | dev = of_device_alloc(np, bus_id, parent); | ||
48 | if (!dev) | ||
49 | return NULL; | ||
50 | |||
51 | dev->dma_mask = 0xffffffffUL; | ||
52 | dev->dev.bus = &of_platform_bus_type; | ||
53 | |||
54 | /* We do not fill the DMA ops for platform devices by default. | ||
55 | * This is currently the responsibility of the platform code | ||
56 | * to do such, possibly using a device notifier | ||
57 | */ | ||
58 | |||
59 | if (of_device_register(dev) != 0) { | ||
60 | of_device_free(dev); | ||
61 | return NULL; | ||
62 | } | ||
63 | |||
64 | return dev; | ||
65 | } | ||
66 | EXPORT_SYMBOL(of_platform_device_create); | ||
67 | |||
68 | /** | ||
69 | * of_platform_bus_create - Create an OF device for a bus node and all its | ||
70 | * children. Optionally recursively instanciate matching busses. | ||
71 | * @bus: device node of the bus to instanciate | ||
72 | * @matches: match table, NULL to use the default, OF_NO_DEEP_PROBE to | ||
73 | * disallow recursive creation of child busses | ||
74 | */ | ||
75 | static int of_platform_bus_create(const struct device_node *bus, | ||
76 | const struct of_device_id *matches, | ||
77 | struct device *parent) | ||
78 | { | ||
79 | struct device_node *child; | ||
80 | struct of_device *dev; | ||
81 | int rc = 0; | ||
82 | |||
83 | for_each_child_of_node(bus, child) { | ||
84 | pr_debug(" create child: %s\n", child->full_name); | ||
85 | dev = of_platform_device_create(child, NULL, parent); | ||
86 | if (dev == NULL) | ||
87 | rc = -ENOMEM; | ||
88 | else if (!of_match_node(matches, child)) | ||
89 | continue; | ||
90 | if (rc == 0) { | ||
91 | pr_debug(" and sub busses\n"); | ||
92 | rc = of_platform_bus_create(child, matches, &dev->dev); | ||
93 | } | ||
94 | if (rc) { | ||
95 | of_node_put(child); | ||
96 | break; | ||
97 | } | ||
98 | } | ||
99 | return rc; | ||
100 | } | ||
101 | |||
102 | |||
103 | /** | ||
104 | * of_platform_bus_probe - Probe the device-tree for platform busses | ||
105 | * @root: parent of the first level to probe or NULL for the root of the tree | ||
106 | * @matches: match table, NULL to use the default | ||
107 | * @parent: parent to hook devices from, NULL for toplevel | ||
108 | * | ||
109 | * Note that children of the provided root are not instanciated as devices | ||
110 | * unless the specified root itself matches the bus list and is not NULL. | ||
111 | */ | ||
112 | |||
113 | int of_platform_bus_probe(struct device_node *root, | ||
114 | const struct of_device_id *matches, | ||
115 | struct device *parent) | ||
116 | { | ||
117 | struct device_node *child; | ||
118 | struct of_device *dev; | ||
119 | int rc = 0; | ||
120 | |||
121 | if (matches == NULL) | ||
122 | matches = of_default_bus_ids; | ||
123 | if (matches == OF_NO_DEEP_PROBE) | ||
124 | return -EINVAL; | ||
125 | if (root == NULL) | ||
126 | root = of_find_node_by_path("/"); | ||
127 | else | ||
128 | of_node_get(root); | ||
129 | |||
130 | pr_debug("of_platform_bus_probe()\n"); | ||
131 | pr_debug(" starting at: %s\n", root->full_name); | ||
132 | |||
133 | /* Do a self check of bus type, if there's a match, create | ||
134 | * children | ||
135 | */ | ||
136 | if (of_match_node(matches, root)) { | ||
137 | pr_debug(" root match, create all sub devices\n"); | ||
138 | dev = of_platform_device_create(root, NULL, parent); | ||
139 | if (dev == NULL) { | ||
140 | rc = -ENOMEM; | ||
141 | goto bail; | ||
142 | } | ||
143 | pr_debug(" create all sub busses\n"); | ||
144 | rc = of_platform_bus_create(root, matches, &dev->dev); | ||
145 | goto bail; | ||
146 | } | ||
147 | for_each_child_of_node(root, child) { | ||
148 | if (!of_match_node(matches, child)) | ||
149 | continue; | ||
150 | |||
151 | pr_debug(" match: %s\n", child->full_name); | ||
152 | dev = of_platform_device_create(child, NULL, parent); | ||
153 | if (dev == NULL) | ||
154 | rc = -ENOMEM; | ||
155 | else | ||
156 | rc = of_platform_bus_create(child, matches, &dev->dev); | ||
157 | if (rc) { | ||
158 | of_node_put(child); | ||
159 | break; | ||
160 | } | ||
161 | } | ||
162 | bail: | ||
163 | of_node_put(root); | ||
164 | return rc; | ||
165 | } | ||
166 | EXPORT_SYMBOL(of_platform_bus_probe); | ||
167 | |||
168 | static int of_dev_node_match(struct device *dev, void *data) | ||
169 | { | ||
170 | return to_of_device(dev)->node == data; | ||
171 | } | ||
172 | |||
173 | struct of_device *of_find_device_by_node(struct device_node *np) | ||
174 | { | ||
175 | struct device *dev; | ||
176 | |||
177 | dev = bus_find_device(&of_platform_bus_type, | ||
178 | NULL, np, of_dev_node_match); | ||
179 | if (dev) | ||
180 | return to_of_device(dev); | ||
181 | return NULL; | ||
182 | } | ||
183 | EXPORT_SYMBOL(of_find_device_by_node); | ||
184 | |||
185 | static int of_dev_phandle_match(struct device *dev, void *data) | ||
186 | { | ||
187 | phandle *ph = data; | ||
188 | return to_of_device(dev)->node->linux_phandle == *ph; | ||
189 | } | ||
190 | |||
191 | struct of_device *of_find_device_by_phandle(phandle ph) | ||
192 | { | ||
193 | struct device *dev; | ||
194 | |||
195 | dev = bus_find_device(&of_platform_bus_type, | ||
196 | NULL, &ph, of_dev_phandle_match); | ||
197 | if (dev) | ||
198 | return to_of_device(dev); | ||
199 | return NULL; | ||
200 | } | ||
201 | EXPORT_SYMBOL(of_find_device_by_phandle); | ||
diff --git a/arch/microblaze/kernel/process.c b/arch/microblaze/kernel/process.c new file mode 100644 index 000000000000..60e9ed7d3132 --- /dev/null +++ b/arch/microblaze/kernel/process.c | |||
@@ -0,0 +1,187 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu> | ||
3 | * Copyright (C) 2008-2009 PetaLogix | ||
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 | */ | ||
10 | |||
11 | #include <linux/module.h> | ||
12 | #include <linux/sched.h> | ||
13 | #include <linux/pm.h> | ||
14 | #include <linux/tick.h> | ||
15 | #include <linux/bitops.h> | ||
16 | #include <asm/system.h> | ||
17 | #include <asm/pgalloc.h> | ||
18 | |||
19 | void show_regs(struct pt_regs *regs) | ||
20 | { | ||
21 | printk(KERN_INFO " Registers dump: mode=%X\r\n", regs->kernel_mode); | ||
22 | printk(KERN_INFO " r1=%08lX, r2=%08lX, r3=%08lX, r4=%08lX\n", | ||
23 | regs->r1, regs->r2, regs->r3, regs->r4); | ||
24 | printk(KERN_INFO " r5=%08lX, r6=%08lX, r7=%08lX, r8=%08lX\n", | ||
25 | regs->r5, regs->r6, regs->r7, regs->r8); | ||
26 | printk(KERN_INFO " r9=%08lX, r10=%08lX, r11=%08lX, r12=%08lX\n", | ||
27 | regs->r9, regs->r10, regs->r11, regs->r12); | ||
28 | printk(KERN_INFO " r13=%08lX, r14=%08lX, r15=%08lX, r16=%08lX\n", | ||
29 | regs->r13, regs->r14, regs->r15, regs->r16); | ||
30 | printk(KERN_INFO " r17=%08lX, r18=%08lX, r19=%08lX, r20=%08lX\n", | ||
31 | regs->r17, regs->r18, regs->r19, regs->r20); | ||
32 | printk(KERN_INFO " r21=%08lX, r22=%08lX, r23=%08lX, r24=%08lX\n", | ||
33 | regs->r21, regs->r22, regs->r23, regs->r24); | ||
34 | printk(KERN_INFO " r25=%08lX, r26=%08lX, r27=%08lX, r28=%08lX\n", | ||
35 | regs->r25, regs->r26, regs->r27, regs->r28); | ||
36 | printk(KERN_INFO " r29=%08lX, r30=%08lX, r31=%08lX, rPC=%08lX\n", | ||
37 | regs->r29, regs->r30, regs->r31, regs->pc); | ||
38 | printk(KERN_INFO " msr=%08lX, ear=%08lX, esr=%08lX, fsr=%08lX\n", | ||
39 | regs->msr, regs->ear, regs->esr, regs->fsr); | ||
40 | while (1) | ||
41 | ; | ||
42 | } | ||
43 | |||
44 | void (*pm_idle)(void); | ||
45 | void (*pm_power_off)(void) = NULL; | ||
46 | EXPORT_SYMBOL(pm_power_off); | ||
47 | |||
48 | static int hlt_counter = 1; | ||
49 | |||
50 | void disable_hlt(void) | ||
51 | { | ||
52 | hlt_counter++; | ||
53 | } | ||
54 | EXPORT_SYMBOL(disable_hlt); | ||
55 | |||
56 | void enable_hlt(void) | ||
57 | { | ||
58 | hlt_counter--; | ||
59 | } | ||
60 | EXPORT_SYMBOL(enable_hlt); | ||
61 | |||
62 | static int __init nohlt_setup(char *__unused) | ||
63 | { | ||
64 | hlt_counter = 1; | ||
65 | return 1; | ||
66 | } | ||
67 | __setup("nohlt", nohlt_setup); | ||
68 | |||
69 | static int __init hlt_setup(char *__unused) | ||
70 | { | ||
71 | hlt_counter = 0; | ||
72 | return 1; | ||
73 | } | ||
74 | __setup("hlt", hlt_setup); | ||
75 | |||
76 | void default_idle(void) | ||
77 | { | ||
78 | if (!hlt_counter) { | ||
79 | clear_thread_flag(TIF_POLLING_NRFLAG); | ||
80 | smp_mb__after_clear_bit(); | ||
81 | local_irq_disable(); | ||
82 | while (!need_resched()) | ||
83 | cpu_sleep(); | ||
84 | local_irq_enable(); | ||
85 | set_thread_flag(TIF_POLLING_NRFLAG); | ||
86 | } else | ||
87 | while (!need_resched()) | ||
88 | cpu_relax(); | ||
89 | } | ||
90 | |||
91 | void cpu_idle(void) | ||
92 | { | ||
93 | set_thread_flag(TIF_POLLING_NRFLAG); | ||
94 | |||
95 | /* endless idle loop with no priority at all */ | ||
96 | while (1) { | ||
97 | void (*idle)(void) = pm_idle; | ||
98 | |||
99 | if (!idle) | ||
100 | idle = default_idle; | ||
101 | |||
102 | tick_nohz_stop_sched_tick(1); | ||
103 | while (!need_resched()) | ||
104 | idle(); | ||
105 | tick_nohz_restart_sched_tick(); | ||
106 | |||
107 | preempt_enable_no_resched(); | ||
108 | schedule(); | ||
109 | preempt_disable(); | ||
110 | check_pgt_cache(); | ||
111 | } | ||
112 | } | ||
113 | |||
114 | void flush_thread(void) | ||
115 | { | ||
116 | } | ||
117 | |||
118 | /* FIXME - here will be a proposed change -> remove nr parameter */ | ||
119 | int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, | ||
120 | unsigned long unused, | ||
121 | struct task_struct *p, struct pt_regs *regs) | ||
122 | { | ||
123 | struct pt_regs *childregs = task_pt_regs(p); | ||
124 | struct thread_info *ti = task_thread_info(p); | ||
125 | |||
126 | *childregs = *regs; | ||
127 | if (user_mode(regs)) | ||
128 | childregs->r1 = usp; | ||
129 | else | ||
130 | childregs->r1 = ((unsigned long) ti) + THREAD_SIZE; | ||
131 | |||
132 | memset(&ti->cpu_context, 0, sizeof(struct cpu_context)); | ||
133 | ti->cpu_context.r1 = (unsigned long)childregs; | ||
134 | ti->cpu_context.msr = (unsigned long)childregs->msr; | ||
135 | ti->cpu_context.r15 = (unsigned long)ret_from_fork - 8; | ||
136 | |||
137 | if (clone_flags & CLONE_SETTLS) | ||
138 | ; | ||
139 | |||
140 | return 0; | ||
141 | } | ||
142 | |||
143 | /* | ||
144 | * Return saved PC of a blocked thread. | ||
145 | */ | ||
146 | unsigned long thread_saved_pc(struct task_struct *tsk) | ||
147 | { | ||
148 | struct cpu_context *ctx = | ||
149 | &(((struct thread_info *)(tsk->stack))->cpu_context); | ||
150 | |||
151 | /* Check whether the thread is blocked in resume() */ | ||
152 | if (in_sched_functions(ctx->r15)) | ||
153 | return (unsigned long)ctx->r15; | ||
154 | else | ||
155 | return ctx->r14; | ||
156 | } | ||
157 | |||
158 | static void kernel_thread_helper(int (*fn)(void *), void *arg) | ||
159 | { | ||
160 | fn(arg); | ||
161 | do_exit(-1); | ||
162 | } | ||
163 | |||
164 | int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) | ||
165 | { | ||
166 | struct pt_regs regs; | ||
167 | int ret; | ||
168 | |||
169 | memset(®s, 0, sizeof(regs)); | ||
170 | /* store them in non-volatile registers */ | ||
171 | regs.r5 = (unsigned long)fn; | ||
172 | regs.r6 = (unsigned long)arg; | ||
173 | local_save_flags(regs.msr); | ||
174 | regs.pc = (unsigned long)kernel_thread_helper; | ||
175 | regs.kernel_mode = 1; | ||
176 | |||
177 | ret = do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, | ||
178 | ®s, 0, NULL, NULL); | ||
179 | |||
180 | return ret; | ||
181 | } | ||
182 | |||
183 | unsigned long get_wchan(struct task_struct *p) | ||
184 | { | ||
185 | /* TBD (used by procfs) */ | ||
186 | return 0; | ||
187 | } | ||
diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c new file mode 100644 index 000000000000..475b1fac5cfd --- /dev/null +++ b/arch/microblaze/kernel/prom.c | |||
@@ -0,0 +1,1147 @@ | |||
1 | /* | ||
2 | * Procedures for creating, accessing and interpreting the device tree. | ||
3 | * | ||
4 | * Paul Mackerras August 1996. | ||
5 | * Copyright (C) 1996-2005 Paul Mackerras. | ||
6 | * | ||
7 | * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner. | ||
8 | * {engebret|bergner}@us.ibm.com | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or | ||
11 | * modify it under the terms of the GNU General Public License | ||
12 | * as published by the Free Software Foundation; either version | ||
13 | * 2 of the License, or (at your option) any later version. | ||
14 | */ | ||
15 | |||
16 | #include <stdarg.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/string.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/threads.h> | ||
21 | #include <linux/spinlock.h> | ||
22 | #include <linux/types.h> | ||
23 | #include <linux/pci.h> | ||
24 | #include <linux/stringify.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <linux/initrd.h> | ||
27 | #include <linux/bitops.h> | ||
28 | #include <linux/module.h> | ||
29 | #include <linux/kexec.h> | ||
30 | #include <linux/debugfs.h> | ||
31 | #include <linux/irq.h> | ||
32 | #include <linux/lmb.h> | ||
33 | |||
34 | #include <asm/prom.h> | ||
35 | #include <asm/page.h> | ||
36 | #include <asm/processor.h> | ||
37 | #include <asm/irq.h> | ||
38 | #include <linux/io.h> | ||
39 | #include <asm/system.h> | ||
40 | #include <asm/mmu.h> | ||
41 | #include <asm/pgtable.h> | ||
42 | #include <linux/pci.h> | ||
43 | #include <asm/sections.h> | ||
44 | #include <asm/pci-bridge.h> | ||
45 | |||
46 | static int __initdata dt_root_addr_cells; | ||
47 | static int __initdata dt_root_size_cells; | ||
48 | |||
49 | typedef u32 cell_t; | ||
50 | |||
51 | static struct boot_param_header *initial_boot_params; | ||
52 | |||
53 | /* export that to outside world */ | ||
54 | struct device_node *of_chosen; | ||
55 | |||
56 | static inline char *find_flat_dt_string(u32 offset) | ||
57 | { | ||
58 | return ((char *)initial_boot_params) + | ||
59 | initial_boot_params->off_dt_strings + offset; | ||
60 | } | ||
61 | |||
62 | /** | ||
63 | * This function is used to scan the flattened device-tree, it is | ||
64 | * used to extract the memory informations at boot before we can | ||
65 | * unflatten the tree | ||
66 | */ | ||
67 | int __init of_scan_flat_dt(int (*it)(unsigned long node, | ||
68 | const char *uname, int depth, | ||
69 | void *data), | ||
70 | void *data) | ||
71 | { | ||
72 | unsigned long p = ((unsigned long)initial_boot_params) + | ||
73 | initial_boot_params->off_dt_struct; | ||
74 | int rc = 0; | ||
75 | int depth = -1; | ||
76 | |||
77 | do { | ||
78 | u32 tag = *((u32 *)p); | ||
79 | char *pathp; | ||
80 | |||
81 | p += 4; | ||
82 | if (tag == OF_DT_END_NODE) { | ||
83 | depth--; | ||
84 | continue; | ||
85 | } | ||
86 | if (tag == OF_DT_NOP) | ||
87 | continue; | ||
88 | if (tag == OF_DT_END) | ||
89 | break; | ||
90 | if (tag == OF_DT_PROP) { | ||
91 | u32 sz = *((u32 *)p); | ||
92 | p += 8; | ||
93 | if (initial_boot_params->version < 0x10) | ||
94 | p = _ALIGN(p, sz >= 8 ? 8 : 4); | ||
95 | p += sz; | ||
96 | p = _ALIGN(p, 4); | ||
97 | continue; | ||
98 | } | ||
99 | if (tag != OF_DT_BEGIN_NODE) { | ||
100 | printk(KERN_WARNING "Invalid tag %x scanning flattened" | ||
101 | " device tree !\n", tag); | ||
102 | return -EINVAL; | ||
103 | } | ||
104 | depth++; | ||
105 | pathp = (char *)p; | ||
106 | p = _ALIGN(p + strlen(pathp) + 1, 4); | ||
107 | if ((*pathp) == '/') { | ||
108 | char *lp, *np; | ||
109 | for (lp = NULL, np = pathp; *np; np++) | ||
110 | if ((*np) == '/') | ||
111 | lp = np+1; | ||
112 | if (lp != NULL) | ||
113 | pathp = lp; | ||
114 | } | ||
115 | rc = it(p, pathp, depth, data); | ||
116 | if (rc != 0) | ||
117 | break; | ||
118 | } while (1); | ||
119 | |||
120 | return rc; | ||
121 | } | ||
122 | |||
123 | unsigned long __init of_get_flat_dt_root(void) | ||
124 | { | ||
125 | unsigned long p = ((unsigned long)initial_boot_params) + | ||
126 | initial_boot_params->off_dt_struct; | ||
127 | |||
128 | while (*((u32 *)p) == OF_DT_NOP) | ||
129 | p += 4; | ||
130 | BUG_ON(*((u32 *)p) != OF_DT_BEGIN_NODE); | ||
131 | p += 4; | ||
132 | return _ALIGN(p + strlen((char *)p) + 1, 4); | ||
133 | } | ||
134 | |||
135 | /** | ||
136 | * This function can be used within scan_flattened_dt callback to get | ||
137 | * access to properties | ||
138 | */ | ||
139 | void *__init of_get_flat_dt_prop(unsigned long node, const char *name, | ||
140 | unsigned long *size) | ||
141 | { | ||
142 | unsigned long p = node; | ||
143 | |||
144 | do { | ||
145 | u32 tag = *((u32 *)p); | ||
146 | u32 sz, noff; | ||
147 | const char *nstr; | ||
148 | |||
149 | p += 4; | ||
150 | if (tag == OF_DT_NOP) | ||
151 | continue; | ||
152 | if (tag != OF_DT_PROP) | ||
153 | return NULL; | ||
154 | |||
155 | sz = *((u32 *)p); | ||
156 | noff = *((u32 *)(p + 4)); | ||
157 | p += 8; | ||
158 | if (initial_boot_params->version < 0x10) | ||
159 | p = _ALIGN(p, sz >= 8 ? 8 : 4); | ||
160 | |||
161 | nstr = find_flat_dt_string(noff); | ||
162 | if (nstr == NULL) { | ||
163 | printk(KERN_WARNING "Can't find property index" | ||
164 | " name !\n"); | ||
165 | return NULL; | ||
166 | } | ||
167 | if (strcmp(name, nstr) == 0) { | ||
168 | if (size) | ||
169 | *size = sz; | ||
170 | return (void *)p; | ||
171 | } | ||
172 | p += sz; | ||
173 | p = _ALIGN(p, 4); | ||
174 | } while (1); | ||
175 | } | ||
176 | |||
177 | int __init of_flat_dt_is_compatible(unsigned long node, const char *compat) | ||
178 | { | ||
179 | const char *cp; | ||
180 | unsigned long cplen, l; | ||
181 | |||
182 | cp = of_get_flat_dt_prop(node, "compatible", &cplen); | ||
183 | if (cp == NULL) | ||
184 | return 0; | ||
185 | while (cplen > 0) { | ||
186 | if (strncasecmp(cp, compat, strlen(compat)) == 0) | ||
187 | return 1; | ||
188 | l = strlen(cp) + 1; | ||
189 | cp += l; | ||
190 | cplen -= l; | ||
191 | } | ||
192 | |||
193 | return 0; | ||
194 | } | ||
195 | |||
196 | static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size, | ||
197 | unsigned long align) | ||
198 | { | ||
199 | void *res; | ||
200 | |||
201 | *mem = _ALIGN(*mem, align); | ||
202 | res = (void *)*mem; | ||
203 | *mem += size; | ||
204 | |||
205 | return res; | ||
206 | } | ||
207 | |||
208 | static unsigned long __init unflatten_dt_node(unsigned long mem, | ||
209 | unsigned long *p, | ||
210 | struct device_node *dad, | ||
211 | struct device_node ***allnextpp, | ||
212 | unsigned long fpsize) | ||
213 | { | ||
214 | struct device_node *np; | ||
215 | struct property *pp, **prev_pp = NULL; | ||
216 | char *pathp; | ||
217 | u32 tag; | ||
218 | unsigned int l, allocl; | ||
219 | int has_name = 0; | ||
220 | int new_format = 0; | ||
221 | |||
222 | tag = *((u32 *)(*p)); | ||
223 | if (tag != OF_DT_BEGIN_NODE) { | ||
224 | printk("Weird tag at start of node: %x\n", tag); | ||
225 | return mem; | ||
226 | } | ||
227 | *p += 4; | ||
228 | pathp = (char *)*p; | ||
229 | l = allocl = strlen(pathp) + 1; | ||
230 | *p = _ALIGN(*p + l, 4); | ||
231 | |||
232 | /* version 0x10 has a more compact unit name here instead of the full | ||
233 | * path. we accumulate the full path size using "fpsize", we'll rebuild | ||
234 | * it later. We detect this because the first character of the name is | ||
235 | * not '/'. | ||
236 | */ | ||
237 | if ((*pathp) != '/') { | ||
238 | new_format = 1; | ||
239 | if (fpsize == 0) { | ||
240 | /* root node: special case. fpsize accounts for path | ||
241 | * plus terminating zero. root node only has '/', so | ||
242 | * fpsize should be 2, but we want to avoid the first | ||
243 | * level nodes to have two '/' so we use fpsize 1 here | ||
244 | */ | ||
245 | fpsize = 1; | ||
246 | allocl = 2; | ||
247 | } else { | ||
248 | /* account for '/' and path size minus terminal 0 | ||
249 | * already in 'l' | ||
250 | */ | ||
251 | fpsize += l; | ||
252 | allocl = fpsize; | ||
253 | } | ||
254 | } | ||
255 | |||
256 | np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + allocl, | ||
257 | __alignof__(struct device_node)); | ||
258 | if (allnextpp) { | ||
259 | memset(np, 0, sizeof(*np)); | ||
260 | np->full_name = ((char *)np) + sizeof(struct device_node); | ||
261 | if (new_format) { | ||
262 | char *p2 = np->full_name; | ||
263 | /* rebuild full path for new format */ | ||
264 | if (dad && dad->parent) { | ||
265 | strcpy(p2, dad->full_name); | ||
266 | #ifdef DEBUG | ||
267 | if ((strlen(p2) + l + 1) != allocl) { | ||
268 | pr_debug("%s: p: %d, l: %d, a: %d\n", | ||
269 | pathp, (int)strlen(p2), | ||
270 | l, allocl); | ||
271 | } | ||
272 | #endif | ||
273 | p2 += strlen(p2); | ||
274 | } | ||
275 | *(p2++) = '/'; | ||
276 | memcpy(p2, pathp, l); | ||
277 | } else | ||
278 | memcpy(np->full_name, pathp, l); | ||
279 | prev_pp = &np->properties; | ||
280 | **allnextpp = np; | ||
281 | *allnextpp = &np->allnext; | ||
282 | if (dad != NULL) { | ||
283 | np->parent = dad; | ||
284 | /* we temporarily use the next field as `last_child'*/ | ||
285 | if (dad->next == NULL) | ||
286 | dad->child = np; | ||
287 | else | ||
288 | dad->next->sibling = np; | ||
289 | dad->next = np; | ||
290 | } | ||
291 | kref_init(&np->kref); | ||
292 | } | ||
293 | while (1) { | ||
294 | u32 sz, noff; | ||
295 | char *pname; | ||
296 | |||
297 | tag = *((u32 *)(*p)); | ||
298 | if (tag == OF_DT_NOP) { | ||
299 | *p += 4; | ||
300 | continue; | ||
301 | } | ||
302 | if (tag != OF_DT_PROP) | ||
303 | break; | ||
304 | *p += 4; | ||
305 | sz = *((u32 *)(*p)); | ||
306 | noff = *((u32 *)((*p) + 4)); | ||
307 | *p += 8; | ||
308 | if (initial_boot_params->version < 0x10) | ||
309 | *p = _ALIGN(*p, sz >= 8 ? 8 : 4); | ||
310 | |||
311 | pname = find_flat_dt_string(noff); | ||
312 | if (pname == NULL) { | ||
313 | printk(KERN_INFO | ||
314 | "Can't find property name in list !\n"); | ||
315 | break; | ||
316 | } | ||
317 | if (strcmp(pname, "name") == 0) | ||
318 | has_name = 1; | ||
319 | l = strlen(pname) + 1; | ||
320 | pp = unflatten_dt_alloc(&mem, sizeof(struct property), | ||
321 | __alignof__(struct property)); | ||
322 | if (allnextpp) { | ||
323 | if (strcmp(pname, "linux,phandle") == 0) { | ||
324 | np->node = *((u32 *)*p); | ||
325 | if (np->linux_phandle == 0) | ||
326 | np->linux_phandle = np->node; | ||
327 | } | ||
328 | if (strcmp(pname, "ibm,phandle") == 0) | ||
329 | np->linux_phandle = *((u32 *)*p); | ||
330 | pp->name = pname; | ||
331 | pp->length = sz; | ||
332 | pp->value = (void *)*p; | ||
333 | *prev_pp = pp; | ||
334 | prev_pp = &pp->next; | ||
335 | } | ||
336 | *p = _ALIGN((*p) + sz, 4); | ||
337 | } | ||
338 | /* with version 0x10 we may not have the name property, recreate | ||
339 | * it here from the unit name if absent | ||
340 | */ | ||
341 | if (!has_name) { | ||
342 | char *p1 = pathp, *ps = pathp, *pa = NULL; | ||
343 | int sz; | ||
344 | |||
345 | while (*p1) { | ||
346 | if ((*p1) == '@') | ||
347 | pa = p1; | ||
348 | if ((*p1) == '/') | ||
349 | ps = p1 + 1; | ||
350 | p1++; | ||
351 | } | ||
352 | if (pa < ps) | ||
353 | pa = p1; | ||
354 | sz = (pa - ps) + 1; | ||
355 | pp = unflatten_dt_alloc(&mem, sizeof(struct property) + sz, | ||
356 | __alignof__(struct property)); | ||
357 | if (allnextpp) { | ||
358 | pp->name = "name"; | ||
359 | pp->length = sz; | ||
360 | pp->value = pp + 1; | ||
361 | *prev_pp = pp; | ||
362 | prev_pp = &pp->next; | ||
363 | memcpy(pp->value, ps, sz - 1); | ||
364 | ((char *)pp->value)[sz - 1] = 0; | ||
365 | pr_debug("fixed up name for %s -> %s\n", pathp, | ||
366 | (char *)pp->value); | ||
367 | } | ||
368 | } | ||
369 | if (allnextpp) { | ||
370 | *prev_pp = NULL; | ||
371 | np->name = of_get_property(np, "name", NULL); | ||
372 | np->type = of_get_property(np, "device_type", NULL); | ||
373 | |||
374 | if (!np->name) | ||
375 | np->name = "<NULL>"; | ||
376 | if (!np->type) | ||
377 | np->type = "<NULL>"; | ||
378 | } | ||
379 | while (tag == OF_DT_BEGIN_NODE) { | ||
380 | mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize); | ||
381 | tag = *((u32 *)(*p)); | ||
382 | } | ||
383 | if (tag != OF_DT_END_NODE) { | ||
384 | printk(KERN_INFO "Weird tag at end of node: %x\n", tag); | ||
385 | return mem; | ||
386 | } | ||
387 | *p += 4; | ||
388 | return mem; | ||
389 | } | ||
390 | |||
391 | /** | ||
392 | * unflattens the device-tree passed by the firmware, creating the | ||
393 | * tree of struct device_node. It also fills the "name" and "type" | ||
394 | * pointers of the nodes so the normal device-tree walking functions | ||
395 | * can be used (this used to be done by finish_device_tree) | ||
396 | */ | ||
397 | void __init unflatten_device_tree(void) | ||
398 | { | ||
399 | unsigned long start, mem, size; | ||
400 | struct device_node **allnextp = &allnodes; | ||
401 | |||
402 | pr_debug(" -> unflatten_device_tree()\n"); | ||
403 | |||
404 | /* First pass, scan for size */ | ||
405 | start = ((unsigned long)initial_boot_params) + | ||
406 | initial_boot_params->off_dt_struct; | ||
407 | size = unflatten_dt_node(0, &start, NULL, NULL, 0); | ||
408 | size = (size | 3) + 1; | ||
409 | |||
410 | pr_debug(" size is %lx, allocating...\n", size); | ||
411 | |||
412 | /* Allocate memory for the expanded device tree */ | ||
413 | mem = lmb_alloc(size + 4, __alignof__(struct device_node)); | ||
414 | mem = (unsigned long) __va(mem); | ||
415 | |||
416 | ((u32 *)mem)[size / 4] = 0xdeadbeef; | ||
417 | |||
418 | pr_debug(" unflattening %lx...\n", mem); | ||
419 | |||
420 | /* Second pass, do actual unflattening */ | ||
421 | start = ((unsigned long)initial_boot_params) + | ||
422 | initial_boot_params->off_dt_struct; | ||
423 | unflatten_dt_node(mem, &start, NULL, &allnextp, 0); | ||
424 | if (*((u32 *)start) != OF_DT_END) | ||
425 | printk(KERN_WARNING "Weird tag at end of tree: %08x\n", | ||
426 | *((u32 *)start)); | ||
427 | if (((u32 *)mem)[size / 4] != 0xdeadbeef) | ||
428 | printk(KERN_WARNING "End of tree marker overwritten: %08x\n", | ||
429 | ((u32 *)mem)[size / 4]); | ||
430 | *allnextp = NULL; | ||
431 | |||
432 | /* Get pointer to OF "/chosen" node for use everywhere */ | ||
433 | of_chosen = of_find_node_by_path("/chosen"); | ||
434 | if (of_chosen == NULL) | ||
435 | of_chosen = of_find_node_by_path("/chosen@0"); | ||
436 | |||
437 | pr_debug(" <- unflatten_device_tree()\n"); | ||
438 | } | ||
439 | |||
440 | #define early_init_dt_scan_drconf_memory(node) 0 | ||
441 | |||
442 | static int __init early_init_dt_scan_cpus(unsigned long node, | ||
443 | const char *uname, int depth, | ||
444 | void *data) | ||
445 | { | ||
446 | static int logical_cpuid; | ||
447 | char *type = of_get_flat_dt_prop(node, "device_type", NULL); | ||
448 | const u32 *intserv; | ||
449 | int i, nthreads; | ||
450 | int found = 0; | ||
451 | |||
452 | /* We are scanning "cpu" nodes only */ | ||
453 | if (type == NULL || strcmp(type, "cpu") != 0) | ||
454 | return 0; | ||
455 | |||
456 | /* Get physical cpuid */ | ||
457 | intserv = of_get_flat_dt_prop(node, "reg", NULL); | ||
458 | nthreads = 1; | ||
459 | |||
460 | /* | ||
461 | * Now see if any of these threads match our boot cpu. | ||
462 | * NOTE: This must match the parsing done in smp_setup_cpu_maps. | ||
463 | */ | ||
464 | for (i = 0; i < nthreads; i++) { | ||
465 | /* | ||
466 | * version 2 of the kexec param format adds the phys cpuid of | ||
467 | * booted proc. | ||
468 | */ | ||
469 | if (initial_boot_params && initial_boot_params->version >= 2) { | ||
470 | if (intserv[i] == | ||
471 | initial_boot_params->boot_cpuid_phys) { | ||
472 | found = 1; | ||
473 | break; | ||
474 | } | ||
475 | } else { | ||
476 | /* | ||
477 | * Check if it's the boot-cpu, set it's hw index now, | ||
478 | * unfortunately this format did not support booting | ||
479 | * off secondary threads. | ||
480 | */ | ||
481 | if (of_get_flat_dt_prop(node, | ||
482 | "linux,boot-cpu", NULL) != NULL) { | ||
483 | found = 1; | ||
484 | break; | ||
485 | } | ||
486 | } | ||
487 | |||
488 | #ifdef CONFIG_SMP | ||
489 | /* logical cpu id is always 0 on UP kernels */ | ||
490 | logical_cpuid++; | ||
491 | #endif | ||
492 | } | ||
493 | |||
494 | if (found) { | ||
495 | pr_debug("boot cpu: logical %d physical %d\n", logical_cpuid, | ||
496 | intserv[i]); | ||
497 | boot_cpuid = logical_cpuid; | ||
498 | } | ||
499 | |||
500 | return 0; | ||
501 | } | ||
502 | |||
503 | #ifdef CONFIG_BLK_DEV_INITRD | ||
504 | static void __init early_init_dt_check_for_initrd(unsigned long node) | ||
505 | { | ||
506 | unsigned long l; | ||
507 | u32 *prop; | ||
508 | |||
509 | pr_debug("Looking for initrd properties... "); | ||
510 | |||
511 | prop = of_get_flat_dt_prop(node, "linux,initrd-start", &l); | ||
512 | if (prop) { | ||
513 | initrd_start = (unsigned long)__va(of_read_ulong(prop, l/4)); | ||
514 | |||
515 | prop = of_get_flat_dt_prop(node, "linux,initrd-end", &l); | ||
516 | if (prop) { | ||
517 | initrd_end = (unsigned long) | ||
518 | __va(of_read_ulong(prop, l/4)); | ||
519 | initrd_below_start_ok = 1; | ||
520 | } else { | ||
521 | initrd_start = 0; | ||
522 | } | ||
523 | } | ||
524 | |||
525 | pr_debug("initrd_start=0x%lx initrd_end=0x%lx\n", | ||
526 | initrd_start, initrd_end); | ||
527 | } | ||
528 | #else | ||
529 | static inline void early_init_dt_check_for_initrd(unsigned long node) | ||
530 | { | ||
531 | } | ||
532 | #endif /* CONFIG_BLK_DEV_INITRD */ | ||
533 | |||
534 | static int __init early_init_dt_scan_chosen(unsigned long node, | ||
535 | const char *uname, int depth, void *data) | ||
536 | { | ||
537 | unsigned long l; | ||
538 | char *p; | ||
539 | |||
540 | pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname); | ||
541 | |||
542 | if (depth != 1 || | ||
543 | (strcmp(uname, "chosen") != 0 && | ||
544 | strcmp(uname, "chosen@0") != 0)) | ||
545 | return 0; | ||
546 | |||
547 | #ifdef CONFIG_KEXEC | ||
548 | lprop = (u64 *)of_get_flat_dt_prop(node, | ||
549 | "linux,crashkernel-base", NULL); | ||
550 | if (lprop) | ||
551 | crashk_res.start = *lprop; | ||
552 | |||
553 | lprop = (u64 *)of_get_flat_dt_prop(node, | ||
554 | "linux,crashkernel-size", NULL); | ||
555 | if (lprop) | ||
556 | crashk_res.end = crashk_res.start + *lprop - 1; | ||
557 | #endif | ||
558 | |||
559 | early_init_dt_check_for_initrd(node); | ||
560 | |||
561 | /* Retreive command line */ | ||
562 | p = of_get_flat_dt_prop(node, "bootargs", &l); | ||
563 | if (p != NULL && l > 0) | ||
564 | strlcpy(cmd_line, p, min((int)l, COMMAND_LINE_SIZE)); | ||
565 | |||
566 | #ifdef CONFIG_CMDLINE | ||
567 | if (p == NULL || l == 0 || (l == 1 && (*p) == 0)) | ||
568 | strlcpy(cmd_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE); | ||
569 | #endif /* CONFIG_CMDLINE */ | ||
570 | |||
571 | pr_debug("Command line is: %s\n", cmd_line); | ||
572 | |||
573 | /* break now */ | ||
574 | return 1; | ||
575 | } | ||
576 | |||
577 | static int __init early_init_dt_scan_root(unsigned long node, | ||
578 | const char *uname, int depth, void *data) | ||
579 | { | ||
580 | u32 *prop; | ||
581 | |||
582 | if (depth != 0) | ||
583 | return 0; | ||
584 | |||
585 | prop = of_get_flat_dt_prop(node, "#size-cells", NULL); | ||
586 | dt_root_size_cells = (prop == NULL) ? 1 : *prop; | ||
587 | pr_debug("dt_root_size_cells = %x\n", dt_root_size_cells); | ||
588 | |||
589 | prop = of_get_flat_dt_prop(node, "#address-cells", NULL); | ||
590 | dt_root_addr_cells = (prop == NULL) ? 2 : *prop; | ||
591 | pr_debug("dt_root_addr_cells = %x\n", dt_root_addr_cells); | ||
592 | |||
593 | /* break now */ | ||
594 | return 1; | ||
595 | } | ||
596 | |||
597 | static u64 __init dt_mem_next_cell(int s, cell_t **cellp) | ||
598 | { | ||
599 | cell_t *p = *cellp; | ||
600 | |||
601 | *cellp = p + s; | ||
602 | return of_read_number(p, s); | ||
603 | } | ||
604 | |||
605 | static int __init early_init_dt_scan_memory(unsigned long node, | ||
606 | const char *uname, int depth, void *data) | ||
607 | { | ||
608 | char *type = of_get_flat_dt_prop(node, "device_type", NULL); | ||
609 | cell_t *reg, *endp; | ||
610 | unsigned long l; | ||
611 | |||
612 | /* Look for the ibm,dynamic-reconfiguration-memory node */ | ||
613 | /* if (depth == 1 && | ||
614 | strcmp(uname, "ibm,dynamic-reconfiguration-memory") == 0) | ||
615 | return early_init_dt_scan_drconf_memory(node); | ||
616 | */ | ||
617 | /* We are scanning "memory" nodes only */ | ||
618 | if (type == NULL) { | ||
619 | /* | ||
620 | * The longtrail doesn't have a device_type on the | ||
621 | * /memory node, so look for the node called /memory@0. | ||
622 | */ | ||
623 | if (depth != 1 || strcmp(uname, "memory@0") != 0) | ||
624 | return 0; | ||
625 | } else if (strcmp(type, "memory") != 0) | ||
626 | return 0; | ||
627 | |||
628 | reg = (cell_t *)of_get_flat_dt_prop(node, "linux,usable-memory", &l); | ||
629 | if (reg == NULL) | ||
630 | reg = (cell_t *)of_get_flat_dt_prop(node, "reg", &l); | ||
631 | if (reg == NULL) | ||
632 | return 0; | ||
633 | |||
634 | endp = reg + (l / sizeof(cell_t)); | ||
635 | |||
636 | pr_debug("memory scan node %s, reg size %ld, data: %x %x %x %x,\n", | ||
637 | uname, l, reg[0], reg[1], reg[2], reg[3]); | ||
638 | |||
639 | while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) { | ||
640 | u64 base, size; | ||
641 | |||
642 | base = dt_mem_next_cell(dt_root_addr_cells, ®); | ||
643 | size = dt_mem_next_cell(dt_root_size_cells, ®); | ||
644 | |||
645 | if (size == 0) | ||
646 | continue; | ||
647 | pr_debug(" - %llx , %llx\n", (unsigned long long)base, | ||
648 | (unsigned long long)size); | ||
649 | |||
650 | lmb_add(base, size); | ||
651 | } | ||
652 | return 0; | ||
653 | } | ||
654 | |||
655 | #ifdef CONFIG_PHYP_DUMP | ||
656 | /** | ||
657 | * phyp_dump_calculate_reserve_size() - reserve variable boot area 5% or arg | ||
658 | * | ||
659 | * Function to find the largest size we need to reserve | ||
660 | * during early boot process. | ||
661 | * | ||
662 | * It either looks for boot param and returns that OR | ||
663 | * returns larger of 256 or 5% rounded down to multiples of 256MB. | ||
664 | * | ||
665 | */ | ||
666 | static inline unsigned long phyp_dump_calculate_reserve_size(void) | ||
667 | { | ||
668 | unsigned long tmp; | ||
669 | |||
670 | if (phyp_dump_info->reserve_bootvar) | ||
671 | return phyp_dump_info->reserve_bootvar; | ||
672 | |||
673 | /* divide by 20 to get 5% of value */ | ||
674 | tmp = lmb_end_of_DRAM(); | ||
675 | do_div(tmp, 20); | ||
676 | |||
677 | /* round it down in multiples of 256 */ | ||
678 | tmp = tmp & ~0x0FFFFFFFUL; | ||
679 | |||
680 | return (tmp > PHYP_DUMP_RMR_END ? tmp : PHYP_DUMP_RMR_END); | ||
681 | } | ||
682 | |||
683 | /** | ||
684 | * phyp_dump_reserve_mem() - reserve all not-yet-dumped mmemory | ||
685 | * | ||
686 | * This routine may reserve memory regions in the kernel only | ||
687 | * if the system is supported and a dump was taken in last | ||
688 | * boot instance or if the hardware is supported and the | ||
689 | * scratch area needs to be setup. In other instances it returns | ||
690 | * without reserving anything. The memory in case of dump being | ||
691 | * active is freed when the dump is collected (by userland tools). | ||
692 | */ | ||
693 | static void __init phyp_dump_reserve_mem(void) | ||
694 | { | ||
695 | unsigned long base, size; | ||
696 | unsigned long variable_reserve_size; | ||
697 | |||
698 | if (!phyp_dump_info->phyp_dump_configured) { | ||
699 | printk(KERN_ERR "Phyp-dump not supported on this hardware\n"); | ||
700 | return; | ||
701 | } | ||
702 | |||
703 | if (!phyp_dump_info->phyp_dump_at_boot) { | ||
704 | printk(KERN_INFO "Phyp-dump disabled at boot time\n"); | ||
705 | return; | ||
706 | } | ||
707 | |||
708 | variable_reserve_size = phyp_dump_calculate_reserve_size(); | ||
709 | |||
710 | if (phyp_dump_info->phyp_dump_is_active) { | ||
711 | /* Reserve *everything* above RMR.Area freed by userland tools*/ | ||
712 | base = variable_reserve_size; | ||
713 | size = lmb_end_of_DRAM() - base; | ||
714 | |||
715 | /* XXX crashed_ram_end is wrong, since it may be beyond | ||
716 | * the memory_limit, it will need to be adjusted. */ | ||
717 | lmb_reserve(base, size); | ||
718 | |||
719 | phyp_dump_info->init_reserve_start = base; | ||
720 | phyp_dump_info->init_reserve_size = size; | ||
721 | } else { | ||
722 | size = phyp_dump_info->cpu_state_size + | ||
723 | phyp_dump_info->hpte_region_size + | ||
724 | variable_reserve_size; | ||
725 | base = lmb_end_of_DRAM() - size; | ||
726 | lmb_reserve(base, size); | ||
727 | phyp_dump_info->init_reserve_start = base; | ||
728 | phyp_dump_info->init_reserve_size = size; | ||
729 | } | ||
730 | } | ||
731 | #else | ||
732 | static inline void __init phyp_dump_reserve_mem(void) {} | ||
733 | #endif /* CONFIG_PHYP_DUMP && CONFIG_PPC_RTAS */ | ||
734 | |||
735 | #ifdef CONFIG_EARLY_PRINTK | ||
736 | /* MS this is Microblaze specifig function */ | ||
737 | static int __init early_init_dt_scan_serial(unsigned long node, | ||
738 | const char *uname, int depth, void *data) | ||
739 | { | ||
740 | unsigned long l; | ||
741 | char *p; | ||
742 | int *addr; | ||
743 | |||
744 | pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname); | ||
745 | |||
746 | /* find all serial nodes */ | ||
747 | if (strncmp(uname, "serial", 6) != 0) | ||
748 | return 0; | ||
749 | |||
750 | early_init_dt_check_for_initrd(node); | ||
751 | |||
752 | /* find compatible node with uartlite */ | ||
753 | p = of_get_flat_dt_prop(node, "compatible", &l); | ||
754 | if ((strncmp(p, "xlnx,xps-uartlite", 17) != 0) && | ||
755 | (strncmp(p, "xlnx,opb-uartlite", 17) != 0)) | ||
756 | return 0; | ||
757 | |||
758 | addr = of_get_flat_dt_prop(node, "reg", &l); | ||
759 | return *addr; /* return address */ | ||
760 | } | ||
761 | |||
762 | /* this function is looking for early uartlite console - Microblaze specific */ | ||
763 | int __init early_uartlite_console(void) | ||
764 | { | ||
765 | return of_scan_flat_dt(early_init_dt_scan_serial, NULL); | ||
766 | } | ||
767 | #endif | ||
768 | |||
769 | void __init early_init_devtree(void *params) | ||
770 | { | ||
771 | pr_debug(" -> early_init_devtree(%p)\n", params); | ||
772 | |||
773 | /* Setup flat device-tree pointer */ | ||
774 | initial_boot_params = params; | ||
775 | |||
776 | #ifdef CONFIG_PHYP_DUMP | ||
777 | /* scan tree to see if dump occured during last boot */ | ||
778 | of_scan_flat_dt(early_init_dt_scan_phyp_dump, NULL); | ||
779 | #endif | ||
780 | |||
781 | /* Retrieve various informations from the /chosen node of the | ||
782 | * device-tree, including the platform type, initrd location and | ||
783 | * size, TCE reserve, and more ... | ||
784 | */ | ||
785 | of_scan_flat_dt(early_init_dt_scan_chosen, NULL); | ||
786 | |||
787 | /* Scan memory nodes and rebuild LMBs */ | ||
788 | lmb_init(); | ||
789 | of_scan_flat_dt(early_init_dt_scan_root, NULL); | ||
790 | of_scan_flat_dt(early_init_dt_scan_memory, NULL); | ||
791 | |||
792 | /* Save command line for /proc/cmdline and then parse parameters */ | ||
793 | strlcpy(boot_command_line, cmd_line, COMMAND_LINE_SIZE); | ||
794 | parse_early_param(); | ||
795 | |||
796 | lmb_analyze(); | ||
797 | |||
798 | pr_debug("Phys. mem: %lx\n", (unsigned long) lmb_phys_mem_size()); | ||
799 | |||
800 | pr_debug("Scanning CPUs ...\n"); | ||
801 | |||
802 | /* Retreive CPU related informations from the flat tree | ||
803 | * (altivec support, boot CPU ID, ...) | ||
804 | */ | ||
805 | of_scan_flat_dt(early_init_dt_scan_cpus, NULL); | ||
806 | |||
807 | pr_debug(" <- early_init_devtree()\n"); | ||
808 | } | ||
809 | |||
810 | /** | ||
811 | * Indicates whether the root node has a given value in its | ||
812 | * compatible property. | ||
813 | */ | ||
814 | int machine_is_compatible(const char *compat) | ||
815 | { | ||
816 | struct device_node *root; | ||
817 | int rc = 0; | ||
818 | |||
819 | root = of_find_node_by_path("/"); | ||
820 | if (root) { | ||
821 | rc = of_device_is_compatible(root, compat); | ||
822 | of_node_put(root); | ||
823 | } | ||
824 | return rc; | ||
825 | } | ||
826 | EXPORT_SYMBOL(machine_is_compatible); | ||
827 | |||
828 | /******* | ||
829 | * | ||
830 | * New implementation of the OF "find" APIs, return a refcounted | ||
831 | * object, call of_node_put() when done. The device tree and list | ||
832 | * are protected by a rw_lock. | ||
833 | * | ||
834 | * Note that property management will need some locking as well, | ||
835 | * this isn't dealt with yet. | ||
836 | * | ||
837 | *******/ | ||
838 | |||
839 | /** | ||
840 | * of_find_node_by_phandle - Find a node given a phandle | ||
841 | * @handle: phandle of the node to find | ||
842 | * | ||
843 | * Returns a node pointer with refcount incremented, use | ||
844 | * of_node_put() on it when done. | ||
845 | */ | ||
846 | struct device_node *of_find_node_by_phandle(phandle handle) | ||
847 | { | ||
848 | struct device_node *np; | ||
849 | |||
850 | read_lock(&devtree_lock); | ||
851 | for (np = allnodes; np != NULL; np = np->allnext) | ||
852 | if (np->linux_phandle == handle) | ||
853 | break; | ||
854 | of_node_get(np); | ||
855 | read_unlock(&devtree_lock); | ||
856 | return np; | ||
857 | } | ||
858 | EXPORT_SYMBOL(of_find_node_by_phandle); | ||
859 | |||
860 | /** | ||
861 | * of_find_all_nodes - Get next node in global list | ||
862 | * @prev: Previous node or NULL to start iteration | ||
863 | * of_node_put() will be called on it | ||
864 | * | ||
865 | * Returns a node pointer with refcount incremented, use | ||
866 | * of_node_put() on it when done. | ||
867 | */ | ||
868 | struct device_node *of_find_all_nodes(struct device_node *prev) | ||
869 | { | ||
870 | struct device_node *np; | ||
871 | |||
872 | read_lock(&devtree_lock); | ||
873 | np = prev ? prev->allnext : allnodes; | ||
874 | for (; np != NULL; np = np->allnext) | ||
875 | if (of_node_get(np)) | ||
876 | break; | ||
877 | of_node_put(prev); | ||
878 | read_unlock(&devtree_lock); | ||
879 | return np; | ||
880 | } | ||
881 | EXPORT_SYMBOL(of_find_all_nodes); | ||
882 | |||
883 | /** | ||
884 | * of_node_get - Increment refcount of a node | ||
885 | * @node: Node to inc refcount, NULL is supported to | ||
886 | * simplify writing of callers | ||
887 | * | ||
888 | * Returns node. | ||
889 | */ | ||
890 | struct device_node *of_node_get(struct device_node *node) | ||
891 | { | ||
892 | if (node) | ||
893 | kref_get(&node->kref); | ||
894 | return node; | ||
895 | } | ||
896 | EXPORT_SYMBOL(of_node_get); | ||
897 | |||
898 | static inline struct device_node *kref_to_device_node(struct kref *kref) | ||
899 | { | ||
900 | return container_of(kref, struct device_node, kref); | ||
901 | } | ||
902 | |||
903 | /** | ||
904 | * of_node_release - release a dynamically allocated node | ||
905 | * @kref: kref element of the node to be released | ||
906 | * | ||
907 | * In of_node_put() this function is passed to kref_put() | ||
908 | * as the destructor. | ||
909 | */ | ||
910 | static void of_node_release(struct kref *kref) | ||
911 | { | ||
912 | struct device_node *node = kref_to_device_node(kref); | ||
913 | struct property *prop = node->properties; | ||
914 | |||
915 | /* We should never be releasing nodes that haven't been detached. */ | ||
916 | if (!of_node_check_flag(node, OF_DETACHED)) { | ||
917 | printk(KERN_INFO "WARNING: Bad of_node_put() on %s\n", | ||
918 | node->full_name); | ||
919 | dump_stack(); | ||
920 | kref_init(&node->kref); | ||
921 | return; | ||
922 | } | ||
923 | |||
924 | if (!of_node_check_flag(node, OF_DYNAMIC)) | ||
925 | return; | ||
926 | |||
927 | while (prop) { | ||
928 | struct property *next = prop->next; | ||
929 | kfree(prop->name); | ||
930 | kfree(prop->value); | ||
931 | kfree(prop); | ||
932 | prop = next; | ||
933 | |||
934 | if (!prop) { | ||
935 | prop = node->deadprops; | ||
936 | node->deadprops = NULL; | ||
937 | } | ||
938 | } | ||
939 | kfree(node->full_name); | ||
940 | kfree(node->data); | ||
941 | kfree(node); | ||
942 | } | ||
943 | |||
944 | /** | ||
945 | * of_node_put - Decrement refcount of a node | ||
946 | * @node: Node to dec refcount, NULL is supported to | ||
947 | * simplify writing of callers | ||
948 | * | ||
949 | */ | ||
950 | void of_node_put(struct device_node *node) | ||
951 | { | ||
952 | if (node) | ||
953 | kref_put(&node->kref, of_node_release); | ||
954 | } | ||
955 | EXPORT_SYMBOL(of_node_put); | ||
956 | |||
957 | /* | ||
958 | * Plug a device node into the tree and global list. | ||
959 | */ | ||
960 | void of_attach_node(struct device_node *np) | ||
961 | { | ||
962 | unsigned long flags; | ||
963 | |||
964 | write_lock_irqsave(&devtree_lock, flags); | ||
965 | np->sibling = np->parent->child; | ||
966 | np->allnext = allnodes; | ||
967 | np->parent->child = np; | ||
968 | allnodes = np; | ||
969 | write_unlock_irqrestore(&devtree_lock, flags); | ||
970 | } | ||
971 | |||
972 | /* | ||
973 | * "Unplug" a node from the device tree. The caller must hold | ||
974 | * a reference to the node. The memory associated with the node | ||
975 | * is not freed until its refcount goes to zero. | ||
976 | */ | ||
977 | void of_detach_node(struct device_node *np) | ||
978 | { | ||
979 | struct device_node *parent; | ||
980 | unsigned long flags; | ||
981 | |||
982 | write_lock_irqsave(&devtree_lock, flags); | ||
983 | |||
984 | parent = np->parent; | ||
985 | if (!parent) | ||
986 | goto out_unlock; | ||
987 | |||
988 | if (allnodes == np) | ||
989 | allnodes = np->allnext; | ||
990 | else { | ||
991 | struct device_node *prev; | ||
992 | for (prev = allnodes; | ||
993 | prev->allnext != np; | ||
994 | prev = prev->allnext) | ||
995 | ; | ||
996 | prev->allnext = np->allnext; | ||
997 | } | ||
998 | |||
999 | if (parent->child == np) | ||
1000 | parent->child = np->sibling; | ||
1001 | else { | ||
1002 | struct device_node *prevsib; | ||
1003 | for (prevsib = np->parent->child; | ||
1004 | prevsib->sibling != np; | ||
1005 | prevsib = prevsib->sibling) | ||
1006 | ; | ||
1007 | prevsib->sibling = np->sibling; | ||
1008 | } | ||
1009 | |||
1010 | of_node_set_flag(np, OF_DETACHED); | ||
1011 | |||
1012 | out_unlock: | ||
1013 | write_unlock_irqrestore(&devtree_lock, flags); | ||
1014 | } | ||
1015 | |||
1016 | /* | ||
1017 | * Add a property to a node | ||
1018 | */ | ||
1019 | int prom_add_property(struct device_node *np, struct property *prop) | ||
1020 | { | ||
1021 | struct property **next; | ||
1022 | unsigned long flags; | ||
1023 | |||
1024 | prop->next = NULL; | ||
1025 | write_lock_irqsave(&devtree_lock, flags); | ||
1026 | next = &np->properties; | ||
1027 | while (*next) { | ||
1028 | if (strcmp(prop->name, (*next)->name) == 0) { | ||
1029 | /* duplicate ! don't insert it */ | ||
1030 | write_unlock_irqrestore(&devtree_lock, flags); | ||
1031 | return -1; | ||
1032 | } | ||
1033 | next = &(*next)->next; | ||
1034 | } | ||
1035 | *next = prop; | ||
1036 | write_unlock_irqrestore(&devtree_lock, flags); | ||
1037 | |||
1038 | #ifdef CONFIG_PROC_DEVICETREE | ||
1039 | /* try to add to proc as well if it was initialized */ | ||
1040 | if (np->pde) | ||
1041 | proc_device_tree_add_prop(np->pde, prop); | ||
1042 | #endif /* CONFIG_PROC_DEVICETREE */ | ||
1043 | |||
1044 | return 0; | ||
1045 | } | ||
1046 | |||
1047 | /* | ||
1048 | * Remove a property from a node. Note that we don't actually | ||
1049 | * remove it, since we have given out who-knows-how-many pointers | ||
1050 | * to the data using get-property. Instead we just move the property | ||
1051 | * to the "dead properties" list, so it won't be found any more. | ||
1052 | */ | ||
1053 | int prom_remove_property(struct device_node *np, struct property *prop) | ||
1054 | { | ||
1055 | struct property **next; | ||
1056 | unsigned long flags; | ||
1057 | int found = 0; | ||
1058 | |||
1059 | write_lock_irqsave(&devtree_lock, flags); | ||
1060 | next = &np->properties; | ||
1061 | while (*next) { | ||
1062 | if (*next == prop) { | ||
1063 | /* found the node */ | ||
1064 | *next = prop->next; | ||
1065 | prop->next = np->deadprops; | ||
1066 | np->deadprops = prop; | ||
1067 | found = 1; | ||
1068 | break; | ||
1069 | } | ||
1070 | next = &(*next)->next; | ||
1071 | } | ||
1072 | write_unlock_irqrestore(&devtree_lock, flags); | ||
1073 | |||
1074 | if (!found) | ||
1075 | return -ENODEV; | ||
1076 | |||
1077 | #ifdef CONFIG_PROC_DEVICETREE | ||
1078 | /* try to remove the proc node as well */ | ||
1079 | if (np->pde) | ||
1080 | proc_device_tree_remove_prop(np->pde, prop); | ||
1081 | #endif /* CONFIG_PROC_DEVICETREE */ | ||
1082 | |||
1083 | return 0; | ||
1084 | } | ||
1085 | |||
1086 | /* | ||
1087 | * Update a property in a node. Note that we don't actually | ||
1088 | * remove it, since we have given out who-knows-how-many pointers | ||
1089 | * to the data using get-property. Instead we just move the property | ||
1090 | * to the "dead properties" list, and add the new property to the | ||
1091 | * property list | ||
1092 | */ | ||
1093 | int prom_update_property(struct device_node *np, | ||
1094 | struct property *newprop, | ||
1095 | struct property *oldprop) | ||
1096 | { | ||
1097 | struct property **next; | ||
1098 | unsigned long flags; | ||
1099 | int found = 0; | ||
1100 | |||
1101 | write_lock_irqsave(&devtree_lock, flags); | ||
1102 | next = &np->properties; | ||
1103 | while (*next) { | ||
1104 | if (*next == oldprop) { | ||
1105 | /* found the node */ | ||
1106 | newprop->next = oldprop->next; | ||
1107 | *next = newprop; | ||
1108 | oldprop->next = np->deadprops; | ||
1109 | np->deadprops = oldprop; | ||
1110 | found = 1; | ||
1111 | break; | ||
1112 | } | ||
1113 | next = &(*next)->next; | ||
1114 | } | ||
1115 | write_unlock_irqrestore(&devtree_lock, flags); | ||
1116 | |||
1117 | if (!found) | ||
1118 | return -ENODEV; | ||
1119 | |||
1120 | #ifdef CONFIG_PROC_DEVICETREE | ||
1121 | /* try to add to proc as well if it was initialized */ | ||
1122 | if (np->pde) | ||
1123 | proc_device_tree_update_prop(np->pde, newprop, oldprop); | ||
1124 | #endif /* CONFIG_PROC_DEVICETREE */ | ||
1125 | |||
1126 | return 0; | ||
1127 | } | ||
1128 | |||
1129 | #if defined(CONFIG_DEBUG_FS) && defined(DEBUG) | ||
1130 | static struct debugfs_blob_wrapper flat_dt_blob; | ||
1131 | |||
1132 | static int __init export_flat_device_tree(void) | ||
1133 | { | ||
1134 | struct dentry *d; | ||
1135 | |||
1136 | flat_dt_blob.data = initial_boot_params; | ||
1137 | flat_dt_blob.size = initial_boot_params->totalsize; | ||
1138 | |||
1139 | d = debugfs_create_blob("flat-device-tree", S_IFREG | S_IRUSR, | ||
1140 | of_debugfs_root, &flat_dt_blob); | ||
1141 | if (!d) | ||
1142 | return 1; | ||
1143 | |||
1144 | return 0; | ||
1145 | } | ||
1146 | device_initcall(export_flat_device_tree); | ||
1147 | #endif | ||
diff --git a/arch/microblaze/kernel/prom_parse.c b/arch/microblaze/kernel/prom_parse.c new file mode 100644 index 000000000000..ae0352ecd5a9 --- /dev/null +++ b/arch/microblaze/kernel/prom_parse.c | |||
@@ -0,0 +1,1025 @@ | |||
1 | #undef DEBUG | ||
2 | |||
3 | #include <linux/kernel.h> | ||
4 | #include <linux/string.h> | ||
5 | #include <linux/pci_regs.h> | ||
6 | #include <linux/module.h> | ||
7 | #include <linux/ioport.h> | ||
8 | #include <linux/etherdevice.h> | ||
9 | #include <asm/prom.h> | ||
10 | #include <asm/pci-bridge.h> | ||
11 | |||
12 | #define PRu64 "%llx" | ||
13 | |||
14 | /* Max address size we deal with */ | ||
15 | #define OF_MAX_ADDR_CELLS 4 | ||
16 | #define OF_CHECK_COUNTS(na, ns) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \ | ||
17 | (ns) > 0) | ||
18 | |||
19 | static struct of_bus *of_match_bus(struct device_node *np); | ||
20 | static int __of_address_to_resource(struct device_node *dev, | ||
21 | const u32 *addrp, u64 size, unsigned int flags, | ||
22 | struct resource *r); | ||
23 | |||
24 | /* Debug utility */ | ||
25 | #ifdef DEBUG | ||
26 | static void of_dump_addr(const char *s, const u32 *addr, int na) | ||
27 | { | ||
28 | printk(KERN_INFO "%s", s); | ||
29 | while (na--) | ||
30 | printk(KERN_INFO " %08x", *(addr++)); | ||
31 | printk(KERN_INFO "\n"); | ||
32 | } | ||
33 | #else | ||
34 | static void of_dump_addr(const char *s, const u32 *addr, int na) { } | ||
35 | #endif | ||
36 | |||
37 | /* Callbacks for bus specific translators */ | ||
38 | struct of_bus { | ||
39 | const char *name; | ||
40 | const char *addresses; | ||
41 | int (*match)(struct device_node *parent); | ||
42 | void (*count_cells)(struct device_node *child, | ||
43 | int *addrc, int *sizec); | ||
44 | u64 (*map)(u32 *addr, const u32 *range, | ||
45 | int na, int ns, int pna); | ||
46 | int (*translate)(u32 *addr, u64 offset, int na); | ||
47 | unsigned int (*get_flags)(const u32 *addr); | ||
48 | }; | ||
49 | |||
50 | /* | ||
51 | * Default translator (generic bus) | ||
52 | */ | ||
53 | |||
54 | static void of_bus_default_count_cells(struct device_node *dev, | ||
55 | int *addrc, int *sizec) | ||
56 | { | ||
57 | if (addrc) | ||
58 | *addrc = of_n_addr_cells(dev); | ||
59 | if (sizec) | ||
60 | *sizec = of_n_size_cells(dev); | ||
61 | } | ||
62 | |||
63 | static u64 of_bus_default_map(u32 *addr, const u32 *range, | ||
64 | int na, int ns, int pna) | ||
65 | { | ||
66 | u64 cp, s, da; | ||
67 | |||
68 | cp = of_read_number(range, na); | ||
69 | s = of_read_number(range + na + pna, ns); | ||
70 | da = of_read_number(addr, na); | ||
71 | |||
72 | pr_debug("OF: default map, cp="PRu64", s="PRu64", da="PRu64"\n", | ||
73 | cp, s, da); | ||
74 | |||
75 | if (da < cp || da >= (cp + s)) | ||
76 | return OF_BAD_ADDR; | ||
77 | return da - cp; | ||
78 | } | ||
79 | |||
80 | static int of_bus_default_translate(u32 *addr, u64 offset, int na) | ||
81 | { | ||
82 | u64 a = of_read_number(addr, na); | ||
83 | memset(addr, 0, na * 4); | ||
84 | a += offset; | ||
85 | if (na > 1) | ||
86 | addr[na - 2] = a >> 32; | ||
87 | addr[na - 1] = a & 0xffffffffu; | ||
88 | |||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | static unsigned int of_bus_default_get_flags(const u32 *addr) | ||
93 | { | ||
94 | return IORESOURCE_MEM; | ||
95 | } | ||
96 | |||
97 | #ifdef CONFIG_PCI | ||
98 | /* | ||
99 | * PCI bus specific translator | ||
100 | */ | ||
101 | |||
102 | static int of_bus_pci_match(struct device_node *np) | ||
103 | { | ||
104 | /* "vci" is for the /chaos bridge on 1st-gen PCI powermacs */ | ||
105 | return !strcmp(np->type, "pci") || !strcmp(np->type, "vci"); | ||
106 | } | ||
107 | |||
108 | static void of_bus_pci_count_cells(struct device_node *np, | ||
109 | int *addrc, int *sizec) | ||
110 | { | ||
111 | if (addrc) | ||
112 | *addrc = 3; | ||
113 | if (sizec) | ||
114 | *sizec = 2; | ||
115 | } | ||
116 | |||
117 | static u64 of_bus_pci_map(u32 *addr, const u32 *range, int na, int ns, int pna) | ||
118 | { | ||
119 | u64 cp, s, da; | ||
120 | |||
121 | /* Check address type match */ | ||
122 | if ((addr[0] ^ range[0]) & 0x03000000) | ||
123 | return OF_BAD_ADDR; | ||
124 | |||
125 | /* Read address values, skipping high cell */ | ||
126 | cp = of_read_number(range + 1, na - 1); | ||
127 | s = of_read_number(range + na + pna, ns); | ||
128 | da = of_read_number(addr + 1, na - 1); | ||
129 | |||
130 | pr_debug("OF: PCI map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da); | ||
131 | |||
132 | if (da < cp || da >= (cp + s)) | ||
133 | return OF_BAD_ADDR; | ||
134 | return da - cp; | ||
135 | } | ||
136 | |||
137 | static int of_bus_pci_translate(u32 *addr, u64 offset, int na) | ||
138 | { | ||
139 | return of_bus_default_translate(addr + 1, offset, na - 1); | ||
140 | } | ||
141 | |||
142 | static unsigned int of_bus_pci_get_flags(const u32 *addr) | ||
143 | { | ||
144 | unsigned int flags = 0; | ||
145 | u32 w = addr[0]; | ||
146 | |||
147 | switch ((w >> 24) & 0x03) { | ||
148 | case 0x01: | ||
149 | flags |= IORESOURCE_IO; | ||
150 | break; | ||
151 | case 0x02: /* 32 bits */ | ||
152 | case 0x03: /* 64 bits */ | ||
153 | flags |= IORESOURCE_MEM; | ||
154 | break; | ||
155 | } | ||
156 | if (w & 0x40000000) | ||
157 | flags |= IORESOURCE_PREFETCH; | ||
158 | return flags; | ||
159 | } | ||
160 | |||
161 | const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, | ||
162 | unsigned int *flags) | ||
163 | { | ||
164 | const u32 *prop; | ||
165 | unsigned int psize; | ||
166 | struct device_node *parent; | ||
167 | struct of_bus *bus; | ||
168 | int onesize, i, na, ns; | ||
169 | |||
170 | /* Get parent & match bus type */ | ||
171 | parent = of_get_parent(dev); | ||
172 | if (parent == NULL) | ||
173 | return NULL; | ||
174 | bus = of_match_bus(parent); | ||
175 | if (strcmp(bus->name, "pci")) { | ||
176 | of_node_put(parent); | ||
177 | return NULL; | ||
178 | } | ||
179 | bus->count_cells(dev, &na, &ns); | ||
180 | of_node_put(parent); | ||
181 | if (!OF_CHECK_COUNTS(na, ns)) | ||
182 | return NULL; | ||
183 | |||
184 | /* Get "reg" or "assigned-addresses" property */ | ||
185 | prop = of_get_property(dev, bus->addresses, &psize); | ||
186 | if (prop == NULL) | ||
187 | return NULL; | ||
188 | psize /= 4; | ||
189 | |||
190 | onesize = na + ns; | ||
191 | for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++) | ||
192 | if ((prop[0] & 0xff) == ((bar_no * 4) + PCI_BASE_ADDRESS_0)) { | ||
193 | if (size) | ||
194 | *size = of_read_number(prop + na, ns); | ||
195 | if (flags) | ||
196 | *flags = bus->get_flags(prop); | ||
197 | return prop; | ||
198 | } | ||
199 | return NULL; | ||
200 | } | ||
201 | EXPORT_SYMBOL(of_get_pci_address); | ||
202 | |||
203 | int of_pci_address_to_resource(struct device_node *dev, int bar, | ||
204 | struct resource *r) | ||
205 | { | ||
206 | const u32 *addrp; | ||
207 | u64 size; | ||
208 | unsigned int flags; | ||
209 | |||
210 | addrp = of_get_pci_address(dev, bar, &size, &flags); | ||
211 | if (addrp == NULL) | ||
212 | return -EINVAL; | ||
213 | return __of_address_to_resource(dev, addrp, size, flags, r); | ||
214 | } | ||
215 | EXPORT_SYMBOL_GPL(of_pci_address_to_resource); | ||
216 | |||
217 | static u8 of_irq_pci_swizzle(u8 slot, u8 pin) | ||
218 | { | ||
219 | return (((pin - 1) + slot) % 4) + 1; | ||
220 | } | ||
221 | |||
222 | int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq) | ||
223 | { | ||
224 | struct device_node *dn, *ppnode; | ||
225 | struct pci_dev *ppdev; | ||
226 | u32 lspec; | ||
227 | u32 laddr[3]; | ||
228 | u8 pin; | ||
229 | int rc; | ||
230 | |||
231 | /* Check if we have a device node, if yes, fallback to standard OF | ||
232 | * parsing | ||
233 | */ | ||
234 | dn = pci_device_to_OF_node(pdev); | ||
235 | if (dn) | ||
236 | return of_irq_map_one(dn, 0, out_irq); | ||
237 | |||
238 | /* Ok, we don't, time to have fun. Let's start by building up an | ||
239 | * interrupt spec. we assume #interrupt-cells is 1, which is standard | ||
240 | * for PCI. If you do different, then don't use that routine. | ||
241 | */ | ||
242 | rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin); | ||
243 | if (rc != 0) | ||
244 | return rc; | ||
245 | /* No pin, exit */ | ||
246 | if (pin == 0) | ||
247 | return -ENODEV; | ||
248 | |||
249 | /* Now we walk up the PCI tree */ | ||
250 | lspec = pin; | ||
251 | for (;;) { | ||
252 | /* Get the pci_dev of our parent */ | ||
253 | ppdev = pdev->bus->self; | ||
254 | |||
255 | /* Ouch, it's a host bridge... */ | ||
256 | if (ppdev == NULL) { | ||
257 | struct pci_controller *host; | ||
258 | host = pci_bus_to_host(pdev->bus); | ||
259 | ppnode = host ? host->arch_data : NULL; | ||
260 | /* No node for host bridge ? give up */ | ||
261 | if (ppnode == NULL) | ||
262 | return -EINVAL; | ||
263 | } else | ||
264 | /* We found a P2P bridge, check if it has a node */ | ||
265 | ppnode = pci_device_to_OF_node(ppdev); | ||
266 | |||
267 | /* Ok, we have found a parent with a device-node, hand over to | ||
268 | * the OF parsing code. | ||
269 | * We build a unit address from the linux device to be used for | ||
270 | * resolution. Note that we use the linux bus number which may | ||
271 | * not match your firmware bus numbering. | ||
272 | * Fortunately, in most cases, interrupt-map-mask doesn't | ||
273 | * include the bus number as part of the matching. | ||
274 | * You should still be careful about that though if you intend | ||
275 | * to rely on this function (you ship a firmware that doesn't | ||
276 | * create device nodes for all PCI devices). | ||
277 | */ | ||
278 | if (ppnode) | ||
279 | break; | ||
280 | |||
281 | /* We can only get here if we hit a P2P bridge with no node, | ||
282 | * let's do standard swizzling and try again | ||
283 | */ | ||
284 | lspec = of_irq_pci_swizzle(PCI_SLOT(pdev->devfn), lspec); | ||
285 | pdev = ppdev; | ||
286 | } | ||
287 | |||
288 | laddr[0] = (pdev->bus->number << 16) | ||
289 | | (pdev->devfn << 8); | ||
290 | laddr[1] = laddr[2] = 0; | ||
291 | return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq); | ||
292 | } | ||
293 | EXPORT_SYMBOL_GPL(of_irq_map_pci); | ||
294 | #endif /* CONFIG_PCI */ | ||
295 | |||
296 | /* | ||
297 | * ISA bus specific translator | ||
298 | */ | ||
299 | |||
300 | static int of_bus_isa_match(struct device_node *np) | ||
301 | { | ||
302 | return !strcmp(np->name, "isa"); | ||
303 | } | ||
304 | |||
305 | static void of_bus_isa_count_cells(struct device_node *child, | ||
306 | int *addrc, int *sizec) | ||
307 | { | ||
308 | if (addrc) | ||
309 | *addrc = 2; | ||
310 | if (sizec) | ||
311 | *sizec = 1; | ||
312 | } | ||
313 | |||
314 | static u64 of_bus_isa_map(u32 *addr, const u32 *range, int na, int ns, int pna) | ||
315 | { | ||
316 | u64 cp, s, da; | ||
317 | |||
318 | /* Check address type match */ | ||
319 | if ((addr[0] ^ range[0]) & 0x00000001) | ||
320 | return OF_BAD_ADDR; | ||
321 | |||
322 | /* Read address values, skipping high cell */ | ||
323 | cp = of_read_number(range + 1, na - 1); | ||
324 | s = of_read_number(range + na + pna, ns); | ||
325 | da = of_read_number(addr + 1, na - 1); | ||
326 | |||
327 | pr_debug("OF: ISA map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da); | ||
328 | |||
329 | if (da < cp || da >= (cp + s)) | ||
330 | return OF_BAD_ADDR; | ||
331 | return da - cp; | ||
332 | } | ||
333 | |||
334 | static int of_bus_isa_translate(u32 *addr, u64 offset, int na) | ||
335 | { | ||
336 | return of_bus_default_translate(addr + 1, offset, na - 1); | ||
337 | } | ||
338 | |||
339 | static unsigned int of_bus_isa_get_flags(const u32 *addr) | ||
340 | { | ||
341 | unsigned int flags = 0; | ||
342 | u32 w = addr[0]; | ||
343 | |||
344 | if (w & 1) | ||
345 | flags |= IORESOURCE_IO; | ||
346 | else | ||
347 | flags |= IORESOURCE_MEM; | ||
348 | return flags; | ||
349 | } | ||
350 | |||
351 | /* | ||
352 | * Array of bus specific translators | ||
353 | */ | ||
354 | |||
355 | static struct of_bus of_busses[] = { | ||
356 | #ifdef CONFIG_PCI | ||
357 | /* PCI */ | ||
358 | { | ||
359 | .name = "pci", | ||
360 | .addresses = "assigned-addresses", | ||
361 | .match = of_bus_pci_match, | ||
362 | .count_cells = of_bus_pci_count_cells, | ||
363 | .map = of_bus_pci_map, | ||
364 | .translate = of_bus_pci_translate, | ||
365 | .get_flags = of_bus_pci_get_flags, | ||
366 | }, | ||
367 | #endif /* CONFIG_PCI */ | ||
368 | /* ISA */ | ||
369 | { | ||
370 | .name = "isa", | ||
371 | .addresses = "reg", | ||
372 | .match = of_bus_isa_match, | ||
373 | .count_cells = of_bus_isa_count_cells, | ||
374 | .map = of_bus_isa_map, | ||
375 | .translate = of_bus_isa_translate, | ||
376 | .get_flags = of_bus_isa_get_flags, | ||
377 | }, | ||
378 | /* Default */ | ||
379 | { | ||
380 | .name = "default", | ||
381 | .addresses = "reg", | ||
382 | .match = NULL, | ||
383 | .count_cells = of_bus_default_count_cells, | ||
384 | .map = of_bus_default_map, | ||
385 | .translate = of_bus_default_translate, | ||
386 | .get_flags = of_bus_default_get_flags, | ||
387 | }, | ||
388 | }; | ||
389 | |||
390 | static struct of_bus *of_match_bus(struct device_node *np) | ||
391 | { | ||
392 | int i; | ||
393 | |||
394 | for (i = 0; i < ARRAY_SIZE(of_busses); i++) | ||
395 | if (!of_busses[i].match || of_busses[i].match(np)) | ||
396 | return &of_busses[i]; | ||
397 | BUG(); | ||
398 | return NULL; | ||
399 | } | ||
400 | |||
401 | static int of_translate_one(struct device_node *parent, struct of_bus *bus, | ||
402 | struct of_bus *pbus, u32 *addr, | ||
403 | int na, int ns, int pna) | ||
404 | { | ||
405 | const u32 *ranges; | ||
406 | unsigned int rlen; | ||
407 | int rone; | ||
408 | u64 offset = OF_BAD_ADDR; | ||
409 | |||
410 | /* Normally, an absence of a "ranges" property means we are | ||
411 | * crossing a non-translatable boundary, and thus the addresses | ||
412 | * below the current not cannot be converted to CPU physical ones. | ||
413 | * Unfortunately, while this is very clear in the spec, it's not | ||
414 | * what Apple understood, and they do have things like /uni-n or | ||
415 | * /ht nodes with no "ranges" property and a lot of perfectly | ||
416 | * useable mapped devices below them. Thus we treat the absence of | ||
417 | * "ranges" as equivalent to an empty "ranges" property which means | ||
418 | * a 1:1 translation at that level. It's up to the caller not to try | ||
419 | * to translate addresses that aren't supposed to be translated in | ||
420 | * the first place. --BenH. | ||
421 | */ | ||
422 | ranges = of_get_property(parent, "ranges", (int *) &rlen); | ||
423 | if (ranges == NULL || rlen == 0) { | ||
424 | offset = of_read_number(addr, na); | ||
425 | memset(addr, 0, pna * 4); | ||
426 | pr_debug("OF: no ranges, 1:1 translation\n"); | ||
427 | goto finish; | ||
428 | } | ||
429 | |||
430 | pr_debug("OF: walking ranges...\n"); | ||
431 | |||
432 | /* Now walk through the ranges */ | ||
433 | rlen /= 4; | ||
434 | rone = na + pna + ns; | ||
435 | for (; rlen >= rone; rlen -= rone, ranges += rone) { | ||
436 | offset = bus->map(addr, ranges, na, ns, pna); | ||
437 | if (offset != OF_BAD_ADDR) | ||
438 | break; | ||
439 | } | ||
440 | if (offset == OF_BAD_ADDR) { | ||
441 | pr_debug("OF: not found !\n"); | ||
442 | return 1; | ||
443 | } | ||
444 | memcpy(addr, ranges + na, 4 * pna); | ||
445 | |||
446 | finish: | ||
447 | of_dump_addr("OF: parent translation for:", addr, pna); | ||
448 | pr_debug("OF: with offset: "PRu64"\n", offset); | ||
449 | |||
450 | /* Translate it into parent bus space */ | ||
451 | return pbus->translate(addr, offset, pna); | ||
452 | } | ||
453 | |||
454 | /* | ||
455 | * Translate an address from the device-tree into a CPU physical address, | ||
456 | * this walks up the tree and applies the various bus mappings on the | ||
457 | * way. | ||
458 | * | ||
459 | * Note: We consider that crossing any level with #size-cells == 0 to mean | ||
460 | * that translation is impossible (that is we are not dealing with a value | ||
461 | * that can be mapped to a cpu physical address). This is not really specified | ||
462 | * that way, but this is traditionally the way IBM at least do things | ||
463 | */ | ||
464 | u64 of_translate_address(struct device_node *dev, const u32 *in_addr) | ||
465 | { | ||
466 | struct device_node *parent = NULL; | ||
467 | struct of_bus *bus, *pbus; | ||
468 | u32 addr[OF_MAX_ADDR_CELLS]; | ||
469 | int na, ns, pna, pns; | ||
470 | u64 result = OF_BAD_ADDR; | ||
471 | |||
472 | pr_debug("OF: ** translation for device %s **\n", dev->full_name); | ||
473 | |||
474 | /* Increase refcount at current level */ | ||
475 | of_node_get(dev); | ||
476 | |||
477 | /* Get parent & match bus type */ | ||
478 | parent = of_get_parent(dev); | ||
479 | if (parent == NULL) | ||
480 | goto bail; | ||
481 | bus = of_match_bus(parent); | ||
482 | |||
483 | /* Cound address cells & copy address locally */ | ||
484 | bus->count_cells(dev, &na, &ns); | ||
485 | if (!OF_CHECK_COUNTS(na, ns)) { | ||
486 | printk(KERN_ERR "prom_parse: Bad cell count for %s\n", | ||
487 | dev->full_name); | ||
488 | goto bail; | ||
489 | } | ||
490 | memcpy(addr, in_addr, na * 4); | ||
491 | |||
492 | pr_debug("OF: bus is %s (na=%d, ns=%d) on %s\n", | ||
493 | bus->name, na, ns, parent->full_name); | ||
494 | of_dump_addr("OF: translating address:", addr, na); | ||
495 | |||
496 | /* Translate */ | ||
497 | for (;;) { | ||
498 | /* Switch to parent bus */ | ||
499 | of_node_put(dev); | ||
500 | dev = parent; | ||
501 | parent = of_get_parent(dev); | ||
502 | |||
503 | /* If root, we have finished */ | ||
504 | if (parent == NULL) { | ||
505 | pr_debug("OF: reached root node\n"); | ||
506 | result = of_read_number(addr, na); | ||
507 | break; | ||
508 | } | ||
509 | |||
510 | /* Get new parent bus and counts */ | ||
511 | pbus = of_match_bus(parent); | ||
512 | pbus->count_cells(dev, &pna, &pns); | ||
513 | if (!OF_CHECK_COUNTS(pna, pns)) { | ||
514 | printk(KERN_ERR "prom_parse: Bad cell count for %s\n", | ||
515 | dev->full_name); | ||
516 | break; | ||
517 | } | ||
518 | |||
519 | pr_debug("OF: parent bus is %s (na=%d, ns=%d) on %s\n", | ||
520 | pbus->name, pna, pns, parent->full_name); | ||
521 | |||
522 | /* Apply bus translation */ | ||
523 | if (of_translate_one(dev, bus, pbus, addr, na, ns, pna)) | ||
524 | break; | ||
525 | |||
526 | /* Complete the move up one level */ | ||
527 | na = pna; | ||
528 | ns = pns; | ||
529 | bus = pbus; | ||
530 | |||
531 | of_dump_addr("OF: one level translation:", addr, na); | ||
532 | } | ||
533 | bail: | ||
534 | of_node_put(parent); | ||
535 | of_node_put(dev); | ||
536 | |||
537 | return result; | ||
538 | } | ||
539 | EXPORT_SYMBOL(of_translate_address); | ||
540 | |||
541 | const u32 *of_get_address(struct device_node *dev, int index, u64 *size, | ||
542 | unsigned int *flags) | ||
543 | { | ||
544 | const u32 *prop; | ||
545 | unsigned int psize; | ||
546 | struct device_node *parent; | ||
547 | struct of_bus *bus; | ||
548 | int onesize, i, na, ns; | ||
549 | |||
550 | /* Get parent & match bus type */ | ||
551 | parent = of_get_parent(dev); | ||
552 | if (parent == NULL) | ||
553 | return NULL; | ||
554 | bus = of_match_bus(parent); | ||
555 | bus->count_cells(dev, &na, &ns); | ||
556 | of_node_put(parent); | ||
557 | if (!OF_CHECK_COUNTS(na, ns)) | ||
558 | return NULL; | ||
559 | |||
560 | /* Get "reg" or "assigned-addresses" property */ | ||
561 | prop = of_get_property(dev, bus->addresses, (int *) &psize); | ||
562 | if (prop == NULL) | ||
563 | return NULL; | ||
564 | psize /= 4; | ||
565 | |||
566 | onesize = na + ns; | ||
567 | for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++) | ||
568 | if (i == index) { | ||
569 | if (size) | ||
570 | *size = of_read_number(prop + na, ns); | ||
571 | if (flags) | ||
572 | *flags = bus->get_flags(prop); | ||
573 | return prop; | ||
574 | } | ||
575 | return NULL; | ||
576 | } | ||
577 | EXPORT_SYMBOL(of_get_address); | ||
578 | |||
579 | static int __of_address_to_resource(struct device_node *dev, const u32 *addrp, | ||
580 | u64 size, unsigned int flags, | ||
581 | struct resource *r) | ||
582 | { | ||
583 | u64 taddr; | ||
584 | |||
585 | if ((flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0) | ||
586 | return -EINVAL; | ||
587 | taddr = of_translate_address(dev, addrp); | ||
588 | if (taddr == OF_BAD_ADDR) | ||
589 | return -EINVAL; | ||
590 | memset(r, 0, sizeof(struct resource)); | ||
591 | if (flags & IORESOURCE_IO) { | ||
592 | unsigned long port; | ||
593 | port = -1; /* pci_address_to_pio(taddr); */ | ||
594 | if (port == (unsigned long)-1) | ||
595 | return -EINVAL; | ||
596 | r->start = port; | ||
597 | r->end = port + size - 1; | ||
598 | } else { | ||
599 | r->start = taddr; | ||
600 | r->end = taddr + size - 1; | ||
601 | } | ||
602 | r->flags = flags; | ||
603 | r->name = dev->name; | ||
604 | return 0; | ||
605 | } | ||
606 | |||
607 | int of_address_to_resource(struct device_node *dev, int index, | ||
608 | struct resource *r) | ||
609 | { | ||
610 | const u32 *addrp; | ||
611 | u64 size; | ||
612 | unsigned int flags; | ||
613 | |||
614 | addrp = of_get_address(dev, index, &size, &flags); | ||
615 | if (addrp == NULL) | ||
616 | return -EINVAL; | ||
617 | return __of_address_to_resource(dev, addrp, size, flags, r); | ||
618 | } | ||
619 | EXPORT_SYMBOL_GPL(of_address_to_resource); | ||
620 | |||
621 | void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, | ||
622 | unsigned long *busno, unsigned long *phys, unsigned long *size) | ||
623 | { | ||
624 | const u32 *dma_window; | ||
625 | u32 cells; | ||
626 | const unsigned char *prop; | ||
627 | |||
628 | dma_window = dma_window_prop; | ||
629 | |||
630 | /* busno is always one cell */ | ||
631 | *busno = *(dma_window++); | ||
632 | |||
633 | prop = of_get_property(dn, "ibm,#dma-address-cells", NULL); | ||
634 | if (!prop) | ||
635 | prop = of_get_property(dn, "#address-cells", NULL); | ||
636 | |||
637 | cells = prop ? *(u32 *)prop : of_n_addr_cells(dn); | ||
638 | *phys = of_read_number(dma_window, cells); | ||
639 | |||
640 | dma_window += cells; | ||
641 | |||
642 | prop = of_get_property(dn, "ibm,#dma-size-cells", NULL); | ||
643 | cells = prop ? *(u32 *)prop : of_n_size_cells(dn); | ||
644 | *size = of_read_number(dma_window, cells); | ||
645 | } | ||
646 | |||
647 | /* | ||
648 | * Interrupt remapper | ||
649 | */ | ||
650 | |||
651 | static unsigned int of_irq_workarounds; | ||
652 | static struct device_node *of_irq_dflt_pic; | ||
653 | |||
654 | static struct device_node *of_irq_find_parent(struct device_node *child) | ||
655 | { | ||
656 | struct device_node *p; | ||
657 | const phandle *parp; | ||
658 | |||
659 | if (!of_node_get(child)) | ||
660 | return NULL; | ||
661 | |||
662 | do { | ||
663 | parp = of_get_property(child, "interrupt-parent", NULL); | ||
664 | if (parp == NULL) | ||
665 | p = of_get_parent(child); | ||
666 | else { | ||
667 | if (of_irq_workarounds & OF_IMAP_NO_PHANDLE) | ||
668 | p = of_node_get(of_irq_dflt_pic); | ||
669 | else | ||
670 | p = of_find_node_by_phandle(*parp); | ||
671 | } | ||
672 | of_node_put(child); | ||
673 | child = p; | ||
674 | } while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL); | ||
675 | |||
676 | return p; | ||
677 | } | ||
678 | |||
679 | /* This doesn't need to be called if you don't have any special workaround | ||
680 | * flags to pass | ||
681 | */ | ||
682 | void of_irq_map_init(unsigned int flags) | ||
683 | { | ||
684 | of_irq_workarounds = flags; | ||
685 | |||
686 | /* OldWorld, don't bother looking at other things */ | ||
687 | if (flags & OF_IMAP_OLDWORLD_MAC) | ||
688 | return; | ||
689 | |||
690 | /* If we don't have phandles, let's try to locate a default interrupt | ||
691 | * controller (happens when booting with BootX). We do a first match | ||
692 | * here, hopefully, that only ever happens on machines with one | ||
693 | * controller. | ||
694 | */ | ||
695 | if (flags & OF_IMAP_NO_PHANDLE) { | ||
696 | struct device_node *np; | ||
697 | |||
698 | for (np = NULL; (np = of_find_all_nodes(np)) != NULL;) { | ||
699 | if (of_get_property(np, "interrupt-controller", NULL) | ||
700 | == NULL) | ||
701 | continue; | ||
702 | /* Skip /chosen/interrupt-controller */ | ||
703 | if (strcmp(np->name, "chosen") == 0) | ||
704 | continue; | ||
705 | /* It seems like at least one person on this planet | ||
706 | * wants to use BootX on a machine with an AppleKiwi | ||
707 | * controller which happens to pretend to be an | ||
708 | * interrupt controller too. | ||
709 | */ | ||
710 | if (strcmp(np->name, "AppleKiwi") == 0) | ||
711 | continue; | ||
712 | /* I think we found one ! */ | ||
713 | of_irq_dflt_pic = np; | ||
714 | break; | ||
715 | } | ||
716 | } | ||
717 | |||
718 | } | ||
719 | |||
720 | int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize, | ||
721 | const u32 *addr, struct of_irq *out_irq) | ||
722 | { | ||
723 | struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL; | ||
724 | const u32 *tmp, *imap, *imask; | ||
725 | u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0; | ||
726 | int imaplen, match, i; | ||
727 | |||
728 | pr_debug("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...]," | ||
729 | "ointsize=%d\n", | ||
730 | parent->full_name, intspec[0], intspec[1], ointsize); | ||
731 | |||
732 | ipar = of_node_get(parent); | ||
733 | |||
734 | /* First get the #interrupt-cells property of the current cursor | ||
735 | * that tells us how to interpret the passed-in intspec. If there | ||
736 | * is none, we are nice and just walk up the tree | ||
737 | */ | ||
738 | do { | ||
739 | tmp = of_get_property(ipar, "#interrupt-cells", NULL); | ||
740 | if (tmp != NULL) { | ||
741 | intsize = *tmp; | ||
742 | break; | ||
743 | } | ||
744 | tnode = ipar; | ||
745 | ipar = of_irq_find_parent(ipar); | ||
746 | of_node_put(tnode); | ||
747 | } while (ipar); | ||
748 | if (ipar == NULL) { | ||
749 | pr_debug(" -> no parent found !\n"); | ||
750 | goto fail; | ||
751 | } | ||
752 | |||
753 | pr_debug("of_irq_map_raw: ipar=%s, size=%d\n", | ||
754 | ipar->full_name, intsize); | ||
755 | |||
756 | if (ointsize != intsize) | ||
757 | return -EINVAL; | ||
758 | |||
759 | /* Look for this #address-cells. We have to implement the old linux | ||
760 | * trick of looking for the parent here as some device-trees rely on it | ||
761 | */ | ||
762 | old = of_node_get(ipar); | ||
763 | do { | ||
764 | tmp = of_get_property(old, "#address-cells", NULL); | ||
765 | tnode = of_get_parent(old); | ||
766 | of_node_put(old); | ||
767 | old = tnode; | ||
768 | } while (old && tmp == NULL); | ||
769 | of_node_put(old); | ||
770 | old = NULL; | ||
771 | addrsize = (tmp == NULL) ? 2 : *tmp; | ||
772 | |||
773 | pr_debug(" -> addrsize=%d\n", addrsize); | ||
774 | |||
775 | /* Now start the actual "proper" walk of the interrupt tree */ | ||
776 | while (ipar != NULL) { | ||
777 | /* Now check if cursor is an interrupt-controller and if it is | ||
778 | * then we are done | ||
779 | */ | ||
780 | if (of_get_property(ipar, "interrupt-controller", NULL) != | ||
781 | NULL) { | ||
782 | pr_debug(" -> got it !\n"); | ||
783 | memcpy(out_irq->specifier, intspec, | ||
784 | intsize * sizeof(u32)); | ||
785 | out_irq->size = intsize; | ||
786 | out_irq->controller = ipar; | ||
787 | of_node_put(old); | ||
788 | return 0; | ||
789 | } | ||
790 | |||
791 | /* Now look for an interrupt-map */ | ||
792 | imap = of_get_property(ipar, "interrupt-map", &imaplen); | ||
793 | /* No interrupt map, check for an interrupt parent */ | ||
794 | if (imap == NULL) { | ||
795 | pr_debug(" -> no map, getting parent\n"); | ||
796 | newpar = of_irq_find_parent(ipar); | ||
797 | goto skiplevel; | ||
798 | } | ||
799 | imaplen /= sizeof(u32); | ||
800 | |||
801 | /* Look for a mask */ | ||
802 | imask = of_get_property(ipar, "interrupt-map-mask", NULL); | ||
803 | |||
804 | /* If we were passed no "reg" property and we attempt to parse | ||
805 | * an interrupt-map, then #address-cells must be 0. | ||
806 | * Fail if it's not. | ||
807 | */ | ||
808 | if (addr == NULL && addrsize != 0) { | ||
809 | pr_debug(" -> no reg passed in when needed !\n"); | ||
810 | goto fail; | ||
811 | } | ||
812 | |||
813 | /* Parse interrupt-map */ | ||
814 | match = 0; | ||
815 | while (imaplen > (addrsize + intsize + 1) && !match) { | ||
816 | /* Compare specifiers */ | ||
817 | match = 1; | ||
818 | for (i = 0; i < addrsize && match; ++i) { | ||
819 | u32 mask = imask ? imask[i] : 0xffffffffu; | ||
820 | match = ((addr[i] ^ imap[i]) & mask) == 0; | ||
821 | } | ||
822 | for (; i < (addrsize + intsize) && match; ++i) { | ||
823 | u32 mask = imask ? imask[i] : 0xffffffffu; | ||
824 | match = | ||
825 | ((intspec[i-addrsize] ^ imap[i]) | ||
826 | & mask) == 0; | ||
827 | } | ||
828 | imap += addrsize + intsize; | ||
829 | imaplen -= addrsize + intsize; | ||
830 | |||
831 | pr_debug(" -> match=%d (imaplen=%d)\n", match, imaplen); | ||
832 | |||
833 | /* Get the interrupt parent */ | ||
834 | if (of_irq_workarounds & OF_IMAP_NO_PHANDLE) | ||
835 | newpar = of_node_get(of_irq_dflt_pic); | ||
836 | else | ||
837 | newpar = | ||
838 | of_find_node_by_phandle((phandle)*imap); | ||
839 | imap++; | ||
840 | --imaplen; | ||
841 | |||
842 | /* Check if not found */ | ||
843 | if (newpar == NULL) { | ||
844 | pr_debug(" -> imap parent not found !\n"); | ||
845 | goto fail; | ||
846 | } | ||
847 | |||
848 | /* Get #interrupt-cells and #address-cells of new | ||
849 | * parent | ||
850 | */ | ||
851 | tmp = of_get_property(newpar, "#interrupt-cells", NULL); | ||
852 | if (tmp == NULL) { | ||
853 | pr_debug(" -> parent lacks " | ||
854 | "#interrupt-cells!\n"); | ||
855 | goto fail; | ||
856 | } | ||
857 | newintsize = *tmp; | ||
858 | tmp = of_get_property(newpar, "#address-cells", NULL); | ||
859 | newaddrsize = (tmp == NULL) ? 0 : *tmp; | ||
860 | |||
861 | pr_debug(" -> newintsize=%d, newaddrsize=%d\n", | ||
862 | newintsize, newaddrsize); | ||
863 | |||
864 | /* Check for malformed properties */ | ||
865 | if (imaplen < (newaddrsize + newintsize)) | ||
866 | goto fail; | ||
867 | |||
868 | imap += newaddrsize + newintsize; | ||
869 | imaplen -= newaddrsize + newintsize; | ||
870 | |||
871 | pr_debug(" -> imaplen=%d\n", imaplen); | ||
872 | } | ||
873 | if (!match) | ||
874 | goto fail; | ||
875 | |||
876 | of_node_put(old); | ||
877 | old = of_node_get(newpar); | ||
878 | addrsize = newaddrsize; | ||
879 | intsize = newintsize; | ||
880 | intspec = imap - intsize; | ||
881 | addr = intspec - addrsize; | ||
882 | |||
883 | skiplevel: | ||
884 | /* Iterate again with new parent */ | ||
885 | pr_debug(" -> new parent: %s\n", | ||
886 | newpar ? newpar->full_name : "<>"); | ||
887 | of_node_put(ipar); | ||
888 | ipar = newpar; | ||
889 | newpar = NULL; | ||
890 | } | ||
891 | fail: | ||
892 | of_node_put(ipar); | ||
893 | of_node_put(old); | ||
894 | of_node_put(newpar); | ||
895 | |||
896 | return -EINVAL; | ||
897 | } | ||
898 | EXPORT_SYMBOL_GPL(of_irq_map_raw); | ||
899 | |||
900 | int of_irq_map_one(struct device_node *device, | ||
901 | int index, struct of_irq *out_irq) | ||
902 | { | ||
903 | struct device_node *p; | ||
904 | const u32 *intspec, *tmp, *addr; | ||
905 | u32 intsize, intlen; | ||
906 | int res; | ||
907 | |||
908 | pr_debug("of_irq_map_one: dev=%s, index=%d\n", | ||
909 | device->full_name, index); | ||
910 | |||
911 | /* Get the interrupts property */ | ||
912 | intspec = of_get_property(device, "interrupts", (int *) &intlen); | ||
913 | if (intspec == NULL) | ||
914 | return -EINVAL; | ||
915 | intlen /= sizeof(u32); | ||
916 | |||
917 | pr_debug(" intspec=%d intlen=%d\n", *intspec, intlen); | ||
918 | |||
919 | /* Get the reg property (if any) */ | ||
920 | addr = of_get_property(device, "reg", NULL); | ||
921 | |||
922 | /* Look for the interrupt parent. */ | ||
923 | p = of_irq_find_parent(device); | ||
924 | if (p == NULL) | ||
925 | return -EINVAL; | ||
926 | |||
927 | /* Get size of interrupt specifier */ | ||
928 | tmp = of_get_property(p, "#interrupt-cells", NULL); | ||
929 | if (tmp == NULL) { | ||
930 | of_node_put(p); | ||
931 | return -EINVAL; | ||
932 | } | ||
933 | intsize = *tmp; | ||
934 | |||
935 | pr_debug(" intsize=%d intlen=%d\n", intsize, intlen); | ||
936 | |||
937 | /* Check index */ | ||
938 | if ((index + 1) * intsize > intlen) | ||
939 | return -EINVAL; | ||
940 | |||
941 | /* Get new specifier and map it */ | ||
942 | res = of_irq_map_raw(p, intspec + index * intsize, intsize, | ||
943 | addr, out_irq); | ||
944 | of_node_put(p); | ||
945 | return res; | ||
946 | } | ||
947 | EXPORT_SYMBOL_GPL(of_irq_map_one); | ||
948 | |||
949 | /** | ||
950 | * Search the device tree for the best MAC address to use. 'mac-address' is | ||
951 | * checked first, because that is supposed to contain to "most recent" MAC | ||
952 | * address. If that isn't set, then 'local-mac-address' is checked next, | ||
953 | * because that is the default address. If that isn't set, then the obsolete | ||
954 | * 'address' is checked, just in case we're using an old device tree. | ||
955 | * | ||
956 | * Note that the 'address' property is supposed to contain a virtual address of | ||
957 | * the register set, but some DTS files have redefined that property to be the | ||
958 | * MAC address. | ||
959 | * | ||
960 | * All-zero MAC addresses are rejected, because those could be properties that | ||
961 | * exist in the device tree, but were not set by U-Boot. For example, the | ||
962 | * DTS could define 'mac-address' and 'local-mac-address', with zero MAC | ||
963 | * addresses. Some older U-Boots only initialized 'local-mac-address'. In | ||
964 | * this case, the real MAC is in 'local-mac-address', and 'mac-address' exists | ||
965 | * but is all zeros. | ||
966 | */ | ||
967 | const void *of_get_mac_address(struct device_node *np) | ||
968 | { | ||
969 | struct property *pp; | ||
970 | |||
971 | pp = of_find_property(np, "mac-address", NULL); | ||
972 | if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value)) | ||
973 | return pp->value; | ||
974 | |||
975 | pp = of_find_property(np, "local-mac-address", NULL); | ||
976 | if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value)) | ||
977 | return pp->value; | ||
978 | |||
979 | pp = of_find_property(np, "address", NULL); | ||
980 | if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value)) | ||
981 | return pp->value; | ||
982 | |||
983 | return NULL; | ||
984 | } | ||
985 | EXPORT_SYMBOL(of_get_mac_address); | ||
986 | |||
987 | int of_irq_to_resource(struct device_node *dev, int index, struct resource *r) | ||
988 | { | ||
989 | struct of_irq out_irq; | ||
990 | int irq; | ||
991 | int res; | ||
992 | |||
993 | res = of_irq_map_one(dev, index, &out_irq); | ||
994 | |||
995 | /* Get irq for the device */ | ||
996 | if (res) { | ||
997 | pr_debug("IRQ not found... code = %d", res); | ||
998 | return NO_IRQ; | ||
999 | } | ||
1000 | /* Assuming single interrupt controller... */ | ||
1001 | irq = out_irq.specifier[0]; | ||
1002 | |||
1003 | pr_debug("IRQ found = %d", irq); | ||
1004 | |||
1005 | /* Only dereference the resource if both the | ||
1006 | * resource and the irq are valid. */ | ||
1007 | if (r && irq != NO_IRQ) { | ||
1008 | r->start = r->end = irq; | ||
1009 | r->flags = IORESOURCE_IRQ; | ||
1010 | } | ||
1011 | |||
1012 | return irq; | ||
1013 | } | ||
1014 | EXPORT_SYMBOL_GPL(of_irq_to_resource); | ||
1015 | |||
1016 | void __iomem *of_iomap(struct device_node *np, int index) | ||
1017 | { | ||
1018 | struct resource res; | ||
1019 | |||
1020 | if (of_address_to_resource(np, index, &res)) | ||
1021 | return NULL; | ||
1022 | |||
1023 | return ioremap(res.start, 1 + res.end - res.start); | ||
1024 | } | ||
1025 | EXPORT_SYMBOL(of_iomap); | ||
diff --git a/arch/microblaze/kernel/ptrace.c b/arch/microblaze/kernel/ptrace.c new file mode 100644 index 000000000000..3171e39e3220 --- /dev/null +++ b/arch/microblaze/kernel/ptrace.c | |||
@@ -0,0 +1,182 @@ | |||
1 | /* | ||
2 | * `ptrace' system call | ||
3 | * | ||
4 | * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu> | ||
5 | * Copyright (C) 2007-2009 PetaLogix | ||
6 | * Copyright (C) 2004-2007 John Williams <john.williams@petalogix.com> | ||
7 | * | ||
8 | * derived from arch/v850/kernel/ptrace.c | ||
9 | * | ||
10 | * Copyright (C) 2002,03 NEC Electronics Corporation | ||
11 | * Copyright (C) 2002,03 Miles Bader <miles@gnu.org> | ||
12 | * | ||
13 | * Derived from arch/mips/kernel/ptrace.c: | ||
14 | * | ||
15 | * Copyright (C) 1992 Ross Biro | ||
16 | * Copyright (C) Linus Torvalds | ||
17 | * Copyright (C) 1994, 95, 96, 97, 98, 2000 Ralf Baechle | ||
18 | * Copyright (C) 1996 David S. Miller | ||
19 | * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com | ||
20 | * Copyright (C) 1999 MIPS Technologies, Inc. | ||
21 | * | ||
22 | * This file is subject to the terms and conditions of the GNU General | ||
23 | * Public License. See the file COPYING in the main directory of this | ||
24 | * archive for more details. | ||
25 | */ | ||
26 | |||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/mm.h> | ||
29 | #include <linux/sched.h> | ||
30 | #include <linux/smp_lock.h> | ||
31 | #include <linux/ptrace.h> | ||
32 | #include <linux/signal.h> | ||
33 | |||
34 | #include <linux/errno.h> | ||
35 | #include <linux/ptrace.h> | ||
36 | #include <asm/processor.h> | ||
37 | #include <linux/uaccess.h> | ||
38 | #include <asm/asm-offsets.h> | ||
39 | |||
40 | /* Returns the address where the register at REG_OFFS in P is stashed away. */ | ||
41 | static microblaze_reg_t *reg_save_addr(unsigned reg_offs, | ||
42 | struct task_struct *t) | ||
43 | { | ||
44 | struct pt_regs *regs; | ||
45 | |||
46 | /* | ||
47 | * Three basic cases: | ||
48 | * | ||
49 | * (1) A register normally saved before calling the scheduler, is | ||
50 | * available in the kernel entry pt_regs structure at the top | ||
51 | * of the kernel stack. The kernel trap/irq exit path takes | ||
52 | * care to save/restore almost all registers for ptrace'd | ||
53 | * processes. | ||
54 | * | ||
55 | * (2) A call-clobbered register, where the process P entered the | ||
56 | * kernel via [syscall] trap, is not stored anywhere; that's | ||
57 | * OK, because such registers are not expected to be preserved | ||
58 | * when the trap returns anyway (so we don't actually bother to | ||
59 | * test for this case). | ||
60 | * | ||
61 | * (3) A few registers not used at all by the kernel, and so | ||
62 | * normally never saved except by context-switches, are in the | ||
63 | * context switch state. | ||
64 | */ | ||
65 | |||
66 | /* Register saved during kernel entry (or not available). */ | ||
67 | regs = task_pt_regs(t); | ||
68 | |||
69 | return (microblaze_reg_t *)((char *)regs + reg_offs); | ||
70 | } | ||
71 | |||
72 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) | ||
73 | { | ||
74 | int rval; | ||
75 | unsigned long val = 0; | ||
76 | unsigned long copied; | ||
77 | |||
78 | switch (request) { | ||
79 | case PTRACE_PEEKTEXT: /* read word at location addr. */ | ||
80 | case PTRACE_PEEKDATA: | ||
81 | pr_debug("PEEKTEXT/PEEKDATA at %08lX\n", addr); | ||
82 | copied = access_process_vm(child, addr, &val, sizeof(val), 0); | ||
83 | rval = -EIO; | ||
84 | if (copied != sizeof(val)) | ||
85 | break; | ||
86 | rval = put_user(val, (unsigned long *)data); | ||
87 | break; | ||
88 | |||
89 | case PTRACE_POKETEXT: /* write the word at location addr. */ | ||
90 | case PTRACE_POKEDATA: | ||
91 | pr_debug("POKETEXT/POKEDATA to %08lX\n", addr); | ||
92 | rval = 0; | ||
93 | if (access_process_vm(child, addr, &data, sizeof(data), 1) | ||
94 | == sizeof(data)) | ||
95 | break; | ||
96 | rval = -EIO; | ||
97 | break; | ||
98 | |||
99 | /* Read/write the word at location ADDR in the registers. */ | ||
100 | case PTRACE_PEEKUSR: | ||
101 | case PTRACE_POKEUSR: | ||
102 | pr_debug("PEEKUSR/POKEUSR : 0x%08lx\n", addr); | ||
103 | rval = 0; | ||
104 | if (addr >= PT_SIZE && request == PTRACE_PEEKUSR) { | ||
105 | /* | ||
106 | * Special requests that don't actually correspond | ||
107 | * to offsets in struct pt_regs. | ||
108 | */ | ||
109 | if (addr == PT_TEXT_ADDR) { | ||
110 | val = child->mm->start_code; | ||
111 | } else if (addr == PT_DATA_ADDR) { | ||
112 | val = child->mm->start_data; | ||
113 | } else if (addr == PT_TEXT_LEN) { | ||
114 | val = child->mm->end_code | ||
115 | - child->mm->start_code; | ||
116 | } else { | ||
117 | rval = -EIO; | ||
118 | } | ||
119 | } else if (addr >= 0 && addr < PT_SIZE && (addr & 0x3) == 0) { | ||
120 | microblaze_reg_t *reg_addr = reg_save_addr(addr, child); | ||
121 | if (request == PTRACE_PEEKUSR) | ||
122 | val = *reg_addr; | ||
123 | else | ||
124 | *reg_addr = data; | ||
125 | } else | ||
126 | rval = -EIO; | ||
127 | |||
128 | if (rval == 0 && request == PTRACE_PEEKUSR) | ||
129 | rval = put_user(val, (unsigned long *)data); | ||
130 | break; | ||
131 | /* Continue and stop at next (return from) syscall */ | ||
132 | case PTRACE_SYSCALL: | ||
133 | pr_debug("PTRACE_SYSCALL\n"); | ||
134 | case PTRACE_SINGLESTEP: | ||
135 | pr_debug("PTRACE_SINGLESTEP\n"); | ||
136 | /* Restart after a signal. */ | ||
137 | case PTRACE_CONT: | ||
138 | pr_debug("PTRACE_CONT\n"); | ||
139 | rval = -EIO; | ||
140 | if (!valid_signal(data)) | ||
141 | break; | ||
142 | |||
143 | if (request == PTRACE_SYSCALL) | ||
144 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | ||
145 | else | ||
146 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | ||
147 | |||
148 | child->exit_code = data; | ||
149 | pr_debug("wakeup_process\n"); | ||
150 | wake_up_process(child); | ||
151 | rval = 0; | ||
152 | break; | ||
153 | |||
154 | /* | ||
155 | * make the child exit. Best I can do is send it a sigkill. | ||
156 | * perhaps it should be put in the status that it wants to | ||
157 | * exit. | ||
158 | */ | ||
159 | case PTRACE_KILL: | ||
160 | pr_debug("PTRACE_KILL\n"); | ||
161 | rval = 0; | ||
162 | if (child->exit_state == EXIT_ZOMBIE) /* already dead */ | ||
163 | break; | ||
164 | child->exit_code = SIGKILL; | ||
165 | wake_up_process(child); | ||
166 | break; | ||
167 | |||
168 | case PTRACE_DETACH: /* detach a process that was attached. */ | ||
169 | pr_debug("PTRACE_DETACH\n"); | ||
170 | rval = ptrace_detach(child, data); | ||
171 | break; | ||
172 | default: | ||
173 | /* rval = ptrace_request(child, request, addr, data); noMMU */ | ||
174 | rval = -EIO; | ||
175 | } | ||
176 | return rval; | ||
177 | } | ||
178 | |||
179 | void ptrace_disable(struct task_struct *child) | ||
180 | { | ||
181 | /* nothing to do */ | ||
182 | } | ||
diff --git a/arch/microblaze/kernel/selfmod.c b/arch/microblaze/kernel/selfmod.c new file mode 100644 index 000000000000..89508bdc9f3c --- /dev/null +++ b/arch/microblaze/kernel/selfmod.c | |||
@@ -0,0 +1,81 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> | ||
3 | * Copyright (C) 2009 PetaLogix | ||
4 | * | ||
5 | * This file is subject to the terms and conditions of the GNU General Public | ||
6 | * License. See the file "COPYING" in the main directory of this archive | ||
7 | * for more details. | ||
8 | */ | ||
9 | |||
10 | #include <linux/interrupt.h> | ||
11 | #include <asm/selfmod.h> | ||
12 | |||
13 | #undef DEBUG | ||
14 | |||
15 | #if __GNUC__ > 3 | ||
16 | #error GCC 4 unsupported SELFMOD. Please disable SELFMOD from menuconfig. | ||
17 | #endif | ||
18 | |||
19 | #define OPCODE_IMM 0xB0000000 | ||
20 | #define OPCODE_LWI 0xE8000000 | ||
21 | #define OPCODE_LWI_MASK 0xEC000000 | ||
22 | #define OPCODE_RTSD 0xB60F0008 /* return from func: rtsd r15, 8 */ | ||
23 | #define OPCODE_ADDIK 0x30000000 | ||
24 | #define OPCODE_ADDIK_MASK 0xFC000000 | ||
25 | |||
26 | #define IMM_BASE (OPCODE_IMM | (BARRIER_BASE_ADDR >> 16)) | ||
27 | #define LWI_BASE (OPCODE_LWI | (BARRIER_BASE_ADDR & 0x0000ff00)) | ||
28 | #define LWI_BASE_MASK (OPCODE_LWI_MASK | (BARRIER_BASE_ADDR & 0x0000ff00)) | ||
29 | #define ADDIK_BASE (OPCODE_ADDIK | (BARRIER_BASE_ADDR & 0x0000ff00)) | ||
30 | #define ADDIK_BASE_MASK (OPCODE_ADDIK_MASK | (BARRIER_BASE_ADDR & 0x0000ff00)) | ||
31 | |||
32 | #define MODIFY_INSTR { \ | ||
33 | pr_debug("%s: curr instr, (%d):0x%x, next(%d):0x%x\n", \ | ||
34 | __func__, i, addr[i], i + 1, addr[i + 1]); \ | ||
35 | addr[i] = OPCODE_IMM + (base >> 16); \ | ||
36 | /* keep instruction opcode and add only last 16bits */ \ | ||
37 | addr[i + 1] = (addr[i + 1] & 0xffff00ff) + (base & 0xffff); \ | ||
38 | __invalidate_icache(addr[i]); \ | ||
39 | __invalidate_icache(addr[i + 1]); \ | ||
40 | pr_debug("%s: hack instr, (%d):0x%x, next(%d):0x%x\n", \ | ||
41 | __func__, i, addr[i], i + 1, addr[i + 1]); } | ||
42 | |||
43 | /* NOTE | ||
44 | * self-modified part of code for improvement of interrupt controller | ||
45 | * save instruction in interrupt rutine | ||
46 | */ | ||
47 | void selfmod_function(const int *arr_fce, const unsigned int base) | ||
48 | { | ||
49 | unsigned int flags, i, j, *addr = NULL; | ||
50 | |||
51 | local_irq_save(flags); | ||
52 | __disable_icache(); | ||
53 | |||
54 | /* zero terminated array */ | ||
55 | for (j = 0; arr_fce[j] != 0; j++) { | ||
56 | /* get start address of function */ | ||
57 | addr = (unsigned int *) arr_fce[j]; | ||
58 | pr_debug("%s: func(%d) at 0x%x\n", | ||
59 | __func__, j, (unsigned int) addr); | ||
60 | for (i = 0; ; i++) { | ||
61 | pr_debug("%s: instruction code at %d: 0x%x\n", | ||
62 | __func__, i, addr[i]); | ||
63 | if (addr[i] == IMM_BASE) { | ||
64 | /* detecting of lwi (0xE8) or swi (0xF8) instr | ||
65 | * I can detect both opcode with one mask */ | ||
66 | if ((addr[i + 1] & LWI_BASE_MASK) == LWI_BASE) { | ||
67 | MODIFY_INSTR; | ||
68 | } else /* detection addik for ack */ | ||
69 | if ((addr[i + 1] & ADDIK_BASE_MASK) == | ||
70 | ADDIK_BASE) { | ||
71 | MODIFY_INSTR; | ||
72 | } | ||
73 | } else if (addr[i] == OPCODE_RTSD) { | ||
74 | /* return from function means end of function */ | ||
75 | pr_debug("%s: end of array %d\n", __func__, i); | ||
76 | break; | ||
77 | } | ||
78 | } | ||
79 | } | ||
80 | local_irq_restore(flags); | ||
81 | } /* end of self-modified code */ | ||
diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c new file mode 100644 index 000000000000..eb6b41758e23 --- /dev/null +++ b/arch/microblaze/kernel/setup.c | |||
@@ -0,0 +1,199 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> | ||
3 | * Copyright (C) 2007-2009 PetaLogix | ||
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 | */ | ||
10 | |||
11 | #include <linux/init.h> | ||
12 | #include <linux/string.h> | ||
13 | #include <linux/seq_file.h> | ||
14 | #include <linux/cpu.h> | ||
15 | #include <linux/initrd.h> | ||
16 | #include <linux/console.h> | ||
17 | #include <linux/debugfs.h> | ||
18 | |||
19 | #include <asm/setup.h> | ||
20 | #include <asm/sections.h> | ||
21 | #include <asm/page.h> | ||
22 | #include <linux/io.h> | ||
23 | #include <linux/bug.h> | ||
24 | #include <linux/param.h> | ||
25 | #include <linux/cache.h> | ||
26 | #include <asm/cacheflush.h> | ||
27 | #include <asm/entry.h> | ||
28 | #include <asm/cpuinfo.h> | ||
29 | |||
30 | #include <asm/system.h> | ||
31 | #include <asm/prom.h> | ||
32 | #include <asm/pgtable.h> | ||
33 | |||
34 | DEFINE_PER_CPU(unsigned int, KSP); /* Saved kernel stack pointer */ | ||
35 | DEFINE_PER_CPU(unsigned int, KM); /* Kernel/user mode */ | ||
36 | DEFINE_PER_CPU(unsigned int, ENTRY_SP); /* Saved SP on kernel entry */ | ||
37 | DEFINE_PER_CPU(unsigned int, R11_SAVE); /* Temp variable for entry */ | ||
38 | DEFINE_PER_CPU(unsigned int, CURRENT_SAVE); /* Saved current pointer */ | ||
39 | |||
40 | unsigned int boot_cpuid; | ||
41 | char cmd_line[COMMAND_LINE_SIZE]; | ||
42 | |||
43 | void __init setup_arch(char **cmdline_p) | ||
44 | { | ||
45 | #ifdef CONFIG_CMDLINE_FORCE | ||
46 | strlcpy(cmd_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE); | ||
47 | strlcpy(boot_command_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE); | ||
48 | #endif | ||
49 | *cmdline_p = cmd_line; | ||
50 | |||
51 | console_verbose(); | ||
52 | |||
53 | unflatten_device_tree(); | ||
54 | |||
55 | /* NOTE I think that this function is not necessary to call */ | ||
56 | /* irq_early_init(); */ | ||
57 | setup_cpuinfo(); | ||
58 | |||
59 | __invalidate_icache_all(); | ||
60 | __enable_icache(); | ||
61 | |||
62 | __invalidate_dcache_all(); | ||
63 | __enable_dcache(); | ||
64 | |||
65 | panic_timeout = 120; | ||
66 | |||
67 | setup_memory(); | ||
68 | |||
69 | #if defined(CONFIG_SELFMOD_INTC) || defined(CONFIG_SELFMOD_TIMER) | ||
70 | printk(KERN_NOTICE "Self modified code enable\n"); | ||
71 | #endif | ||
72 | |||
73 | #ifdef CONFIG_VT | ||
74 | #if defined(CONFIG_XILINX_CONSOLE) | ||
75 | conswitchp = &xil_con; | ||
76 | #elif defined(CONFIG_DUMMY_CONSOLE) | ||
77 | conswitchp = &dummy_con; | ||
78 | #endif | ||
79 | #endif | ||
80 | } | ||
81 | |||
82 | #ifdef CONFIG_MTD_UCLINUX | ||
83 | /* Handle both romfs and cramfs types, without generating unnecessary | ||
84 | code (ie no point checking for CRAMFS if it's not even enabled) */ | ||
85 | inline unsigned get_romfs_len(unsigned *addr) | ||
86 | { | ||
87 | #ifdef CONFIG_ROMFS_FS | ||
88 | if (memcmp(&addr[0], "-rom1fs-", 8) == 0) /* romfs */ | ||
89 | return be32_to_cpu(addr[2]); | ||
90 | #endif | ||
91 | |||
92 | #ifdef CONFIG_CRAMFS | ||
93 | if (addr[0] == le32_to_cpu(0x28cd3d45)) /* cramfs */ | ||
94 | return le32_to_cpu(addr[1]); | ||
95 | #endif | ||
96 | return 0; | ||
97 | } | ||
98 | #endif /* CONFIG_MTD_UCLINUX_EBSS */ | ||
99 | |||
100 | void __init machine_early_init(const char *cmdline, unsigned int ram, | ||
101 | unsigned int fdt) | ||
102 | { | ||
103 | unsigned long *src, *dst = (unsigned long *)0x0; | ||
104 | |||
105 | /* clearing bss section */ | ||
106 | memset(__bss_start, 0, __bss_stop-__bss_start); | ||
107 | memset(_ssbss, 0, _esbss-_ssbss); | ||
108 | |||
109 | /* | ||
110 | * Copy command line passed from bootloader, or use default | ||
111 | * if none provided, or forced | ||
112 | */ | ||
113 | #ifndef CONFIG_CMDLINE_BOOL | ||
114 | if (cmdline && cmdline[0] != '\0') | ||
115 | strlcpy(cmd_line, cmdline, COMMAND_LINE_SIZE); | ||
116 | #endif | ||
117 | |||
118 | /* initialize device tree for usage in early_printk */ | ||
119 | early_init_devtree((void *)_fdt_start); | ||
120 | |||
121 | #ifdef CONFIG_EARLY_PRINTK | ||
122 | setup_early_printk(NULL); | ||
123 | #endif | ||
124 | |||
125 | early_printk("Ramdisk addr 0x%08x, FDT 0x%08x\n", ram, fdt); | ||
126 | printk(KERN_NOTICE "Found FDT at 0x%08x\n", fdt); | ||
127 | |||
128 | #ifdef CONFIG_MTD_UCLINUX | ||
129 | { | ||
130 | int size; | ||
131 | unsigned int romfs_base; | ||
132 | romfs_base = (ram ? ram : (unsigned int)&__init_end); | ||
133 | /* if CONFIG_MTD_UCLINUX_EBSS is defined, assume ROMFS is at the | ||
134 | * end of kernel, which is ROMFS_LOCATION defined above. */ | ||
135 | size = PAGE_ALIGN(get_romfs_len((unsigned *)romfs_base)); | ||
136 | early_printk("Found romfs @ 0x%08x (0x%08x)\n", | ||
137 | romfs_base, size); | ||
138 | early_printk("#### klimit %p ####\n", klimit); | ||
139 | BUG_ON(size < 0); /* What else can we do? */ | ||
140 | |||
141 | /* Use memmove to handle likely case of memory overlap */ | ||
142 | early_printk("Moving 0x%08x bytes from 0x%08x to 0x%08x\n", | ||
143 | size, romfs_base, (unsigned)&_ebss); | ||
144 | memmove(&_ebss, (int *)romfs_base, size); | ||
145 | |||
146 | /* update klimit */ | ||
147 | klimit += PAGE_ALIGN(size); | ||
148 | early_printk("New klimit: 0x%08x\n", (unsigned)klimit); | ||
149 | } | ||
150 | #endif | ||
151 | |||
152 | for (src = __ivt_start; src < __ivt_end; src++, dst++) | ||
153 | *dst = *src; | ||
154 | |||
155 | /* Initialize global data */ | ||
156 | per_cpu(KM, 0) = 0x1; /* We start in kernel mode */ | ||
157 | per_cpu(CURRENT_SAVE, 0) = (unsigned long)current; | ||
158 | } | ||
159 | |||
160 | #ifdef CONFIG_DEBUG_FS | ||
161 | struct dentry *of_debugfs_root; | ||
162 | |||
163 | static int microblaze_debugfs_init(void) | ||
164 | { | ||
165 | of_debugfs_root = debugfs_create_dir("microblaze", NULL); | ||
166 | |||
167 | return of_debugfs_root == NULL; | ||
168 | } | ||
169 | arch_initcall(microblaze_debugfs_init); | ||
170 | #endif | ||
171 | |||
172 | void machine_restart(char *cmd) | ||
173 | { | ||
174 | printk(KERN_NOTICE "Machine restart...\n"); | ||
175 | dump_stack(); | ||
176 | while (1) | ||
177 | ; | ||
178 | } | ||
179 | |||
180 | void machine_shutdown(void) | ||
181 | { | ||
182 | printk(KERN_NOTICE "Machine shutdown...\n"); | ||
183 | while (1) | ||
184 | ; | ||
185 | } | ||
186 | |||
187 | void machine_halt(void) | ||
188 | { | ||
189 | printk(KERN_NOTICE "Machine halt...\n"); | ||
190 | while (1) | ||
191 | ; | ||
192 | } | ||
193 | |||
194 | void machine_power_off(void) | ||
195 | { | ||
196 | printk(KERN_NOTICE "Machine power off...\n"); | ||
197 | while (1) | ||
198 | ; | ||
199 | } | ||
diff --git a/arch/microblaze/kernel/signal.c b/arch/microblaze/kernel/signal.c new file mode 100644 index 000000000000..ff347b98863a --- /dev/null +++ b/arch/microblaze/kernel/signal.c | |||
@@ -0,0 +1,538 @@ | |||
1 | /* | ||
2 | * Signal handling | ||
3 | * | ||
4 | * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu> | ||
5 | * Copyright (C) 2008-2009 PetaLogix | ||
6 | * Copyright (C) 2003,2004 John Williams <jwilliams@itee.uq.edu.au> | ||
7 | * Copyright (C) 2001 NEC Corporation | ||
8 | * Copyright (C) 2001 Miles Bader <miles@gnu.org> | ||
9 | * Copyright (C) 1999,2000 Niibe Yutaka & Kaz Kojima | ||
10 | * Copyright (C) 1991,1992 Linus Torvalds | ||
11 | * | ||
12 | * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson | ||
13 | * | ||
14 | * This file was was derived from the sh version, arch/sh/kernel/signal.c | ||
15 | * | ||
16 | * This file is subject to the terms and conditions of the GNU General | ||
17 | * Public License. See the file COPYING in the main directory of this | ||
18 | * archive for more details. | ||
19 | */ | ||
20 | |||
21 | #include <linux/sched.h> | ||
22 | #include <linux/mm.h> | ||
23 | #include <linux/smp.h> | ||
24 | #include <linux/smp_lock.h> | ||
25 | #include <linux/kernel.h> | ||
26 | #include <linux/signal.h> | ||
27 | #include <linux/errno.h> | ||
28 | #include <linux/wait.h> | ||
29 | #include <linux/ptrace.h> | ||
30 | #include <linux/unistd.h> | ||
31 | #include <linux/stddef.h> | ||
32 | #include <linux/personality.h> | ||
33 | #include <linux/percpu.h> | ||
34 | #include <linux/linkage.h> | ||
35 | #include <asm/entry.h> | ||
36 | #include <asm/ucontext.h> | ||
37 | #include <linux/uaccess.h> | ||
38 | #include <asm/pgtable.h> | ||
39 | #include <asm/pgalloc.h> | ||
40 | #include <linux/signal.h> | ||
41 | #include <linux/syscalls.h> | ||
42 | #include <asm/cacheflush.h> | ||
43 | #include <asm/syscalls.h> | ||
44 | |||
45 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) | ||
46 | |||
47 | asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_sycall); | ||
48 | |||
49 | /* | ||
50 | * Atomically swap in the new signal mask, and wait for a signal. | ||
51 | */ | ||
52 | asmlinkage int | ||
53 | sys_sigsuspend(old_sigset_t mask, struct pt_regs *regs) | ||
54 | { | ||
55 | sigset_t saveset; | ||
56 | |||
57 | mask &= _BLOCKABLE; | ||
58 | spin_lock_irq(¤t->sighand->siglock); | ||
59 | saveset = current->blocked; | ||
60 | siginitset(¤t->blocked, mask); | ||
61 | recalc_sigpending(); | ||
62 | spin_unlock_irq(¤t->sighand->siglock); | ||
63 | |||
64 | regs->r3 = -EINTR; | ||
65 | while (1) { | ||
66 | current->state = TASK_INTERRUPTIBLE; | ||
67 | schedule(); | ||
68 | if (do_signal(regs, &saveset, 1)) | ||
69 | return -EINTR; | ||
70 | } | ||
71 | } | ||
72 | |||
73 | asmlinkage int | ||
74 | sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, | ||
75 | struct pt_regs *regs) | ||
76 | { | ||
77 | sigset_t saveset, newset; | ||
78 | |||
79 | /* XXX: Don't preclude handling different sized sigset_t's. */ | ||
80 | if (sigsetsize != sizeof(sigset_t)) | ||
81 | return -EINVAL; | ||
82 | |||
83 | if (copy_from_user(&newset, unewset, sizeof(newset))) | ||
84 | return -EFAULT; | ||
85 | sigdelsetmask(&newset, ~_BLOCKABLE); | ||
86 | spin_lock_irq(¤t->sighand->siglock); | ||
87 | saveset = current->blocked; | ||
88 | current->blocked = newset; | ||
89 | recalc_sigpending(); | ||
90 | spin_unlock_irq(¤t->sighand->siglock); | ||
91 | |||
92 | regs->r3 = -EINTR; | ||
93 | while (1) { | ||
94 | current->state = TASK_INTERRUPTIBLE; | ||
95 | schedule(); | ||
96 | if (do_signal(regs, &saveset, 1)) | ||
97 | return -EINTR; | ||
98 | } | ||
99 | } | ||
100 | |||
101 | asmlinkage int | ||
102 | sys_sigaction(int sig, const struct old_sigaction *act, | ||
103 | struct old_sigaction *oact) | ||
104 | { | ||
105 | struct k_sigaction new_ka, old_ka; | ||
106 | int ret; | ||
107 | |||
108 | if (act) { | ||
109 | old_sigset_t mask; | ||
110 | if (!access_ok(VERIFY_READ, act, sizeof(*act)) || | ||
111 | __get_user(new_ka.sa.sa_handler, &act->sa_handler) || | ||
112 | __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) | ||
113 | return -EFAULT; | ||
114 | __get_user(new_ka.sa.sa_flags, &act->sa_flags); | ||
115 | __get_user(mask, &act->sa_mask); | ||
116 | siginitset(&new_ka.sa.sa_mask, mask); | ||
117 | } | ||
118 | |||
119 | ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); | ||
120 | |||
121 | if (!ret && oact) { | ||
122 | if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || | ||
123 | __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || | ||
124 | __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) | ||
125 | return -EFAULT; | ||
126 | __put_user(old_ka.sa.sa_flags, &oact->sa_flags); | ||
127 | __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); | ||
128 | } | ||
129 | |||
130 | return ret; | ||
131 | } | ||
132 | |||
133 | asmlinkage int | ||
134 | sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, | ||
135 | struct pt_regs *regs) | ||
136 | { | ||
137 | return do_sigaltstack(uss, uoss, regs->r1); | ||
138 | } | ||
139 | |||
140 | /* | ||
141 | * Do a signal return; undo the signal stack. | ||
142 | */ | ||
143 | |||
144 | struct sigframe { | ||
145 | struct sigcontext sc; | ||
146 | unsigned long extramask[_NSIG_WORDS-1]; | ||
147 | unsigned long tramp[2]; /* signal trampoline */ | ||
148 | }; | ||
149 | |||
150 | struct rt_sigframe { | ||
151 | struct siginfo info; | ||
152 | struct ucontext uc; | ||
153 | unsigned long tramp[2]; /* signal trampoline */ | ||
154 | }; | ||
155 | |||
156 | static int | ||
157 | restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc, int *rval_p) | ||
158 | { | ||
159 | unsigned int err = 0; | ||
160 | |||
161 | #define COPY(x) {err |= __get_user(regs->x, &sc->regs.x); } | ||
162 | COPY(r0); | ||
163 | COPY(r1); | ||
164 | COPY(r2); COPY(r3); COPY(r4); COPY(r5); | ||
165 | COPY(r6); COPY(r7); COPY(r8); COPY(r9); | ||
166 | COPY(r10); COPY(r11); COPY(r12); COPY(r13); | ||
167 | COPY(r14); COPY(r15); COPY(r16); COPY(r17); | ||
168 | COPY(r18); COPY(r19); COPY(r20); COPY(r21); | ||
169 | COPY(r22); COPY(r23); COPY(r24); COPY(r25); | ||
170 | COPY(r26); COPY(r27); COPY(r28); COPY(r29); | ||
171 | COPY(r30); COPY(r31); | ||
172 | COPY(pc); COPY(ear); COPY(esr); COPY(fsr); | ||
173 | #undef COPY | ||
174 | |||
175 | *rval_p = regs->r3; | ||
176 | |||
177 | return err; | ||
178 | } | ||
179 | |||
180 | asmlinkage int sys_sigreturn(struct pt_regs *regs) | ||
181 | { | ||
182 | struct sigframe *frame = (struct sigframe *)regs->r1; | ||
183 | sigset_t set; | ||
184 | int rval; | ||
185 | |||
186 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) | ||
187 | goto badframe; | ||
188 | |||
189 | if (__get_user(set.sig[0], &frame->sc.oldmask) | ||
190 | || (_NSIG_WORDS > 1 | ||
191 | && __copy_from_user(&set.sig[1], &frame->extramask, | ||
192 | sizeof(frame->extramask)))) | ||
193 | goto badframe; | ||
194 | |||
195 | sigdelsetmask(&set, ~_BLOCKABLE); | ||
196 | |||
197 | spin_lock_irq(¤t->sighand->siglock); | ||
198 | current->blocked = set; | ||
199 | recalc_sigpending(); | ||
200 | spin_unlock_irq(¤t->sighand->siglock); | ||
201 | |||
202 | if (restore_sigcontext(regs, &frame->sc, &rval)) | ||
203 | goto badframe; | ||
204 | return rval; | ||
205 | |||
206 | badframe: | ||
207 | force_sig(SIGSEGV, current); | ||
208 | return 0; | ||
209 | } | ||
210 | |||
211 | asmlinkage int sys_rt_sigreturn(struct pt_regs *regs) | ||
212 | { | ||
213 | struct rt_sigframe *frame = (struct rt_sigframe *)regs->r1; | ||
214 | sigset_t set; | ||
215 | stack_t st; | ||
216 | int rval; | ||
217 | |||
218 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) | ||
219 | goto badframe; | ||
220 | |||
221 | if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) | ||
222 | goto badframe; | ||
223 | |||
224 | sigdelsetmask(&set, ~_BLOCKABLE); | ||
225 | spin_lock_irq(¤t->sighand->siglock); | ||
226 | current->blocked = set; | ||
227 | recalc_sigpending(); | ||
228 | spin_unlock_irq(¤t->sighand->siglock); | ||
229 | |||
230 | if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &rval)) | ||
231 | goto badframe; | ||
232 | |||
233 | if (__copy_from_user((void *)&st, &frame->uc.uc_stack, sizeof(st))) | ||
234 | goto badframe; | ||
235 | /* It is more difficult to avoid calling this function than to | ||
236 | call it and ignore errors. */ | ||
237 | do_sigaltstack(&st, NULL, regs->r1); | ||
238 | |||
239 | return rval; | ||
240 | |||
241 | badframe: | ||
242 | force_sig(SIGSEGV, current); | ||
243 | return 0; | ||
244 | } | ||
245 | |||
246 | /* | ||
247 | * Set up a signal frame. | ||
248 | */ | ||
249 | |||
250 | static int | ||
251 | setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs, | ||
252 | unsigned long mask) | ||
253 | { | ||
254 | int err = 0; | ||
255 | |||
256 | #define COPY(x) {err |= __put_user(regs->x, &sc->regs.x); } | ||
257 | COPY(r0); | ||
258 | COPY(r1); | ||
259 | COPY(r2); COPY(r3); COPY(r4); COPY(r5); | ||
260 | COPY(r6); COPY(r7); COPY(r8); COPY(r9); | ||
261 | COPY(r10); COPY(r11); COPY(r12); COPY(r13); | ||
262 | COPY(r14); COPY(r15); COPY(r16); COPY(r17); | ||
263 | COPY(r18); COPY(r19); COPY(r20); COPY(r21); | ||
264 | COPY(r22); COPY(r23); COPY(r24); COPY(r25); | ||
265 | COPY(r26); COPY(r27); COPY(r28); COPY(r29); | ||
266 | COPY(r30); COPY(r31); | ||
267 | COPY(pc); COPY(ear); COPY(esr); COPY(fsr); | ||
268 | #undef COPY | ||
269 | |||
270 | err |= __put_user(mask, &sc->oldmask); | ||
271 | |||
272 | return err; | ||
273 | } | ||
274 | |||
275 | /* | ||
276 | * Determine which stack to use.. | ||
277 | */ | ||
278 | static inline void * | ||
279 | get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) | ||
280 | { | ||
281 | /* Default to using normal stack */ | ||
282 | unsigned long sp = regs->r1; | ||
283 | |||
284 | if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && !on_sig_stack(sp)) | ||
285 | sp = current->sas_ss_sp + current->sas_ss_size; | ||
286 | |||
287 | return (void *)((sp - frame_size) & -8UL); | ||
288 | } | ||
289 | |||
290 | static void setup_frame(int sig, struct k_sigaction *ka, | ||
291 | sigset_t *set, struct pt_regs *regs) | ||
292 | { | ||
293 | struct sigframe *frame; | ||
294 | int err = 0; | ||
295 | int signal; | ||
296 | |||
297 | frame = get_sigframe(ka, regs, sizeof(*frame)); | ||
298 | |||
299 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) | ||
300 | goto give_sigsegv; | ||
301 | |||
302 | signal = current_thread_info()->exec_domain | ||
303 | && current_thread_info()->exec_domain->signal_invmap | ||
304 | && sig < 32 | ||
305 | ? current_thread_info()->exec_domain->signal_invmap[sig] | ||
306 | : sig; | ||
307 | |||
308 | err |= setup_sigcontext(&frame->sc, regs, set->sig[0]); | ||
309 | |||
310 | if (_NSIG_WORDS > 1) { | ||
311 | err |= __copy_to_user(frame->extramask, &set->sig[1], | ||
312 | sizeof(frame->extramask)); | ||
313 | } | ||
314 | |||
315 | /* Set up to return from userspace. If provided, use a stub | ||
316 | already in userspace. */ | ||
317 | /* minus 8 is offset to cater for "rtsd r15,8" offset */ | ||
318 | if (ka->sa.sa_flags & SA_RESTORER) { | ||
319 | regs->r15 = ((unsigned long)ka->sa.sa_restorer)-8; | ||
320 | } else { | ||
321 | /* Note, these encodings are _big endian_! */ | ||
322 | |||
323 | /* addi r12, r0, __NR_sigreturn */ | ||
324 | err |= __put_user(0x31800000 | __NR_sigreturn , | ||
325 | frame->tramp + 0); | ||
326 | /* brki r14, 0x8 */ | ||
327 | err |= __put_user(0xb9cc0008, frame->tramp + 1); | ||
328 | |||
329 | /* Return from sighandler will jump to the tramp. | ||
330 | Negative 8 offset because return is rtsd r15, 8 */ | ||
331 | regs->r15 = ((unsigned long)frame->tramp)-8; | ||
332 | |||
333 | __invalidate_cache_sigtramp((unsigned long)frame->tramp); | ||
334 | } | ||
335 | |||
336 | if (err) | ||
337 | goto give_sigsegv; | ||
338 | |||
339 | /* Set up registers for signal handler */ | ||
340 | regs->r1 = (unsigned long) frame; | ||
341 | /* Signal handler args: */ | ||
342 | regs->r5 = signal; /* Arg 0: signum */ | ||
343 | regs->r6 = (unsigned long) &frame->sc; /* arg 1: sigcontext */ | ||
344 | |||
345 | /* Offset of 4 to handle microblaze rtid r14, 0 */ | ||
346 | regs->pc = (unsigned long)ka->sa.sa_handler; | ||
347 | |||
348 | set_fs(USER_DS); | ||
349 | |||
350 | #ifdef DEBUG_SIG | ||
351 | printk(KERN_INFO "SIG deliver (%s:%d): sp=%p pc=%08lx\n", | ||
352 | current->comm, current->pid, frame, regs->pc); | ||
353 | #endif | ||
354 | |||
355 | return; | ||
356 | |||
357 | give_sigsegv: | ||
358 | if (sig == SIGSEGV) | ||
359 | ka->sa.sa_handler = SIG_DFL; | ||
360 | force_sig(SIGSEGV, current); | ||
361 | } | ||
362 | |||
363 | static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | ||
364 | sigset_t *set, struct pt_regs *regs) | ||
365 | { | ||
366 | struct rt_sigframe *frame; | ||
367 | int err = 0; | ||
368 | int signal; | ||
369 | |||
370 | frame = get_sigframe(ka, regs, sizeof(*frame)); | ||
371 | |||
372 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) | ||
373 | goto give_sigsegv; | ||
374 | |||
375 | signal = current_thread_info()->exec_domain | ||
376 | && current_thread_info()->exec_domain->signal_invmap | ||
377 | && sig < 32 | ||
378 | ? current_thread_info()->exec_domain->signal_invmap[sig] | ||
379 | : sig; | ||
380 | |||
381 | err |= copy_siginfo_to_user(&frame->info, info); | ||
382 | |||
383 | /* Create the ucontext. */ | ||
384 | err |= __put_user(0, &frame->uc.uc_flags); | ||
385 | err |= __put_user(0, &frame->uc.uc_link); | ||
386 | err |= __put_user((void *)current->sas_ss_sp, | ||
387 | &frame->uc.uc_stack.ss_sp); | ||
388 | err |= __put_user(sas_ss_flags(regs->r1), | ||
389 | &frame->uc.uc_stack.ss_flags); | ||
390 | err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); | ||
391 | err |= setup_sigcontext(&frame->uc.uc_mcontext, | ||
392 | regs, set->sig[0]); | ||
393 | err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); | ||
394 | |||
395 | /* Set up to return from userspace. If provided, use a stub | ||
396 | already in userspace. */ | ||
397 | /* minus 8 is offset to cater for "rtsd r15,8" */ | ||
398 | if (ka->sa.sa_flags & SA_RESTORER) { | ||
399 | regs->r15 = ((unsigned long)ka->sa.sa_restorer)-8; | ||
400 | } else { | ||
401 | /* addi r12, r0, __NR_sigreturn */ | ||
402 | err |= __put_user(0x31800000 | __NR_rt_sigreturn , | ||
403 | frame->tramp + 0); | ||
404 | /* brki r14, 0x8 */ | ||
405 | err |= __put_user(0xb9cc0008, frame->tramp + 1); | ||
406 | |||
407 | /* Return from sighandler will jump to the tramp. | ||
408 | Negative 8 offset because return is rtsd r15, 8 */ | ||
409 | regs->r15 = ((unsigned long)frame->tramp)-8; | ||
410 | |||
411 | __invalidate_cache_sigtramp((unsigned long)frame->tramp); | ||
412 | } | ||
413 | |||
414 | if (err) | ||
415 | goto give_sigsegv; | ||
416 | |||
417 | /* Set up registers for signal handler */ | ||
418 | regs->r1 = (unsigned long) frame; | ||
419 | /* Signal handler args: */ | ||
420 | regs->r5 = signal; /* arg 0: signum */ | ||
421 | regs->r6 = (unsigned long) &frame->info; /* arg 1: siginfo */ | ||
422 | regs->r7 = (unsigned long) &frame->uc; /* arg2: ucontext */ | ||
423 | /* Offset to handle microblaze rtid r14, 0 */ | ||
424 | regs->pc = (unsigned long)ka->sa.sa_handler; | ||
425 | |||
426 | set_fs(USER_DS); | ||
427 | |||
428 | #ifdef DEBUG_SIG | ||
429 | printk(KERN_INFO "SIG deliver (%s:%d): sp=%p pc=%08lx\n", | ||
430 | current->comm, current->pid, frame, regs->pc); | ||
431 | #endif | ||
432 | |||
433 | return; | ||
434 | |||
435 | give_sigsegv: | ||
436 | if (sig == SIGSEGV) | ||
437 | ka->sa.sa_handler = SIG_DFL; | ||
438 | force_sig(SIGSEGV, current); | ||
439 | } | ||
440 | |||
441 | /* Handle restarting system calls */ | ||
442 | static inline void | ||
443 | handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler) | ||
444 | { | ||
445 | switch (regs->r3) { | ||
446 | case -ERESTART_RESTARTBLOCK: | ||
447 | case -ERESTARTNOHAND: | ||
448 | if (!has_handler) | ||
449 | goto do_restart; | ||
450 | regs->r3 = -EINTR; | ||
451 | break; | ||
452 | case -ERESTARTSYS: | ||
453 | if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) { | ||
454 | regs->r3 = -EINTR; | ||
455 | break; | ||
456 | } | ||
457 | /* fallthrough */ | ||
458 | case -ERESTARTNOINTR: | ||
459 | do_restart: | ||
460 | /* offset of 4 bytes to re-execute trap (brki) instruction */ | ||
461 | regs->pc -= 4; | ||
462 | break; | ||
463 | } | ||
464 | } | ||
465 | |||
466 | /* | ||
467 | * OK, we're invoking a handler | ||
468 | */ | ||
469 | |||
470 | static void | ||
471 | handle_signal(unsigned long sig, struct k_sigaction *ka, | ||
472 | siginfo_t *info, sigset_t *oldset, struct pt_regs *regs) | ||
473 | { | ||
474 | /* Set up the stack frame */ | ||
475 | if (ka->sa.sa_flags & SA_SIGINFO) | ||
476 | setup_rt_frame(sig, ka, info, oldset, regs); | ||
477 | else | ||
478 | setup_frame(sig, ka, oldset, regs); | ||
479 | |||
480 | if (ka->sa.sa_flags & SA_ONESHOT) | ||
481 | ka->sa.sa_handler = SIG_DFL; | ||
482 | |||
483 | if (!(ka->sa.sa_flags & SA_NODEFER)) { | ||
484 | spin_lock_irq(¤t->sighand->siglock); | ||
485 | sigorsets(¤t->blocked, | ||
486 | ¤t->blocked, &ka->sa.sa_mask); | ||
487 | sigaddset(¤t->blocked, sig); | ||
488 | recalc_sigpending(); | ||
489 | spin_unlock_irq(¤t->sighand->siglock); | ||
490 | } | ||
491 | } | ||
492 | |||
493 | /* | ||
494 | * Note that 'init' is a special process: it doesn't get signals it doesn't | ||
495 | * want to handle. Thus you cannot kill init even with a SIGKILL even by | ||
496 | * mistake. | ||
497 | * | ||
498 | * Note that we go through the signals twice: once to check the signals that | ||
499 | * the kernel can handle, and then we build all the user-level signal handling | ||
500 | * stack-frames in one go after that. | ||
501 | */ | ||
502 | int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_syscall) | ||
503 | { | ||
504 | siginfo_t info; | ||
505 | int signr; | ||
506 | struct k_sigaction ka; | ||
507 | #ifdef DEBUG_SIG | ||
508 | printk(KERN_INFO "do signal: %p %p %d\n", regs, oldset, in_syscall); | ||
509 | printk(KERN_INFO "do signal2: %lx %lx %ld [%lx]\n", regs->pc, regs->r1, | ||
510 | regs->r12, current_thread_info()->flags); | ||
511 | #endif | ||
512 | /* | ||
513 | * We want the common case to go fast, which | ||
514 | * is why we may in certain cases get here from | ||
515 | * kernel mode. Just return without doing anything | ||
516 | * if so. | ||
517 | */ | ||
518 | if (kernel_mode(regs)) | ||
519 | return 1; | ||
520 | |||
521 | if (!oldset) | ||
522 | oldset = ¤t->blocked; | ||
523 | |||
524 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); | ||
525 | if (signr > 0) { | ||
526 | /* Whee! Actually deliver the signal. */ | ||
527 | if (in_syscall) | ||
528 | handle_restart(regs, &ka, 1); | ||
529 | handle_signal(signr, &ka, &info, oldset, regs); | ||
530 | return 1; | ||
531 | } | ||
532 | |||
533 | if (in_syscall) | ||
534 | handle_restart(regs, NULL, 0); | ||
535 | |||
536 | /* Did we come from a system call? */ | ||
537 | return 0; | ||
538 | } | ||
diff --git a/arch/microblaze/kernel/sys_microblaze.c b/arch/microblaze/kernel/sys_microblaze.c new file mode 100644 index 000000000000..d90b548fb1bb --- /dev/null +++ b/arch/microblaze/kernel/sys_microblaze.c | |||
@@ -0,0 +1,227 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> | ||
3 | * Copyright (C) 2007-2009 PetaLogix | ||
4 | * Copyright (C) 2007 John Williams <john.williams@petalogix.com> | ||
5 | * | ||
6 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
7 | * Yasushi SHOJI <yashi@atmark-techno.com> | ||
8 | * Tetsuya OHKAWA <tetsuya@atmark-techno.com> | ||
9 | * | ||
10 | * This file is subject to the terms and conditions of the GNU General Public | ||
11 | * License. See the file "COPYING" in the main directory of this archive | ||
12 | * for more details. | ||
13 | */ | ||
14 | |||
15 | #include <linux/errno.h> | ||
16 | #include <linux/mm.h> | ||
17 | #include <linux/smp.h> | ||
18 | #include <linux/smp_lock.h> | ||
19 | #include <linux/syscalls.h> | ||
20 | #include <linux/sem.h> | ||
21 | #include <linux/msg.h> | ||
22 | #include <linux/shm.h> | ||
23 | #include <linux/stat.h> | ||
24 | #include <linux/mman.h> | ||
25 | #include <linux/sys.h> | ||
26 | #include <linux/ipc.h> | ||
27 | #include <linux/utsname.h> | ||
28 | #include <linux/file.h> | ||
29 | #include <linux/module.h> | ||
30 | #include <linux/err.h> | ||
31 | #include <linux/fs.h> | ||
32 | #include <linux/ipc.h> | ||
33 | #include <linux/semaphore.h> | ||
34 | #include <linux/syscalls.h> | ||
35 | #include <linux/uaccess.h> | ||
36 | #include <linux/unistd.h> | ||
37 | |||
38 | #include <asm/syscalls.h> | ||
39 | /* | ||
40 | * sys_ipc() is the de-multiplexer for the SysV IPC calls.. | ||
41 | * | ||
42 | * This is really horribly ugly. This will be remove with new toolchain. | ||
43 | */ | ||
44 | asmlinkage int | ||
45 | sys_ipc(uint call, int first, int second, int third, void *ptr, long fifth) | ||
46 | { | ||
47 | int version, ret; | ||
48 | |||
49 | version = call >> 16; /* hack for backward compatibility */ | ||
50 | call &= 0xffff; | ||
51 | |||
52 | ret = -EINVAL; | ||
53 | switch (call) { | ||
54 | case SEMOP: | ||
55 | ret = sys_semop(first, (struct sembuf *)ptr, second); | ||
56 | break; | ||
57 | case SEMGET: | ||
58 | ret = sys_semget(first, second, third); | ||
59 | break; | ||
60 | case SEMCTL: | ||
61 | { | ||
62 | union semun fourth; | ||
63 | |||
64 | if (!ptr) | ||
65 | break; | ||
66 | ret = (access_ok(VERIFY_READ, ptr, sizeof(long)) ? 0 : -EFAULT) | ||
67 | || (get_user(fourth.__pad, (void **)ptr)) ; | ||
68 | if (ret) | ||
69 | break; | ||
70 | ret = sys_semctl(first, second, third, fourth); | ||
71 | break; | ||
72 | } | ||
73 | case MSGSND: | ||
74 | ret = sys_msgsnd(first, (struct msgbuf *) ptr, second, third); | ||
75 | break; | ||
76 | case MSGRCV: | ||
77 | switch (version) { | ||
78 | case 0: { | ||
79 | struct ipc_kludge tmp; | ||
80 | |||
81 | if (!ptr) | ||
82 | break; | ||
83 | ret = (access_ok(VERIFY_READ, ptr, sizeof(tmp)) | ||
84 | ? 0 : -EFAULT) || copy_from_user(&tmp, | ||
85 | (struct ipc_kludge *) ptr, sizeof(tmp)); | ||
86 | if (ret) | ||
87 | break; | ||
88 | ret = sys_msgrcv(first, tmp.msgp, second, tmp.msgtyp, | ||
89 | third); | ||
90 | break; | ||
91 | } | ||
92 | default: | ||
93 | ret = sys_msgrcv(first, (struct msgbuf *) ptr, | ||
94 | second, fifth, third); | ||
95 | break; | ||
96 | } | ||
97 | break; | ||
98 | case MSGGET: | ||
99 | ret = sys_msgget((key_t) first, second); | ||
100 | break; | ||
101 | case MSGCTL: | ||
102 | ret = sys_msgctl(first, second, (struct msqid_ds *) ptr); | ||
103 | break; | ||
104 | case SHMAT: | ||
105 | switch (version) { | ||
106 | default: { | ||
107 | ulong raddr; | ||
108 | ret = access_ok(VERIFY_WRITE, (ulong *) third, | ||
109 | sizeof(ulong)) ? 0 : -EFAULT; | ||
110 | if (ret) | ||
111 | break; | ||
112 | ret = do_shmat(first, (char *) ptr, second, &raddr); | ||
113 | if (ret) | ||
114 | break; | ||
115 | ret = put_user(raddr, (ulong *) third); | ||
116 | break; | ||
117 | } | ||
118 | case 1: /* iBCS2 emulator entry point */ | ||
119 | if (!segment_eq(get_fs(), get_ds())) | ||
120 | break; | ||
121 | ret = do_shmat(first, (char *) ptr, second, | ||
122 | (ulong *) third); | ||
123 | break; | ||
124 | } | ||
125 | break; | ||
126 | case SHMDT: | ||
127 | ret = sys_shmdt((char *)ptr); | ||
128 | break; | ||
129 | case SHMGET: | ||
130 | ret = sys_shmget(first, second, third); | ||
131 | break; | ||
132 | case SHMCTL: | ||
133 | ret = sys_shmctl(first, second, (struct shmid_ds *) ptr); | ||
134 | break; | ||
135 | } | ||
136 | return -EINVAL; | ||
137 | } | ||
138 | |||
139 | asmlinkage int sys_vfork(struct pt_regs *regs) | ||
140 | { | ||
141 | return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->r1, | ||
142 | regs, 0, NULL, NULL); | ||
143 | } | ||
144 | |||
145 | asmlinkage int sys_clone(int flags, unsigned long stack, struct pt_regs *regs) | ||
146 | { | ||
147 | if (!stack) | ||
148 | stack = regs->r1; | ||
149 | return do_fork(flags, stack, regs, 0, NULL, NULL); | ||
150 | } | ||
151 | |||
152 | asmlinkage int sys_execve(char __user *filenamei, char __user *__user *argv, | ||
153 | char __user *__user *envp, struct pt_regs *regs) | ||
154 | { | ||
155 | int error; | ||
156 | char *filename; | ||
157 | |||
158 | filename = getname(filenamei); | ||
159 | error = PTR_ERR(filename); | ||
160 | if (IS_ERR(filename)) | ||
161 | goto out; | ||
162 | error = do_execve(filename, argv, envp, regs); | ||
163 | putname(filename); | ||
164 | out: | ||
165 | return error; | ||
166 | } | ||
167 | |||
168 | asmlinkage unsigned long | ||
169 | sys_mmap2(unsigned long addr, size_t len, | ||
170 | unsigned long prot, unsigned long flags, | ||
171 | unsigned long fd, unsigned long pgoff) | ||
172 | { | ||
173 | struct file *file = NULL; | ||
174 | int ret = -EBADF; | ||
175 | |||
176 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
177 | if (!(flags & MAP_ANONYMOUS)) { | ||
178 | file = fget(fd); | ||
179 | if (!file) { | ||
180 | printk(KERN_INFO "no fd in mmap\r\n"); | ||
181 | goto out; | ||
182 | } | ||
183 | } | ||
184 | |||
185 | down_write(¤t->mm->mmap_sem); | ||
186 | ret = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); | ||
187 | up_write(¤t->mm->mmap_sem); | ||
188 | if (file) | ||
189 | fput(file); | ||
190 | out: | ||
191 | return ret; | ||
192 | } | ||
193 | |||
194 | asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len, | ||
195 | unsigned long prot, unsigned long flags, | ||
196 | unsigned long fd, off_t offset) | ||
197 | { | ||
198 | int err = -EINVAL; | ||
199 | |||
200 | if (offset & ~PAGE_MASK) { | ||
201 | printk(KERN_INFO "no pagemask in mmap\r\n"); | ||
202 | goto out; | ||
203 | } | ||
204 | |||
205 | err = sys_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT); | ||
206 | out: | ||
207 | return err; | ||
208 | } | ||
209 | |||
210 | /* | ||
211 | * Do a system call from kernel instead of calling sys_execve so we | ||
212 | * end up with proper pt_regs. | ||
213 | */ | ||
214 | int kernel_execve(const char *filename, char *const argv[], char *const envp[]) | ||
215 | { | ||
216 | register const char *__a __asm__("r5") = filename; | ||
217 | register const void *__b __asm__("r6") = argv; | ||
218 | register const void *__c __asm__("r7") = envp; | ||
219 | register unsigned long __syscall __asm__("r12") = __NR_execve; | ||
220 | register unsigned long __ret __asm__("r3"); | ||
221 | __asm__ __volatile__ ("brki r14, 0x8" | ||
222 | : "=r" (__ret), "=r" (__syscall) | ||
223 | : "1" (__syscall), "r" (__a), "r" (__b), "r" (__c) | ||
224 | : "r4", "r8", "r9", | ||
225 | "r10", "r11", "r14", "cc", "memory"); | ||
226 | return __ret; | ||
227 | } | ||
diff --git a/arch/microblaze/kernel/syscall_table.S b/arch/microblaze/kernel/syscall_table.S new file mode 100644 index 000000000000..529b0dbf4fe9 --- /dev/null +++ b/arch/microblaze/kernel/syscall_table.S | |||
@@ -0,0 +1,365 @@ | |||
1 | ENTRY(sys_call_table) | ||
2 | .long sys_restart_syscall /* 0 - old "setup()" system call, | ||
3 | * used for restarting */ | ||
4 | .long sys_exit | ||
5 | .long sys_ni_syscall /* was fork */ | ||
6 | .long sys_read | ||
7 | .long sys_write | ||
8 | .long sys_open /* 5 */ | ||
9 | .long sys_close | ||
10 | .long sys_waitpid | ||
11 | .long sys_creat | ||
12 | .long sys_link | ||
13 | .long sys_unlink /* 10 */ | ||
14 | .long sys_execve_wrapper | ||
15 | .long sys_chdir | ||
16 | .long sys_time | ||
17 | .long sys_mknod | ||
18 | .long sys_chmod /* 15 */ | ||
19 | .long sys_lchown | ||
20 | .long sys_ni_syscall /* old break syscall holder */ | ||
21 | .long sys_ni_syscall /* old stat */ | ||
22 | .long sys_lseek | ||
23 | .long sys_getpid /* 20 */ | ||
24 | .long sys_mount | ||
25 | .long sys_oldumount | ||
26 | .long sys_setuid | ||
27 | .long sys_getuid | ||
28 | .long sys_stime /* 25 */ | ||
29 | .long sys_ptrace | ||
30 | .long sys_alarm | ||
31 | .long sys_ni_syscall /* oldfstat */ | ||
32 | .long sys_pause | ||
33 | .long sys_utime /* 30 */ | ||
34 | .long sys_ni_syscall /* old stty syscall holder */ | ||
35 | .long sys_ni_syscall /* old gtty syscall holder */ | ||
36 | .long sys_access | ||
37 | .long sys_nice | ||
38 | .long sys_ni_syscall /* 35 - old ftime syscall holder */ | ||
39 | .long sys_sync | ||
40 | .long sys_kill | ||
41 | .long sys_rename | ||
42 | .long sys_mkdir | ||
43 | .long sys_rmdir /* 40 */ | ||
44 | .long sys_dup | ||
45 | .long sys_pipe | ||
46 | .long sys_times | ||
47 | .long sys_ni_syscall /* old prof syscall holder */ | ||
48 | .long sys_brk /* 45 */ | ||
49 | .long sys_setgid | ||
50 | .long sys_getgid | ||
51 | .long sys_signal | ||
52 | .long sys_geteuid | ||
53 | .long sys_getegid /* 50 */ | ||
54 | .long sys_acct | ||
55 | .long sys_umount /* recycled never used phys() */ | ||
56 | .long sys_ni_syscall /* old lock syscall holder */ | ||
57 | .long sys_ioctl | ||
58 | .long sys_fcntl /* 55 */ | ||
59 | .long sys_ni_syscall /* old mpx syscall holder */ | ||
60 | .long sys_setpgid | ||
61 | .long sys_ni_syscall /* old ulimit syscall holder */ | ||
62 | .long sys_ni_syscall /* olduname */ | ||
63 | .long sys_umask /* 60 */ | ||
64 | .long sys_chroot | ||
65 | .long sys_ustat | ||
66 | .long sys_dup2 | ||
67 | .long sys_getppid | ||
68 | .long sys_getpgrp /* 65 */ | ||
69 | .long sys_setsid | ||
70 | .long sys_sigaction | ||
71 | .long sys_sgetmask | ||
72 | .long sys_ssetmask | ||
73 | .long sys_setreuid /* 70 */ | ||
74 | .long sys_setregid | ||
75 | .long sys_sigsuspend_wrapper | ||
76 | .long sys_sigpending | ||
77 | .long sys_sethostname | ||
78 | .long sys_setrlimit /* 75 */ | ||
79 | .long sys_ni_syscall /* old_getrlimit */ | ||
80 | .long sys_getrusage | ||
81 | .long sys_gettimeofday | ||
82 | .long sys_settimeofday | ||
83 | .long sys_getgroups /* 80 */ | ||
84 | .long sys_setgroups | ||
85 | .long sys_ni_syscall /* old_select */ | ||
86 | .long sys_symlink | ||
87 | .long sys_ni_syscall /* oldlstat */ | ||
88 | .long sys_readlink /* 85 */ | ||
89 | .long sys_uselib | ||
90 | .long sys_swapon | ||
91 | .long sys_reboot | ||
92 | .long sys_ni_syscall /* old_readdir */ | ||
93 | .long sys_mmap /* 90 */ /* old_mmap */ | ||
94 | .long sys_munmap | ||
95 | .long sys_truncate | ||
96 | .long sys_ftruncate | ||
97 | .long sys_fchmod | ||
98 | .long sys_fchown /* 95 */ | ||
99 | .long sys_getpriority | ||
100 | .long sys_setpriority | ||
101 | .long sys_ni_syscall /* old profil syscall holder */ | ||
102 | .long sys_statfs | ||
103 | .long sys_fstatfs /* 100 */ | ||
104 | .long sys_ni_syscall /* ioperm */ | ||
105 | .long sys_socketcall | ||
106 | .long sys_syslog /* operation with system console */ | ||
107 | .long sys_setitimer | ||
108 | .long sys_getitimer /* 105 */ | ||
109 | .long sys_newstat | ||
110 | .long sys_newlstat | ||
111 | .long sys_newfstat | ||
112 | .long sys_ni_syscall /* uname */ | ||
113 | .long sys_ni_syscall /* 110 */ /* iopl */ | ||
114 | .long sys_vhangup | ||
115 | .long sys_ni_syscall /* old "idle" system call */ | ||
116 | .long sys_ni_syscall /* old sys_vm86old */ | ||
117 | .long sys_wait4 | ||
118 | .long sys_swapoff /* 115 */ | ||
119 | .long sys_sysinfo | ||
120 | .long sys_ipc | ||
121 | .long sys_fsync | ||
122 | .long sys_sigreturn_wrapper | ||
123 | .long sys_clone_wrapper /* 120 */ | ||
124 | .long sys_setdomainname | ||
125 | .long sys_newuname | ||
126 | .long sys_ni_syscall /* modify_ldt */ | ||
127 | .long sys_adjtimex | ||
128 | .long sys_mprotect /* 125: sys_mprotect */ | ||
129 | .long sys_sigprocmask | ||
130 | .long sys_ni_syscall /* old "create_module" */ | ||
131 | .long sys_init_module | ||
132 | .long sys_delete_module | ||
133 | .long sys_ni_syscall /* 130: old "get_kernel_syms" */ | ||
134 | .long sys_quotactl | ||
135 | .long sys_getpgid | ||
136 | .long sys_fchdir | ||
137 | .long sys_bdflush | ||
138 | .long sys_sysfs /* 135 */ | ||
139 | .long sys_personality | ||
140 | .long sys_ni_syscall /* reserved for afs_syscall */ | ||
141 | .long sys_setfsuid | ||
142 | .long sys_setfsgid | ||
143 | .long sys_llseek /* 140 */ | ||
144 | .long sys_getdents | ||
145 | .long sys_select | ||
146 | .long sys_flock | ||
147 | .long sys_msync | ||
148 | .long sys_readv /* 145 */ | ||
149 | .long sys_writev | ||
150 | .long sys_getsid | ||
151 | .long sys_fdatasync | ||
152 | .long sys_sysctl | ||
153 | .long sys_mlock /* 150: sys_mlock */ | ||
154 | .long sys_munlock | ||
155 | .long sys_mlockall | ||
156 | .long sys_munlockall | ||
157 | .long sys_sched_setparam | ||
158 | .long sys_sched_getparam /* 155 */ | ||
159 | .long sys_sched_setscheduler | ||
160 | .long sys_sched_getscheduler | ||
161 | .long sys_sched_yield | ||
162 | .long sys_sched_get_priority_max | ||
163 | .long sys_sched_get_priority_min /* 160 */ | ||
164 | .long sys_sched_rr_get_interval | ||
165 | .long sys_nanosleep | ||
166 | .long sys_mremap | ||
167 | .long sys_setresuid | ||
168 | .long sys_getresuid /* 165 */ | ||
169 | .long sys_ni_syscall /* sys_vm86 */ | ||
170 | .long sys_ni_syscall /* Old sys_query_module */ | ||
171 | .long sys_poll | ||
172 | .long sys_nfsservctl | ||
173 | .long sys_setresgid /* 170 */ | ||
174 | .long sys_getresgid | ||
175 | .long sys_prctl | ||
176 | .long sys_rt_sigreturn_wrapper | ||
177 | .long sys_rt_sigaction | ||
178 | .long sys_rt_sigprocmask /* 175 */ | ||
179 | .long sys_rt_sigpending | ||
180 | .long sys_rt_sigtimedwait | ||
181 | .long sys_rt_sigqueueinfo | ||
182 | .long sys_rt_sigsuspend_wrapper | ||
183 | .long sys_pread64 /* 180 */ | ||
184 | .long sys_pwrite64 | ||
185 | .long sys_chown | ||
186 | .long sys_getcwd | ||
187 | .long sys_capget | ||
188 | .long sys_capset /* 185 */ | ||
189 | .long sys_ni_syscall /* sigaltstack */ | ||
190 | .long sys_sendfile | ||
191 | .long sys_ni_syscall /* reserved for streams1 */ | ||
192 | .long sys_ni_syscall /* reserved for streams2 */ | ||
193 | .long sys_vfork_wrapper /* 190 */ | ||
194 | .long sys_getrlimit | ||
195 | .long sys_mmap2 /* mmap2 */ | ||
196 | .long sys_truncate64 | ||
197 | .long sys_ftruncate64 | ||
198 | .long sys_stat64 /* 195 */ | ||
199 | .long sys_lstat64 | ||
200 | .long sys_fstat64 | ||
201 | .long sys_lchown | ||
202 | .long sys_getuid | ||
203 | .long sys_getgid /* 200 */ | ||
204 | .long sys_geteuid | ||
205 | .long sys_getegid | ||
206 | .long sys_setreuid | ||
207 | .long sys_setregid | ||
208 | .long sys_getgroups /* 205 */ | ||
209 | .long sys_setgroups | ||
210 | .long sys_fchown | ||
211 | .long sys_setresuid | ||
212 | .long sys_getresuid | ||
213 | .long sys_setresgid /* 210 */ | ||
214 | .long sys_getresgid | ||
215 | .long sys_chown | ||
216 | .long sys_setuid | ||
217 | .long sys_setgid | ||
218 | .long sys_setfsuid /* 215 */ | ||
219 | .long sys_setfsgid | ||
220 | .long sys_pivot_root | ||
221 | .long sys_mincore | ||
222 | .long sys_madvise | ||
223 | .long sys_getdents64 /* 220 */ | ||
224 | .long sys_fcntl64 | ||
225 | .long sys_ni_syscall /* reserved for TUX */ | ||
226 | .long sys_ni_syscall | ||
227 | .long sys_gettid | ||
228 | .long sys_readahead /* 225 */ | ||
229 | .long sys_setxattr | ||
230 | .long sys_lsetxattr | ||
231 | .long sys_fsetxattr | ||
232 | .long sys_getxattr | ||
233 | .long sys_lgetxattr /* 230 */ | ||
234 | .long sys_fgetxattr | ||
235 | .long sys_listxattr | ||
236 | .long sys_llistxattr | ||
237 | .long sys_flistxattr | ||
238 | .long sys_removexattr /* 235 */ | ||
239 | .long sys_lremovexattr | ||
240 | .long sys_fremovexattr | ||
241 | .long sys_tkill | ||
242 | .long sys_sendfile64 | ||
243 | .long sys_futex /* 240 */ | ||
244 | .long sys_sched_setaffinity | ||
245 | .long sys_sched_getaffinity | ||
246 | .long sys_ni_syscall /* set_thread_area */ | ||
247 | .long sys_ni_syscall /* get_thread_area */ | ||
248 | .long sys_io_setup /* 245 */ | ||
249 | .long sys_io_destroy | ||
250 | .long sys_io_getevents | ||
251 | .long sys_io_submit | ||
252 | .long sys_io_cancel | ||
253 | .long sys_fadvise64 /* 250 */ | ||
254 | .long sys_ni_syscall | ||
255 | .long sys_exit_group | ||
256 | .long sys_lookup_dcookie | ||
257 | .long sys_epoll_create | ||
258 | .long sys_epoll_ctl /* 255 */ | ||
259 | .long sys_epoll_wait | ||
260 | .long sys_remap_file_pages | ||
261 | .long sys_set_tid_address | ||
262 | .long sys_timer_create | ||
263 | .long sys_timer_settime /* 260 */ | ||
264 | .long sys_timer_gettime | ||
265 | .long sys_timer_getoverrun | ||
266 | .long sys_timer_delete | ||
267 | .long sys_clock_settime | ||
268 | .long sys_clock_gettime /* 265 */ | ||
269 | .long sys_clock_getres | ||
270 | .long sys_clock_nanosleep | ||
271 | .long sys_statfs64 | ||
272 | .long sys_fstatfs64 | ||
273 | .long sys_tgkill /* 270 */ | ||
274 | .long sys_utimes | ||
275 | .long sys_fadvise64_64 | ||
276 | .long sys_ni_syscall /* sys_vserver */ | ||
277 | .long sys_mbind | ||
278 | .long sys_get_mempolicy | ||
279 | .long sys_set_mempolicy | ||
280 | .long sys_mq_open | ||
281 | .long sys_mq_unlink | ||
282 | .long sys_mq_timedsend | ||
283 | .long sys_mq_timedreceive /* 280 */ | ||
284 | .long sys_mq_notify | ||
285 | .long sys_mq_getsetattr | ||
286 | .long sys_kexec_load | ||
287 | .long sys_waitid | ||
288 | .long sys_ni_syscall /* 285 */ /* available */ | ||
289 | .long sys_add_key | ||
290 | .long sys_request_key | ||
291 | .long sys_keyctl | ||
292 | .long sys_ioprio_set | ||
293 | .long sys_ioprio_get /* 290 */ | ||
294 | .long sys_inotify_init | ||
295 | .long sys_inotify_add_watch | ||
296 | .long sys_inotify_rm_watch | ||
297 | .long sys_ni_syscall /* sys_migrate_pages */ | ||
298 | .long sys_openat /* 295 */ | ||
299 | .long sys_mkdirat | ||
300 | .long sys_mknodat | ||
301 | .long sys_fchownat | ||
302 | .long sys_ni_syscall | ||
303 | .long sys_fstatat64 /* 300 */ | ||
304 | .long sys_unlinkat | ||
305 | .long sys_renameat | ||
306 | .long sys_linkat | ||
307 | .long sys_symlinkat | ||
308 | .long sys_readlinkat /* 305 */ | ||
309 | .long sys_fchmodat | ||
310 | .long sys_faccessat | ||
311 | .long sys_ni_syscall /* pselect6 */ | ||
312 | .long sys_ni_syscall /* sys_ppoll */ | ||
313 | .long sys_unshare /* 310 */ | ||
314 | .long sys_set_robust_list | ||
315 | .long sys_get_robust_list | ||
316 | .long sys_splice | ||
317 | .long sys_sync_file_range | ||
318 | .long sys_tee /* 315 */ | ||
319 | .long sys_vmsplice | ||
320 | .long sys_move_pages | ||
321 | .long sys_getcpu | ||
322 | .long sys_epoll_pwait | ||
323 | .long sys_utimensat /* 320 */ | ||
324 | .long sys_signalfd | ||
325 | .long sys_timerfd_create | ||
326 | .long sys_eventfd | ||
327 | .long sys_fallocate | ||
328 | .long sys_semtimedop /* 325 */ | ||
329 | .long sys_timerfd_settime | ||
330 | .long sys_timerfd_gettime | ||
331 | .long sys_semctl | ||
332 | .long sys_semget | ||
333 | .long sys_semop /* 330 */ | ||
334 | .long sys_msgctl | ||
335 | .long sys_msgget | ||
336 | .long sys_msgrcv | ||
337 | .long sys_msgsnd | ||
338 | .long sys_shmat /* 335 */ | ||
339 | .long sys_shmctl | ||
340 | .long sys_shmdt | ||
341 | .long sys_shmget | ||
342 | .long sys_signalfd4 /* new syscall */ | ||
343 | .long sys_eventfd2 /* 340 */ | ||
344 | .long sys_epoll_create1 | ||
345 | .long sys_dup3 | ||
346 | .long sys_pipe2 | ||
347 | .long sys_inotify_init1 | ||
348 | .long sys_socket /* 345 */ | ||
349 | .long sys_socketpair | ||
350 | .long sys_bind | ||
351 | .long sys_listen | ||
352 | .long sys_accept | ||
353 | .long sys_connect /* 350 */ | ||
354 | .long sys_getsockname | ||
355 | .long sys_getpeername | ||
356 | .long sys_sendto | ||
357 | .long sys_send | ||
358 | .long sys_recvfrom /* 355 */ | ||
359 | .long sys_recv | ||
360 | .long sys_setsockopt | ||
361 | .long sys_getsockopt | ||
362 | .long sys_shutdown | ||
363 | .long sys_sendmsg /* 360 */ | ||
364 | .long sys_recvmsg | ||
365 | .long sys_ni_syscall | ||
diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c new file mode 100644 index 000000000000..05a497eefd78 --- /dev/null +++ b/arch/microblaze/kernel/timer.c | |||
@@ -0,0 +1,262 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> | ||
3 | * Copyright (C) 2007-2009 PetaLogix | ||
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 | */ | ||
10 | |||
11 | #include <linux/init.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/param.h> | ||
14 | #include <linux/interrupt.h> | ||
15 | #include <linux/profile.h> | ||
16 | #include <linux/irq.h> | ||
17 | #include <linux/delay.h> | ||
18 | #include <linux/sched.h> | ||
19 | #include <linux/spinlock.h> | ||
20 | #include <linux/err.h> | ||
21 | #include <linux/clk.h> | ||
22 | #include <linux/clocksource.h> | ||
23 | #include <linux/clockchips.h> | ||
24 | #include <linux/io.h> | ||
25 | #include <asm/cpuinfo.h> | ||
26 | #include <asm/setup.h> | ||
27 | #include <asm/prom.h> | ||
28 | #include <asm/irq.h> | ||
29 | #include <asm/system.h> | ||
30 | |||
31 | #ifdef CONFIG_SELFMOD_TIMER | ||
32 | #include <asm/selfmod.h> | ||
33 | #define TIMER_BASE BARRIER_BASE_ADDR | ||
34 | #else | ||
35 | static unsigned int timer_baseaddr; | ||
36 | #define TIMER_BASE timer_baseaddr | ||
37 | #endif | ||
38 | |||
39 | #define TCSR0 (0x00) | ||
40 | #define TLR0 (0x04) | ||
41 | #define TCR0 (0x08) | ||
42 | #define TCSR1 (0x10) | ||
43 | #define TLR1 (0x14) | ||
44 | #define TCR1 (0x18) | ||
45 | |||
46 | #define TCSR_MDT (1<<0) | ||
47 | #define TCSR_UDT (1<<1) | ||
48 | #define TCSR_GENT (1<<2) | ||
49 | #define TCSR_CAPT (1<<3) | ||
50 | #define TCSR_ARHT (1<<4) | ||
51 | #define TCSR_LOAD (1<<5) | ||
52 | #define TCSR_ENIT (1<<6) | ||
53 | #define TCSR_ENT (1<<7) | ||
54 | #define TCSR_TINT (1<<8) | ||
55 | #define TCSR_PWMA (1<<9) | ||
56 | #define TCSR_ENALL (1<<10) | ||
57 | |||
58 | static inline void microblaze_timer0_stop(void) | ||
59 | { | ||
60 | out_be32(TIMER_BASE + TCSR0, in_be32(TIMER_BASE + TCSR0) & ~TCSR_ENT); | ||
61 | } | ||
62 | |||
63 | static inline void microblaze_timer0_start_periodic(unsigned long load_val) | ||
64 | { | ||
65 | if (!load_val) | ||
66 | load_val = 1; | ||
67 | out_be32(TIMER_BASE + TLR0, load_val); /* loading value to timer reg */ | ||
68 | |||
69 | /* load the initial value */ | ||
70 | out_be32(TIMER_BASE + TCSR0, TCSR_LOAD); | ||
71 | |||
72 | /* see timer data sheet for detail | ||
73 | * !ENALL - don't enable 'em all | ||
74 | * !PWMA - disable pwm | ||
75 | * TINT - clear interrupt status | ||
76 | * ENT- enable timer itself | ||
77 | * EINT - enable interrupt | ||
78 | * !LOAD - clear the bit to let go | ||
79 | * ARHT - auto reload | ||
80 | * !CAPT - no external trigger | ||
81 | * !GENT - no external signal | ||
82 | * UDT - set the timer as down counter | ||
83 | * !MDT0 - generate mode | ||
84 | */ | ||
85 | out_be32(TIMER_BASE + TCSR0, | ||
86 | TCSR_TINT|TCSR_ENIT|TCSR_ENT|TCSR_ARHT|TCSR_UDT); | ||
87 | } | ||
88 | |||
89 | static inline void microblaze_timer0_start_oneshot(unsigned long load_val) | ||
90 | { | ||
91 | if (!load_val) | ||
92 | load_val = 1; | ||
93 | out_be32(TIMER_BASE + TLR0, load_val); /* loading value to timer reg */ | ||
94 | |||
95 | /* load the initial value */ | ||
96 | out_be32(TIMER_BASE + TCSR0, TCSR_LOAD); | ||
97 | |||
98 | out_be32(TIMER_BASE + TCSR0, | ||
99 | TCSR_TINT|TCSR_ENIT|TCSR_ENT|TCSR_ARHT|TCSR_UDT); | ||
100 | } | ||
101 | |||
102 | static int microblaze_timer_set_next_event(unsigned long delta, | ||
103 | struct clock_event_device *dev) | ||
104 | { | ||
105 | pr_debug("%s: next event, delta %x\n", __func__, (u32)delta); | ||
106 | microblaze_timer0_start_oneshot(delta); | ||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | static void microblaze_timer_set_mode(enum clock_event_mode mode, | ||
111 | struct clock_event_device *evt) | ||
112 | { | ||
113 | switch (mode) { | ||
114 | case CLOCK_EVT_MODE_PERIODIC: | ||
115 | printk(KERN_INFO "%s: periodic\n", __func__); | ||
116 | microblaze_timer0_start_periodic(cpuinfo.freq_div_hz); | ||
117 | break; | ||
118 | case CLOCK_EVT_MODE_ONESHOT: | ||
119 | printk(KERN_INFO "%s: oneshot\n", __func__); | ||
120 | break; | ||
121 | case CLOCK_EVT_MODE_UNUSED: | ||
122 | printk(KERN_INFO "%s: unused\n", __func__); | ||
123 | break; | ||
124 | case CLOCK_EVT_MODE_SHUTDOWN: | ||
125 | printk(KERN_INFO "%s: shutdown\n", __func__); | ||
126 | microblaze_timer0_stop(); | ||
127 | break; | ||
128 | case CLOCK_EVT_MODE_RESUME: | ||
129 | printk(KERN_INFO "%s: resume\n", __func__); | ||
130 | break; | ||
131 | } | ||
132 | } | ||
133 | |||
134 | static struct clock_event_device clockevent_microblaze_timer = { | ||
135 | .name = "microblaze_clockevent", | ||
136 | .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC, | ||
137 | .shift = 24, | ||
138 | .rating = 300, | ||
139 | .set_next_event = microblaze_timer_set_next_event, | ||
140 | .set_mode = microblaze_timer_set_mode, | ||
141 | }; | ||
142 | |||
143 | static inline void timer_ack(void) | ||
144 | { | ||
145 | out_be32(TIMER_BASE + TCSR0, in_be32(TIMER_BASE + TCSR0)); | ||
146 | } | ||
147 | |||
148 | static irqreturn_t timer_interrupt(int irq, void *dev_id) | ||
149 | { | ||
150 | struct clock_event_device *evt = &clockevent_microblaze_timer; | ||
151 | #ifdef CONFIG_HEART_BEAT | ||
152 | heartbeat(); | ||
153 | #endif | ||
154 | timer_ack(); | ||
155 | evt->event_handler(evt); | ||
156 | return IRQ_HANDLED; | ||
157 | } | ||
158 | |||
159 | static struct irqaction timer_irqaction = { | ||
160 | .handler = timer_interrupt, | ||
161 | .flags = IRQF_DISABLED | IRQF_TIMER, | ||
162 | .name = "timer", | ||
163 | .dev_id = &clockevent_microblaze_timer, | ||
164 | }; | ||
165 | |||
166 | static __init void microblaze_clockevent_init(void) | ||
167 | { | ||
168 | clockevent_microblaze_timer.mult = | ||
169 | div_sc(cpuinfo.cpu_clock_freq, NSEC_PER_SEC, | ||
170 | clockevent_microblaze_timer.shift); | ||
171 | clockevent_microblaze_timer.max_delta_ns = | ||
172 | clockevent_delta2ns((u32)~0, &clockevent_microblaze_timer); | ||
173 | clockevent_microblaze_timer.min_delta_ns = | ||
174 | clockevent_delta2ns(1, &clockevent_microblaze_timer); | ||
175 | clockevent_microblaze_timer.cpumask = cpumask_of(0); | ||
176 | clockevents_register_device(&clockevent_microblaze_timer); | ||
177 | } | ||
178 | |||
179 | static cycle_t microblaze_read(void) | ||
180 | { | ||
181 | /* reading actual value of timer 1 */ | ||
182 | return (cycle_t) (in_be32(TIMER_BASE + TCR1)); | ||
183 | } | ||
184 | |||
185 | static struct clocksource clocksource_microblaze = { | ||
186 | .name = "microblaze_clocksource", | ||
187 | .rating = 300, | ||
188 | .read = microblaze_read, | ||
189 | .mask = CLOCKSOURCE_MASK(32), | ||
190 | .shift = 24, /* I can shift it */ | ||
191 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | ||
192 | }; | ||
193 | |||
194 | static int __init microblaze_clocksource_init(void) | ||
195 | { | ||
196 | clocksource_microblaze.mult = | ||
197 | clocksource_hz2mult(cpuinfo.cpu_clock_freq, | ||
198 | clocksource_microblaze.shift); | ||
199 | if (clocksource_register(&clocksource_microblaze)) | ||
200 | panic("failed to register clocksource"); | ||
201 | |||
202 | /* stop timer1 */ | ||
203 | out_be32(TIMER_BASE + TCSR1, in_be32(TIMER_BASE + TCSR1) & ~TCSR_ENT); | ||
204 | /* start timer1 - up counting without interrupt */ | ||
205 | out_be32(TIMER_BASE + TCSR1, TCSR_TINT|TCSR_ENT|TCSR_ARHT); | ||
206 | return 0; | ||
207 | } | ||
208 | |||
209 | void __init time_init(void) | ||
210 | { | ||
211 | u32 irq, i = 0; | ||
212 | u32 timer_num = 1; | ||
213 | struct device_node *timer = NULL; | ||
214 | #ifdef CONFIG_SELFMOD_TIMER | ||
215 | unsigned int timer_baseaddr = 0; | ||
216 | int arr_func[] = { | ||
217 | (int)µblaze_read, | ||
218 | (int)&timer_interrupt, | ||
219 | (int)µblaze_clocksource_init, | ||
220 | (int)µblaze_timer_set_mode, | ||
221 | (int)µblaze_timer_set_next_event, | ||
222 | 0 | ||
223 | }; | ||
224 | #endif | ||
225 | char *timer_list[] = { | ||
226 | "xlnx,xps-timer-1.00.a", | ||
227 | "xlnx,opb-timer-1.00.b", | ||
228 | "xlnx,opb-timer-1.00.a", | ||
229 | NULL | ||
230 | }; | ||
231 | |||
232 | for (i = 0; timer_list[i] != NULL; i++) { | ||
233 | timer = of_find_compatible_node(NULL, NULL, timer_list[i]); | ||
234 | if (timer) | ||
235 | break; | ||
236 | } | ||
237 | |||
238 | timer_baseaddr = *(int *) of_get_property(timer, "reg", NULL); | ||
239 | timer_baseaddr = (unsigned long) ioremap(timer_baseaddr, PAGE_SIZE); | ||
240 | irq = *(int *) of_get_property(timer, "interrupts", NULL); | ||
241 | timer_num = | ||
242 | *(int *) of_get_property(timer, "xlnx,one-timer-only", NULL); | ||
243 | if (timer_num) { | ||
244 | printk(KERN_EMERG "Please enable two timers in HW\n"); | ||
245 | BUG(); | ||
246 | } | ||
247 | |||
248 | #ifdef CONFIG_SELFMOD_TIMER | ||
249 | selfmod_function((int *) arr_func, timer_baseaddr); | ||
250 | #endif | ||
251 | printk(KERN_INFO "%s #0 at 0x%08x, irq=%d\n", | ||
252 | timer_list[i], timer_baseaddr, irq); | ||
253 | |||
254 | cpuinfo.freq_div_hz = cpuinfo.cpu_clock_freq / HZ; | ||
255 | |||
256 | setup_irq(irq, &timer_irqaction); | ||
257 | #ifdef CONFIG_HEART_BEAT | ||
258 | setup_heartbeat(); | ||
259 | #endif | ||
260 | microblaze_clocksource_init(); | ||
261 | microblaze_clockevent_init(); | ||
262 | } | ||
diff --git a/arch/microblaze/kernel/traps.c b/arch/microblaze/kernel/traps.c new file mode 100644 index 000000000000..fbdc533c61e3 --- /dev/null +++ b/arch/microblaze/kernel/traps.c | |||
@@ -0,0 +1,107 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> | ||
3 | * Copyright (C) 2007-2009 PetaLogix | ||
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 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/kallsyms.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/sched.h> | ||
15 | #include <linux/debug_locks.h> | ||
16 | |||
17 | #include <asm/exceptions.h> | ||
18 | #include <asm/system.h> | ||
19 | |||
20 | void trap_init(void) | ||
21 | { | ||
22 | __enable_hw_exceptions(); | ||
23 | } | ||
24 | |||
25 | void __bad_xchg(volatile void *ptr, int size) | ||
26 | { | ||
27 | printk(KERN_INFO "xchg: bad data size: pc 0x%p, ptr 0x%p, size %d\n", | ||
28 | __builtin_return_address(0), ptr, size); | ||
29 | BUG(); | ||
30 | } | ||
31 | EXPORT_SYMBOL(__bad_xchg); | ||
32 | |||
33 | static int kstack_depth_to_print = 24; | ||
34 | |||
35 | static int __init kstack_setup(char *s) | ||
36 | { | ||
37 | kstack_depth_to_print = strict_strtoul(s, 0, 0); | ||
38 | |||
39 | return 1; | ||
40 | } | ||
41 | __setup("kstack=", kstack_setup); | ||
42 | |||
43 | void show_trace(struct task_struct *task, unsigned long *stack) | ||
44 | { | ||
45 | unsigned long addr; | ||
46 | |||
47 | if (!stack) | ||
48 | stack = (unsigned long *)&stack; | ||
49 | |||
50 | printk(KERN_NOTICE "Call Trace: "); | ||
51 | #ifdef CONFIG_KALLSYMS | ||
52 | printk(KERN_NOTICE "\n"); | ||
53 | #endif | ||
54 | while (!kstack_end(stack)) { | ||
55 | addr = *stack++; | ||
56 | /* | ||
57 | * If the address is either in the text segment of the | ||
58 | * kernel, or in the region which contains vmalloc'ed | ||
59 | * memory, it *may* be the address of a calling | ||
60 | * routine; if so, print it so that someone tracing | ||
61 | * down the cause of the crash will be able to figure | ||
62 | * out the call path that was taken. | ||
63 | */ | ||
64 | if (kernel_text_address(addr)) | ||
65 | print_ip_sym(addr); | ||
66 | } | ||
67 | printk(KERN_NOTICE "\n"); | ||
68 | |||
69 | if (!task) | ||
70 | task = current; | ||
71 | |||
72 | debug_show_held_locks(task); | ||
73 | } | ||
74 | |||
75 | void show_stack(struct task_struct *task, unsigned long *sp) | ||
76 | { | ||
77 | unsigned long *stack; | ||
78 | int i; | ||
79 | |||
80 | if (sp == NULL) { | ||
81 | if (task) | ||
82 | sp = (unsigned long *) ((struct thread_info *) | ||
83 | (task->stack))->cpu_context.r1; | ||
84 | else | ||
85 | sp = (unsigned long *)&sp; | ||
86 | } | ||
87 | |||
88 | stack = sp; | ||
89 | |||
90 | printk(KERN_INFO "\nStack:\n "); | ||
91 | |||
92 | for (i = 0; i < kstack_depth_to_print; i++) { | ||
93 | if (kstack_end(sp)) | ||
94 | break; | ||
95 | if (i && ((i % 8) == 0)) | ||
96 | printk("\n "); | ||
97 | printk("%08lx ", *sp++); | ||
98 | } | ||
99 | printk("\n"); | ||
100 | show_trace(task, stack); | ||
101 | } | ||
102 | |||
103 | void dump_stack(void) | ||
104 | { | ||
105 | show_stack(NULL, NULL); | ||
106 | } | ||
107 | EXPORT_SYMBOL(dump_stack); | ||
diff --git a/arch/microblaze/kernel/vmlinux.lds.S b/arch/microblaze/kernel/vmlinux.lds.S new file mode 100644 index 000000000000..840385e51291 --- /dev/null +++ b/arch/microblaze/kernel/vmlinux.lds.S | |||
@@ -0,0 +1,163 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu> | ||
3 | * Copyright (C) 2008-2009 PetaLogix | ||
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 | */ | ||
10 | |||
11 | OUTPUT_FORMAT("elf32-microblaze", "elf32-microblaze", "elf32-microblaze") | ||
12 | OUTPUT_ARCH(microblaze) | ||
13 | ENTRY(_start) | ||
14 | |||
15 | #include <asm-generic/vmlinux.lds.h> | ||
16 | |||
17 | jiffies = jiffies_64 + 4; | ||
18 | |||
19 | SECTIONS { | ||
20 | . = CONFIG_KERNEL_BASE_ADDR; | ||
21 | |||
22 | .text : { | ||
23 | _text = . ; | ||
24 | _stext = . ; | ||
25 | *(.text .text.*) | ||
26 | *(.fixup) | ||
27 | |||
28 | *(.exitcall.exit) | ||
29 | SCHED_TEXT | ||
30 | LOCK_TEXT | ||
31 | KPROBES_TEXT | ||
32 | . = ALIGN (4) ; | ||
33 | _etext = . ; | ||
34 | } | ||
35 | |||
36 | . = ALIGN (4) ; | ||
37 | _fdt_start = . ; /* place for fdt blob */ | ||
38 | . = . + 0x4000; | ||
39 | _fdt_end = . ; | ||
40 | |||
41 | . = ALIGN(16); | ||
42 | RODATA | ||
43 | . = ALIGN(16); | ||
44 | __ex_table : { | ||
45 | __start___ex_table = .; | ||
46 | *(__ex_table) | ||
47 | __stop___ex_table = .; | ||
48 | } | ||
49 | |||
50 | /* | ||
51 | * sdata2 section can go anywhere, but must be word aligned | ||
52 | * and SDA2_BASE must point to the middle of it | ||
53 | */ | ||
54 | .sdata2 : { | ||
55 | _ssrw = .; | ||
56 | . = ALIGN(4096); /* page aligned when MMU used - origin 0x8 */ | ||
57 | *(.sdata2) | ||
58 | . = ALIGN(8); | ||
59 | _essrw = .; | ||
60 | _ssrw_size = _essrw - _ssrw; | ||
61 | _KERNEL_SDA2_BASE_ = _ssrw + (_ssrw_size / 2); | ||
62 | } | ||
63 | |||
64 | _sdata = . ; | ||
65 | .data ALIGN (4096) : { /* page aligned when MMU used - origin 0x4 */ | ||
66 | *(.data) | ||
67 | } | ||
68 | . = ALIGN(32); | ||
69 | .data.cacheline_aligned : { *(.data.cacheline_aligned) } | ||
70 | _edata = . ; | ||
71 | |||
72 | /* Reserve some low RAM for r0 based memory references */ | ||
73 | . = ALIGN(0x4) ; | ||
74 | r0_ram = . ; | ||
75 | . = . + 4096; /* a page should be enough */ | ||
76 | |||
77 | /* The initial task */ | ||
78 | . = ALIGN(8192); | ||
79 | .data.init_task : { *(.data.init_task) } | ||
80 | |||
81 | /* Under the microblaze ABI, .sdata and .sbss must be contiguous */ | ||
82 | . = ALIGN(8); | ||
83 | .sdata : { | ||
84 | _ssro = .; | ||
85 | *(.sdata) | ||
86 | } | ||
87 | |||
88 | .sbss : { | ||
89 | _ssbss = .; | ||
90 | *(.sbss) | ||
91 | _esbss = .; | ||
92 | _essro = .; | ||
93 | _ssro_size = _essro - _ssro ; | ||
94 | _KERNEL_SDA_BASE_ = _ssro + (_ssro_size / 2) ; | ||
95 | } | ||
96 | |||
97 | __init_begin = .; | ||
98 | |||
99 | . = ALIGN(4096); | ||
100 | .init.text : { | ||
101 | _sinittext = . ; | ||
102 | *(.init.text) | ||
103 | *(.exit.text) | ||
104 | *(.exit.data) | ||
105 | _einittext = .; | ||
106 | } | ||
107 | |||
108 | .init.data : { *(.init.data) } | ||
109 | |||
110 | . = ALIGN(4); | ||
111 | .init.ivt : { | ||
112 | __ivt_start = .; | ||
113 | *(.init.ivt) | ||
114 | __ivt_end = .; | ||
115 | } | ||
116 | |||
117 | .init.setup : { | ||
118 | __setup_start = .; | ||
119 | *(.init.setup) | ||
120 | __setup_end = .; | ||
121 | } | ||
122 | |||
123 | .initcall.init : { | ||
124 | __initcall_start = .; | ||
125 | INITCALLS | ||
126 | __initcall_end = .; | ||
127 | } | ||
128 | |||
129 | .con_initcall.init : { | ||
130 | __con_initcall_start = .; | ||
131 | *(.con_initcall.init) | ||
132 | __con_initcall_end = .; | ||
133 | } | ||
134 | |||
135 | __init_end_before_initramfs = .; | ||
136 | |||
137 | .init.ramfs ALIGN(4096) : { | ||
138 | __initramfs_start = .; | ||
139 | *(.init.ramfs) | ||
140 | __initramfs_end = .; | ||
141 | . = ALIGN(4); | ||
142 | LONG(0); | ||
143 | /* | ||
144 | * FIXME this can break initramfs for MMU. | ||
145 | * Pad init.ramfs up to page boundary, | ||
146 | * so that __init_end == __bss_start. This will make image.elf | ||
147 | * consistent with the image.bin | ||
148 | */ | ||
149 | /* . = ALIGN(4096); */ | ||
150 | } | ||
151 | __init_end = .; | ||
152 | |||
153 | .bss ALIGN (4096) : { /* page aligned when MMU used */ | ||
154 | __bss_start = . ; | ||
155 | *(.bss*) | ||
156 | *(COMMON) | ||
157 | . = ALIGN (4) ; | ||
158 | __bss_stop = . ; | ||
159 | _ebss = . ; | ||
160 | } | ||
161 | . = ALIGN(4096); | ||
162 | _end = .; | ||
163 | } | ||
diff --git a/arch/microblaze/lib/Makefile b/arch/microblaze/lib/Makefile new file mode 100644 index 000000000000..d27126bf306a --- /dev/null +++ b/arch/microblaze/lib/Makefile | |||
@@ -0,0 +1,13 @@ | |||
1 | # | ||
2 | # Makefile | ||
3 | # | ||
4 | |||
5 | lib-y := memset.o checksum.o | ||
6 | |||
7 | ifeq ($(CONFIG_OPT_LIB_ASM),y) | ||
8 | lib-y += fastcopy.o | ||
9 | else | ||
10 | lib-y += memcpy.o memmove.o | ||
11 | endif | ||
12 | |||
13 | lib-y += uaccess.o | ||
diff --git a/arch/microblaze/lib/checksum.c b/arch/microblaze/lib/checksum.c new file mode 100644 index 000000000000..809340070a13 --- /dev/null +++ b/arch/microblaze/lib/checksum.c | |||
@@ -0,0 +1,163 @@ | |||
1 | /* | ||
2 | * | ||
3 | * INET An implementation of the TCP/IP protocol suite for the LINUX | ||
4 | * operating system. INET is implemented using the BSD Socket | ||
5 | * interface as the means of communication with the user level. | ||
6 | * | ||
7 | * IP/TCP/UDP checksumming routines | ||
8 | * | ||
9 | * Authors: Jorge Cwik, <jorge@laser.satlink.net> | ||
10 | * Arnt Gulbrandsen, <agulbra@nvg.unit.no> | ||
11 | * Tom May, <ftom@netcom.com> | ||
12 | * Andreas Schwab, <schwab@issan.informatik.uni-dortmund.de> | ||
13 | * Lots of code moved from tcp.c and ip.c; see those files | ||
14 | * for more names. | ||
15 | * | ||
16 | * 03/02/96 Jes Sorensen, Andreas Schwab, Roman Hodek: | ||
17 | * Fixed some nasty bugs, causing some horrible crashes. | ||
18 | * A: At some points, the sum (%0) was used as | ||
19 | * length-counter instead of the length counter | ||
20 | * (%1). Thanks to Roman Hodek for pointing this out. | ||
21 | * B: GCC seems to mess up if one uses too many | ||
22 | * data-registers to hold input values and one tries to | ||
23 | * specify d0 and d1 as scratch registers. Letting gcc | ||
24 | * choose these registers itself solves the problem. | ||
25 | * | ||
26 | * This program is free software; you can redistribute it and/or | ||
27 | * modify it under the terms of the GNU General Public License | ||
28 | * as published by the Free Software Foundation; either version | ||
29 | * 2 of the License, or (at your option) any later version. | ||
30 | */ | ||
31 | |||
32 | /* Revised by Kenneth Albanowski for m68knommu. Basic problem: unaligned access | ||
33 | kills, so most of the assembly has to go. */ | ||
34 | |||
35 | #include <net/checksum.h> | ||
36 | #include <asm/checksum.h> | ||
37 | #include <linux/module.h> | ||
38 | |||
39 | static inline unsigned short from32to16(unsigned long x) | ||
40 | { | ||
41 | /* add up 16-bit and 16-bit for 16+c bit */ | ||
42 | x = (x & 0xffff) + (x >> 16); | ||
43 | /* add up carry.. */ | ||
44 | x = (x & 0xffff) + (x >> 16); | ||
45 | return x; | ||
46 | } | ||
47 | |||
48 | static unsigned int do_csum(const unsigned char *buff, int len) | ||
49 | { | ||
50 | int odd, count; | ||
51 | unsigned long result = 0; | ||
52 | |||
53 | if (len <= 0) | ||
54 | goto out; | ||
55 | odd = 1 & (unsigned long) buff; | ||
56 | if (odd) { | ||
57 | result = *buff; | ||
58 | len--; | ||
59 | buff++; | ||
60 | } | ||
61 | count = len >> 1; /* nr of 16-bit words.. */ | ||
62 | if (count) { | ||
63 | if (2 & (unsigned long) buff) { | ||
64 | result += *(unsigned short *) buff; | ||
65 | count--; | ||
66 | len -= 2; | ||
67 | buff += 2; | ||
68 | } | ||
69 | count >>= 1; /* nr of 32-bit words.. */ | ||
70 | if (count) { | ||
71 | unsigned long carry = 0; | ||
72 | do { | ||
73 | unsigned long w = *(unsigned long *) buff; | ||
74 | count--; | ||
75 | buff += 4; | ||
76 | result += carry; | ||
77 | result += w; | ||
78 | carry = (w > result); | ||
79 | } while (count); | ||
80 | result += carry; | ||
81 | result = (result & 0xffff) + (result >> 16); | ||
82 | } | ||
83 | if (len & 2) { | ||
84 | result += *(unsigned short *) buff; | ||
85 | buff += 2; | ||
86 | } | ||
87 | } | ||
88 | if (len & 1) | ||
89 | result += (*buff << 8); | ||
90 | result = from32to16(result); | ||
91 | if (odd) | ||
92 | result = ((result >> 8) & 0xff) | ((result & 0xff) << 8); | ||
93 | out: | ||
94 | return result; | ||
95 | } | ||
96 | |||
97 | /* | ||
98 | * This is a version of ip_compute_csum() optimized for IP headers, | ||
99 | * which always checksum on 4 octet boundaries. | ||
100 | */ | ||
101 | __sum16 ip_fast_csum(const void *iph, unsigned int ihl) | ||
102 | { | ||
103 | return (__force __sum16)~do_csum(iph, ihl*4); | ||
104 | } | ||
105 | |||
106 | /* | ||
107 | * computes the checksum of a memory block at buff, length len, | ||
108 | * and adds in "sum" (32-bit) | ||
109 | * | ||
110 | * returns a 32-bit number suitable for feeding into itself | ||
111 | * or csum_tcpudp_magic | ||
112 | * | ||
113 | * this function must be called with even lengths, except | ||
114 | * for the last fragment, which may be odd | ||
115 | * | ||
116 | * it's best to have buff aligned on a 32-bit boundary | ||
117 | */ | ||
118 | __wsum csum_partial(const void *buff, int len, __wsum sum) | ||
119 | { | ||
120 | unsigned int result = do_csum(buff, len); | ||
121 | |||
122 | /* add in old sum, and carry.. */ | ||
123 | result += sum; | ||
124 | if (sum > result) | ||
125 | result += 1; | ||
126 | return result; | ||
127 | } | ||
128 | EXPORT_SYMBOL(csum_partial); | ||
129 | |||
130 | /* | ||
131 | * this routine is used for miscellaneous IP-like checksums, mainly | ||
132 | * in icmp.c | ||
133 | */ | ||
134 | __sum16 ip_compute_csum(const unsigned char *buff, int len) | ||
135 | { | ||
136 | return ~do_csum(buff, len); | ||
137 | } | ||
138 | EXPORT_SYMBOL(ip_compute_csum); | ||
139 | |||
140 | /* | ||
141 | * copy from fs while checksumming, otherwise like csum_partial | ||
142 | */ | ||
143 | __wsum | ||
144 | csum_partial_copy_from_user(const char __user *src, char *dst, int len, | ||
145 | int sum, int *csum_err) | ||
146 | { | ||
147 | if (csum_err) | ||
148 | *csum_err = 0; | ||
149 | memcpy(dst, src, len); | ||
150 | return csum_partial(dst, len, sum); | ||
151 | } | ||
152 | EXPORT_SYMBOL(csum_partial_copy_from_user); | ||
153 | |||
154 | /* | ||
155 | * copy from ds while checksumming, otherwise like csum_partial | ||
156 | */ | ||
157 | __wsum | ||
158 | csum_partial_copy(const char *src, char *dst, int len, int sum) | ||
159 | { | ||
160 | memcpy(dst, src, len); | ||
161 | return csum_partial(dst, len, sum); | ||
162 | } | ||
163 | EXPORT_SYMBOL(csum_partial_copy); | ||
diff --git a/arch/microblaze/lib/fastcopy.S b/arch/microblaze/lib/fastcopy.S new file mode 100644 index 000000000000..02e3ab4eddf3 --- /dev/null +++ b/arch/microblaze/lib/fastcopy.S | |||
@@ -0,0 +1,662 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu> | ||
3 | * Copyright (C) 2008-2009 PetaLogix | ||
4 | * Copyright (C) 2008 Jim Law - Iris LP All rights reserved. | ||
5 | * | ||
6 | * This file is subject to the terms and conditions of the GNU General | ||
7 | * Public License. See the file COPYING in the main directory of this | ||
8 | * archive for more details. | ||
9 | * | ||
10 | * Written by Jim Law <jlaw@irispower.com> | ||
11 | * | ||
12 | * intended to replace: | ||
13 | * memcpy in memcpy.c and | ||
14 | * memmove in memmove.c | ||
15 | * ... in arch/microblaze/lib | ||
16 | * | ||
17 | * | ||
18 | * assly_fastcopy.S | ||
19 | * | ||
20 | * Attempt at quicker memcpy and memmove for MicroBlaze | ||
21 | * Input : Operand1 in Reg r5 - destination address | ||
22 | * Operand2 in Reg r6 - source address | ||
23 | * Operand3 in Reg r7 - number of bytes to transfer | ||
24 | * Output: Result in Reg r3 - starting destinaition address | ||
25 | * | ||
26 | * | ||
27 | * Explanation: | ||
28 | * Perform (possibly unaligned) copy of a block of memory | ||
29 | * between mem locations with size of xfer spec'd in bytes | ||
30 | */ | ||
31 | |||
32 | #include <linux/linkage.h> | ||
33 | |||
34 | .globl memcpy | ||
35 | .ent memcpy | ||
36 | |||
37 | memcpy: | ||
38 | fast_memcpy_ascending: | ||
39 | /* move d to return register as value of function */ | ||
40 | addi r3, r5, 0 | ||
41 | |||
42 | addi r4, r0, 4 /* n = 4 */ | ||
43 | cmpu r4, r4, r7 /* n = c - n (unsigned) */ | ||
44 | blti r4, a_xfer_end /* if n < 0, less than one word to transfer */ | ||
45 | |||
46 | /* transfer first 0~3 bytes to get aligned dest address */ | ||
47 | andi r4, r5, 3 /* n = d & 3 */ | ||
48 | /* if zero, destination already aligned */ | ||
49 | beqi r4, a_dalign_done | ||
50 | /* n = 4 - n (yields 3, 2, 1 transfers for 1, 2, 3 addr offset) */ | ||
51 | rsubi r4, r4, 4 | ||
52 | rsub r7, r4, r7 /* c = c - n adjust c */ | ||
53 | |||
54 | a_xfer_first_loop: | ||
55 | /* if no bytes left to transfer, transfer the bulk */ | ||
56 | beqi r4, a_dalign_done | ||
57 | lbui r11, r6, 0 /* h = *s */ | ||
58 | sbi r11, r5, 0 /* *d = h */ | ||
59 | addi r6, r6, 1 /* s++ */ | ||
60 | addi r5, r5, 1 /* d++ */ | ||
61 | brid a_xfer_first_loop /* loop */ | ||
62 | addi r4, r4, -1 /* n-- (IN DELAY SLOT) */ | ||
63 | |||
64 | a_dalign_done: | ||
65 | addi r4, r0, 32 /* n = 32 */ | ||
66 | cmpu r4, r4, r7 /* n = c - n (unsigned) */ | ||
67 | /* if n < 0, less than one block to transfer */ | ||
68 | blti r4, a_block_done | ||
69 | |||
70 | a_block_xfer: | ||
71 | andi r4, r7, 0xffffffe0 /* n = c & ~31 */ | ||
72 | rsub r7, r4, r7 /* c = c - n */ | ||
73 | |||
74 | andi r9, r6, 3 /* t1 = s & 3 */ | ||
75 | /* if temp != 0, unaligned transfers needed */ | ||
76 | bnei r9, a_block_unaligned | ||
77 | |||
78 | a_block_aligned: | ||
79 | lwi r9, r6, 0 /* t1 = *(s + 0) */ | ||
80 | lwi r10, r6, 4 /* t2 = *(s + 4) */ | ||
81 | lwi r11, r6, 8 /* t3 = *(s + 8) */ | ||
82 | lwi r12, r6, 12 /* t4 = *(s + 12) */ | ||
83 | swi r9, r5, 0 /* *(d + 0) = t1 */ | ||
84 | swi r10, r5, 4 /* *(d + 4) = t2 */ | ||
85 | swi r11, r5, 8 /* *(d + 8) = t3 */ | ||
86 | swi r12, r5, 12 /* *(d + 12) = t4 */ | ||
87 | lwi r9, r6, 16 /* t1 = *(s + 16) */ | ||
88 | lwi r10, r6, 20 /* t2 = *(s + 20) */ | ||
89 | lwi r11, r6, 24 /* t3 = *(s + 24) */ | ||
90 | lwi r12, r6, 28 /* t4 = *(s + 28) */ | ||
91 | swi r9, r5, 16 /* *(d + 16) = t1 */ | ||
92 | swi r10, r5, 20 /* *(d + 20) = t2 */ | ||
93 | swi r11, r5, 24 /* *(d + 24) = t3 */ | ||
94 | swi r12, r5, 28 /* *(d + 28) = t4 */ | ||
95 | addi r6, r6, 32 /* s = s + 32 */ | ||
96 | addi r4, r4, -32 /* n = n - 32 */ | ||
97 | bneid r4, a_block_aligned /* while (n) loop */ | ||
98 | addi r5, r5, 32 /* d = d + 32 (IN DELAY SLOT) */ | ||
99 | bri a_block_done | ||
100 | |||
101 | a_block_unaligned: | ||
102 | andi r8, r6, 0xfffffffc /* as = s & ~3 */ | ||
103 | add r6, r6, r4 /* s = s + n */ | ||
104 | lwi r11, r8, 0 /* h = *(as + 0) */ | ||
105 | |||
106 | addi r9, r9, -1 | ||
107 | beqi r9, a_block_u1 /* t1 was 1 => 1 byte offset */ | ||
108 | addi r9, r9, -1 | ||
109 | beqi r9, a_block_u2 /* t1 was 2 => 2 byte offset */ | ||
110 | |||
111 | a_block_u3: | ||
112 | bslli r11, r11, 24 /* h = h << 24 */ | ||
113 | a_bu3_loop: | ||
114 | lwi r12, r8, 4 /* v = *(as + 4) */ | ||
115 | bsrli r9, r12, 8 /* t1 = v >> 8 */ | ||
116 | or r9, r11, r9 /* t1 = h | t1 */ | ||
117 | swi r9, r5, 0 /* *(d + 0) = t1 */ | ||
118 | bslli r11, r12, 24 /* h = v << 24 */ | ||
119 | lwi r12, r8, 8 /* v = *(as + 8) */ | ||
120 | bsrli r9, r12, 8 /* t1 = v >> 8 */ | ||
121 | or r9, r11, r9 /* t1 = h | t1 */ | ||
122 | swi r9, r5, 4 /* *(d + 4) = t1 */ | ||
123 | bslli r11, r12, 24 /* h = v << 24 */ | ||
124 | lwi r12, r8, 12 /* v = *(as + 12) */ | ||
125 | bsrli r9, r12, 8 /* t1 = v >> 8 */ | ||
126 | or r9, r11, r9 /* t1 = h | t1 */ | ||
127 | swi r9, r5, 8 /* *(d + 8) = t1 */ | ||
128 | bslli r11, r12, 24 /* h = v << 24 */ | ||
129 | lwi r12, r8, 16 /* v = *(as + 16) */ | ||
130 | bsrli r9, r12, 8 /* t1 = v >> 8 */ | ||
131 | or r9, r11, r9 /* t1 = h | t1 */ | ||
132 | swi r9, r5, 12 /* *(d + 12) = t1 */ | ||
133 | bslli r11, r12, 24 /* h = v << 24 */ | ||
134 | lwi r12, r8, 20 /* v = *(as + 20) */ | ||
135 | bsrli r9, r12, 8 /* t1 = v >> 8 */ | ||
136 | or r9, r11, r9 /* t1 = h | t1 */ | ||
137 | swi r9, r5, 16 /* *(d + 16) = t1 */ | ||
138 | bslli r11, r12, 24 /* h = v << 24 */ | ||
139 | lwi r12, r8, 24 /* v = *(as + 24) */ | ||
140 | bsrli r9, r12, 8 /* t1 = v >> 8 */ | ||
141 | or r9, r11, r9 /* t1 = h | t1 */ | ||
142 | swi r9, r5, 20 /* *(d + 20) = t1 */ | ||
143 | bslli r11, r12, 24 /* h = v << 24 */ | ||
144 | lwi r12, r8, 28 /* v = *(as + 28) */ | ||
145 | bsrli r9, r12, 8 /* t1 = v >> 8 */ | ||
146 | or r9, r11, r9 /* t1 = h | t1 */ | ||
147 | swi r9, r5, 24 /* *(d + 24) = t1 */ | ||
148 | bslli r11, r12, 24 /* h = v << 24 */ | ||
149 | lwi r12, r8, 32 /* v = *(as + 32) */ | ||
150 | bsrli r9, r12, 8 /* t1 = v >> 8 */ | ||
151 | or r9, r11, r9 /* t1 = h | t1 */ | ||
152 | swi r9, r5, 28 /* *(d + 28) = t1 */ | ||
153 | bslli r11, r12, 24 /* h = v << 24 */ | ||
154 | addi r8, r8, 32 /* as = as + 32 */ | ||
155 | addi r4, r4, -32 /* n = n - 32 */ | ||
156 | bneid r4, a_bu3_loop /* while (n) loop */ | ||
157 | addi r5, r5, 32 /* d = d + 32 (IN DELAY SLOT) */ | ||
158 | bri a_block_done | ||
159 | |||
160 | a_block_u1: | ||
161 | bslli r11, r11, 8 /* h = h << 8 */ | ||
162 | a_bu1_loop: | ||
163 | lwi r12, r8, 4 /* v = *(as + 4) */ | ||
164 | bsrli r9, r12, 24 /* t1 = v >> 24 */ | ||
165 | or r9, r11, r9 /* t1 = h | t1 */ | ||
166 | swi r9, r5, 0 /* *(d + 0) = t1 */ | ||
167 | bslli r11, r12, 8 /* h = v << 8 */ | ||
168 | lwi r12, r8, 8 /* v = *(as + 8) */ | ||
169 | bsrli r9, r12, 24 /* t1 = v >> 24 */ | ||
170 | or r9, r11, r9 /* t1 = h | t1 */ | ||
171 | swi r9, r5, 4 /* *(d + 4) = t1 */ | ||
172 | bslli r11, r12, 8 /* h = v << 8 */ | ||
173 | lwi r12, r8, 12 /* v = *(as + 12) */ | ||
174 | bsrli r9, r12, 24 /* t1 = v >> 24 */ | ||
175 | or r9, r11, r9 /* t1 = h | t1 */ | ||
176 | swi r9, r5, 8 /* *(d + 8) = t1 */ | ||
177 | bslli r11, r12, 8 /* h = v << 8 */ | ||
178 | lwi r12, r8, 16 /* v = *(as + 16) */ | ||
179 | bsrli r9, r12, 24 /* t1 = v >> 24 */ | ||
180 | or r9, r11, r9 /* t1 = h | t1 */ | ||
181 | swi r9, r5, 12 /* *(d + 12) = t1 */ | ||
182 | bslli r11, r12, 8 /* h = v << 8 */ | ||
183 | lwi r12, r8, 20 /* v = *(as + 20) */ | ||
184 | bsrli r9, r12, 24 /* t1 = v >> 24 */ | ||
185 | or r9, r11, r9 /* t1 = h | t1 */ | ||
186 | swi r9, r5, 16 /* *(d + 16) = t1 */ | ||
187 | bslli r11, r12, 8 /* h = v << 8 */ | ||
188 | lwi r12, r8, 24 /* v = *(as + 24) */ | ||
189 | bsrli r9, r12, 24 /* t1 = v >> 24 */ | ||
190 | or r9, r11, r9 /* t1 = h | t1 */ | ||
191 | swi r9, r5, 20 /* *(d + 20) = t1 */ | ||
192 | bslli r11, r12, 8 /* h = v << 8 */ | ||
193 | lwi r12, r8, 28 /* v = *(as + 28) */ | ||
194 | bsrli r9, r12, 24 /* t1 = v >> 24 */ | ||
195 | or r9, r11, r9 /* t1 = h | t1 */ | ||
196 | swi r9, r5, 24 /* *(d + 24) = t1 */ | ||
197 | bslli r11, r12, 8 /* h = v << 8 */ | ||
198 | lwi r12, r8, 32 /* v = *(as + 32) */ | ||
199 | bsrli r9, r12, 24 /* t1 = v >> 24 */ | ||
200 | or r9, r11, r9 /* t1 = h | t1 */ | ||
201 | swi r9, r5, 28 /* *(d + 28) = t1 */ | ||
202 | bslli r11, r12, 8 /* h = v << 8 */ | ||
203 | addi r8, r8, 32 /* as = as + 32 */ | ||
204 | addi r4, r4, -32 /* n = n - 32 */ | ||
205 | bneid r4, a_bu1_loop /* while (n) loop */ | ||
206 | addi r5, r5, 32 /* d = d + 32 (IN DELAY SLOT) */ | ||
207 | bri a_block_done | ||
208 | |||
209 | a_block_u2: | ||
210 | bslli r11, r11, 16 /* h = h << 16 */ | ||
211 | a_bu2_loop: | ||
212 | lwi r12, r8, 4 /* v = *(as + 4) */ | ||
213 | bsrli r9, r12, 16 /* t1 = v >> 16 */ | ||
214 | or r9, r11, r9 /* t1 = h | t1 */ | ||
215 | swi r9, r5, 0 /* *(d + 0) = t1 */ | ||
216 | bslli r11, r12, 16 /* h = v << 16 */ | ||
217 | lwi r12, r8, 8 /* v = *(as + 8) */ | ||
218 | bsrli r9, r12, 16 /* t1 = v >> 16 */ | ||
219 | or r9, r11, r9 /* t1 = h | t1 */ | ||
220 | swi r9, r5, 4 /* *(d + 4) = t1 */ | ||
221 | bslli r11, r12, 16 /* h = v << 16 */ | ||
222 | lwi r12, r8, 12 /* v = *(as + 12) */ | ||
223 | bsrli r9, r12, 16 /* t1 = v >> 16 */ | ||
224 | or r9, r11, r9 /* t1 = h | t1 */ | ||
225 | swi r9, r5, 8 /* *(d + 8) = t1 */ | ||
226 | bslli r11, r12, 16 /* h = v << 16 */ | ||
227 | lwi r12, r8, 16 /* v = *(as + 16) */ | ||
228 | bsrli r9, r12, 16 /* t1 = v >> 16 */ | ||
229 | or r9, r11, r9 /* t1 = h | t1 */ | ||
230 | swi r9, r5, 12 /* *(d + 12) = t1 */ | ||
231 | bslli r11, r12, 16 /* h = v << 16 */ | ||
232 | lwi r12, r8, 20 /* v = *(as + 20) */ | ||
233 | bsrli r9, r12, 16 /* t1 = v >> 16 */ | ||
234 | or r9, r11, r9 /* t1 = h | t1 */ | ||
235 | swi r9, r5, 16 /* *(d + 16) = t1 */ | ||
236 | bslli r11, r12, 16 /* h = v << 16 */ | ||
237 | lwi r12, r8, 24 /* v = *(as + 24) */ | ||
238 | bsrli r9, r12, 16 /* t1 = v >> 16 */ | ||
239 | or r9, r11, r9 /* t1 = h | t1 */ | ||
240 | swi r9, r5, 20 /* *(d + 20) = t1 */ | ||
241 | bslli r11, r12, 16 /* h = v << 16 */ | ||
242 | lwi r12, r8, 28 /* v = *(as + 28) */ | ||
243 | bsrli r9, r12, 16 /* t1 = v >> 16 */ | ||
244 | or r9, r11, r9 /* t1 = h | t1 */ | ||
245 | swi r9, r5, 24 /* *(d + 24) = t1 */ | ||
246 | bslli r11, r12, 16 /* h = v << 16 */ | ||
247 | lwi r12, r8, 32 /* v = *(as + 32) */ | ||
248 | bsrli r9, r12, 16 /* t1 = v >> 16 */ | ||
249 | or r9, r11, r9 /* t1 = h | t1 */ | ||
250 | swi r9, r5, 28 /* *(d + 28) = t1 */ | ||
251 | bslli r11, r12, 16 /* h = v << 16 */ | ||
252 | addi r8, r8, 32 /* as = as + 32 */ | ||
253 | addi r4, r4, -32 /* n = n - 32 */ | ||
254 | bneid r4, a_bu2_loop /* while (n) loop */ | ||
255 | addi r5, r5, 32 /* d = d + 32 (IN DELAY SLOT) */ | ||
256 | |||
257 | a_block_done: | ||
258 | addi r4, r0, 4 /* n = 4 */ | ||
259 | cmpu r4, r4, r7 /* n = c - n (unsigned) */ | ||
260 | blti r4, a_xfer_end /* if n < 0, less than one word to transfer */ | ||
261 | |||
262 | a_word_xfer: | ||
263 | andi r4, r7, 0xfffffffc /* n = c & ~3 */ | ||
264 | addi r10, r0, 0 /* offset = 0 */ | ||
265 | |||
266 | andi r9, r6, 3 /* t1 = s & 3 */ | ||
267 | /* if temp != 0, unaligned transfers needed */ | ||
268 | bnei r9, a_word_unaligned | ||
269 | |||
270 | a_word_aligned: | ||
271 | lw r9, r6, r10 /* t1 = *(s+offset) */ | ||
272 | sw r9, r5, r10 /* *(d+offset) = t1 */ | ||
273 | addi r4, r4,-4 /* n-- */ | ||
274 | bneid r4, a_word_aligned /* loop */ | ||
275 | addi r10, r10, 4 /* offset++ (IN DELAY SLOT) */ | ||
276 | |||
277 | bri a_word_done | ||
278 | |||
279 | a_word_unaligned: | ||
280 | andi r8, r6, 0xfffffffc /* as = s & ~3 */ | ||
281 | lwi r11, r8, 0 /* h = *(as + 0) */ | ||
282 | addi r8, r8, 4 /* as = as + 4 */ | ||
283 | |||
284 | addi r9, r9, -1 | ||
285 | beqi r9, a_word_u1 /* t1 was 1 => 1 byte offset */ | ||
286 | addi r9, r9, -1 | ||
287 | beqi r9, a_word_u2 /* t1 was 2 => 2 byte offset */ | ||
288 | |||
289 | a_word_u3: | ||
290 | bslli r11, r11, 24 /* h = h << 24 */ | ||
291 | a_wu3_loop: | ||
292 | lw r12, r8, r10 /* v = *(as + offset) */ | ||
293 | bsrli r9, r12, 8 /* t1 = v >> 8 */ | ||
294 | or r9, r11, r9 /* t1 = h | t1 */ | ||
295 | sw r9, r5, r10 /* *(d + offset) = t1 */ | ||
296 | bslli r11, r12, 24 /* h = v << 24 */ | ||
297 | addi r4, r4,-4 /* n = n - 4 */ | ||
298 | bneid r4, a_wu3_loop /* while (n) loop */ | ||
299 | addi r10, r10, 4 /* offset = ofset + 4 (IN DELAY SLOT) */ | ||
300 | |||
301 | bri a_word_done | ||
302 | |||
303 | a_word_u1: | ||
304 | bslli r11, r11, 8 /* h = h << 8 */ | ||
305 | a_wu1_loop: | ||
306 | lw r12, r8, r10 /* v = *(as + offset) */ | ||
307 | bsrli r9, r12, 24 /* t1 = v >> 24 */ | ||
308 | or r9, r11, r9 /* t1 = h | t1 */ | ||
309 | sw r9, r5, r10 /* *(d + offset) = t1 */ | ||
310 | bslli r11, r12, 8 /* h = v << 8 */ | ||
311 | addi r4, r4,-4 /* n = n - 4 */ | ||
312 | bneid r4, a_wu1_loop /* while (n) loop */ | ||
313 | addi r10, r10, 4 /* offset = ofset + 4 (IN DELAY SLOT) */ | ||
314 | |||
315 | bri a_word_done | ||
316 | |||
317 | a_word_u2: | ||
318 | bslli r11, r11, 16 /* h = h << 16 */ | ||
319 | a_wu2_loop: | ||
320 | lw r12, r8, r10 /* v = *(as + offset) */ | ||
321 | bsrli r9, r12, 16 /* t1 = v >> 16 */ | ||
322 | or r9, r11, r9 /* t1 = h | t1 */ | ||
323 | sw r9, r5, r10 /* *(d + offset) = t1 */ | ||
324 | bslli r11, r12, 16 /* h = v << 16 */ | ||
325 | addi r4, r4,-4 /* n = n - 4 */ | ||
326 | bneid r4, a_wu2_loop /* while (n) loop */ | ||
327 | addi r10, r10, 4 /* offset = ofset + 4 (IN DELAY SLOT) */ | ||
328 | |||
329 | a_word_done: | ||
330 | add r5, r5, r10 /* d = d + offset */ | ||
331 | add r6, r6, r10 /* s = s + offset */ | ||
332 | rsub r7, r10, r7 /* c = c - offset */ | ||
333 | |||
334 | a_xfer_end: | ||
335 | a_xfer_end_loop: | ||
336 | beqi r7, a_done /* while (c) */ | ||
337 | lbui r9, r6, 0 /* t1 = *s */ | ||
338 | addi r6, r6, 1 /* s++ */ | ||
339 | sbi r9, r5, 0 /* *d = t1 */ | ||
340 | addi r7, r7, -1 /* c-- */ | ||
341 | brid a_xfer_end_loop /* loop */ | ||
342 | addi r5, r5, 1 /* d++ (IN DELAY SLOT) */ | ||
343 | |||
344 | a_done: | ||
345 | rtsd r15, 8 | ||
346 | nop | ||
347 | |||
348 | .end memcpy | ||
349 | /*----------------------------------------------------------------------------*/ | ||
350 | .globl memmove | ||
351 | .ent memmove | ||
352 | |||
353 | memmove: | ||
354 | cmpu r4, r5, r6 /* n = s - d */ | ||
355 | bgei r4,fast_memcpy_ascending | ||
356 | |||
357 | fast_memcpy_descending: | ||
358 | /* move d to return register as value of function */ | ||
359 | addi r3, r5, 0 | ||
360 | |||
361 | add r5, r5, r7 /* d = d + c */ | ||
362 | add r6, r6, r7 /* s = s + c */ | ||
363 | |||
364 | addi r4, r0, 4 /* n = 4 */ | ||
365 | cmpu r4, r4, r7 /* n = c - n (unsigned) */ | ||
366 | blti r4,d_xfer_end /* if n < 0, less than one word to transfer */ | ||
367 | |||
368 | /* transfer first 0~3 bytes to get aligned dest address */ | ||
369 | andi r4, r5, 3 /* n = d & 3 */ | ||
370 | /* if zero, destination already aligned */ | ||
371 | beqi r4,d_dalign_done | ||
372 | rsub r7, r4, r7 /* c = c - n adjust c */ | ||
373 | |||
374 | d_xfer_first_loop: | ||
375 | /* if no bytes left to transfer, transfer the bulk */ | ||
376 | beqi r4,d_dalign_done | ||
377 | addi r6, r6, -1 /* s-- */ | ||
378 | addi r5, r5, -1 /* d-- */ | ||
379 | lbui r11, r6, 0 /* h = *s */ | ||
380 | sbi r11, r5, 0 /* *d = h */ | ||
381 | brid d_xfer_first_loop /* loop */ | ||
382 | addi r4, r4, -1 /* n-- (IN DELAY SLOT) */ | ||
383 | |||
384 | d_dalign_done: | ||
385 | addi r4, r0, 32 /* n = 32 */ | ||
386 | cmpu r4, r4, r7 /* n = c - n (unsigned) */ | ||
387 | /* if n < 0, less than one block to transfer */ | ||
388 | blti r4, d_block_done | ||
389 | |||
390 | d_block_xfer: | ||
391 | andi r4, r7, 0xffffffe0 /* n = c & ~31 */ | ||
392 | rsub r7, r4, r7 /* c = c - n */ | ||
393 | |||
394 | andi r9, r6, 3 /* t1 = s & 3 */ | ||
395 | /* if temp != 0, unaligned transfers needed */ | ||
396 | bnei r9, d_block_unaligned | ||
397 | |||
398 | d_block_aligned: | ||
399 | addi r6, r6, -32 /* s = s - 32 */ | ||
400 | addi r5, r5, -32 /* d = d - 32 */ | ||
401 | lwi r9, r6, 28 /* t1 = *(s + 28) */ | ||
402 | lwi r10, r6, 24 /* t2 = *(s + 24) */ | ||
403 | lwi r11, r6, 20 /* t3 = *(s + 20) */ | ||
404 | lwi r12, r6, 16 /* t4 = *(s + 16) */ | ||
405 | swi r9, r5, 28 /* *(d + 28) = t1 */ | ||
406 | swi r10, r5, 24 /* *(d + 24) = t2 */ | ||
407 | swi r11, r5, 20 /* *(d + 20) = t3 */ | ||
408 | swi r12, r5, 16 /* *(d + 16) = t4 */ | ||
409 | lwi r9, r6, 12 /* t1 = *(s + 12) */ | ||
410 | lwi r10, r6, 8 /* t2 = *(s + 8) */ | ||
411 | lwi r11, r6, 4 /* t3 = *(s + 4) */ | ||
412 | lwi r12, r6, 0 /* t4 = *(s + 0) */ | ||
413 | swi r9, r5, 12 /* *(d + 12) = t1 */ | ||
414 | swi r10, r5, 8 /* *(d + 8) = t2 */ | ||
415 | swi r11, r5, 4 /* *(d + 4) = t3 */ | ||
416 | addi r4, r4, -32 /* n = n - 32 */ | ||
417 | bneid r4, d_block_aligned /* while (n) loop */ | ||
418 | swi r12, r5, 0 /* *(d + 0) = t4 (IN DELAY SLOT) */ | ||
419 | bri d_block_done | ||
420 | |||
421 | d_block_unaligned: | ||
422 | andi r8, r6, 0xfffffffc /* as = s & ~3 */ | ||
423 | rsub r6, r4, r6 /* s = s - n */ | ||
424 | lwi r11, r8, 0 /* h = *(as + 0) */ | ||
425 | |||
426 | addi r9, r9, -1 | ||
427 | beqi r9,d_block_u1 /* t1 was 1 => 1 byte offset */ | ||
428 | addi r9, r9, -1 | ||
429 | beqi r9,d_block_u2 /* t1 was 2 => 2 byte offset */ | ||
430 | |||
431 | d_block_u3: | ||
432 | bsrli r11, r11, 8 /* h = h >> 8 */ | ||
433 | d_bu3_loop: | ||
434 | addi r8, r8, -32 /* as = as - 32 */ | ||
435 | addi r5, r5, -32 /* d = d - 32 */ | ||
436 | lwi r12, r8, 28 /* v = *(as + 28) */ | ||
437 | bslli r9, r12, 24 /* t1 = v << 24 */ | ||
438 | or r9, r11, r9 /* t1 = h | t1 */ | ||
439 | swi r9, r5, 28 /* *(d + 28) = t1 */ | ||
440 | bsrli r11, r12, 8 /* h = v >> 8 */ | ||
441 | lwi r12, r8, 24 /* v = *(as + 24) */ | ||
442 | bslli r9, r12, 24 /* t1 = v << 24 */ | ||
443 | or r9, r11, r9 /* t1 = h | t1 */ | ||
444 | swi r9, r5, 24 /* *(d + 24) = t1 */ | ||
445 | bsrli r11, r12, 8 /* h = v >> 8 */ | ||
446 | lwi r12, r8, 20 /* v = *(as + 20) */ | ||
447 | bslli r9, r12, 24 /* t1 = v << 24 */ | ||
448 | or r9, r11, r9 /* t1 = h | t1 */ | ||
449 | swi r9, r5, 20 /* *(d + 20) = t1 */ | ||
450 | bsrli r11, r12, 8 /* h = v >> 8 */ | ||
451 | lwi r12, r8, 16 /* v = *(as + 16) */ | ||
452 | bslli r9, r12, 24 /* t1 = v << 24 */ | ||
453 | or r9, r11, r9 /* t1 = h | t1 */ | ||
454 | swi r9, r5, 16 /* *(d + 16) = t1 */ | ||
455 | bsrli r11, r12, 8 /* h = v >> 8 */ | ||
456 | lwi r12, r8, 12 /* v = *(as + 12) */ | ||
457 | bslli r9, r12, 24 /* t1 = v << 24 */ | ||
458 | or r9, r11, r9 /* t1 = h | t1 */ | ||
459 | swi r9, r5, 12 /* *(d + 112) = t1 */ | ||
460 | bsrli r11, r12, 8 /* h = v >> 8 */ | ||
461 | lwi r12, r8, 8 /* v = *(as + 8) */ | ||
462 | bslli r9, r12, 24 /* t1 = v << 24 */ | ||
463 | or r9, r11, r9 /* t1 = h | t1 */ | ||
464 | swi r9, r5, 8 /* *(d + 8) = t1 */ | ||
465 | bsrli r11, r12, 8 /* h = v >> 8 */ | ||
466 | lwi r12, r8, 4 /* v = *(as + 4) */ | ||
467 | bslli r9, r12, 24 /* t1 = v << 24 */ | ||
468 | or r9, r11, r9 /* t1 = h | t1 */ | ||
469 | swi r9, r5, 4 /* *(d + 4) = t1 */ | ||
470 | bsrli r11, r12, 8 /* h = v >> 8 */ | ||
471 | lwi r12, r8, 0 /* v = *(as + 0) */ | ||
472 | bslli r9, r12, 24 /* t1 = v << 24 */ | ||
473 | or r9, r11, r9 /* t1 = h | t1 */ | ||
474 | swi r9, r5, 0 /* *(d + 0) = t1 */ | ||
475 | addi r4, r4, -32 /* n = n - 32 */ | ||
476 | bneid r4, d_bu3_loop /* while (n) loop */ | ||
477 | bsrli r11, r12, 8 /* h = v >> 8 (IN DELAY SLOT) */ | ||
478 | bri d_block_done | ||
479 | |||
480 | d_block_u1: | ||
481 | bsrli r11, r11, 24 /* h = h >> 24 */ | ||
482 | d_bu1_loop: | ||
483 | addi r8, r8, -32 /* as = as - 32 */ | ||
484 | addi r5, r5, -32 /* d = d - 32 */ | ||
485 | lwi r12, r8, 28 /* v = *(as + 28) */ | ||
486 | bslli r9, r12, 8 /* t1 = v << 8 */ | ||
487 | or r9, r11, r9 /* t1 = h | t1 */ | ||
488 | swi r9, r5, 28 /* *(d + 28) = t1 */ | ||
489 | bsrli r11, r12, 24 /* h = v >> 24 */ | ||
490 | lwi r12, r8, 24 /* v = *(as + 24) */ | ||
491 | bslli r9, r12, 8 /* t1 = v << 8 */ | ||
492 | or r9, r11, r9 /* t1 = h | t1 */ | ||
493 | swi r9, r5, 24 /* *(d + 24) = t1 */ | ||
494 | bsrli r11, r12, 24 /* h = v >> 24 */ | ||
495 | lwi r12, r8, 20 /* v = *(as + 20) */ | ||
496 | bslli r9, r12, 8 /* t1 = v << 8 */ | ||
497 | or r9, r11, r9 /* t1 = h | t1 */ | ||
498 | swi r9, r5, 20 /* *(d + 20) = t1 */ | ||
499 | bsrli r11, r12, 24 /* h = v >> 24 */ | ||
500 | lwi r12, r8, 16 /* v = *(as + 16) */ | ||
501 | bslli r9, r12, 8 /* t1 = v << 8 */ | ||
502 | or r9, r11, r9 /* t1 = h | t1 */ | ||
503 | swi r9, r5, 16 /* *(d + 16) = t1 */ | ||
504 | bsrli r11, r12, 24 /* h = v >> 24 */ | ||
505 | lwi r12, r8, 12 /* v = *(as + 12) */ | ||
506 | bslli r9, r12, 8 /* t1 = v << 8 */ | ||
507 | or r9, r11, r9 /* t1 = h | t1 */ | ||
508 | swi r9, r5, 12 /* *(d + 112) = t1 */ | ||
509 | bsrli r11, r12, 24 /* h = v >> 24 */ | ||
510 | lwi r12, r8, 8 /* v = *(as + 8) */ | ||
511 | bslli r9, r12, 8 /* t1 = v << 8 */ | ||
512 | or r9, r11, r9 /* t1 = h | t1 */ | ||
513 | swi r9, r5, 8 /* *(d + 8) = t1 */ | ||
514 | bsrli r11, r12, 24 /* h = v >> 24 */ | ||
515 | lwi r12, r8, 4 /* v = *(as + 4) */ | ||
516 | bslli r9, r12, 8 /* t1 = v << 8 */ | ||
517 | or r9, r11, r9 /* t1 = h | t1 */ | ||
518 | swi r9, r5, 4 /* *(d + 4) = t1 */ | ||
519 | bsrli r11, r12, 24 /* h = v >> 24 */ | ||
520 | lwi r12, r8, 0 /* v = *(as + 0) */ | ||
521 | bslli r9, r12, 8 /* t1 = v << 8 */ | ||
522 | or r9, r11, r9 /* t1 = h | t1 */ | ||
523 | swi r9, r5, 0 /* *(d + 0) = t1 */ | ||
524 | addi r4, r4, -32 /* n = n - 32 */ | ||
525 | bneid r4, d_bu1_loop /* while (n) loop */ | ||
526 | bsrli r11, r12, 24 /* h = v >> 24 (IN DELAY SLOT) */ | ||
527 | bri d_block_done | ||
528 | |||
529 | d_block_u2: | ||
530 | bsrli r11, r11, 16 /* h = h >> 16 */ | ||
531 | d_bu2_loop: | ||
532 | addi r8, r8, -32 /* as = as - 32 */ | ||
533 | addi r5, r5, -32 /* d = d - 32 */ | ||
534 | lwi r12, r8, 28 /* v = *(as + 28) */ | ||
535 | bslli r9, r12, 16 /* t1 = v << 16 */ | ||
536 | or r9, r11, r9 /* t1 = h | t1 */ | ||
537 | swi r9, r5, 28 /* *(d + 28) = t1 */ | ||
538 | bsrli r11, r12, 16 /* h = v >> 16 */ | ||
539 | lwi r12, r8, 24 /* v = *(as + 24) */ | ||
540 | bslli r9, r12, 16 /* t1 = v << 16 */ | ||
541 | or r9, r11, r9 /* t1 = h | t1 */ | ||
542 | swi r9, r5, 24 /* *(d + 24) = t1 */ | ||
543 | bsrli r11, r12, 16 /* h = v >> 16 */ | ||
544 | lwi r12, r8, 20 /* v = *(as + 20) */ | ||
545 | bslli r9, r12, 16 /* t1 = v << 16 */ | ||
546 | or r9, r11, r9 /* t1 = h | t1 */ | ||
547 | swi r9, r5, 20 /* *(d + 20) = t1 */ | ||
548 | bsrli r11, r12, 16 /* h = v >> 16 */ | ||
549 | lwi r12, r8, 16 /* v = *(as + 16) */ | ||
550 | bslli r9, r12, 16 /* t1 = v << 16 */ | ||
551 | or r9, r11, r9 /* t1 = h | t1 */ | ||
552 | swi r9, r5, 16 /* *(d + 16) = t1 */ | ||
553 | bsrli r11, r12, 16 /* h = v >> 16 */ | ||
554 | lwi r12, r8, 12 /* v = *(as + 12) */ | ||
555 | bslli r9, r12, 16 /* t1 = v << 16 */ | ||
556 | or r9, r11, r9 /* t1 = h | t1 */ | ||
557 | swi r9, r5, 12 /* *(d + 112) = t1 */ | ||
558 | bsrli r11, r12, 16 /* h = v >> 16 */ | ||
559 | lwi r12, r8, 8 /* v = *(as + 8) */ | ||
560 | bslli r9, r12, 16 /* t1 = v << 16 */ | ||
561 | or r9, r11, r9 /* t1 = h | t1 */ | ||
562 | swi r9, r5, 8 /* *(d + 8) = t1 */ | ||
563 | bsrli r11, r12, 16 /* h = v >> 16 */ | ||
564 | lwi r12, r8, 4 /* v = *(as + 4) */ | ||
565 | bslli r9, r12, 16 /* t1 = v << 16 */ | ||
566 | or r9, r11, r9 /* t1 = h | t1 */ | ||
567 | swi r9, r5, 4 /* *(d + 4) = t1 */ | ||
568 | bsrli r11, r12, 16 /* h = v >> 16 */ | ||
569 | lwi r12, r8, 0 /* v = *(as + 0) */ | ||
570 | bslli r9, r12, 16 /* t1 = v << 16 */ | ||
571 | or r9, r11, r9 /* t1 = h | t1 */ | ||
572 | swi r9, r5, 0 /* *(d + 0) = t1 */ | ||
573 | addi r4, r4, -32 /* n = n - 32 */ | ||
574 | bneid r4, d_bu2_loop /* while (n) loop */ | ||
575 | bsrli r11, r12, 16 /* h = v >> 16 (IN DELAY SLOT) */ | ||
576 | |||
577 | d_block_done: | ||
578 | addi r4, r0, 4 /* n = 4 */ | ||
579 | cmpu r4, r4, r7 /* n = c - n (unsigned) */ | ||
580 | blti r4,d_xfer_end /* if n < 0, less than one word to transfer */ | ||
581 | |||
582 | d_word_xfer: | ||
583 | andi r4, r7, 0xfffffffc /* n = c & ~3 */ | ||
584 | rsub r5, r4, r5 /* d = d - n */ | ||
585 | rsub r6, r4, r6 /* s = s - n */ | ||
586 | rsub r7, r4, r7 /* c = c - n */ | ||
587 | |||
588 | andi r9, r6, 3 /* t1 = s & 3 */ | ||
589 | /* if temp != 0, unaligned transfers needed */ | ||
590 | bnei r9, d_word_unaligned | ||
591 | |||
592 | d_word_aligned: | ||
593 | addi r4, r4,-4 /* n-- */ | ||
594 | lw r9, r6, r4 /* t1 = *(s+n) */ | ||
595 | bneid r4, d_word_aligned /* loop */ | ||
596 | sw r9, r5, r4 /* *(d+n) = t1 (IN DELAY SLOT) */ | ||
597 | |||
598 | bri d_word_done | ||
599 | |||
600 | d_word_unaligned: | ||
601 | andi r8, r6, 0xfffffffc /* as = s & ~3 */ | ||
602 | lw r11, r8, r4 /* h = *(as + n) */ | ||
603 | |||
604 | addi r9, r9, -1 | ||
605 | beqi r9,d_word_u1 /* t1 was 1 => 1 byte offset */ | ||
606 | addi r9, r9, -1 | ||
607 | beqi r9,d_word_u2 /* t1 was 2 => 2 byte offset */ | ||
608 | |||
609 | d_word_u3: | ||
610 | bsrli r11, r11, 8 /* h = h >> 8 */ | ||
611 | d_wu3_loop: | ||
612 | addi r4, r4,-4 /* n = n - 4 */ | ||
613 | lw r12, r8, r4 /* v = *(as + n) */ | ||
614 | bslli r9, r12, 24 /* t1 = v << 24 */ | ||
615 | or r9, r11, r9 /* t1 = h | t1 */ | ||
616 | sw r9, r5, r4 /* *(d + n) = t1 */ | ||
617 | bneid r4, d_wu3_loop /* while (n) loop */ | ||
618 | bsrli r11, r12, 8 /* h = v >> 8 (IN DELAY SLOT) */ | ||
619 | |||
620 | bri d_word_done | ||
621 | |||
622 | d_word_u1: | ||
623 | bsrli r11, r11, 24 /* h = h >> 24 */ | ||
624 | d_wu1_loop: | ||
625 | addi r4, r4,-4 /* n = n - 4 */ | ||
626 | lw r12, r8, r4 /* v = *(as + n) */ | ||
627 | bslli r9, r12, 8 /* t1 = v << 8 */ | ||
628 | or r9, r11, r9 /* t1 = h | t1 */ | ||
629 | sw r9, r5, r4 /* *(d + n) = t1 */ | ||
630 | bneid r4, d_wu1_loop /* while (n) loop */ | ||
631 | bsrli r11, r12, 24 /* h = v >> 24 (IN DELAY SLOT) */ | ||
632 | |||
633 | bri d_word_done | ||
634 | |||
635 | d_word_u2: | ||
636 | bsrli r11, r11, 16 /* h = h >> 16 */ | ||
637 | d_wu2_loop: | ||
638 | addi r4, r4,-4 /* n = n - 4 */ | ||
639 | lw r12, r8, r4 /* v = *(as + n) */ | ||
640 | bslli r9, r12, 16 /* t1 = v << 16 */ | ||
641 | or r9, r11, r9 /* t1 = h | t1 */ | ||
642 | sw r9, r5, r4 /* *(d + n) = t1 */ | ||
643 | bneid r4, d_wu2_loop /* while (n) loop */ | ||
644 | bsrli r11, r12, 16 /* h = v >> 16 (IN DELAY SLOT) */ | ||
645 | |||
646 | d_word_done: | ||
647 | |||
648 | d_xfer_end: | ||
649 | d_xfer_end_loop: | ||
650 | beqi r7, a_done /* while (c) */ | ||
651 | addi r6, r6, -1 /* s-- */ | ||
652 | lbui r9, r6, 0 /* t1 = *s */ | ||
653 | addi r5, r5, -1 /* d-- */ | ||
654 | sbi r9, r5, 0 /* *d = t1 */ | ||
655 | brid d_xfer_end_loop /* loop */ | ||
656 | addi r7, r7, -1 /* c-- (IN DELAY SLOT) */ | ||
657 | |||
658 | d_done: | ||
659 | rtsd r15, 8 | ||
660 | nop | ||
661 | |||
662 | .end memmove | ||
diff --git a/arch/microblaze/lib/memcpy.c b/arch/microblaze/lib/memcpy.c new file mode 100644 index 000000000000..5880119c4487 --- /dev/null +++ b/arch/microblaze/lib/memcpy.c | |||
@@ -0,0 +1,161 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu> | ||
3 | * Copyright (C) 2008-2009 PetaLogix | ||
4 | * Copyright (C) 2007 John Williams | ||
5 | * | ||
6 | * Reasonably optimised generic C-code for memcpy on Microblaze | ||
7 | * This is generic C code to do efficient, alignment-aware memcpy. | ||
8 | * | ||
9 | * It is based on demo code originally Copyright 2001 by Intel Corp, taken from | ||
10 | * http://www.embedded.com/showArticle.jhtml?articleID=19205567 | ||
11 | * | ||
12 | * Attempts were made, unsuccesfully, to contact the original | ||
13 | * author of this code (Michael Morrow, Intel). Below is the original | ||
14 | * copyright notice. | ||
15 | * | ||
16 | * This software has been developed by Intel Corporation. | ||
17 | * Intel specifically disclaims all warranties, express or | ||
18 | * implied, and all liability, including consequential and | ||
19 | * other indirect damages, for the use of this program, including | ||
20 | * liability for infringement of any proprietary rights, | ||
21 | * and including the warranties of merchantability and fitness | ||
22 | * for a particular purpose. Intel does not assume any | ||
23 | * responsibility for and errors which may appear in this program | ||
24 | * not any responsibility to update it. | ||
25 | */ | ||
26 | |||
27 | #include <linux/types.h> | ||
28 | #include <linux/stddef.h> | ||
29 | #include <linux/compiler.h> | ||
30 | #include <linux/module.h> | ||
31 | |||
32 | #include <linux/string.h> | ||
33 | #include <asm/system.h> | ||
34 | |||
35 | #ifdef __HAVE_ARCH_MEMCPY | ||
36 | void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c) | ||
37 | { | ||
38 | const char *src = v_src; | ||
39 | char *dst = v_dst; | ||
40 | #ifndef CONFIG_OPT_LIB_FUNCTION | ||
41 | /* Simple, byte oriented memcpy. */ | ||
42 | while (c--) | ||
43 | *dst++ = *src++; | ||
44 | |||
45 | return v_dst; | ||
46 | #else | ||
47 | /* The following code tries to optimize the copy by using unsigned | ||
48 | * alignment. This will work fine if both source and destination are | ||
49 | * aligned on the same boundary. However, if they are aligned on | ||
50 | * different boundaries shifts will be necessary. This might result in | ||
51 | * bad performance on MicroBlaze systems without a barrel shifter. | ||
52 | */ | ||
53 | const uint32_t *i_src; | ||
54 | uint32_t *i_dst; | ||
55 | |||
56 | if (c >= 4) { | ||
57 | unsigned value, buf_hold; | ||
58 | |||
59 | /* Align the dstination to a word boundry. */ | ||
60 | /* This is done in an endian independant manner. */ | ||
61 | switch ((unsigned long)dst & 3) { | ||
62 | case 1: | ||
63 | *dst++ = *src++; | ||
64 | --c; | ||
65 | case 2: | ||
66 | *dst++ = *src++; | ||
67 | --c; | ||
68 | case 3: | ||
69 | *dst++ = *src++; | ||
70 | --c; | ||
71 | } | ||
72 | |||
73 | i_dst = (void *)dst; | ||
74 | |||
75 | /* Choose a copy scheme based on the source */ | ||
76 | /* alignment relative to dstination. */ | ||
77 | switch ((unsigned long)src & 3) { | ||
78 | case 0x0: /* Both byte offsets are aligned */ | ||
79 | i_src = (const void *)src; | ||
80 | |||
81 | for (; c >= 4; c -= 4) | ||
82 | *i_dst++ = *i_src++; | ||
83 | |||
84 | src = (const void *)i_src; | ||
85 | break; | ||
86 | case 0x1: /* Unaligned - Off by 1 */ | ||
87 | /* Word align the source */ | ||
88 | i_src = (const void *) ((unsigned)src & ~3); | ||
89 | |||
90 | /* Load the holding buffer */ | ||
91 | buf_hold = *i_src++ << 8; | ||
92 | |||
93 | for (; c >= 4; c -= 4) { | ||
94 | value = *i_src++; | ||
95 | *i_dst++ = buf_hold | value >> 24; | ||
96 | buf_hold = value << 8; | ||
97 | } | ||
98 | |||
99 | /* Realign the source */ | ||
100 | src = (const void *)i_src; | ||
101 | src -= 3; | ||
102 | break; | ||
103 | case 0x2: /* Unaligned - Off by 2 */ | ||
104 | /* Word align the source */ | ||
105 | i_src = (const void *) ((unsigned)src & ~3); | ||
106 | |||
107 | /* Load the holding buffer */ | ||
108 | buf_hold = *i_src++ << 16; | ||
109 | |||
110 | for (; c >= 4; c -= 4) { | ||
111 | value = *i_src++; | ||
112 | *i_dst++ = buf_hold | value >> 16; | ||
113 | buf_hold = value << 16; | ||
114 | } | ||
115 | |||
116 | /* Realign the source */ | ||
117 | src = (const void *)i_src; | ||
118 | src -= 2; | ||
119 | break; | ||
120 | case 0x3: /* Unaligned - Off by 3 */ | ||
121 | /* Word align the source */ | ||
122 | i_src = (const void *) ((unsigned)src & ~3); | ||
123 | |||
124 | /* Load the holding buffer */ | ||
125 | buf_hold = *i_src++ << 24; | ||
126 | |||
127 | for (; c >= 4; c -= 4) { | ||
128 | value = *i_src++; | ||
129 | *i_dst++ = buf_hold | value >> 8; | ||
130 | buf_hold = value << 24; | ||
131 | } | ||
132 | |||
133 | /* Realign the source */ | ||
134 | src = (const void *)i_src; | ||
135 | src -= 1; | ||
136 | break; | ||
137 | } | ||
138 | dst = (void *)i_dst; | ||
139 | } | ||
140 | |||
141 | /* Finish off any remaining bytes */ | ||
142 | /* simple fast copy, ... unless a cache boundry is crossed */ | ||
143 | switch (c) { | ||
144 | case 3: | ||
145 | *dst++ = *src++; | ||
146 | case 2: | ||
147 | *dst++ = *src++; | ||
148 | case 1: | ||
149 | *dst++ = *src++; | ||
150 | } | ||
151 | |||
152 | return v_dst; | ||
153 | #endif | ||
154 | } | ||
155 | EXPORT_SYMBOL(memcpy); | ||
156 | #endif /* __HAVE_ARCH_MEMCPY */ | ||
157 | |||
158 | void *cacheable_memcpy(void *d, const void *s, __kernel_size_t c) | ||
159 | { | ||
160 | return memcpy(d, s, c); | ||
161 | } | ||
diff --git a/arch/microblaze/lib/memmove.c b/arch/microblaze/lib/memmove.c new file mode 100644 index 000000000000..d4e9f49a71f7 --- /dev/null +++ b/arch/microblaze/lib/memmove.c | |||
@@ -0,0 +1,175 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu> | ||
3 | * Copyright (C) 2008-2009 PetaLogix | ||
4 | * Copyright (C) 2007 John Williams | ||
5 | * | ||
6 | * Reasonably optimised generic C-code for memcpy on Microblaze | ||
7 | * This is generic C code to do efficient, alignment-aware memmove. | ||
8 | * | ||
9 | * It is based on demo code originally Copyright 2001 by Intel Corp, taken from | ||
10 | * http://www.embedded.com/showArticle.jhtml?articleID=19205567 | ||
11 | * | ||
12 | * Attempts were made, unsuccesfully, to contact the original | ||
13 | * author of this code (Michael Morrow, Intel). Below is the original | ||
14 | * copyright notice. | ||
15 | * | ||
16 | * This software has been developed by Intel Corporation. | ||
17 | * Intel specifically disclaims all warranties, express or | ||
18 | * implied, and all liability, including consequential and | ||
19 | * other indirect damages, for the use of this program, including | ||
20 | * liability for infringement of any proprietary rights, | ||
21 | * and including the warranties of merchantability and fitness | ||
22 | * for a particular purpose. Intel does not assume any | ||
23 | * responsibility for and errors which may appear in this program | ||
24 | * not any responsibility to update it. | ||
25 | */ | ||
26 | |||
27 | #include <linux/types.h> | ||
28 | #include <linux/stddef.h> | ||
29 | #include <linux/compiler.h> | ||
30 | #include <linux/module.h> | ||
31 | #include <linux/string.h> | ||
32 | |||
33 | #ifdef __HAVE_ARCH_MEMMOVE | ||
34 | void *memmove(void *v_dst, const void *v_src, __kernel_size_t c) | ||
35 | { | ||
36 | const char *src = v_src; | ||
37 | char *dst = v_dst; | ||
38 | |||
39 | #ifdef CONFIG_OPT_LIB_FUNCTION | ||
40 | const uint32_t *i_src; | ||
41 | uint32_t *i_dst; | ||
42 | #endif | ||
43 | |||
44 | if (!c) | ||
45 | return v_dst; | ||
46 | |||
47 | /* Use memcpy when source is higher than dest */ | ||
48 | if (v_dst <= v_src) | ||
49 | return memcpy(v_dst, v_src, c); | ||
50 | |||
51 | #ifndef CONFIG_OPT_LIB_FUNCTION | ||
52 | /* copy backwards, from end to beginning */ | ||
53 | src += c; | ||
54 | dst += c; | ||
55 | |||
56 | /* Simple, byte oriented memmove. */ | ||
57 | while (c--) | ||
58 | *--dst = *--src; | ||
59 | |||
60 | return v_dst; | ||
61 | #else | ||
62 | /* The following code tries to optimize the copy by using unsigned | ||
63 | * alignment. This will work fine if both source and destination are | ||
64 | * aligned on the same boundary. However, if they are aligned on | ||
65 | * different boundaries shifts will be necessary. This might result in | ||
66 | * bad performance on MicroBlaze systems without a barrel shifter. | ||
67 | */ | ||
68 | /* FIXME this part needs more test */ | ||
69 | /* Do a descending copy - this is a bit trickier! */ | ||
70 | dst += c; | ||
71 | src += c; | ||
72 | |||
73 | if (c >= 4) { | ||
74 | unsigned value, buf_hold; | ||
75 | |||
76 | /* Align the destination to a word boundry. */ | ||
77 | /* This is done in an endian independant manner. */ | ||
78 | |||
79 | switch ((unsigned long)dst & 3) { | ||
80 | case 3: | ||
81 | *--dst = *--src; | ||
82 | --c; | ||
83 | case 2: | ||
84 | *--dst = *--src; | ||
85 | --c; | ||
86 | case 1: | ||
87 | *--dst = *--src; | ||
88 | --c; | ||
89 | } | ||
90 | |||
91 | i_dst = (void *)dst; | ||
92 | /* Choose a copy scheme based on the source */ | ||
93 | /* alignment relative to dstination. */ | ||
94 | switch ((unsigned long)src & 3) { | ||
95 | case 0x0: /* Both byte offsets are aligned */ | ||
96 | |||
97 | i_src = (const void *)src; | ||
98 | |||
99 | for (; c >= 4; c -= 4) | ||
100 | *--i_dst = *--i_src; | ||
101 | |||
102 | src = (const void *)i_src; | ||
103 | break; | ||
104 | case 0x1: /* Unaligned - Off by 1 */ | ||
105 | /* Word align the source */ | ||
106 | i_src = (const void *) (((unsigned)src + 4) & ~3); | ||
107 | |||
108 | /* Load the holding buffer */ | ||
109 | buf_hold = *--i_src >> 24; | ||
110 | |||
111 | for (; c >= 4; c -= 4) { | ||
112 | value = *--i_src; | ||
113 | *--i_dst = buf_hold << 8 | value; | ||
114 | buf_hold = value >> 24; | ||
115 | } | ||
116 | |||
117 | /* Realign the source */ | ||
118 | src = (const void *)i_src; | ||
119 | src += 1; | ||
120 | break; | ||
121 | case 0x2: /* Unaligned - Off by 2 */ | ||
122 | /* Word align the source */ | ||
123 | i_src = (const void *) (((unsigned)src + 4) & ~3); | ||
124 | |||
125 | /* Load the holding buffer */ | ||
126 | buf_hold = *--i_src >> 16; | ||
127 | |||
128 | for (; c >= 4; c -= 4) { | ||
129 | value = *--i_src; | ||
130 | *--i_dst = buf_hold << 16 | value; | ||
131 | buf_hold = value >> 16; | ||
132 | } | ||
133 | |||
134 | /* Realign the source */ | ||
135 | src = (const void *)i_src; | ||
136 | src += 2; | ||
137 | break; | ||
138 | case 0x3: /* Unaligned - Off by 3 */ | ||
139 | /* Word align the source */ | ||
140 | i_src = (const void *) (((unsigned)src + 4) & ~3); | ||
141 | |||
142 | /* Load the holding buffer */ | ||
143 | buf_hold = *--i_src >> 8; | ||
144 | |||
145 | for (; c >= 4; c -= 4) { | ||
146 | value = *--i_src; | ||
147 | *--i_dst = buf_hold << 24 | value; | ||
148 | buf_hold = value >> 8; | ||
149 | } | ||
150 | |||
151 | /* Realign the source */ | ||
152 | src = (const void *)i_src; | ||
153 | src += 3; | ||
154 | break; | ||
155 | } | ||
156 | dst = (void *)i_dst; | ||
157 | } | ||
158 | |||
159 | /* simple fast copy, ... unless a cache boundry is crossed */ | ||
160 | /* Finish off any remaining bytes */ | ||
161 | switch (c) { | ||
162 | case 4: | ||
163 | *--dst = *--src; | ||
164 | case 3: | ||
165 | *--dst = *--src; | ||
166 | case 2: | ||
167 | *--dst = *--src; | ||
168 | case 1: | ||
169 | *--dst = *--src; | ||
170 | } | ||
171 | return v_dst; | ||
172 | #endif | ||
173 | } | ||
174 | EXPORT_SYMBOL(memmove); | ||
175 | #endif /* __HAVE_ARCH_MEMMOVE */ | ||
diff --git a/arch/microblaze/lib/memset.c b/arch/microblaze/lib/memset.c new file mode 100644 index 000000000000..941dc8f94b03 --- /dev/null +++ b/arch/microblaze/lib/memset.c | |||
@@ -0,0 +1,82 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu> | ||
3 | * Copyright (C) 2008-2009 PetaLogix | ||
4 | * Copyright (C) 2007 John Williams | ||
5 | * | ||
6 | * Reasonably optimised generic C-code for memset on Microblaze | ||
7 | * This is generic C code to do efficient, alignment-aware memcpy. | ||
8 | * | ||
9 | * It is based on demo code originally Copyright 2001 by Intel Corp, taken from | ||
10 | * http://www.embedded.com/showArticle.jhtml?articleID=19205567 | ||
11 | * | ||
12 | * Attempts were made, unsuccesfully, to contact the original | ||
13 | * author of this code (Michael Morrow, Intel). Below is the original | ||
14 | * copyright notice. | ||
15 | * | ||
16 | * This software has been developed by Intel Corporation. | ||
17 | * Intel specifically disclaims all warranties, express or | ||
18 | * implied, and all liability, including consequential and | ||
19 | * other indirect damages, for the use of this program, including | ||
20 | * liability for infringement of any proprietary rights, | ||
21 | * and including the warranties of merchantability and fitness | ||
22 | * for a particular purpose. Intel does not assume any | ||
23 | * responsibility for and errors which may appear in this program | ||
24 | * not any responsibility to update it. | ||
25 | */ | ||
26 | |||
27 | #include <linux/types.h> | ||
28 | #include <linux/stddef.h> | ||
29 | #include <linux/compiler.h> | ||
30 | #include <linux/module.h> | ||
31 | #include <linux/string.h> | ||
32 | |||
33 | #ifdef __HAVE_ARCH_MEMSET | ||
34 | void *memset(void *v_src, int c, __kernel_size_t n) | ||
35 | { | ||
36 | |||
37 | char *src = v_src; | ||
38 | #ifdef CONFIG_OPT_LIB_FUNCTION | ||
39 | uint32_t *i_src; | ||
40 | uint32_t w32; | ||
41 | #endif | ||
42 | /* Truncate c to 8 bits */ | ||
43 | c = (c & 0xFF); | ||
44 | |||
45 | #ifdef CONFIG_OPT_LIB_FUNCTION | ||
46 | /* Make a repeating word out of it */ | ||
47 | w32 = c; | ||
48 | w32 |= w32 << 8; | ||
49 | w32 |= w32 << 16; | ||
50 | |||
51 | if (n >= 4) { | ||
52 | /* Align the destination to a word boundary */ | ||
53 | /* This is done in an endian independant manner */ | ||
54 | switch ((unsigned) src & 3) { | ||
55 | case 1: | ||
56 | *src++ = c; | ||
57 | --n; | ||
58 | case 2: | ||
59 | *src++ = c; | ||
60 | --n; | ||
61 | case 3: | ||
62 | *src++ = c; | ||
63 | --n; | ||
64 | } | ||
65 | |||
66 | i_src = (void *)src; | ||
67 | |||
68 | /* Do as many full-word copies as we can */ | ||
69 | for (; n >= 4; n -= 4) | ||
70 | *i_src++ = w32; | ||
71 | |||
72 | src = (void *)i_src; | ||
73 | } | ||
74 | #endif | ||
75 | /* Simple, byte oriented memset or the rest of count. */ | ||
76 | while (n--) | ||
77 | *src++ = c; | ||
78 | |||
79 | return v_src; | ||
80 | } | ||
81 | EXPORT_SYMBOL(memset); | ||
82 | #endif /* __HAVE_ARCH_MEMSET */ | ||
diff --git a/arch/microblaze/lib/uaccess.c b/arch/microblaze/lib/uaccess.c new file mode 100644 index 000000000000..8eb9df5a26c9 --- /dev/null +++ b/arch/microblaze/lib/uaccess.c | |||
@@ -0,0 +1,41 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
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 | |||
9 | #include <linux/string.h> | ||
10 | #include <asm/uaccess.h> | ||
11 | |||
12 | #include <asm/bug.h> | ||
13 | |||
14 | long strnlen_user(const char __user *src, long count) | ||
15 | { | ||
16 | return strlen(src) + 1; | ||
17 | } | ||
18 | |||
19 | #define __do_strncpy_from_user(dst, src, count, res) \ | ||
20 | do { \ | ||
21 | char *tmp; \ | ||
22 | strncpy(dst, src, count); \ | ||
23 | for (tmp = dst; *tmp && count > 0; tmp++, count--) \ | ||
24 | ; \ | ||
25 | res = (tmp - dst); \ | ||
26 | } while (0) | ||
27 | |||
28 | long __strncpy_from_user(char *dst, const char __user *src, long count) | ||
29 | { | ||
30 | long res; | ||
31 | __do_strncpy_from_user(dst, src, count, res); | ||
32 | return res; | ||
33 | } | ||
34 | |||
35 | long strncpy_from_user(char *dst, const char __user *src, long count) | ||
36 | { | ||
37 | long res = -EFAULT; | ||
38 | if (access_ok(VERIFY_READ, src, 1)) | ||
39 | __do_strncpy_from_user(dst, src, count, res); | ||
40 | return res; | ||
41 | } | ||
diff --git a/arch/microblaze/mm/Makefile b/arch/microblaze/mm/Makefile new file mode 100644 index 000000000000..bf9e4479a1fd --- /dev/null +++ b/arch/microblaze/mm/Makefile | |||
@@ -0,0 +1,5 @@ | |||
1 | # | ||
2 | # Makefile | ||
3 | # | ||
4 | |||
5 | obj-y := init.o | ||
diff --git a/arch/microblaze/mm/init.c b/arch/microblaze/mm/init.c new file mode 100644 index 000000000000..b0c8213cd6cf --- /dev/null +++ b/arch/microblaze/mm/init.c | |||
@@ -0,0 +1,201 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007-2008 Michal Simek <monstr@monstr.eu> | ||
3 | * Copyright (C) 2006 Atmark Techno, Inc. | ||
4 | * | ||
5 | * This file is subject to the terms and conditions of the GNU General Public | ||
6 | * License. See the file "COPYING" in the main directory of this archive | ||
7 | * for more details. | ||
8 | */ | ||
9 | |||
10 | #include <linux/bootmem.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/lmb.h> | ||
14 | #include <linux/mm.h> /* mem_init */ | ||
15 | #include <linux/initrd.h> | ||
16 | #include <linux/pagemap.h> | ||
17 | #include <linux/pfn.h> | ||
18 | #include <linux/swap.h> | ||
19 | |||
20 | #include <asm/page.h> | ||
21 | #include <asm/mmu_context.h> | ||
22 | #include <asm/pgalloc.h> | ||
23 | #include <asm/sections.h> | ||
24 | #include <asm/tlb.h> | ||
25 | |||
26 | unsigned int __page_offset; | ||
27 | /* EXPORT_SYMBOL(__page_offset); */ | ||
28 | |||
29 | char *klimit = _end; | ||
30 | |||
31 | /* | ||
32 | * Initialize the bootmem system and give it all the memory we | ||
33 | * have available. | ||
34 | */ | ||
35 | unsigned int memory_start; | ||
36 | unsigned int memory_end; /* due to mm/nommu.c */ | ||
37 | unsigned int memory_size; | ||
38 | |||
39 | /* | ||
40 | * paging_init() sets up the page tables - in fact we've already done this. | ||
41 | */ | ||
42 | static void __init paging_init(void) | ||
43 | { | ||
44 | int i; | ||
45 | unsigned long zones_size[MAX_NR_ZONES]; | ||
46 | |||
47 | /* | ||
48 | * old: we can DMA to/from any address.put all page into ZONE_DMA | ||
49 | * We use only ZONE_NORMAL | ||
50 | */ | ||
51 | zones_size[ZONE_NORMAL] = max_mapnr; | ||
52 | |||
53 | /* every other zones are empty */ | ||
54 | for (i = 1; i < MAX_NR_ZONES; i++) | ||
55 | zones_size[i] = 0; | ||
56 | |||
57 | free_area_init(zones_size); | ||
58 | } | ||
59 | |||
60 | void __init setup_memory(void) | ||
61 | { | ||
62 | int i; | ||
63 | unsigned long map_size; | ||
64 | u32 kernel_align_start, kernel_align_size; | ||
65 | |||
66 | /* Find main memory where is the kernel */ | ||
67 | for (i = 0; i < lmb.memory.cnt; i++) { | ||
68 | memory_start = (u32) lmb.memory.region[i].base; | ||
69 | memory_end = (u32) lmb.memory.region[i].base | ||
70 | + (u32) lmb.memory.region[i].size; | ||
71 | if ((memory_start <= (u32)_text) && | ||
72 | ((u32)_text <= memory_end)) { | ||
73 | memory_size = memory_end - memory_start; | ||
74 | PAGE_OFFSET = memory_start; | ||
75 | printk(KERN_INFO "%s: Main mem: 0x%x-0x%x, " | ||
76 | "size 0x%08x\n", __func__, memory_start, | ||
77 | memory_end, memory_size); | ||
78 | break; | ||
79 | } | ||
80 | } | ||
81 | |||
82 | if (!memory_start || !memory_end) { | ||
83 | panic("%s: Missing memory setting 0x%08x-0x%08x\n", | ||
84 | __func__, memory_start, memory_end); | ||
85 | } | ||
86 | |||
87 | /* reservation of region where is the kernel */ | ||
88 | kernel_align_start = PAGE_DOWN((u32)_text); | ||
89 | /* ALIGN can be remove because _end in vmlinux.lds.S is align */ | ||
90 | kernel_align_size = PAGE_UP((u32)klimit) - kernel_align_start; | ||
91 | lmb_reserve(kernel_align_start, kernel_align_size); | ||
92 | printk(KERN_INFO "%s: kernel addr=0x%08x-0x%08x size=0x%08x\n", | ||
93 | __func__, kernel_align_start, kernel_align_start | ||
94 | + kernel_align_size, kernel_align_size); | ||
95 | |||
96 | /* | ||
97 | * Kernel: | ||
98 | * start: base phys address of kernel - page align | ||
99 | * end: base phys address of kernel - page align | ||
100 | * | ||
101 | * min_low_pfn - the first page (mm/bootmem.c - node_boot_start) | ||
102 | * max_low_pfn | ||
103 | * max_mapnr - the first unused page (mm/bootmem.c - node_low_pfn) | ||
104 | * num_physpages - number of all pages | ||
105 | */ | ||
106 | |||
107 | /* memory start is from the kernel end (aligned) to higher addr */ | ||
108 | min_low_pfn = memory_start >> PAGE_SHIFT; /* minimum for allocation */ | ||
109 | /* RAM is assumed contiguous */ | ||
110 | num_physpages = max_mapnr = memory_size >> PAGE_SHIFT; | ||
111 | max_pfn = max_low_pfn = memory_end >> PAGE_SHIFT; | ||
112 | |||
113 | printk(KERN_INFO "%s: max_mapnr: %#lx\n", __func__, max_mapnr); | ||
114 | printk(KERN_INFO "%s: min_low_pfn: %#lx\n", __func__, min_low_pfn); | ||
115 | printk(KERN_INFO "%s: max_low_pfn: %#lx\n", __func__, max_low_pfn); | ||
116 | |||
117 | /* | ||
118 | * Find an area to use for the bootmem bitmap. | ||
119 | * We look for the first area which is at least | ||
120 | * 128kB in length (128kB is enough for a bitmap | ||
121 | * for 4GB of memory, using 4kB pages), plus 1 page | ||
122 | * (in case the address isn't page-aligned). | ||
123 | */ | ||
124 | map_size = init_bootmem_node(NODE_DATA(0), PFN_UP(TOPHYS((u32)_end)), | ||
125 | min_low_pfn, max_low_pfn); | ||
126 | |||
127 | lmb_reserve(PFN_UP(TOPHYS((u32)_end)) << PAGE_SHIFT, map_size); | ||
128 | |||
129 | /* free bootmem is whole main memory */ | ||
130 | free_bootmem(memory_start, memory_size); | ||
131 | |||
132 | /* reserve allocate blocks */ | ||
133 | for (i = 0; i < lmb.reserved.cnt; i++) { | ||
134 | pr_debug("reserved %d - 0x%08x-0x%08x\n", i, | ||
135 | (u32) lmb.reserved.region[i].base, | ||
136 | (u32) lmb_size_bytes(&lmb.reserved, i)); | ||
137 | reserve_bootmem(lmb.reserved.region[i].base, | ||
138 | lmb_size_bytes(&lmb.reserved, i) - 1, BOOTMEM_DEFAULT); | ||
139 | } | ||
140 | paging_init(); | ||
141 | } | ||
142 | |||
143 | void free_init_pages(char *what, unsigned long begin, unsigned long end) | ||
144 | { | ||
145 | unsigned long addr; | ||
146 | |||
147 | for (addr = begin; addr < end; addr += PAGE_SIZE) { | ||
148 | ClearPageReserved(virt_to_page(addr)); | ||
149 | init_page_count(virt_to_page(addr)); | ||
150 | memset((void *)addr, 0xcc, PAGE_SIZE); | ||
151 | free_page(addr); | ||
152 | totalram_pages++; | ||
153 | } | ||
154 | printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10); | ||
155 | } | ||
156 | |||
157 | #ifdef CONFIG_BLK_DEV_INITRD | ||
158 | void free_initrd_mem(unsigned long start, unsigned long end) | ||
159 | { | ||
160 | int pages = 0; | ||
161 | for (; start < end; start += PAGE_SIZE) { | ||
162 | ClearPageReserved(virt_to_page(start)); | ||
163 | init_page_count(virt_to_page(start)); | ||
164 | free_page(start); | ||
165 | totalram_pages++; | ||
166 | pages++; | ||
167 | } | ||
168 | printk(KERN_NOTICE "Freeing initrd memory: %dk freed\n", pages); | ||
169 | } | ||
170 | #endif | ||
171 | |||
172 | void free_initmem(void) | ||
173 | { | ||
174 | free_init_pages("unused kernel memory", | ||
175 | (unsigned long)(&__init_begin), | ||
176 | (unsigned long)(&__init_end)); | ||
177 | } | ||
178 | |||
179 | /* FIXME from arch/powerpc/mm/mem.c*/ | ||
180 | void show_mem(void) | ||
181 | { | ||
182 | printk(KERN_NOTICE "%s\n", __func__); | ||
183 | } | ||
184 | |||
185 | void __init mem_init(void) | ||
186 | { | ||
187 | high_memory = (void *)__va(memory_end); | ||
188 | /* this will put all memory onto the freelists */ | ||
189 | totalram_pages += free_all_bootmem(); | ||
190 | |||
191 | printk(KERN_INFO "Memory: %luk/%luk available\n", | ||
192 | (unsigned long) nr_free_pages() << (PAGE_SHIFT-10), | ||
193 | num_physpages << (PAGE_SHIFT-10)); | ||
194 | } | ||
195 | |||
196 | /* Check against bounds of physical memory */ | ||
197 | int ___range_ok(unsigned long addr, unsigned long size) | ||
198 | { | ||
199 | return ((addr < memory_start) || | ||
200 | ((addr + size) > memory_end)); | ||
201 | } | ||
diff --git a/arch/microblaze/platform/Kconfig.platform b/arch/microblaze/platform/Kconfig.platform new file mode 100644 index 000000000000..8e9b4752d3ff --- /dev/null +++ b/arch/microblaze/platform/Kconfig.platform | |||
@@ -0,0 +1,85 @@ | |||
1 | # For a description of the syntax of this configuration file, | ||
2 | # see Documentation/kbuild/kconfig-language.txt. | ||
3 | # | ||
4 | # Platform selection Kconfig menu for MicroBlaze targets | ||
5 | # | ||
6 | |||
7 | menu "Platform options" | ||
8 | choice | ||
9 | prompt "Platform" | ||
10 | default PLATFORM_MICROBLAZE_AUTO | ||
11 | help | ||
12 | Choose which hardware board/platform you are targeting. | ||
13 | |||
14 | config PLATFORM_GENERIC | ||
15 | bool "Generic" | ||
16 | help | ||
17 | Choose this option for the Generic platform. | ||
18 | |||
19 | endchoice | ||
20 | |||
21 | config SELFMOD | ||
22 | bool "Use self modified code for intc/timer" | ||
23 | depends on EXPERIMENTAL && NO_MMU | ||
24 | default n | ||
25 | help | ||
26 | This choice enables self-modified code for interrupt controller | ||
27 | and timer. | ||
28 | |||
29 | config SELFMOD_INTC | ||
30 | bool "Use self modified code for intc" | ||
31 | depends on SELFMOD | ||
32 | default y | ||
33 | help | ||
34 | This choice enables self-modified code for interrupt controller. | ||
35 | |||
36 | config SELFMOD_TIMER | ||
37 | bool "Use self modified code for timer" | ||
38 | depends on SELFMOD | ||
39 | default y | ||
40 | help | ||
41 | This choice enables self-modified code for timer. | ||
42 | |||
43 | config OPT_LIB_FUNCTION | ||
44 | bool "Optimalized lib function" | ||
45 | default y | ||
46 | help | ||
47 | Allows turn on optimalized library function (memcpy and memmove). | ||
48 | They are optimized by using word alignment. This will work | ||
49 | fine if both source and destination are aligned on the same | ||
50 | boundary. However, if they are aligned on different boundaries | ||
51 | shifts will be necessary. This might result in bad performance | ||
52 | on MicroBlaze systems without a barrel shifter. | ||
53 | |||
54 | config OPT_LIB_ASM | ||
55 | bool "Optimalized lib function ASM" | ||
56 | depends on OPT_LIB_FUNCTION | ||
57 | default n | ||
58 | help | ||
59 | Allows turn on optimalized library function (memcpy and memmove). | ||
60 | Function are written in asm code. | ||
61 | |||
62 | # This is still a bit broken - disabling for now JW 20070504 | ||
63 | config ALLOW_EDIT_AUTO | ||
64 | bool "Permit Display/edit of Kconfig.auto platform settings" | ||
65 | default n | ||
66 | help | ||
67 | Allows the editing of auto-generated platform settings from | ||
68 | the Kconfig.auto file. Obviously this does not change the | ||
69 | underlying hardware, so be very careful if you go editing | ||
70 | these settings. | ||
71 | |||
72 | Also, if you enable this, and edit various Kconfig.auto | ||
73 | settings, YOUR CHANGES WILL BE LOST if you then disable it | ||
74 | again. You have been warned! | ||
75 | |||
76 | If unsure, say no. | ||
77 | |||
78 | comment "Automatic platform settings from Kconfig.auto" | ||
79 | depends on ALLOW_EDIT_AUTO | ||
80 | |||
81 | if PLATFORM_GENERIC=y | ||
82 | source "arch/microblaze/platform/generic/Kconfig.auto" | ||
83 | endif | ||
84 | |||
85 | endmenu | ||
diff --git a/arch/microblaze/platform/Makefile b/arch/microblaze/platform/Makefile new file mode 100644 index 000000000000..ea1b75cc5775 --- /dev/null +++ b/arch/microblaze/platform/Makefile | |||
@@ -0,0 +1,6 @@ | |||
1 | # | ||
2 | # Makefile for arch/microblaze/platform directory | ||
3 | # | ||
4 | #obj-$(CONFIG_PLATFORM_GENERIC) += generic/ | ||
5 | |||
6 | obj-y += platform.o | ||
diff --git a/arch/microblaze/platform/generic/Kconfig.auto b/arch/microblaze/platform/generic/Kconfig.auto new file mode 100644 index 000000000000..fbca22d9c8b9 --- /dev/null +++ b/arch/microblaze/platform/generic/Kconfig.auto | |||
@@ -0,0 +1,62 @@ | |||
1 | # | ||
2 | # (C) Copyright 2007 Michal Simek | ||
3 | # | ||
4 | # Michal SIMEK <monstr@monstr.eu> | ||
5 | # | ||
6 | # This program is free software; you can redistribute it and/or | ||
7 | # modify it under the terms of the GNU General Public License as | ||
8 | # published by the Free Software Foundation; either version 2 of | ||
9 | # the License, or (at your option) any later version. | ||
10 | # | ||
11 | # This program is distributed in the hope that it will be useful, | ||
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | # GNU General Public License for more details. | ||
15 | # | ||
16 | # You should have received a copy of the GNU General Public License | ||
17 | # along with this program; if not, write to the Free Software | ||
18 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, | ||
19 | # MA 02111-1307 USA | ||
20 | # | ||
21 | |||
22 | # Definitions for MICROBLAZE0 | ||
23 | comment "Definitions for MICROBLAZE0" | ||
24 | depends on ALLOW_EDIT_AUTO | ||
25 | |||
26 | config KERNEL_BASE_ADDR | ||
27 | hex "Physical address where Linux Kernel is" | ||
28 | default "0x90000000" | ||
29 | help | ||
30 | BASE Address for kernel | ||
31 | |||
32 | config XILINX_MICROBLAZE0_FAMILY | ||
33 | string "Targetted FPGA family" if ALLOW_EDIT_AUTO | ||
34 | default "virtex5" | ||
35 | |||
36 | config XILINX_MICROBLAZE0_USE_MSR_INSTR | ||
37 | int "USE_MSR_INSTR range (0:1)" if ALLOW_EDIT_AUTO | ||
38 | default 1 | ||
39 | |||
40 | config XILINX_MICROBLAZE0_USE_PCMP_INSTR | ||
41 | int "USE_PCMP_INSTR range (0:1)" if ALLOW_EDIT_AUTO | ||
42 | default 1 | ||
43 | |||
44 | config XILINX_MICROBLAZE0_USE_BARREL | ||
45 | int "USE_BARREL range (0:1)" if ALLOW_EDIT_AUTO | ||
46 | default 1 | ||
47 | |||
48 | config XILINX_MICROBLAZE0_USE_DIV | ||
49 | int "USE_DIV range (0:1)" if ALLOW_EDIT_AUTO | ||
50 | default 1 | ||
51 | |||
52 | config XILINX_MICROBLAZE0_USE_HW_MUL | ||
53 | int "USE_HW_MUL values (0=NONE, 1=MUL32, 2=MUL64)" if ALLOW_EDIT_AUTO | ||
54 | default 2 | ||
55 | |||
56 | config XILINX_MICROBLAZE0_USE_FPU | ||
57 | int "USE_FPU values (0=NONE, 1=BASIC, 2=EXTENDED)" if ALLOW_EDIT_AUTO | ||
58 | default 2 | ||
59 | |||
60 | config XILINX_MICROBLAZE0_HW_VER | ||
61 | string "Core version number" if ALLOW_EDIT_AUTO | ||
62 | default 7.10.d | ||
diff --git a/arch/microblaze/platform/generic/Makefile b/arch/microblaze/platform/generic/Makefile new file mode 100644 index 000000000000..9a8b1bd3fa6d --- /dev/null +++ b/arch/microblaze/platform/generic/Makefile | |||
@@ -0,0 +1,3 @@ | |||
1 | # | ||
2 | # Empty Makefile to keep make clean happy | ||
3 | # | ||
diff --git a/arch/microblaze/platform/generic/system.dts b/arch/microblaze/platform/generic/system.dts new file mode 100644 index 000000000000..29993f62b30a --- /dev/null +++ b/arch/microblaze/platform/generic/system.dts | |||
@@ -0,0 +1,332 @@ | |||
1 | /* | ||
2 | * Device Tree Generator version: 1.1 | ||
3 | * | ||
4 | * (C) Copyright 2007-2008 Xilinx, Inc. | ||
5 | * (C) Copyright 2007-2009 Michal Simek | ||
6 | * | ||
7 | * Michal SIMEK <monstr@monstr.eu> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License as | ||
11 | * published by the Free Software Foundation; either version 2 of | ||
12 | * the License, or (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | ||
22 | * MA 02111-1307 USA | ||
23 | * | ||
24 | * CAUTION: This file is automatically generated by libgen. | ||
25 | * Version: Xilinx EDK 10.1.03 EDK_K_SP3.6 | ||
26 | * | ||
27 | * XPS project directory: Xilinx-ML505-ll_temac-sgdma-MMU-FDT-edk101 | ||
28 | */ | ||
29 | |||
30 | /dts-v1/; | ||
31 | / { | ||
32 | #address-cells = <1>; | ||
33 | #size-cells = <1>; | ||
34 | compatible = "xlnx,microblaze"; | ||
35 | model = "testing"; | ||
36 | DDR2_SDRAM: memory@90000000 { | ||
37 | device_type = "memory"; | ||
38 | reg = < 0x90000000 0x10000000 >; | ||
39 | } ; | ||
40 | chosen { | ||
41 | bootargs = "console=ttyUL0,115200 highres=on"; | ||
42 | linux,stdout-path = "/plb@0/serial@84000000"; | ||
43 | } ; | ||
44 | cpus { | ||
45 | #address-cells = <1>; | ||
46 | #cpus = <0x1>; | ||
47 | #size-cells = <0>; | ||
48 | microblaze_0: cpu@0 { | ||
49 | clock-frequency = <125000000>; | ||
50 | compatible = "xlnx,microblaze-7.10.d"; | ||
51 | d-cache-baseaddr = <0x90000000>; | ||
52 | d-cache-highaddr = <0x9fffffff>; | ||
53 | d-cache-line-size = <0x10>; | ||
54 | d-cache-size = <0x2000>; | ||
55 | device_type = "cpu"; | ||
56 | i-cache-baseaddr = <0x90000000>; | ||
57 | i-cache-highaddr = <0x9fffffff>; | ||
58 | i-cache-line-size = <0x10>; | ||
59 | i-cache-size = <0x2000>; | ||
60 | model = "microblaze,7.10.d"; | ||
61 | reg = <0>; | ||
62 | timebase-frequency = <125000000>; | ||
63 | xlnx,addr-tag-bits = <0xf>; | ||
64 | xlnx,allow-dcache-wr = <0x1>; | ||
65 | xlnx,allow-icache-wr = <0x1>; | ||
66 | xlnx,area-optimized = <0x0>; | ||
67 | xlnx,cache-byte-size = <0x2000>; | ||
68 | xlnx,d-lmb = <0x1>; | ||
69 | xlnx,d-opb = <0x0>; | ||
70 | xlnx,d-plb = <0x1>; | ||
71 | xlnx,data-size = <0x20>; | ||
72 | xlnx,dcache-addr-tag = <0xf>; | ||
73 | xlnx,dcache-always-used = <0x1>; | ||
74 | xlnx,dcache-byte-size = <0x2000>; | ||
75 | xlnx,dcache-line-len = <0x4>; | ||
76 | xlnx,dcache-use-fsl = <0x1>; | ||
77 | xlnx,debug-enabled = <0x1>; | ||
78 | xlnx,div-zero-exception = <0x1>; | ||
79 | xlnx,dopb-bus-exception = <0x0>; | ||
80 | xlnx,dynamic-bus-sizing = <0x1>; | ||
81 | xlnx,edge-is-positive = <0x1>; | ||
82 | xlnx,family = "virtex5"; | ||
83 | xlnx,fpu-exception = <0x1>; | ||
84 | xlnx,fsl-data-size = <0x20>; | ||
85 | xlnx,fsl-exception = <0x0>; | ||
86 | xlnx,fsl-links = <0x0>; | ||
87 | xlnx,i-lmb = <0x1>; | ||
88 | xlnx,i-opb = <0x0>; | ||
89 | xlnx,i-plb = <0x1>; | ||
90 | xlnx,icache-always-used = <0x1>; | ||
91 | xlnx,icache-line-len = <0x4>; | ||
92 | xlnx,icache-use-fsl = <0x1>; | ||
93 | xlnx,ill-opcode-exception = <0x1>; | ||
94 | xlnx,instance = "microblaze_0"; | ||
95 | xlnx,interconnect = <0x1>; | ||
96 | xlnx,interrupt-is-edge = <0x0>; | ||
97 | xlnx,iopb-bus-exception = <0x0>; | ||
98 | xlnx,mmu-dtlb-size = <0x4>; | ||
99 | xlnx,mmu-itlb-size = <0x2>; | ||
100 | xlnx,mmu-tlb-access = <0x3>; | ||
101 | xlnx,mmu-zones = <0x10>; | ||
102 | xlnx,number-of-pc-brk = <0x1>; | ||
103 | xlnx,number-of-rd-addr-brk = <0x0>; | ||
104 | xlnx,number-of-wr-addr-brk = <0x0>; | ||
105 | xlnx,opcode-0x0-illegal = <0x1>; | ||
106 | xlnx,pvr = <0x2>; | ||
107 | xlnx,pvr-user1 = <0x0>; | ||
108 | xlnx,pvr-user2 = <0x0>; | ||
109 | xlnx,reset-msr = <0x0>; | ||
110 | xlnx,sco = <0x0>; | ||
111 | xlnx,unaligned-exceptions = <0x1>; | ||
112 | xlnx,use-barrel = <0x1>; | ||
113 | xlnx,use-dcache = <0x1>; | ||
114 | xlnx,use-div = <0x1>; | ||
115 | xlnx,use-ext-brk = <0x1>; | ||
116 | xlnx,use-ext-nm-brk = <0x1>; | ||
117 | xlnx,use-extended-fsl-instr = <0x0>; | ||
118 | xlnx,use-fpu = <0x2>; | ||
119 | xlnx,use-hw-mul = <0x2>; | ||
120 | xlnx,use-icache = <0x1>; | ||
121 | xlnx,use-interrupt = <0x1>; | ||
122 | xlnx,use-mmu = <0x3>; | ||
123 | xlnx,use-msr-instr = <0x1>; | ||
124 | xlnx,use-pcmp-instr = <0x1>; | ||
125 | } ; | ||
126 | } ; | ||
127 | mb_plb: plb@0 { | ||
128 | #address-cells = <1>; | ||
129 | #size-cells = <1>; | ||
130 | compatible = "xlnx,plb-v46-1.03.a", "simple-bus"; | ||
131 | ranges ; | ||
132 | FLASH: flash@a0000000 { | ||
133 | bank-width = <2>; | ||
134 | compatible = "xlnx,xps-mch-emc-2.00.a", "cfi-flash"; | ||
135 | reg = < 0xa0000000 0x2000000 >; | ||
136 | xlnx,family = "virtex5"; | ||
137 | xlnx,include-datawidth-matching-0 = <0x1>; | ||
138 | xlnx,include-datawidth-matching-1 = <0x0>; | ||
139 | xlnx,include-datawidth-matching-2 = <0x0>; | ||
140 | xlnx,include-datawidth-matching-3 = <0x0>; | ||
141 | xlnx,include-negedge-ioregs = <0x0>; | ||
142 | xlnx,include-plb-ipif = <0x1>; | ||
143 | xlnx,include-wrbuf = <0x1>; | ||
144 | xlnx,max-mem-width = <0x10>; | ||
145 | xlnx,mch-native-dwidth = <0x20>; | ||
146 | xlnx,mch-plb-clk-period-ps = <0x1f40>; | ||
147 | xlnx,mch-splb-awidth = <0x20>; | ||
148 | xlnx,mch0-accessbuf-depth = <0x10>; | ||
149 | xlnx,mch0-protocol = <0x0>; | ||
150 | xlnx,mch0-rddatabuf-depth = <0x10>; | ||
151 | xlnx,mch1-accessbuf-depth = <0x10>; | ||
152 | xlnx,mch1-protocol = <0x0>; | ||
153 | xlnx,mch1-rddatabuf-depth = <0x10>; | ||
154 | xlnx,mch2-accessbuf-depth = <0x10>; | ||
155 | xlnx,mch2-protocol = <0x0>; | ||
156 | xlnx,mch2-rddatabuf-depth = <0x10>; | ||
157 | xlnx,mch3-accessbuf-depth = <0x10>; | ||
158 | xlnx,mch3-protocol = <0x0>; | ||
159 | xlnx,mch3-rddatabuf-depth = <0x10>; | ||
160 | xlnx,mem0-width = <0x10>; | ||
161 | xlnx,mem1-width = <0x20>; | ||
162 | xlnx,mem2-width = <0x20>; | ||
163 | xlnx,mem3-width = <0x20>; | ||
164 | xlnx,num-banks-mem = <0x1>; | ||
165 | xlnx,num-channels = <0x0>; | ||
166 | xlnx,priority-mode = <0x0>; | ||
167 | xlnx,synch-mem-0 = <0x0>; | ||
168 | xlnx,synch-mem-1 = <0x0>; | ||
169 | xlnx,synch-mem-2 = <0x0>; | ||
170 | xlnx,synch-mem-3 = <0x0>; | ||
171 | xlnx,synch-pipedelay-0 = <0x2>; | ||
172 | xlnx,synch-pipedelay-1 = <0x2>; | ||
173 | xlnx,synch-pipedelay-2 = <0x2>; | ||
174 | xlnx,synch-pipedelay-3 = <0x2>; | ||
175 | xlnx,tavdv-ps-mem-0 = <0x1adb0>; | ||
176 | xlnx,tavdv-ps-mem-1 = <0x3a98>; | ||
177 | xlnx,tavdv-ps-mem-2 = <0x3a98>; | ||
178 | xlnx,tavdv-ps-mem-3 = <0x3a98>; | ||
179 | xlnx,tcedv-ps-mem-0 = <0x1adb0>; | ||
180 | xlnx,tcedv-ps-mem-1 = <0x3a98>; | ||
181 | xlnx,tcedv-ps-mem-2 = <0x3a98>; | ||
182 | xlnx,tcedv-ps-mem-3 = <0x3a98>; | ||
183 | xlnx,thzce-ps-mem-0 = <0x88b8>; | ||
184 | xlnx,thzce-ps-mem-1 = <0x1b58>; | ||
185 | xlnx,thzce-ps-mem-2 = <0x1b58>; | ||
186 | xlnx,thzce-ps-mem-3 = <0x1b58>; | ||
187 | xlnx,thzoe-ps-mem-0 = <0x1b58>; | ||
188 | xlnx,thzoe-ps-mem-1 = <0x1b58>; | ||
189 | xlnx,thzoe-ps-mem-2 = <0x1b58>; | ||
190 | xlnx,thzoe-ps-mem-3 = <0x1b58>; | ||
191 | xlnx,tlzwe-ps-mem-0 = <0x88b8>; | ||
192 | xlnx,tlzwe-ps-mem-1 = <0x0>; | ||
193 | xlnx,tlzwe-ps-mem-2 = <0x0>; | ||
194 | xlnx,tlzwe-ps-mem-3 = <0x0>; | ||
195 | xlnx,twc-ps-mem-0 = <0x2af8>; | ||
196 | xlnx,twc-ps-mem-1 = <0x3a98>; | ||
197 | xlnx,twc-ps-mem-2 = <0x3a98>; | ||
198 | xlnx,twc-ps-mem-3 = <0x3a98>; | ||
199 | xlnx,twp-ps-mem-0 = <0x11170>; | ||
200 | xlnx,twp-ps-mem-1 = <0x2ee0>; | ||
201 | xlnx,twp-ps-mem-2 = <0x2ee0>; | ||
202 | xlnx,twp-ps-mem-3 = <0x2ee0>; | ||
203 | xlnx,xcl0-linesize = <0x4>; | ||
204 | xlnx,xcl0-writexfer = <0x1>; | ||
205 | xlnx,xcl1-linesize = <0x4>; | ||
206 | xlnx,xcl1-writexfer = <0x1>; | ||
207 | xlnx,xcl2-linesize = <0x4>; | ||
208 | xlnx,xcl2-writexfer = <0x1>; | ||
209 | xlnx,xcl3-linesize = <0x4>; | ||
210 | xlnx,xcl3-writexfer = <0x1>; | ||
211 | } ; | ||
212 | Hard_Ethernet_MAC: xps-ll-temac@81c00000 { | ||
213 | #address-cells = <1>; | ||
214 | #size-cells = <1>; | ||
215 | compatible = "xlnx,compound"; | ||
216 | ethernet@81c00000 { | ||
217 | compatible = "xlnx,xps-ll-temac-1.01.b"; | ||
218 | device_type = "network"; | ||
219 | interrupt-parent = <&xps_intc_0>; | ||
220 | interrupts = < 5 2 >; | ||
221 | llink-connected = <&PIM3>; | ||
222 | local-mac-address = [ 02 00 00 00 00 00 ]; | ||
223 | reg = < 0x81c00000 0x40 >; | ||
224 | xlnx,bus2core-clk-ratio = <0x1>; | ||
225 | xlnx,phy-type = <0x1>; | ||
226 | xlnx,phyaddr = <0x1>; | ||
227 | xlnx,rxcsum = <0x0>; | ||
228 | xlnx,rxfifo = <0x1000>; | ||
229 | xlnx,temac-type = <0x0>; | ||
230 | xlnx,txcsum = <0x0>; | ||
231 | xlnx,txfifo = <0x1000>; | ||
232 | } ; | ||
233 | } ; | ||
234 | IIC_EEPROM: i2c@81600000 { | ||
235 | compatible = "xlnx,xps-iic-2.00.a"; | ||
236 | interrupt-parent = <&xps_intc_0>; | ||
237 | interrupts = < 6 2 >; | ||
238 | reg = < 0x81600000 0x10000 >; | ||
239 | xlnx,clk-freq = <0x7735940>; | ||
240 | xlnx,family = "virtex5"; | ||
241 | xlnx,gpo-width = <0x1>; | ||
242 | xlnx,iic-freq = <0x186a0>; | ||
243 | xlnx,scl-inertial-delay = <0x0>; | ||
244 | xlnx,sda-inertial-delay = <0x0>; | ||
245 | xlnx,ten-bit-adr = <0x0>; | ||
246 | } ; | ||
247 | LEDs_8Bit: gpio@81400000 { | ||
248 | compatible = "xlnx,xps-gpio-1.00.a"; | ||
249 | interrupt-parent = <&xps_intc_0>; | ||
250 | interrupts = < 7 2 >; | ||
251 | reg = < 0x81400000 0x10000 >; | ||
252 | xlnx,all-inputs = <0x0>; | ||
253 | xlnx,all-inputs-2 = <0x0>; | ||
254 | xlnx,dout-default = <0x0>; | ||
255 | xlnx,dout-default-2 = <0x0>; | ||
256 | xlnx,family = "virtex5"; | ||
257 | xlnx,gpio-width = <0x8>; | ||
258 | xlnx,interrupt-present = <0x1>; | ||
259 | xlnx,is-bidir = <0x1>; | ||
260 | xlnx,is-bidir-2 = <0x1>; | ||
261 | xlnx,is-dual = <0x0>; | ||
262 | xlnx,tri-default = <0xffffffff>; | ||
263 | xlnx,tri-default-2 = <0xffffffff>; | ||
264 | } ; | ||
265 | RS232_Uart_1: serial@84000000 { | ||
266 | clock-frequency = <125000000>; | ||
267 | compatible = "xlnx,xps-uartlite-1.00.a"; | ||
268 | current-speed = <115200>; | ||
269 | device_type = "serial"; | ||
270 | interrupt-parent = <&xps_intc_0>; | ||
271 | interrupts = < 8 0 >; | ||
272 | port-number = <0>; | ||
273 | reg = < 0x84000000 0x10000 >; | ||
274 | xlnx,baudrate = <0x1c200>; | ||
275 | xlnx,data-bits = <0x8>; | ||
276 | xlnx,family = "virtex5"; | ||
277 | xlnx,odd-parity = <0x0>; | ||
278 | xlnx,use-parity = <0x0>; | ||
279 | } ; | ||
280 | SysACE_CompactFlash: sysace@83600000 { | ||
281 | compatible = "xlnx,xps-sysace-1.00.a"; | ||
282 | interrupt-parent = <&xps_intc_0>; | ||
283 | interrupts = < 4 2 >; | ||
284 | reg = < 0x83600000 0x10000 >; | ||
285 | xlnx,family = "virtex5"; | ||
286 | xlnx,mem-width = <0x10>; | ||
287 | } ; | ||
288 | debug_module: debug@84400000 { | ||
289 | compatible = "xlnx,mdm-1.00.d"; | ||
290 | reg = < 0x84400000 0x10000 >; | ||
291 | xlnx,family = "virtex5"; | ||
292 | xlnx,interconnect = <0x1>; | ||
293 | xlnx,jtag-chain = <0x2>; | ||
294 | xlnx,mb-dbg-ports = <0x1>; | ||
295 | xlnx,uart-width = <0x8>; | ||
296 | xlnx,use-uart = <0x1>; | ||
297 | xlnx,write-fsl-ports = <0x0>; | ||
298 | } ; | ||
299 | mpmc@90000000 { | ||
300 | #address-cells = <1>; | ||
301 | #size-cells = <1>; | ||
302 | compatible = "xlnx,mpmc-4.02.a"; | ||
303 | PIM3: sdma@84600180 { | ||
304 | compatible = "xlnx,ll-dma-1.00.a"; | ||
305 | interrupt-parent = <&xps_intc_0>; | ||
306 | interrupts = < 2 2 1 2 >; | ||
307 | reg = < 0x84600180 0x80 >; | ||
308 | } ; | ||
309 | } ; | ||
310 | xps_intc_0: interrupt-controller@81800000 { | ||
311 | #interrupt-cells = <0x2>; | ||
312 | compatible = "xlnx,xps-intc-1.00.a"; | ||
313 | interrupt-controller ; | ||
314 | reg = < 0x81800000 0x10000 >; | ||
315 | xlnx,kind-of-intr = <0x100>; | ||
316 | xlnx,num-intr-inputs = <0x9>; | ||
317 | } ; | ||
318 | xps_timer_1: timer@83c00000 { | ||
319 | compatible = "xlnx,xps-timer-1.00.a"; | ||
320 | interrupt-parent = <&xps_intc_0>; | ||
321 | interrupts = < 3 2 >; | ||
322 | reg = < 0x83c00000 0x10000 >; | ||
323 | xlnx,count-width = <0x20>; | ||
324 | xlnx,family = "virtex5"; | ||
325 | xlnx,gen0-assert = <0x1>; | ||
326 | xlnx,gen1-assert = <0x1>; | ||
327 | xlnx,one-timer-only = <0x0>; | ||
328 | xlnx,trig0-assert = <0x1>; | ||
329 | xlnx,trig1-assert = <0x1>; | ||
330 | } ; | ||
331 | } ; | ||
332 | } ; | ||
diff --git a/arch/microblaze/platform/platform.c b/arch/microblaze/platform/platform.c new file mode 100644 index 000000000000..56e0234fa34b --- /dev/null +++ b/arch/microblaze/platform/platform.c | |||
@@ -0,0 +1,31 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Michal Simek <monstr@monstr.eu> | ||
3 | * | ||
4 | * based on virtex.c file | ||
5 | * | ||
6 | * Copyright 2007 Secret Lab Technologies Ltd. | ||
7 | * | ||
8 | * This file is licensed under the terms of the GNU General Public License | ||
9 | * version 2. This program is licensed "as is" without any warranty of any | ||
10 | * kind, whether express or implied. | ||
11 | */ | ||
12 | |||
13 | #include <linux/init.h> | ||
14 | #include <linux/of_platform.h> | ||
15 | #include <asm/prom.h> | ||
16 | |||
17 | static struct of_device_id xilinx_of_bus_ids[] __initdata = { | ||
18 | { .compatible = "simple-bus", }, | ||
19 | { .compatible = "xlnx,plb-v46-1.00.a", }, | ||
20 | { .compatible = "xlnx,opb-v20-1.10.c", }, | ||
21 | { .compatible = "xlnx,opb-v20-1.10.b", }, | ||
22 | { .compatible = "xlnx,compound", }, | ||
23 | {} | ||
24 | }; | ||
25 | |||
26 | static int __init microblaze_device_probe(void) | ||
27 | { | ||
28 | of_platform_bus_probe(NULL, xilinx_of_bus_ids, NULL); | ||
29 | return 0; | ||
30 | } | ||
31 | device_initcall(microblaze_device_probe); | ||