diff options
author | Jiri Kosina <jkosina@suse.cz> | 2013-01-29 04:48:30 -0500 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2013-01-29 04:48:30 -0500 |
commit | 617677295b53a40d0e54aac4cbbc216ffbc755dd (patch) | |
tree | 51b9e87213243ed5efff252c8e8d8fec4eebc588 /arch/xtensa | |
parent | 5c8d1b68e01a144813e38795fe6dbe7ebb506131 (diff) | |
parent | 6abb7c25775b7fb2225ad0508236d63ca710e65f (diff) |
Merge branch 'master' into for-next
Conflicts:
drivers/devfreq/exynos4_bus.c
Sync with Linus' tree to be able to apply patches that are
against newer code (mvneta).
Diffstat (limited to 'arch/xtensa')
93 files changed, 2217 insertions, 575 deletions
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 530f18018d02..68f172948a31 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig | |||
@@ -14,6 +14,8 @@ config XTENSA | |||
14 | select MODULES_USE_ELF_RELA | 14 | select MODULES_USE_ELF_RELA |
15 | select GENERIC_PCI_IOMAP | 15 | select GENERIC_PCI_IOMAP |
16 | select ARCH_WANT_OPTIONAL_GPIOLIB | 16 | select ARCH_WANT_OPTIONAL_GPIOLIB |
17 | select CLONE_BACKWARDS | ||
18 | select IRQ_DOMAIN | ||
17 | help | 19 | help |
18 | Xtensa processors are 32-bit RISC machines designed by Tensilica | 20 | Xtensa processors are 32-bit RISC machines designed by Tensilica |
19 | primarily for embedded systems. These processors are both | 21 | primarily for embedded systems. These processors are both |
@@ -147,6 +149,15 @@ config XTENSA_PLATFORM_S6105 | |||
147 | select SERIAL_CONSOLE | 149 | select SERIAL_CONSOLE |
148 | select NO_IOPORT | 150 | select NO_IOPORT |
149 | 151 | ||
152 | config XTENSA_PLATFORM_XTFPGA | ||
153 | bool "XTFPGA" | ||
154 | select SERIAL_CONSOLE | ||
155 | select ETHOC | ||
156 | select XTENSA_CALIBRATE_CCOUNT | ||
157 | help | ||
158 | XTFPGA is the name of Tensilica board family (LX60, LX110, LX200, ML605). | ||
159 | This hardware is capable of running a full Linux distribution. | ||
160 | |||
150 | endchoice | 161 | endchoice |
151 | 162 | ||
152 | 163 | ||
@@ -174,6 +185,17 @@ config CMDLINE | |||
174 | time by entering them here. As a minimum, you should specify the | 185 | time by entering them here. As a minimum, you should specify the |
175 | memory size and the root device (e.g., mem=64M root=/dev/nfs). | 186 | memory size and the root device (e.g., mem=64M root=/dev/nfs). |
176 | 187 | ||
188 | config USE_OF | ||
189 | bool "Flattened Device Tree support" | ||
190 | select OF | ||
191 | select OF_EARLY_FLATTREE | ||
192 | help | ||
193 | Include support for flattened device tree machine descriptions. | ||
194 | |||
195 | config BUILTIN_DTB | ||
196 | string "DTB to build into the kernel image" | ||
197 | depends on OF | ||
198 | |||
177 | source "mm/Kconfig" | 199 | source "mm/Kconfig" |
178 | 200 | ||
179 | source "drivers/pcmcia/Kconfig" | 201 | source "drivers/pcmcia/Kconfig" |
diff --git a/arch/xtensa/Kconfig.debug b/arch/xtensa/Kconfig.debug index 11c585295dd7..a34010e0e51c 100644 --- a/arch/xtensa/Kconfig.debug +++ b/arch/xtensa/Kconfig.debug | |||
@@ -2,6 +2,26 @@ menu "Kernel hacking" | |||
2 | 2 | ||
3 | source "lib/Kconfig.debug" | 3 | source "lib/Kconfig.debug" |
4 | 4 | ||
5 | endmenu | 5 | config LD_NO_RELAX |
6 | bool "Disable linker relaxation" | ||
7 | default n | ||
8 | help | ||
9 | Enable this function to disable link-time optimizations. | ||
10 | The default linker behavior is to combine identical literal | ||
11 | values to reduce code size and remove unnecessary overhead from | ||
12 | assembler-generated 'longcall' sequences. | ||
13 | Enabling this option improves the link time but increases the | ||
14 | code size, and possibly execution time. | ||
15 | |||
16 | config S32C1I_SELFTEST | ||
17 | bool "Perform S32C1I instruction self-test at boot" | ||
18 | default y | ||
19 | help | ||
20 | Enable this option to test S32C1I instruction behavior at boot. | ||
21 | Correct operation of this instruction requires some cooperation from hardware | ||
22 | external to the processor (such as bus bridge, bus fabric, or memory controller). | ||
23 | It is easy to make wrong hardware configuration, this test should catch it early. | ||
6 | 24 | ||
25 | Say 'N' on stable hardware. | ||
7 | 26 | ||
27 | endmenu | ||
diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile index bb5ba61723f7..0aa72702f179 100644 --- a/arch/xtensa/Makefile +++ b/arch/xtensa/Makefile | |||
@@ -38,6 +38,7 @@ endif | |||
38 | platform-$(CONFIG_XTENSA_PLATFORM_XT2000) := xt2000 | 38 | platform-$(CONFIG_XTENSA_PLATFORM_XT2000) := xt2000 |
39 | platform-$(CONFIG_XTENSA_PLATFORM_ISS) := iss | 39 | platform-$(CONFIG_XTENSA_PLATFORM_ISS) := iss |
40 | platform-$(CONFIG_XTENSA_PLATFORM_S6105) := s6105 | 40 | platform-$(CONFIG_XTENSA_PLATFORM_S6105) := s6105 |
41 | platform-$(CONFIG_XTENSA_PLATFORM_XTFPGA) := xtfpga | ||
41 | 42 | ||
42 | PLATFORM = $(platform-y) | 43 | PLATFORM = $(platform-y) |
43 | export PLATFORM | 44 | export PLATFORM |
@@ -49,6 +50,17 @@ KBUILD_CFLAGS += -pipe -mlongcalls | |||
49 | 50 | ||
50 | KBUILD_CFLAGS += $(call cc-option,-mforce-no-pic,) | 51 | KBUILD_CFLAGS += $(call cc-option,-mforce-no-pic,) |
51 | 52 | ||
53 | ifneq ($(CONFIG_LD_NO_RELAX),) | ||
54 | LDFLAGS := --no-relax | ||
55 | endif | ||
56 | |||
57 | ifeq ($(shell echo -e __XTENSA_EB__ | $(CC) -E - | grep -v "\#"),1) | ||
58 | CHECKFLAGS += -D__XTENSA_EB__ | ||
59 | endif | ||
60 | ifeq ($(shell echo -e __XTENSA_EL__ | $(CC) -E - | grep -v "\#"),1) | ||
61 | CHECKFLAGS += -D__XTENSA_EL__ | ||
62 | endif | ||
63 | |||
52 | vardirs := $(patsubst %,arch/xtensa/variants/%/,$(variant-y)) | 64 | vardirs := $(patsubst %,arch/xtensa/variants/%/,$(variant-y)) |
53 | plfdirs := $(patsubst %,arch/xtensa/platforms/%/,$(platform-y)) | 65 | plfdirs := $(patsubst %,arch/xtensa/platforms/%/,$(platform-y)) |
54 | 66 | ||
@@ -75,6 +87,10 @@ core-y += $(buildvar) $(buildplf) | |||
75 | 87 | ||
76 | libs-y += arch/xtensa/lib/ $(LIBGCC) | 88 | libs-y += arch/xtensa/lib/ $(LIBGCC) |
77 | 89 | ||
90 | ifneq ($(CONFIG_BUILTIN_DTB),"") | ||
91 | core-$(CONFIG_OF) += arch/xtensa/boot/ | ||
92 | endif | ||
93 | |||
78 | boot := arch/xtensa/boot | 94 | boot := arch/xtensa/boot |
79 | 95 | ||
80 | all: zImage | 96 | all: zImage |
@@ -84,7 +100,9 @@ bzImage : zImage | |||
84 | zImage: vmlinux | 100 | zImage: vmlinux |
85 | $(Q)$(MAKE) $(build)=$(boot) $@ | 101 | $(Q)$(MAKE) $(build)=$(boot) $@ |
86 | 102 | ||
103 | %.dtb: | ||
104 | $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ | ||
105 | |||
87 | define archhelp | 106 | define archhelp |
88 | @echo '* zImage - Compressed kernel image (arch/xtensa/boot/images/zImage.*)' | 107 | @echo '* zImage - Compressed kernel image (arch/xtensa/boot/images/zImage.*)' |
89 | endef | 108 | endef |
90 | |||
diff --git a/arch/xtensa/boot/Makefile b/arch/xtensa/boot/Makefile index 4018f8994196..818647e815d7 100644 --- a/arch/xtensa/boot/Makefile +++ b/arch/xtensa/boot/Makefile | |||
@@ -22,12 +22,35 @@ subdir-y := lib | |||
22 | # Subdirs for the boot loader(s) | 22 | # Subdirs for the boot loader(s) |
23 | 23 | ||
24 | bootdir-$(CONFIG_XTENSA_PLATFORM_ISS) += boot-elf | 24 | bootdir-$(CONFIG_XTENSA_PLATFORM_ISS) += boot-elf |
25 | bootdir-$(CONFIG_XTENSA_PLATFORM_XT2000) += boot-redboot boot-elf | 25 | bootdir-$(CONFIG_XTENSA_PLATFORM_XT2000) += boot-redboot boot-elf boot-uboot |
26 | bootdir-$(CONFIG_XTENSA_PLATFORM_XTFPGA) += boot-redboot boot-elf boot-uboot | ||
26 | 27 | ||
27 | 28 | ||
29 | BUILTIN_DTB := $(patsubst "%",%,$(CONFIG_BUILTIN_DTB)).dtb.o | ||
30 | ifneq ($(CONFIG_BUILTIN_DTB),"") | ||
31 | obj-$(CONFIG_OF) += $(BUILTIN_DTB) | ||
32 | endif | ||
33 | |||
34 | # Rule to build device tree blobs | ||
35 | $(obj)/%.dtb: $(src)/dts/%.dts FORCE | ||
36 | $(call if_changed_dep,dtc) | ||
37 | |||
38 | clean-files := *.dtb.S | ||
39 | |||
28 | zImage Image: $(bootdir-y) | 40 | zImage Image: $(bootdir-y) |
29 | 41 | ||
30 | $(bootdir-y): $(addprefix $(obj)/,$(subdir-y)) \ | 42 | $(bootdir-y): $(addprefix $(obj)/,$(subdir-y)) \ |
31 | $(addprefix $(obj)/,$(host-progs)) | 43 | $(addprefix $(obj)/,$(host-progs)) |
32 | $(Q)$(MAKE) $(build)=$(obj)/$@ $(MAKECMDGOALS) | 44 | $(Q)$(MAKE) $(build)=$(obj)/$@ $(MAKECMDGOALS) |
33 | 45 | ||
46 | OBJCOPYFLAGS = --strip-all -R .comment -R .note.gnu.build-id -O binary | ||
47 | |||
48 | vmlinux.bin: vmlinux FORCE | ||
49 | $(call if_changed,objcopy) | ||
50 | |||
51 | vmlinux.bin.gz: vmlinux.bin FORCE | ||
52 | $(call if_changed,gzip) | ||
53 | |||
54 | boot-elf: vmlinux.bin | ||
55 | boot-redboot: vmlinux.bin.gz | ||
56 | boot-uboot: vmlinux.bin.gz | ||
diff --git a/arch/xtensa/boot/boot-elf/Makefile b/arch/xtensa/boot/boot-elf/Makefile index f10992b89027..1fe01b78c124 100644 --- a/arch/xtensa/boot/boot-elf/Makefile +++ b/arch/xtensa/boot/boot-elf/Makefile | |||
@@ -4,9 +4,6 @@ | |||
4 | # for more details. | 4 | # for more details. |
5 | # | 5 | # |
6 | 6 | ||
7 | GZIP = gzip | ||
8 | GZIP_FLAGS = -v9fc | ||
9 | |||
10 | ifeq ($(BIG_ENDIAN),1) | 7 | ifeq ($(BIG_ENDIAN),1) |
11 | OBJCOPY_ARGS := -O elf32-xtensa-be | 8 | OBJCOPY_ARGS := -O elf32-xtensa-be |
12 | else | 9 | else |
@@ -20,18 +17,17 @@ boot-y := bootstrap.o | |||
20 | 17 | ||
21 | OBJS := $(addprefix $(obj)/,$(boot-y)) | 18 | OBJS := $(addprefix $(obj)/,$(boot-y)) |
22 | 19 | ||
23 | vmlinux.tmp: vmlinux | 20 | $(obj)/Image.o: vmlinux.bin $(OBJS) |
24 | $(OBJCOPY) --strip-all -R .comment -R .note.gnu.build-id -O binary \ | 21 | $(Q)$(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ |
25 | $^ $@ | 22 | --add-section image=vmlinux.bin \ |
26 | |||
27 | Image: vmlinux.tmp $(OBJS) arch/$(ARCH)/boot/boot-elf/boot.lds | ||
28 | $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ | ||
29 | --add-section image=vmlinux.tmp \ | ||
30 | --set-section-flags image=contents,alloc,load,load,data \ | 23 | --set-section-flags image=contents,alloc,load,load,data \ |
31 | $(OBJS) $@.tmp | 24 | $(OBJS) $@ |
32 | $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) \ | ||
33 | -T arch/$(ARCH)/boot/boot-elf/boot.lds \ | ||
34 | -o arch/$(ARCH)/boot/$@.elf $@.tmp | ||
35 | 25 | ||
36 | zImage: Image | 26 | $(obj)/../Image.elf: $(obj)/Image.o $(obj)/boot.lds |
27 | $(Q)$(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) \ | ||
28 | -T $(obj)/boot.lds \ | ||
29 | --build-id=none \ | ||
30 | -o $@ $(obj)/Image.o | ||
31 | $(Q)$(kecho) ' Kernel: $@ is ready' | ||
37 | 32 | ||
33 | zImage: $(obj)/../Image.elf | ||
diff --git a/arch/xtensa/boot/boot-redboot/Makefile b/arch/xtensa/boot/boot-redboot/Makefile index 25a78c6b1530..8be8b9436981 100644 --- a/arch/xtensa/boot/boot-redboot/Makefile +++ b/arch/xtensa/boot/boot-redboot/Makefile | |||
@@ -4,8 +4,6 @@ | |||
4 | # for more details. | 4 | # for more details. |
5 | # | 5 | # |
6 | 6 | ||
7 | GZIP = gzip | ||
8 | GZIP_FLAGS = -v9fc | ||
9 | ifeq ($(BIG_ENDIAN),1) | 7 | ifeq ($(BIG_ENDIAN),1) |
10 | OBJCOPY_ARGS := -O elf32-xtensa-be | 8 | OBJCOPY_ARGS := -O elf32-xtensa-be |
11 | else | 9 | else |
@@ -21,17 +19,17 @@ LIBS := arch/xtensa/boot/lib/lib.a arch/xtensa/lib/lib.a | |||
21 | 19 | ||
22 | LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name) | 20 | LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name) |
23 | 21 | ||
24 | vmlinux.tmp: vmlinux | 22 | $(obj)/zImage.o: vmlinux.bin.gz $(OBJS) |
25 | $(OBJCOPY) --strip-all -R .comment -R .note.gnu.build-id -O binary \ | 23 | $(Q)$(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ |
26 | $^ $@ | 24 | --add-section image=vmlinux.bin.gz \ |
25 | --set-section-flags image=contents,alloc,load,load,data \ | ||
26 | $(OBJS) $@ | ||
27 | 27 | ||
28 | vmlinux.tmp.gz: vmlinux.tmp | 28 | $(obj)/zImage.elf: $(obj)/zImage.o $(LIBS) |
29 | $(GZIP) $(GZIP_FLAGS) $^ > $@ | 29 | $(Q)$(LD) $(LD_ARGS) -o $@ $^ -L/xtensa-elf/lib $(LIBGCC) |
30 | 30 | ||
31 | zImage: vmlinux.tmp.gz $(OBJS) $(LIBS) | 31 | $(obj)/../zImage.redboot: $(obj)/zImage.elf |
32 | $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ | 32 | $(Q)$(OBJCOPY) -S -O binary $< $@ |
33 | --add-section image=vmlinux.tmp.gz \ | 33 | $(Q)$(kecho) ' Kernel: $@ is ready' |
34 | --set-section-flags image=contents,alloc,load,load,data \ | 34 | |
35 | $(OBJS) $@.tmp | 35 | zImage: $(obj)/../zImage.redboot |
36 | $(LD) $(LD_ARGS) -o $@.elf $@.tmp $(LIBS) -L/xtensa-elf/lib $(LIBGCC) | ||
37 | $(OBJCOPY) -S -O binary $@.elf arch/$(ARCH)/boot/$@.redboot | ||
diff --git a/arch/xtensa/boot/boot-uboot/Makefile b/arch/xtensa/boot/boot-uboot/Makefile new file mode 100644 index 000000000000..bfbf8af582f1 --- /dev/null +++ b/arch/xtensa/boot/boot-uboot/Makefile | |||
@@ -0,0 +1,14 @@ | |||
1 | # | ||
2 | # This file is subject to the terms and conditions of the GNU General Public | ||
3 | # License. See the file "COPYING" in the main directory of this archive | ||
4 | # for more details. | ||
5 | # | ||
6 | |||
7 | UIMAGE_LOADADDR = 0xd0001000 | ||
8 | UIMAGE_COMPRESSION = gzip | ||
9 | |||
10 | $(obj)/../uImage: vmlinux.bin.gz FORCE | ||
11 | $(call if_changed,uimage) | ||
12 | $(Q)$(kecho) ' Kernel: $@ is ready' | ||
13 | |||
14 | zImage: $(obj)/../uImage | ||
diff --git a/arch/xtensa/boot/dts/lx60.dts b/arch/xtensa/boot/dts/lx60.dts new file mode 100644 index 000000000000..2eab3658e1bd --- /dev/null +++ b/arch/xtensa/boot/dts/lx60.dts | |||
@@ -0,0 +1,11 @@ | |||
1 | /dts-v1/; | ||
2 | /include/ "xtfpga.dtsi" | ||
3 | /include/ "xtfpga-flash-4m.dtsi" | ||
4 | |||
5 | / { | ||
6 | compatible = "xtensa,lx60"; | ||
7 | memory@0 { | ||
8 | device_type = "memory"; | ||
9 | reg = <0x00000000 0x04000000>; | ||
10 | }; | ||
11 | }; | ||
diff --git a/arch/xtensa/boot/dts/ml605.dts b/arch/xtensa/boot/dts/ml605.dts new file mode 100644 index 000000000000..6ed51d6554e6 --- /dev/null +++ b/arch/xtensa/boot/dts/ml605.dts | |||
@@ -0,0 +1,11 @@ | |||
1 | /dts-v1/; | ||
2 | /include/ "xtfpga.dtsi" | ||
3 | /include/ "xtfpga-flash-16m.dtsi" | ||
4 | |||
5 | / { | ||
6 | compatible = "xtensa,ml605"; | ||
7 | memory@0 { | ||
8 | device_type = "memory"; | ||
9 | reg = <0x00000000 0x08000000>; | ||
10 | }; | ||
11 | }; | ||
diff --git a/arch/xtensa/boot/dts/xtfpga-flash-16m.dtsi b/arch/xtensa/boot/dts/xtfpga-flash-16m.dtsi new file mode 100644 index 000000000000..e5703c7beeb6 --- /dev/null +++ b/arch/xtensa/boot/dts/xtfpga-flash-16m.dtsi | |||
@@ -0,0 +1,26 @@ | |||
1 | / { | ||
2 | flash: flash@f8000000 { | ||
3 | #address-cells = <1>; | ||
4 | #size-cells = <1>; | ||
5 | compatible = "cfi-flash"; | ||
6 | reg = <0xf8000000 0x01000000>; | ||
7 | bank-width = <2>; | ||
8 | device-width = <2>; | ||
9 | partition@0x0 { | ||
10 | label = "boot loader area"; | ||
11 | reg = <0x00000000 0x00400000>; | ||
12 | }; | ||
13 | partition@0x400000 { | ||
14 | label = "kernel image"; | ||
15 | reg = <0x00400000 0x00600000>; | ||
16 | }; | ||
17 | partition@0xa00000 { | ||
18 | label = "data"; | ||
19 | reg = <0x00a00000 0x005e0000>; | ||
20 | }; | ||
21 | partition@0xfe0000 { | ||
22 | label = "boot environment"; | ||
23 | reg = <0x00fe0000 0x00020000>; | ||
24 | }; | ||
25 | }; | ||
26 | }; | ||
diff --git a/arch/xtensa/boot/dts/xtfpga-flash-4m.dtsi b/arch/xtensa/boot/dts/xtfpga-flash-4m.dtsi new file mode 100644 index 000000000000..6f9c10d6b689 --- /dev/null +++ b/arch/xtensa/boot/dts/xtfpga-flash-4m.dtsi | |||
@@ -0,0 +1,18 @@ | |||
1 | / { | ||
2 | flash: flash@f8000000 { | ||
3 | #address-cells = <1>; | ||
4 | #size-cells = <1>; | ||
5 | compatible = "cfi-flash"; | ||
6 | reg = <0xf8000000 0x00400000>; | ||
7 | bank-width = <2>; | ||
8 | device-width = <2>; | ||
9 | partition@0x0 { | ||
10 | label = "boot loader area"; | ||
11 | reg = <0x00000000 0x003f0000>; | ||
12 | }; | ||
13 | partition@0x3f0000 { | ||
14 | label = "boot environment"; | ||
15 | reg = <0x003f0000 0x00010000>; | ||
16 | }; | ||
17 | }; | ||
18 | }; | ||
diff --git a/arch/xtensa/boot/dts/xtfpga.dtsi b/arch/xtensa/boot/dts/xtfpga.dtsi new file mode 100644 index 000000000000..7eda6ecf7eef --- /dev/null +++ b/arch/xtensa/boot/dts/xtfpga.dtsi | |||
@@ -0,0 +1,56 @@ | |||
1 | / { | ||
2 | compatible = "xtensa,xtfpga"; | ||
3 | #address-cells = <1>; | ||
4 | #size-cells = <1>; | ||
5 | interrupt-parent = <&pic>; | ||
6 | |||
7 | chosen { | ||
8 | bootargs = "earlycon=uart8250,mmio32,0xfd050020,115200n8 console=ttyS0,115200n8 ip=dhcp root=/dev/nfs rw debug"; | ||
9 | }; | ||
10 | |||
11 | memory@0 { | ||
12 | device_type = "memory"; | ||
13 | reg = <0x00000000 0x06000000>; | ||
14 | }; | ||
15 | |||
16 | cpus { | ||
17 | #address-cells = <1>; | ||
18 | #size-cells = <0>; | ||
19 | cpu@0 { | ||
20 | compatible = "xtensa,cpu"; | ||
21 | reg = <0>; | ||
22 | /* Filled in by platform_setup from FPGA register | ||
23 | * clock-frequency = <100000000>; | ||
24 | */ | ||
25 | }; | ||
26 | }; | ||
27 | |||
28 | pic: pic { | ||
29 | compatible = "xtensa,pic"; | ||
30 | /* one cell: internal irq number, | ||
31 | * two cells: second cell == 0: internal irq number | ||
32 | * second cell == 1: external irq number | ||
33 | */ | ||
34 | #interrupt-cells = <2>; | ||
35 | interrupt-controller; | ||
36 | }; | ||
37 | |||
38 | serial0: serial@fd050020 { | ||
39 | device_type = "serial"; | ||
40 | compatible = "ns16550a"; | ||
41 | no-loopback-test; | ||
42 | reg = <0xfd050020 0x20>; | ||
43 | reg-shift = <2>; | ||
44 | interrupts = <0 1>; /* external irq 0 */ | ||
45 | /* Filled in by platform_setup from FPGA register | ||
46 | * clock-frequency = <100000000>; | ||
47 | */ | ||
48 | }; | ||
49 | |||
50 | enet0: ethoc@fd030000 { | ||
51 | compatible = "opencores,ethoc"; | ||
52 | reg = <0xfd030000 0x4000 0xfd800000 0x4000>; | ||
53 | interrupts = <1 1>; /* external irq 1 */ | ||
54 | local-mac-address = [00 50 c2 13 6f 00]; | ||
55 | }; | ||
56 | }; | ||
diff --git a/arch/xtensa/include/asm/Kbuild b/arch/xtensa/include/asm/Kbuild index 6d1302789995..095f0a2244f7 100644 --- a/arch/xtensa/include/asm/Kbuild +++ b/arch/xtensa/include/asm/Kbuild | |||
@@ -25,4 +25,5 @@ generic-y += siginfo.h | |||
25 | generic-y += statfs.h | 25 | generic-y += statfs.h |
26 | generic-y += termios.h | 26 | generic-y += termios.h |
27 | generic-y += topology.h | 27 | generic-y += topology.h |
28 | generic-y += trace_clock.h | ||
28 | generic-y += xor.h | 29 | generic-y += xor.h |
diff --git a/arch/xtensa/include/asm/atomic.h b/arch/xtensa/include/asm/atomic.h index 24f50cada70c..c3f289174c10 100644 --- a/arch/xtensa/include/asm/atomic.h +++ b/arch/xtensa/include/asm/atomic.h | |||
@@ -66,19 +66,35 @@ | |||
66 | */ | 66 | */ |
67 | static inline void atomic_add(int i, atomic_t * v) | 67 | static inline void atomic_add(int i, atomic_t * v) |
68 | { | 68 | { |
69 | unsigned int vval; | 69 | #if XCHAL_HAVE_S32C1I |
70 | 70 | unsigned long tmp; | |
71 | __asm__ __volatile__( | 71 | int result; |
72 | "rsil a15, "__stringify(LOCKLEVEL)"\n\t" | 72 | |
73 | "l32i %0, %2, 0 \n\t" | 73 | __asm__ __volatile__( |
74 | "add %0, %0, %1 \n\t" | 74 | "1: l32i %1, %3, 0\n" |
75 | "s32i %0, %2, 0 \n\t" | 75 | " wsr %1, scompare1\n" |
76 | "wsr a15, ps \n\t" | 76 | " add %0, %1, %2\n" |
77 | "rsync \n" | 77 | " s32c1i %0, %3, 0\n" |
78 | : "=&a" (vval) | 78 | " bne %0, %1, 1b\n" |
79 | : "a" (i), "a" (v) | 79 | : "=&a" (result), "=&a" (tmp) |
80 | : "a15", "memory" | 80 | : "a" (i), "a" (v) |
81 | ); | 81 | : "memory" |
82 | ); | ||
83 | #else | ||
84 | unsigned int vval; | ||
85 | |||
86 | __asm__ __volatile__( | ||
87 | " rsil a15, "__stringify(LOCKLEVEL)"\n" | ||
88 | " l32i %0, %2, 0\n" | ||
89 | " add %0, %0, %1\n" | ||
90 | " s32i %0, %2, 0\n" | ||
91 | " wsr a15, ps\n" | ||
92 | " rsync\n" | ||
93 | : "=&a" (vval) | ||
94 | : "a" (i), "a" (v) | ||
95 | : "a15", "memory" | ||
96 | ); | ||
97 | #endif | ||
82 | } | 98 | } |
83 | 99 | ||
84 | /** | 100 | /** |
@@ -90,19 +106,35 @@ static inline void atomic_add(int i, atomic_t * v) | |||
90 | */ | 106 | */ |
91 | static inline void atomic_sub(int i, atomic_t *v) | 107 | static inline void atomic_sub(int i, atomic_t *v) |
92 | { | 108 | { |
93 | unsigned int vval; | 109 | #if XCHAL_HAVE_S32C1I |
94 | 110 | unsigned long tmp; | |
95 | __asm__ __volatile__( | 111 | int result; |
96 | "rsil a15, "__stringify(LOCKLEVEL)"\n\t" | 112 | |
97 | "l32i %0, %2, 0 \n\t" | 113 | __asm__ __volatile__( |
98 | "sub %0, %0, %1 \n\t" | 114 | "1: l32i %1, %3, 0\n" |
99 | "s32i %0, %2, 0 \n\t" | 115 | " wsr %1, scompare1\n" |
100 | "wsr a15, ps \n\t" | 116 | " sub %0, %1, %2\n" |
101 | "rsync \n" | 117 | " s32c1i %0, %3, 0\n" |
102 | : "=&a" (vval) | 118 | " bne %0, %1, 1b\n" |
103 | : "a" (i), "a" (v) | 119 | : "=&a" (result), "=&a" (tmp) |
104 | : "a15", "memory" | 120 | : "a" (i), "a" (v) |
105 | ); | 121 | : "memory" |
122 | ); | ||
123 | #else | ||
124 | unsigned int vval; | ||
125 | |||
126 | __asm__ __volatile__( | ||
127 | " rsil a15, "__stringify(LOCKLEVEL)"\n" | ||
128 | " l32i %0, %2, 0\n" | ||
129 | " sub %0, %0, %1\n" | ||
130 | " s32i %0, %2, 0\n" | ||
131 | " wsr a15, ps\n" | ||
132 | " rsync\n" | ||
133 | : "=&a" (vval) | ||
134 | : "a" (i), "a" (v) | ||
135 | : "a15", "memory" | ||
136 | ); | ||
137 | #endif | ||
106 | } | 138 | } |
107 | 139 | ||
108 | /* | 140 | /* |
@@ -111,40 +143,78 @@ static inline void atomic_sub(int i, atomic_t *v) | |||
111 | 143 | ||
112 | static inline int atomic_add_return(int i, atomic_t * v) | 144 | static inline int atomic_add_return(int i, atomic_t * v) |
113 | { | 145 | { |
114 | unsigned int vval; | 146 | #if XCHAL_HAVE_S32C1I |
115 | 147 | unsigned long tmp; | |
116 | __asm__ __volatile__( | 148 | int result; |
117 | "rsil a15,"__stringify(LOCKLEVEL)"\n\t" | 149 | |
118 | "l32i %0, %2, 0 \n\t" | 150 | __asm__ __volatile__( |
119 | "add %0, %0, %1 \n\t" | 151 | "1: l32i %1, %3, 0\n" |
120 | "s32i %0, %2, 0 \n\t" | 152 | " wsr %1, scompare1\n" |
121 | "wsr a15, ps \n\t" | 153 | " add %0, %1, %2\n" |
122 | "rsync \n" | 154 | " s32c1i %0, %3, 0\n" |
123 | : "=&a" (vval) | 155 | " bne %0, %1, 1b\n" |
124 | : "a" (i), "a" (v) | 156 | " add %0, %0, %2\n" |
125 | : "a15", "memory" | 157 | : "=&a" (result), "=&a" (tmp) |
126 | ); | 158 | : "a" (i), "a" (v) |
127 | 159 | : "memory" | |
128 | return vval; | 160 | ); |
161 | |||
162 | return result; | ||
163 | #else | ||
164 | unsigned int vval; | ||
165 | |||
166 | __asm__ __volatile__( | ||
167 | " rsil a15,"__stringify(LOCKLEVEL)"\n" | ||
168 | " l32i %0, %2, 0\n" | ||
169 | " add %0, %0, %1\n" | ||
170 | " s32i %0, %2, 0\n" | ||
171 | " wsr a15, ps\n" | ||
172 | " rsync\n" | ||
173 | : "=&a" (vval) | ||
174 | : "a" (i), "a" (v) | ||
175 | : "a15", "memory" | ||
176 | ); | ||
177 | |||
178 | return vval; | ||
179 | #endif | ||
129 | } | 180 | } |
130 | 181 | ||
131 | static inline int atomic_sub_return(int i, atomic_t * v) | 182 | static inline int atomic_sub_return(int i, atomic_t * v) |
132 | { | 183 | { |
133 | unsigned int vval; | 184 | #if XCHAL_HAVE_S32C1I |
134 | 185 | unsigned long tmp; | |
135 | __asm__ __volatile__( | 186 | int result; |
136 | "rsil a15,"__stringify(LOCKLEVEL)"\n\t" | 187 | |
137 | "l32i %0, %2, 0 \n\t" | 188 | __asm__ __volatile__( |
138 | "sub %0, %0, %1 \n\t" | 189 | "1: l32i %1, %3, 0\n" |
139 | "s32i %0, %2, 0 \n\t" | 190 | " wsr %1, scompare1\n" |
140 | "wsr a15, ps \n\t" | 191 | " sub %0, %1, %2\n" |
141 | "rsync \n" | 192 | " s32c1i %0, %3, 0\n" |
142 | : "=&a" (vval) | 193 | " bne %0, %1, 1b\n" |
143 | : "a" (i), "a" (v) | 194 | " sub %0, %0, %2\n" |
144 | : "a15", "memory" | 195 | : "=&a" (result), "=&a" (tmp) |
145 | ); | 196 | : "a" (i), "a" (v) |
146 | 197 | : "memory" | |
147 | return vval; | 198 | ); |
199 | |||
200 | return result; | ||
201 | #else | ||
202 | unsigned int vval; | ||
203 | |||
204 | __asm__ __volatile__( | ||
205 | " rsil a15,"__stringify(LOCKLEVEL)"\n" | ||
206 | " l32i %0, %2, 0\n" | ||
207 | " sub %0, %0, %1\n" | ||
208 | " s32i %0, %2, 0\n" | ||
209 | " wsr a15, ps\n" | ||
210 | " rsync\n" | ||
211 | : "=&a" (vval) | ||
212 | : "a" (i), "a" (v) | ||
213 | : "a15", "memory" | ||
214 | ); | ||
215 | |||
216 | return vval; | ||
217 | #endif | ||
148 | } | 218 | } |
149 | 219 | ||
150 | /** | 220 | /** |
@@ -251,38 +321,70 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u) | |||
251 | 321 | ||
252 | static inline void atomic_clear_mask(unsigned int mask, atomic_t *v) | 322 | static inline void atomic_clear_mask(unsigned int mask, atomic_t *v) |
253 | { | 323 | { |
254 | unsigned int all_f = -1; | 324 | #if XCHAL_HAVE_S32C1I |
255 | unsigned int vval; | 325 | unsigned long tmp; |
256 | 326 | int result; | |
257 | __asm__ __volatile__( | 327 | |
258 | "rsil a15,"__stringify(LOCKLEVEL)"\n\t" | 328 | __asm__ __volatile__( |
259 | "l32i %0, %2, 0 \n\t" | 329 | "1: l32i %1, %3, 0\n" |
260 | "xor %1, %4, %3 \n\t" | 330 | " wsr %1, scompare1\n" |
261 | "and %0, %0, %4 \n\t" | 331 | " and %0, %1, %2\n" |
262 | "s32i %0, %2, 0 \n\t" | 332 | " s32c1i %0, %3, 0\n" |
263 | "wsr a15, ps \n\t" | 333 | " bne %0, %1, 1b\n" |
264 | "rsync \n" | 334 | : "=&a" (result), "=&a" (tmp) |
265 | : "=&a" (vval), "=a" (mask) | 335 | : "a" (~mask), "a" (v) |
266 | : "a" (v), "a" (all_f), "1" (mask) | 336 | : "memory" |
267 | : "a15", "memory" | 337 | ); |
268 | ); | 338 | #else |
339 | unsigned int all_f = -1; | ||
340 | unsigned int vval; | ||
341 | |||
342 | __asm__ __volatile__( | ||
343 | " rsil a15,"__stringify(LOCKLEVEL)"\n" | ||
344 | " l32i %0, %2, 0\n" | ||
345 | " xor %1, %4, %3\n" | ||
346 | " and %0, %0, %4\n" | ||
347 | " s32i %0, %2, 0\n" | ||
348 | " wsr a15, ps\n" | ||
349 | " rsync\n" | ||
350 | : "=&a" (vval), "=a" (mask) | ||
351 | : "a" (v), "a" (all_f), "1" (mask) | ||
352 | : "a15", "memory" | ||
353 | ); | ||
354 | #endif | ||
269 | } | 355 | } |
270 | 356 | ||
271 | static inline void atomic_set_mask(unsigned int mask, atomic_t *v) | 357 | static inline void atomic_set_mask(unsigned int mask, atomic_t *v) |
272 | { | 358 | { |
273 | unsigned int vval; | 359 | #if XCHAL_HAVE_S32C1I |
274 | 360 | unsigned long tmp; | |
275 | __asm__ __volatile__( | 361 | int result; |
276 | "rsil a15,"__stringify(LOCKLEVEL)"\n\t" | 362 | |
277 | "l32i %0, %2, 0 \n\t" | 363 | __asm__ __volatile__( |
278 | "or %0, %0, %1 \n\t" | 364 | "1: l32i %1, %3, 0\n" |
279 | "s32i %0, %2, 0 \n\t" | 365 | " wsr %1, scompare1\n" |
280 | "wsr a15, ps \n\t" | 366 | " or %0, %1, %2\n" |
281 | "rsync \n" | 367 | " s32c1i %0, %3, 0\n" |
282 | : "=&a" (vval) | 368 | " bne %0, %1, 1b\n" |
283 | : "a" (mask), "a" (v) | 369 | : "=&a" (result), "=&a" (tmp) |
284 | : "a15", "memory" | 370 | : "a" (mask), "a" (v) |
285 | ); | 371 | : "memory" |
372 | ); | ||
373 | #else | ||
374 | unsigned int vval; | ||
375 | |||
376 | __asm__ __volatile__( | ||
377 | " rsil a15,"__stringify(LOCKLEVEL)"\n" | ||
378 | " l32i %0, %2, 0\n" | ||
379 | " or %0, %0, %1\n" | ||
380 | " s32i %0, %2, 0\n" | ||
381 | " wsr a15, ps\n" | ||
382 | " rsync\n" | ||
383 | : "=&a" (vval) | ||
384 | : "a" (mask), "a" (v) | ||
385 | : "a15", "memory" | ||
386 | ); | ||
387 | #endif | ||
286 | } | 388 | } |
287 | 389 | ||
288 | /* Atomic operations are already serializing */ | 390 | /* Atomic operations are already serializing */ |
@@ -294,4 +396,3 @@ static inline void atomic_set_mask(unsigned int mask, atomic_t *v) | |||
294 | #endif /* __KERNEL__ */ | 396 | #endif /* __KERNEL__ */ |
295 | 397 | ||
296 | #endif /* _XTENSA_ATOMIC_H */ | 398 | #endif /* _XTENSA_ATOMIC_H */ |
297 | |||
diff --git a/arch/xtensa/include/asm/barrier.h b/arch/xtensa/include/asm/barrier.h index 55707a8009d3..ef021677d536 100644 --- a/arch/xtensa/include/asm/barrier.h +++ b/arch/xtensa/include/asm/barrier.h | |||
@@ -3,7 +3,7 @@ | |||
3 | * License. See the file "COPYING" in the main directory of this archive | 3 | * License. See the file "COPYING" in the main directory of this archive |
4 | * for more details. | 4 | * for more details. |
5 | * | 5 | * |
6 | * Copyright (C) 2001 - 2005 Tensilica Inc. | 6 | * Copyright (C) 2001 - 2012 Tensilica Inc. |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #ifndef _XTENSA_SYSTEM_H | 9 | #ifndef _XTENSA_SYSTEM_H |
@@ -12,8 +12,8 @@ | |||
12 | #define smp_read_barrier_depends() do { } while(0) | 12 | #define smp_read_barrier_depends() do { } while(0) |
13 | #define read_barrier_depends() do { } while(0) | 13 | #define read_barrier_depends() do { } while(0) |
14 | 14 | ||
15 | #define mb() barrier() | 15 | #define mb() ({ __asm__ __volatile__("memw" : : : "memory"); }) |
16 | #define rmb() mb() | 16 | #define rmb() barrier() |
17 | #define wmb() mb() | 17 | #define wmb() mb() |
18 | 18 | ||
19 | #ifdef CONFIG_SMP | 19 | #ifdef CONFIG_SMP |
diff --git a/arch/xtensa/include/asm/bitops.h b/arch/xtensa/include/asm/bitops.h index 5270197ddd36..84afe58d5d37 100644 --- a/arch/xtensa/include/asm/bitops.h +++ b/arch/xtensa/include/asm/bitops.h | |||
@@ -29,7 +29,6 @@ | |||
29 | #define smp_mb__before_clear_bit() barrier() | 29 | #define smp_mb__before_clear_bit() barrier() |
30 | #define smp_mb__after_clear_bit() barrier() | 30 | #define smp_mb__after_clear_bit() barrier() |
31 | 31 | ||
32 | #include <asm-generic/bitops/atomic.h> | ||
33 | #include <asm-generic/bitops/non-atomic.h> | 32 | #include <asm-generic/bitops/non-atomic.h> |
34 | 33 | ||
35 | #if XCHAL_HAVE_NSA | 34 | #if XCHAL_HAVE_NSA |
@@ -104,6 +103,132 @@ static inline unsigned long __fls(unsigned long word) | |||
104 | #endif | 103 | #endif |
105 | 104 | ||
106 | #include <asm-generic/bitops/fls64.h> | 105 | #include <asm-generic/bitops/fls64.h> |
106 | |||
107 | #if XCHAL_HAVE_S32C1I | ||
108 | |||
109 | static inline void set_bit(unsigned int bit, volatile unsigned long *p) | ||
110 | { | ||
111 | unsigned long tmp, value; | ||
112 | unsigned long mask = 1UL << (bit & 31); | ||
113 | |||
114 | p += bit >> 5; | ||
115 | |||
116 | __asm__ __volatile__( | ||
117 | "1: l32i %1, %3, 0\n" | ||
118 | " wsr %1, scompare1\n" | ||
119 | " or %0, %1, %2\n" | ||
120 | " s32c1i %0, %3, 0\n" | ||
121 | " bne %0, %1, 1b\n" | ||
122 | : "=&a" (tmp), "=&a" (value) | ||
123 | : "a" (mask), "a" (p) | ||
124 | : "memory"); | ||
125 | } | ||
126 | |||
127 | static inline void clear_bit(unsigned int bit, volatile unsigned long *p) | ||
128 | { | ||
129 | unsigned long tmp, value; | ||
130 | unsigned long mask = 1UL << (bit & 31); | ||
131 | |||
132 | p += bit >> 5; | ||
133 | |||
134 | __asm__ __volatile__( | ||
135 | "1: l32i %1, %3, 0\n" | ||
136 | " wsr %1, scompare1\n" | ||
137 | " and %0, %1, %2\n" | ||
138 | " s32c1i %0, %3, 0\n" | ||
139 | " bne %0, %1, 1b\n" | ||
140 | : "=&a" (tmp), "=&a" (value) | ||
141 | : "a" (~mask), "a" (p) | ||
142 | : "memory"); | ||
143 | } | ||
144 | |||
145 | static inline void change_bit(unsigned int bit, volatile unsigned long *p) | ||
146 | { | ||
147 | unsigned long tmp, value; | ||
148 | unsigned long mask = 1UL << (bit & 31); | ||
149 | |||
150 | p += bit >> 5; | ||
151 | |||
152 | __asm__ __volatile__( | ||
153 | "1: l32i %1, %3, 0\n" | ||
154 | " wsr %1, scompare1\n" | ||
155 | " xor %0, %1, %2\n" | ||
156 | " s32c1i %0, %3, 0\n" | ||
157 | " bne %0, %1, 1b\n" | ||
158 | : "=&a" (tmp), "=&a" (value) | ||
159 | : "a" (mask), "a" (p) | ||
160 | : "memory"); | ||
161 | } | ||
162 | |||
163 | static inline int | ||
164 | test_and_set_bit(unsigned int bit, volatile unsigned long *p) | ||
165 | { | ||
166 | unsigned long tmp, value; | ||
167 | unsigned long mask = 1UL << (bit & 31); | ||
168 | |||
169 | p += bit >> 5; | ||
170 | |||
171 | __asm__ __volatile__( | ||
172 | "1: l32i %1, %3, 0\n" | ||
173 | " wsr %1, scompare1\n" | ||
174 | " or %0, %1, %2\n" | ||
175 | " s32c1i %0, %3, 0\n" | ||
176 | " bne %0, %1, 1b\n" | ||
177 | : "=&a" (tmp), "=&a" (value) | ||
178 | : "a" (mask), "a" (p) | ||
179 | : "memory"); | ||
180 | |||
181 | return tmp & mask; | ||
182 | } | ||
183 | |||
184 | static inline int | ||
185 | test_and_clear_bit(unsigned int bit, volatile unsigned long *p) | ||
186 | { | ||
187 | unsigned long tmp, value; | ||
188 | unsigned long mask = 1UL << (bit & 31); | ||
189 | |||
190 | p += bit >> 5; | ||
191 | |||
192 | __asm__ __volatile__( | ||
193 | "1: l32i %1, %3, 0\n" | ||
194 | " wsr %1, scompare1\n" | ||
195 | " and %0, %1, %2\n" | ||
196 | " s32c1i %0, %3, 0\n" | ||
197 | " bne %0, %1, 1b\n" | ||
198 | : "=&a" (tmp), "=&a" (value) | ||
199 | : "a" (~mask), "a" (p) | ||
200 | : "memory"); | ||
201 | |||
202 | return tmp & mask; | ||
203 | } | ||
204 | |||
205 | static inline int | ||
206 | test_and_change_bit(unsigned int bit, volatile unsigned long *p) | ||
207 | { | ||
208 | unsigned long tmp, value; | ||
209 | unsigned long mask = 1UL << (bit & 31); | ||
210 | |||
211 | p += bit >> 5; | ||
212 | |||
213 | __asm__ __volatile__( | ||
214 | "1: l32i %1, %3, 0\n" | ||
215 | " wsr %1, scompare1\n" | ||
216 | " xor %0, %1, %2\n" | ||
217 | " s32c1i %0, %3, 0\n" | ||
218 | " bne %0, %1, 1b\n" | ||
219 | : "=&a" (tmp), "=&a" (value) | ||
220 | : "a" (mask), "a" (p) | ||
221 | : "memory"); | ||
222 | |||
223 | return tmp & mask; | ||
224 | } | ||
225 | |||
226 | #else | ||
227 | |||
228 | #include <asm-generic/bitops/atomic.h> | ||
229 | |||
230 | #endif /* XCHAL_HAVE_S32C1I */ | ||
231 | |||
107 | #include <asm-generic/bitops/find.h> | 232 | #include <asm-generic/bitops/find.h> |
108 | #include <asm-generic/bitops/le.h> | 233 | #include <asm-generic/bitops/le.h> |
109 | 234 | ||
diff --git a/arch/xtensa/include/asm/bootparam.h b/arch/xtensa/include/asm/bootparam.h index 9983f2c1b7ee..0c25799facab 100644 --- a/arch/xtensa/include/asm/bootparam.h +++ b/arch/xtensa/include/asm/bootparam.h | |||
@@ -22,6 +22,7 @@ | |||
22 | #define BP_TAG_MEMORY 0x1003 /* memory addr and size (bp_meminfo) */ | 22 | #define BP_TAG_MEMORY 0x1003 /* memory addr and size (bp_meminfo) */ |
23 | #define BP_TAG_SERIAL_BAUSRATE 0x1004 /* baud rate of current console. */ | 23 | #define BP_TAG_SERIAL_BAUSRATE 0x1004 /* baud rate of current console. */ |
24 | #define BP_TAG_SERIAL_PORT 0x1005 /* serial device of current console */ | 24 | #define BP_TAG_SERIAL_PORT 0x1005 /* serial device of current console */ |
25 | #define BP_TAG_FDT 0x1006 /* flat device tree addr */ | ||
25 | 26 | ||
26 | #define BP_TAG_FIRST 0x7B0B /* first tag with a version number */ | 27 | #define BP_TAG_FIRST 0x7B0B /* first tag with a version number */ |
27 | #define BP_TAG_LAST 0x7E0B /* last tag */ | 28 | #define BP_TAG_LAST 0x7E0B /* last tag */ |
@@ -31,15 +32,15 @@ | |||
31 | /* All records are aligned to 4 bytes */ | 32 | /* All records are aligned to 4 bytes */ |
32 | 33 | ||
33 | typedef struct bp_tag { | 34 | typedef struct bp_tag { |
34 | unsigned short id; /* tag id */ | 35 | unsigned short id; /* tag id */ |
35 | unsigned short size; /* size of this record excluding the structure*/ | 36 | unsigned short size; /* size of this record excluding the structure*/ |
36 | unsigned long data[0]; /* data */ | 37 | unsigned long data[0]; /* data */ |
37 | } bp_tag_t; | 38 | } bp_tag_t; |
38 | 39 | ||
39 | typedef struct meminfo { | 40 | typedef struct meminfo { |
40 | unsigned long type; | 41 | unsigned long type; |
41 | unsigned long start; | 42 | unsigned long start; |
42 | unsigned long end; | 43 | unsigned long end; |
43 | } meminfo_t; | 44 | } meminfo_t; |
44 | 45 | ||
45 | #define SYSMEM_BANKS_MAX 5 | 46 | #define SYSMEM_BANKS_MAX 5 |
@@ -48,14 +49,11 @@ typedef struct meminfo { | |||
48 | #define MEMORY_TYPE_NONE 0x2000 | 49 | #define MEMORY_TYPE_NONE 0x2000 |
49 | 50 | ||
50 | typedef struct sysmem_info { | 51 | typedef struct sysmem_info { |
51 | int nr_banks; | 52 | int nr_banks; |
52 | meminfo_t bank[SYSMEM_BANKS_MAX]; | 53 | meminfo_t bank[SYSMEM_BANKS_MAX]; |
53 | } sysmem_info_t; | 54 | } sysmem_info_t; |
54 | 55 | ||
55 | extern sysmem_info_t sysmem; | 56 | extern sysmem_info_t sysmem; |
56 | 57 | ||
57 | #endif | 58 | #endif |
58 | #endif | 59 | #endif |
59 | |||
60 | |||
61 | |||
diff --git a/arch/xtensa/include/asm/cacheasm.h b/arch/xtensa/include/asm/cacheasm.h index 2c20a58f94cd..60e18773ecb8 100644 --- a/arch/xtensa/include/asm/cacheasm.h +++ b/arch/xtensa/include/asm/cacheasm.h | |||
@@ -174,4 +174,3 @@ | |||
174 | __loop_cache_page \ar \as ihi XCHAL_ICACHE_LINEWIDTH | 174 | __loop_cache_page \ar \as ihi XCHAL_ICACHE_LINEWIDTH |
175 | 175 | ||
176 | .endm | 176 | .endm |
177 | |||
diff --git a/arch/xtensa/include/asm/cacheflush.h b/arch/xtensa/include/asm/cacheflush.h index 569fec4f9a20..127cd48883c4 100644 --- a/arch/xtensa/include/asm/cacheflush.h +++ b/arch/xtensa/include/asm/cacheflush.h | |||
@@ -104,7 +104,8 @@ static inline void __invalidate_icache_page_alias(unsigned long virt, | |||
104 | #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 | 104 | #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 |
105 | extern void flush_dcache_page(struct page*); | 105 | extern void flush_dcache_page(struct page*); |
106 | extern void flush_cache_range(struct vm_area_struct*, ulong, ulong); | 106 | extern void flush_cache_range(struct vm_area_struct*, ulong, ulong); |
107 | extern void flush_cache_page(struct vm_area_struct*, unsigned long, unsigned long); | 107 | extern void flush_cache_page(struct vm_area_struct*, |
108 | unsigned long, unsigned long); | ||
108 | 109 | ||
109 | #else | 110 | #else |
110 | 111 | ||
diff --git a/arch/xtensa/include/asm/checksum.h b/arch/xtensa/include/asm/checksum.h index e4d831a30772..aed7ad68ca46 100644 --- a/arch/xtensa/include/asm/checksum.h +++ b/arch/xtensa/include/asm/checksum.h | |||
@@ -36,8 +36,9 @@ asmlinkage __wsum csum_partial(const void *buff, int len, __wsum sum); | |||
36 | * better 64-bit) boundary | 36 | * better 64-bit) boundary |
37 | */ | 37 | */ |
38 | 38 | ||
39 | asmlinkage __wsum csum_partial_copy_generic(const void *src, void *dst, int len, __wsum sum, | 39 | asmlinkage __wsum csum_partial_copy_generic(const void *src, void *dst, |
40 | int *src_err_ptr, int *dst_err_ptr); | 40 | int len, __wsum sum, |
41 | int *src_err_ptr, int *dst_err_ptr); | ||
41 | 42 | ||
42 | /* | 43 | /* |
43 | * Note: when you get a NULL pointer exception here this means someone | 44 | * Note: when you get a NULL pointer exception here this means someone |
@@ -54,7 +55,7 @@ __wsum csum_partial_copy_nocheck(const void *src, void *dst, | |||
54 | 55 | ||
55 | static inline | 56 | static inline |
56 | __wsum csum_partial_copy_from_user(const void __user *src, void *dst, | 57 | __wsum csum_partial_copy_from_user(const void __user *src, void *dst, |
57 | int len, __wsum sum, int *err_ptr) | 58 | int len, __wsum sum, int *err_ptr) |
58 | { | 59 | { |
59 | return csum_partial_copy_generic((__force const void *)src, dst, | 60 | return csum_partial_copy_generic((__force const void *)src, dst, |
60 | len, sum, err_ptr, NULL); | 61 | len, sum, err_ptr, NULL); |
@@ -112,7 +113,8 @@ static __inline__ __sum16 ip_fast_csum(const void *iph, unsigned int ihl) | |||
112 | /* Since the input registers which are loaded with iph and ihl | 113 | /* Since the input registers which are loaded with iph and ihl |
113 | are modified, we must also specify them as outputs, or gcc | 114 | are modified, we must also specify them as outputs, or gcc |
114 | will assume they contain their original values. */ | 115 | will assume they contain their original values. */ |
115 | : "=r" (sum), "=r" (iph), "=r" (ihl), "=&r" (tmp), "=&r" (endaddr) | 116 | : "=r" (sum), "=r" (iph), "=r" (ihl), "=&r" (tmp), |
117 | "=&r" (endaddr) | ||
116 | : "1" (iph), "2" (ihl) | 118 | : "1" (iph), "2" (ihl) |
117 | : "memory"); | 119 | : "memory"); |
118 | 120 | ||
@@ -168,7 +170,7 @@ static __inline__ __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, | |||
168 | 170 | ||
169 | static __inline__ __sum16 ip_compute_csum(const void *buff, int len) | 171 | static __inline__ __sum16 ip_compute_csum(const void *buff, int len) |
170 | { | 172 | { |
171 | return csum_fold (csum_partial(buff, len, 0)); | 173 | return csum_fold (csum_partial(buff, len, 0)); |
172 | } | 174 | } |
173 | 175 | ||
174 | #define _HAVE_ARCH_IPV6_CSUM | 176 | #define _HAVE_ARCH_IPV6_CSUM |
@@ -238,11 +240,12 @@ static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr, | |||
238 | * Copy and checksum to user | 240 | * Copy and checksum to user |
239 | */ | 241 | */ |
240 | #define HAVE_CSUM_COPY_USER | 242 | #define HAVE_CSUM_COPY_USER |
241 | static __inline__ __wsum csum_and_copy_to_user(const void *src, void __user *dst, | 243 | static __inline__ __wsum csum_and_copy_to_user(const void *src, |
242 | int len, __wsum sum, int *err_ptr) | 244 | void __user *dst, int len, |
245 | __wsum sum, int *err_ptr) | ||
243 | { | 246 | { |
244 | if (access_ok(VERIFY_WRITE, dst, len)) | 247 | if (access_ok(VERIFY_WRITE, dst, len)) |
245 | return csum_partial_copy_generic(src, dst, len, sum, NULL, err_ptr); | 248 | return csum_partial_copy_generic(src,dst,len,sum,NULL,err_ptr); |
246 | 249 | ||
247 | if (len) | 250 | if (len) |
248 | *err_ptr = -EFAULT; | 251 | *err_ptr = -EFAULT; |
diff --git a/arch/xtensa/include/asm/cmpxchg.h b/arch/xtensa/include/asm/cmpxchg.h index 64dad04a9d27..d9ab131bc1aa 100644 --- a/arch/xtensa/include/asm/cmpxchg.h +++ b/arch/xtensa/include/asm/cmpxchg.h | |||
@@ -22,17 +22,30 @@ | |||
22 | static inline unsigned long | 22 | static inline unsigned long |
23 | __cmpxchg_u32(volatile int *p, int old, int new) | 23 | __cmpxchg_u32(volatile int *p, int old, int new) |
24 | { | 24 | { |
25 | __asm__ __volatile__("rsil a15, "__stringify(LOCKLEVEL)"\n\t" | 25 | #if XCHAL_HAVE_S32C1I |
26 | "l32i %0, %1, 0 \n\t" | 26 | __asm__ __volatile__( |
27 | "bne %0, %2, 1f \n\t" | 27 | " wsr %2, scompare1\n" |
28 | "s32i %3, %1, 0 \n\t" | 28 | " s32c1i %0, %1, 0\n" |
29 | "1: \n\t" | 29 | : "+a" (new) |
30 | "wsr a15, ps \n\t" | 30 | : "a" (p), "a" (old) |
31 | "rsync \n\t" | 31 | : "memory" |
32 | : "=&a" (old) | 32 | ); |
33 | : "a" (p), "a" (old), "r" (new) | 33 | |
34 | : "a15", "memory"); | 34 | return new; |
35 | return old; | 35 | #else |
36 | __asm__ __volatile__( | ||
37 | " rsil a15, "__stringify(LOCKLEVEL)"\n" | ||
38 | " l32i %0, %1, 0\n" | ||
39 | " bne %0, %2, 1f\n" | ||
40 | " s32i %3, %1, 0\n" | ||
41 | "1:\n" | ||
42 | " wsr a15, ps\n" | ||
43 | " rsync\n" | ||
44 | : "=&a" (old) | ||
45 | : "a" (p), "a" (old), "r" (new) | ||
46 | : "a15", "memory"); | ||
47 | return old; | ||
48 | #endif | ||
36 | } | 49 | } |
37 | /* This function doesn't exist, so you'll get a linker error | 50 | /* This function doesn't exist, so you'll get a linker error |
38 | * if something tries to do an invalid cmpxchg(). */ | 51 | * if something tries to do an invalid cmpxchg(). */ |
@@ -93,19 +106,36 @@ static inline unsigned long __cmpxchg_local(volatile void *ptr, | |||
93 | 106 | ||
94 | static inline unsigned long xchg_u32(volatile int * m, unsigned long val) | 107 | static inline unsigned long xchg_u32(volatile int * m, unsigned long val) |
95 | { | 108 | { |
96 | unsigned long tmp; | 109 | #if XCHAL_HAVE_S32C1I |
97 | __asm__ __volatile__("rsil a15, "__stringify(LOCKLEVEL)"\n\t" | 110 | unsigned long tmp, result; |
98 | "l32i %0, %1, 0 \n\t" | 111 | __asm__ __volatile__( |
99 | "s32i %2, %1, 0 \n\t" | 112 | "1: l32i %1, %2, 0\n" |
100 | "wsr a15, ps \n\t" | 113 | " mov %0, %3\n" |
101 | "rsync \n\t" | 114 | " wsr %1, scompare1\n" |
102 | : "=&a" (tmp) | 115 | " s32c1i %0, %2, 0\n" |
103 | : "a" (m), "a" (val) | 116 | " bne %0, %1, 1b\n" |
104 | : "a15", "memory"); | 117 | : "=&a" (result), "=&a" (tmp) |
105 | return tmp; | 118 | : "a" (m), "a" (val) |
119 | : "memory" | ||
120 | ); | ||
121 | return result; | ||
122 | #else | ||
123 | unsigned long tmp; | ||
124 | __asm__ __volatile__( | ||
125 | " rsil a15, "__stringify(LOCKLEVEL)"\n" | ||
126 | " l32i %0, %1, 0\n" | ||
127 | " s32i %2, %1, 0\n" | ||
128 | " wsr a15, ps\n" | ||
129 | " rsync\n" | ||
130 | : "=&a" (tmp) | ||
131 | : "a" (m), "a" (val) | ||
132 | : "a15", "memory"); | ||
133 | return tmp; | ||
134 | #endif | ||
106 | } | 135 | } |
107 | 136 | ||
108 | #define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) | 137 | #define xchg(ptr,x) \ |
138 | ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) | ||
109 | 139 | ||
110 | /* | 140 | /* |
111 | * This only works if the compiler isn't horribly bad at optimizing. | 141 | * This only works if the compiler isn't horribly bad at optimizing. |
diff --git a/arch/xtensa/include/asm/current.h b/arch/xtensa/include/asm/current.h index 8d1eb5d78649..47e46dcf5d49 100644 --- a/arch/xtensa/include/asm/current.h +++ b/arch/xtensa/include/asm/current.h | |||
@@ -30,7 +30,7 @@ static inline struct task_struct *get_current(void) | |||
30 | 30 | ||
31 | #define GET_CURRENT(reg,sp) \ | 31 | #define GET_CURRENT(reg,sp) \ |
32 | GET_THREAD_INFO(reg,sp); \ | 32 | GET_THREAD_INFO(reg,sp); \ |
33 | l32i reg, reg, TI_TASK \ | 33 | l32i reg, reg, TI_TASK \ |
34 | 34 | ||
35 | #endif | 35 | #endif |
36 | 36 | ||
diff --git a/arch/xtensa/include/asm/delay.h b/arch/xtensa/include/asm/delay.h index 58c0a4fd4003..61fc5faeb46c 100644 --- a/arch/xtensa/include/asm/delay.h +++ b/arch/xtensa/include/asm/delay.h | |||
@@ -19,9 +19,9 @@ extern unsigned long loops_per_jiffy; | |||
19 | 19 | ||
20 | static inline void __delay(unsigned long loops) | 20 | static inline void __delay(unsigned long loops) |
21 | { | 21 | { |
22 | /* 2 cycles per loop. */ | 22 | /* 2 cycles per loop. */ |
23 | __asm__ __volatile__ ("1: addi %0, %0, -2; bgeui %0, 2, 1b" | 23 | __asm__ __volatile__ ("1: addi %0, %0, -2; bgeui %0, 2, 1b" |
24 | : "=r" (loops) : "0" (loops)); | 24 | : "=r" (loops) : "0" (loops)); |
25 | } | 25 | } |
26 | 26 | ||
27 | static __inline__ u32 xtensa_get_ccount(void) | 27 | static __inline__ u32 xtensa_get_ccount(void) |
@@ -46,4 +46,3 @@ static __inline__ void udelay (unsigned long usecs) | |||
46 | } | 46 | } |
47 | 47 | ||
48 | #endif | 48 | #endif |
49 | |||
diff --git a/arch/xtensa/include/asm/dma-mapping.h b/arch/xtensa/include/asm/dma-mapping.h index 492c95790ad5..4acb5feba1fb 100644 --- a/arch/xtensa/include/asm/dma-mapping.h +++ b/arch/xtensa/include/asm/dma-mapping.h | |||
@@ -16,6 +16,8 @@ | |||
16 | #include <linux/mm.h> | 16 | #include <linux/mm.h> |
17 | #include <linux/scatterlist.h> | 17 | #include <linux/scatterlist.h> |
18 | 18 | ||
19 | #define DMA_ERROR_CODE (~(dma_addr_t)0x0) | ||
20 | |||
19 | /* | 21 | /* |
20 | * DMA-consistent mapping functions. | 22 | * DMA-consistent mapping functions. |
21 | */ | 23 | */ |
@@ -98,8 +100,8 @@ dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, | |||
98 | } | 100 | } |
99 | 101 | ||
100 | static inline void | 102 | static inline void |
101 | dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size, | 103 | dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, |
102 | enum dma_data_direction direction) | 104 | size_t size, enum dma_data_direction direction) |
103 | { | 105 | { |
104 | consistent_sync((void *)bus_to_virt(dma_handle), size, direction); | 106 | consistent_sync((void *)bus_to_virt(dma_handle), size, direction); |
105 | } | 107 | } |
diff --git a/arch/xtensa/include/asm/elf.h b/arch/xtensa/include/asm/elf.h index 5293312bc6a4..264d5fa450d8 100644 --- a/arch/xtensa/include/asm/elf.h +++ b/arch/xtensa/include/asm/elf.h | |||
@@ -168,11 +168,11 @@ extern void xtensa_elf_core_copy_regs (xtensa_gregset_t *, struct pt_regs *); | |||
168 | */ | 168 | */ |
169 | 169 | ||
170 | #define ELF_PLAT_INIT(_r, load_addr) \ | 170 | #define ELF_PLAT_INIT(_r, load_addr) \ |
171 | do { _r->areg[0]=0; /*_r->areg[1]=0;*/ _r->areg[2]=0; _r->areg[3]=0; \ | 171 | do { _r->areg[0]=0; /*_r->areg[1]=0;*/ _r->areg[2]=0; _r->areg[3]=0; \ |
172 | _r->areg[4]=0; _r->areg[5]=0; _r->areg[6]=0; _r->areg[7]=0; \ | 172 | _r->areg[4]=0; _r->areg[5]=0; _r->areg[6]=0; _r->areg[7]=0; \ |
173 | _r->areg[8]=0; _r->areg[9]=0; _r->areg[10]=0; _r->areg[11]=0; \ | 173 | _r->areg[8]=0; _r->areg[9]=0; _r->areg[10]=0; _r->areg[11]=0; \ |
174 | _r->areg[12]=0; _r->areg[13]=0; _r->areg[14]=0; _r->areg[15]=0; \ | 174 | _r->areg[12]=0; _r->areg[13]=0; _r->areg[14]=0; _r->areg[15]=0; \ |
175 | } while (0) | 175 | } while (0) |
176 | 176 | ||
177 | typedef struct { | 177 | typedef struct { |
178 | xtregs_opt_t opt; | 178 | xtregs_opt_t opt; |
diff --git a/arch/xtensa/include/asm/highmem.h b/arch/xtensa/include/asm/highmem.h index 0a046ca5a687..80be15124697 100644 --- a/arch/xtensa/include/asm/highmem.h +++ b/arch/xtensa/include/asm/highmem.h | |||
@@ -14,4 +14,3 @@ | |||
14 | extern void flush_cache_kmaps(void); | 14 | extern void flush_cache_kmaps(void); |
15 | 15 | ||
16 | #endif | 16 | #endif |
17 | |||
diff --git a/arch/xtensa/include/asm/initialize_mmu.h b/arch/xtensa/include/asm/initialize_mmu.h new file mode 100644 index 000000000000..e1f8ba4061ed --- /dev/null +++ b/arch/xtensa/include/asm/initialize_mmu.h | |||
@@ -0,0 +1,55 @@ | |||
1 | /* | ||
2 | * arch/xtensa/include/asm/initialize_mmu.h | ||
3 | * | ||
4 | * Initializes MMU: | ||
5 | * | ||
6 | * For the new V3 MMU we remap the TLB from virtual == physical | ||
7 | * to the standard Linux mapping used in earlier MMU's. | ||
8 | * | ||
9 | * The the MMU we also support a new configuration register that | ||
10 | * specifies how the S32C1I instruction operates with the cache | ||
11 | * controller. | ||
12 | * | ||
13 | * This file is subject to the terms and conditions of the GNU General | ||
14 | * Public License. See the file "COPYING" in the main directory of | ||
15 | * this archive for more details. | ||
16 | * | ||
17 | * Copyright (C) 2008 - 2012 Tensilica, Inc. | ||
18 | * | ||
19 | * Marc Gauthier <marc@tensilica.com> | ||
20 | * Pete Delaney <piet@tensilica.com> | ||
21 | */ | ||
22 | |||
23 | #ifndef _XTENSA_INITIALIZE_MMU_H | ||
24 | #define _XTENSA_INITIALIZE_MMU_H | ||
25 | |||
26 | #ifdef __ASSEMBLY__ | ||
27 | |||
28 | #define XTENSA_HWVERSION_RC_2009_0 230000 | ||
29 | |||
30 | .macro initialize_mmu | ||
31 | |||
32 | #if XCHAL_HAVE_S32C1I && (XCHAL_HW_MIN_VERSION >= XTENSA_HWVERSION_RC_2009_0) | ||
33 | /* | ||
34 | * We Have Atomic Operation Control (ATOMCTL) Register; Initialize it. | ||
35 | * For details see Documentation/xtensa/atomctl.txt | ||
36 | */ | ||
37 | #if XCHAL_DCACHE_IS_COHERENT | ||
38 | movi a3, 0x25 /* For SMP/MX -- internal for writeback, | ||
39 | * RCW otherwise | ||
40 | */ | ||
41 | #else | ||
42 | movi a3, 0x29 /* non-MX -- Most cores use Std Memory | ||
43 | * Controlers which usually can't use RCW | ||
44 | */ | ||
45 | #endif | ||
46 | wsr a3, atomctl | ||
47 | #endif /* XCHAL_HAVE_S32C1I && | ||
48 | * (XCHAL_HW_MIN_VERSION >= XTENSA_HWVERSION_RC_2009_0) | ||
49 | */ | ||
50 | |||
51 | .endm | ||
52 | |||
53 | #endif /*__ASSEMBLY__*/ | ||
54 | |||
55 | #endif /* _XTENSA_INITIALIZE_MMU_H */ | ||
diff --git a/arch/xtensa/include/asm/io.h b/arch/xtensa/include/asm/io.h index e6be5b9091c2..700c2e6f2d25 100644 --- a/arch/xtensa/include/asm/io.h +++ b/arch/xtensa/include/asm/io.h | |||
@@ -62,6 +62,10 @@ static inline void __iomem *ioremap(unsigned long offset, unsigned long size) | |||
62 | static inline void iounmap(volatile void __iomem *addr) | 62 | static inline void iounmap(volatile void __iomem *addr) |
63 | { | 63 | { |
64 | } | 64 | } |
65 | |||
66 | #define virt_to_bus virt_to_phys | ||
67 | #define bus_to_virt phys_to_virt | ||
68 | |||
65 | #endif /* CONFIG_MMU */ | 69 | #endif /* CONFIG_MMU */ |
66 | 70 | ||
67 | /* | 71 | /* |
diff --git a/arch/xtensa/include/asm/mmu.h b/arch/xtensa/include/asm/mmu.h index 04890d6e2335..8554b2c8b17a 100644 --- a/arch/xtensa/include/asm/mmu.h +++ b/arch/xtensa/include/asm/mmu.h | |||
@@ -12,7 +12,7 @@ | |||
12 | #define _XTENSA_MMU_H | 12 | #define _XTENSA_MMU_H |
13 | 13 | ||
14 | #ifndef CONFIG_MMU | 14 | #ifndef CONFIG_MMU |
15 | #include <asm/nommu.h> | 15 | #include <asm-generic/mmu.h> |
16 | #else | 16 | #else |
17 | 17 | ||
18 | /* Default "unsigned long" context */ | 18 | /* Default "unsigned long" context */ |
diff --git a/arch/xtensa/include/asm/mmu_context.h b/arch/xtensa/include/asm/mmu_context.h index feb10af96519..d43525a286bb 100644 --- a/arch/xtensa/include/asm/mmu_context.h +++ b/arch/xtensa/include/asm/mmu_context.h | |||
@@ -107,7 +107,7 @@ activate_mm(struct mm_struct *prev, struct mm_struct *next) | |||
107 | 107 | ||
108 | 108 | ||
109 | static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, | 109 | static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, |
110 | struct task_struct *tsk) | 110 | struct task_struct *tsk) |
111 | { | 111 | { |
112 | unsigned long asid = asid_cache; | 112 | unsigned long asid = asid_cache; |
113 | 113 | ||
diff --git a/arch/xtensa/include/asm/nommu.h b/arch/xtensa/include/asm/nommu.h deleted file mode 100644 index dce2c438c5ba..000000000000 --- a/arch/xtensa/include/asm/nommu.h +++ /dev/null | |||
@@ -1,3 +0,0 @@ | |||
1 | typedef struct { | ||
2 | unsigned long end_brk; | ||
3 | } mm_context_t; | ||
diff --git a/arch/xtensa/include/asm/nommu_context.h b/arch/xtensa/include/asm/nommu_context.h index 599e7a2e729d..3407cf7989b7 100644 --- a/arch/xtensa/include/asm/nommu_context.h +++ b/arch/xtensa/include/asm/nommu_context.h | |||
@@ -2,7 +2,7 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) | |||
2 | { | 2 | { |
3 | } | 3 | } |
4 | 4 | ||
5 | static inline int init_new_context(struct task_struct *tsk, struct mm_struct *mm) | 5 | static inline int init_new_context(struct task_struct *tsk,struct mm_struct *mm) |
6 | { | 6 | { |
7 | return 0; | 7 | return 0; |
8 | } | 8 | } |
diff --git a/arch/xtensa/include/asm/page.h b/arch/xtensa/include/asm/page.h index 7a5591a71f85..47f582333f6b 100644 --- a/arch/xtensa/include/asm/page.h +++ b/arch/xtensa/include/asm/page.h | |||
@@ -29,19 +29,19 @@ | |||
29 | * PAGE_SHIFT determines the page size | 29 | * PAGE_SHIFT determines the page size |
30 | */ | 30 | */ |
31 | 31 | ||
32 | #define PAGE_SHIFT 12 | 32 | #define PAGE_SHIFT 12 |
33 | #define PAGE_SIZE (__XTENSA_UL_CONST(1) << PAGE_SHIFT) | 33 | #define PAGE_SIZE (__XTENSA_UL_CONST(1) << PAGE_SHIFT) |
34 | #define PAGE_MASK (~(PAGE_SIZE-1)) | 34 | #define PAGE_MASK (~(PAGE_SIZE-1)) |
35 | 35 | ||
36 | #ifdef CONFIG_MMU | 36 | #ifdef CONFIG_MMU |
37 | #define PAGE_OFFSET XCHAL_KSEG_CACHED_VADDR | 37 | #define PAGE_OFFSET XCHAL_KSEG_CACHED_VADDR |
38 | #define MAX_MEM_PFN XCHAL_KSEG_SIZE | 38 | #define MAX_MEM_PFN XCHAL_KSEG_SIZE |
39 | #else | 39 | #else |
40 | #define PAGE_OFFSET 0 | 40 | #define PAGE_OFFSET 0 |
41 | #define MAX_MEM_PFN (PLATFORM_DEFAULT_MEM_START + PLATFORM_DEFAULT_MEM_SIZE) | 41 | #define MAX_MEM_PFN (PLATFORM_DEFAULT_MEM_START + PLATFORM_DEFAULT_MEM_SIZE) |
42 | #endif | 42 | #endif |
43 | 43 | ||
44 | #define PGTABLE_START 0x80000000 | 44 | #define PGTABLE_START 0x80000000 |
45 | 45 | ||
46 | /* | 46 | /* |
47 | * Cache aliasing: | 47 | * Cache aliasing: |
@@ -161,7 +161,9 @@ extern void copy_user_page(void*, void*, unsigned long, struct page*); | |||
161 | 161 | ||
162 | #define __pa(x) ((unsigned long) (x) - PAGE_OFFSET) | 162 | #define __pa(x) ((unsigned long) (x) - PAGE_OFFSET) |
163 | #define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET)) | 163 | #define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET)) |
164 | #define pfn_valid(pfn) ((pfn) >= ARCH_PFN_OFFSET && ((pfn) - ARCH_PFN_OFFSET) < max_mapnr) | 164 | #define pfn_valid(pfn) \ |
165 | ((pfn) >= ARCH_PFN_OFFSET && ((pfn) - ARCH_PFN_OFFSET) < max_mapnr) | ||
166 | |||
165 | #ifdef CONFIG_DISCONTIGMEM | 167 | #ifdef CONFIG_DISCONTIGMEM |
166 | # error CONFIG_DISCONTIGMEM not supported | 168 | # error CONFIG_DISCONTIGMEM not supported |
167 | #endif | 169 | #endif |
diff --git a/arch/xtensa/include/asm/pci-bridge.h b/arch/xtensa/include/asm/pci-bridge.h index 00fcbd7c534a..0b68c76ec1e6 100644 --- a/arch/xtensa/include/asm/pci-bridge.h +++ b/arch/xtensa/include/asm/pci-bridge.h | |||
@@ -35,7 +35,7 @@ struct pci_space { | |||
35 | struct pci_controller { | 35 | struct pci_controller { |
36 | int index; /* used for pci_controller_num */ | 36 | int index; /* used for pci_controller_num */ |
37 | struct pci_controller *next; | 37 | struct pci_controller *next; |
38 | struct pci_bus *bus; | 38 | struct pci_bus *bus; |
39 | void *arch_data; | 39 | void *arch_data; |
40 | 40 | ||
41 | int first_busno; | 41 | int first_busno; |
diff --git a/arch/xtensa/include/asm/pci.h b/arch/xtensa/include/asm/pci.h index 05244f07dd31..614be031a79a 100644 --- a/arch/xtensa/include/asm/pci.h +++ b/arch/xtensa/include/asm/pci.h | |||
@@ -53,7 +53,7 @@ struct pci_dev; | |||
53 | 53 | ||
54 | /* Map a range of PCI memory or I/O space for a device into user space */ | 54 | /* Map a range of PCI memory or I/O space for a device into user space */ |
55 | int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma, | 55 | int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma, |
56 | enum pci_mmap_state mmap_state, int write_combine); | 56 | enum pci_mmap_state mmap_state, int write_combine); |
57 | 57 | ||
58 | /* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */ | 58 | /* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */ |
59 | #define HAVE_PCI_MMAP 1 | 59 | #define HAVE_PCI_MMAP 1 |
diff --git a/arch/xtensa/include/asm/pgalloc.h b/arch/xtensa/include/asm/pgalloc.h index 40cf9bceda2c..cf914c8c249a 100644 --- a/arch/xtensa/include/asm/pgalloc.h +++ b/arch/xtensa/include/asm/pgalloc.h | |||
@@ -42,7 +42,7 @@ static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) | |||
42 | 42 | ||
43 | extern struct kmem_cache *pgtable_cache; | 43 | extern struct kmem_cache *pgtable_cache; |
44 | 44 | ||
45 | static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, | 45 | static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, |
46 | unsigned long address) | 46 | unsigned long address) |
47 | { | 47 | { |
48 | return kmem_cache_alloc(pgtable_cache, GFP_KERNEL|__GFP_REPEAT); | 48 | return kmem_cache_alloc(pgtable_cache, GFP_KERNEL|__GFP_REPEAT); |
diff --git a/arch/xtensa/include/asm/pgtable.h b/arch/xtensa/include/asm/pgtable.h index b03c043ce75b..c90ea5bfa1b4 100644 --- a/arch/xtensa/include/asm/pgtable.h +++ b/arch/xtensa/include/asm/pgtable.h | |||
@@ -284,7 +284,7 @@ struct vm_area_struct; | |||
284 | 284 | ||
285 | static inline int | 285 | static inline int |
286 | ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, | 286 | ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, |
287 | pte_t *ptep) | 287 | pte_t *ptep) |
288 | { | 288 | { |
289 | pte_t pte = *ptep; | 289 | pte_t pte = *ptep; |
290 | if (!pte_young(pte)) | 290 | if (!pte_young(pte)) |
@@ -304,8 +304,8 @@ ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) | |||
304 | static inline void | 304 | static inline void |
305 | ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep) | 305 | ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep) |
306 | { | 306 | { |
307 | pte_t pte = *ptep; | 307 | pte_t pte = *ptep; |
308 | update_pte(ptep, pte_wrprotect(pte)); | 308 | update_pte(ptep, pte_wrprotect(pte)); |
309 | } | 309 | } |
310 | 310 | ||
311 | /* to find an entry in a kernel page-table-directory */ | 311 | /* to find an entry in a kernel page-table-directory */ |
@@ -399,7 +399,7 @@ extern void update_mmu_cache(struct vm_area_struct * vma, | |||
399 | */ | 399 | */ |
400 | 400 | ||
401 | #define io_remap_pfn_range(vma,from,pfn,size,prot) \ | 401 | #define io_remap_pfn_range(vma,from,pfn,size,prot) \ |
402 | remap_pfn_range(vma, from, pfn, size, prot) | 402 | remap_pfn_range(vma, from, pfn, size, prot) |
403 | 403 | ||
404 | typedef pte_t *pte_addr_t; | 404 | typedef pte_t *pte_addr_t; |
405 | 405 | ||
diff --git a/arch/xtensa/include/asm/platform.h b/arch/xtensa/include/asm/platform.h index 7d936e58e9be..ec098b68fb9a 100644 --- a/arch/xtensa/include/asm/platform.h +++ b/arch/xtensa/include/asm/platform.h | |||
@@ -75,4 +75,3 @@ extern int platform_pcibios_fixup (void); | |||
75 | extern void platform_calibrate_ccount (void); | 75 | extern void platform_calibrate_ccount (void); |
76 | 76 | ||
77 | #endif /* _XTENSA_PLATFORM_H */ | 77 | #endif /* _XTENSA_PLATFORM_H */ |
78 | |||
diff --git a/arch/xtensa/include/asm/processor.h b/arch/xtensa/include/asm/processor.h index 5c371d8d4528..e5fb6b0abdf4 100644 --- a/arch/xtensa/include/asm/processor.h +++ b/arch/xtensa/include/asm/processor.h | |||
@@ -89,7 +89,7 @@ | |||
89 | #define MAKE_PC_FROM_RA(ra,sp) (((ra) & 0x3fffffff) | ((sp) & 0xc0000000)) | 89 | #define MAKE_PC_FROM_RA(ra,sp) (((ra) & 0x3fffffff) | ((sp) & 0xc0000000)) |
90 | 90 | ||
91 | typedef struct { | 91 | typedef struct { |
92 | unsigned long seg; | 92 | unsigned long seg; |
93 | } mm_segment_t; | 93 | } mm_segment_t; |
94 | 94 | ||
95 | struct thread_struct { | 95 | struct thread_struct { |
@@ -145,13 +145,14 @@ struct thread_struct { | |||
145 | * set_thread_state in signal.c depends on it. | 145 | * set_thread_state in signal.c depends on it. |
146 | */ | 146 | */ |
147 | #define USER_PS_VALUE ((1 << PS_WOE_BIT) | \ | 147 | #define USER_PS_VALUE ((1 << PS_WOE_BIT) | \ |
148 | (1 << PS_CALLINC_SHIFT) | \ | 148 | (1 << PS_CALLINC_SHIFT) | \ |
149 | (USER_RING << PS_RING_SHIFT) | \ | 149 | (USER_RING << PS_RING_SHIFT) | \ |
150 | (1 << PS_UM_BIT) | \ | 150 | (1 << PS_UM_BIT) | \ |
151 | (1 << PS_EXCM_BIT)) | 151 | (1 << PS_EXCM_BIT)) |
152 | 152 | ||
153 | /* Clearing a0 terminates the backtrace. */ | 153 | /* Clearing a0 terminates the backtrace. */ |
154 | #define start_thread(regs, new_pc, new_sp) \ | 154 | #define start_thread(regs, new_pc, new_sp) \ |
155 | memset(regs, 0, sizeof(*regs)); \ | ||
155 | regs->pc = new_pc; \ | 156 | regs->pc = new_pc; \ |
156 | regs->ps = USER_PS_VALUE; \ | 157 | regs->ps = USER_PS_VALUE; \ |
157 | regs->areg[1] = new_sp; \ | 158 | regs->areg[1] = new_sp; \ |
@@ -168,9 +169,6 @@ struct mm_struct; | |||
168 | /* Free all resources held by a thread. */ | 169 | /* Free all resources held by a thread. */ |
169 | #define release_thread(thread) do { } while(0) | 170 | #define release_thread(thread) do { } while(0) |
170 | 171 | ||
171 | /* Create a kernel thread without removing it from tasklists */ | ||
172 | extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); | ||
173 | |||
174 | /* Copy and release all segment info associated with a VM */ | 172 | /* Copy and release all segment info associated with a VM */ |
175 | #define copy_segments(p, mm) do { } while(0) | 173 | #define copy_segments(p, mm) do { } while(0) |
176 | #define release_segments(mm) do { } while(0) | 174 | #define release_segments(mm) do { } while(0) |
diff --git a/arch/xtensa/include/asm/prom.h b/arch/xtensa/include/asm/prom.h new file mode 100644 index 000000000000..f3d7cd2c0de7 --- /dev/null +++ b/arch/xtensa/include/asm/prom.h | |||
@@ -0,0 +1,6 @@ | |||
1 | #ifndef _XTENSA_ASM_PROM_H | ||
2 | #define _XTENSA_ASM_PROM_H | ||
3 | |||
4 | #define HAVE_ARCH_DEVTREE_FIXUPS | ||
5 | |||
6 | #endif /* _XTENSA_ASM_PROM_H */ | ||
diff --git a/arch/xtensa/include/asm/ptrace.h b/arch/xtensa/include/asm/ptrace.h index da21c17f23aa..682b1deac1f2 100644 --- a/arch/xtensa/include/asm/ptrace.h +++ b/arch/xtensa/include/asm/ptrace.h | |||
@@ -37,7 +37,7 @@ struct pt_regs { | |||
37 | unsigned long windowstart; /* 52 */ | 37 | unsigned long windowstart; /* 52 */ |
38 | unsigned long syscall; /* 56 */ | 38 | unsigned long syscall; /* 56 */ |
39 | unsigned long icountlevel; /* 60 */ | 39 | unsigned long icountlevel; /* 60 */ |
40 | int reserved[1]; /* 64 */ | 40 | unsigned long scompare1; /* 64 */ |
41 | 41 | ||
42 | /* Additional configurable registers that are used by the compiler. */ | 42 | /* Additional configurable registers that are used by the compiler. */ |
43 | xtregs_opt_t xtregs_opt; | 43 | xtregs_opt_t xtregs_opt; |
@@ -55,7 +55,7 @@ struct pt_regs { | |||
55 | 55 | ||
56 | # define arch_has_single_step() (1) | 56 | # define arch_has_single_step() (1) |
57 | # define task_pt_regs(tsk) ((struct pt_regs*) \ | 57 | # define task_pt_regs(tsk) ((struct pt_regs*) \ |
58 | (task_stack_page(tsk) + KERNEL_STACK_SIZE - (XCHAL_NUM_AREGS-16)*4) - 1) | 58 | (task_stack_page(tsk) + KERNEL_STACK_SIZE - (XCHAL_NUM_AREGS-16)*4) - 1) |
59 | # define user_mode(regs) (((regs)->ps & 0x00000020)!=0) | 59 | # define user_mode(regs) (((regs)->ps & 0x00000020)!=0) |
60 | # define instruction_pointer(regs) ((regs)->pc) | 60 | # define instruction_pointer(regs) ((regs)->pc) |
61 | 61 | ||
@@ -63,6 +63,8 @@ struct pt_regs { | |||
63 | # define profile_pc(regs) instruction_pointer(regs) | 63 | # define profile_pc(regs) instruction_pointer(regs) |
64 | # endif | 64 | # endif |
65 | 65 | ||
66 | #define user_stack_pointer(regs) ((regs)->areg[1]) | ||
67 | |||
66 | #else /* __ASSEMBLY__ */ | 68 | #else /* __ASSEMBLY__ */ |
67 | 69 | ||
68 | # include <asm/asm-offsets.h> | 70 | # include <asm/asm-offsets.h> |
diff --git a/arch/xtensa/include/asm/regs.h b/arch/xtensa/include/asm/regs.h index 8a8aa61ccc8d..76096a4e5b8d 100644 --- a/arch/xtensa/include/asm/regs.h +++ b/arch/xtensa/include/asm/regs.h | |||
@@ -52,6 +52,10 @@ | |||
52 | #define EXCCAUSE_SPECULATION 7 | 52 | #define EXCCAUSE_SPECULATION 7 |
53 | #define EXCCAUSE_PRIVILEGED 8 | 53 | #define EXCCAUSE_PRIVILEGED 8 |
54 | #define EXCCAUSE_UNALIGNED 9 | 54 | #define EXCCAUSE_UNALIGNED 9 |
55 | #define EXCCAUSE_INSTR_DATA_ERROR 12 | ||
56 | #define EXCCAUSE_LOAD_STORE_DATA_ERROR 13 | ||
57 | #define EXCCAUSE_INSTR_ADDR_ERROR 14 | ||
58 | #define EXCCAUSE_LOAD_STORE_ADDR_ERROR 15 | ||
55 | #define EXCCAUSE_ITLB_MISS 16 | 59 | #define EXCCAUSE_ITLB_MISS 16 |
56 | #define EXCCAUSE_ITLB_MULTIHIT 17 | 60 | #define EXCCAUSE_ITLB_MULTIHIT 17 |
57 | #define EXCCAUSE_ITLB_PRIVILEGE 18 | 61 | #define EXCCAUSE_ITLB_PRIVILEGE 18 |
@@ -105,4 +109,3 @@ | |||
105 | #define DEBUGCAUSE_ICOUNT_BIT 0 /* ICOUNT would incr. to zero */ | 109 | #define DEBUGCAUSE_ICOUNT_BIT 0 /* ICOUNT would incr. to zero */ |
106 | 110 | ||
107 | #endif /* _XTENSA_SPECREG_H */ | 111 | #endif /* _XTENSA_SPECREG_H */ |
108 | |||
diff --git a/arch/xtensa/include/asm/signal.h b/arch/xtensa/include/asm/signal.h index 72fd44c85b70..6f586bd90e18 100644 --- a/arch/xtensa/include/asm/signal.h +++ b/arch/xtensa/include/asm/signal.h | |||
@@ -27,7 +27,6 @@ struct k_sigaction { | |||
27 | }; | 27 | }; |
28 | 28 | ||
29 | #include <asm/sigcontext.h> | 29 | #include <asm/sigcontext.h> |
30 | #define ptrace_signal_deliver(regs, cookie) do { } while (0) | ||
31 | 30 | ||
32 | #endif /* __ASSEMBLY__ */ | 31 | #endif /* __ASSEMBLY__ */ |
33 | #endif /* _XTENSA_SIGNAL_H */ | 32 | #endif /* _XTENSA_SIGNAL_H */ |
diff --git a/arch/xtensa/include/asm/spinlock.h b/arch/xtensa/include/asm/spinlock.h index 8ff23649581b..03975906b36f 100644 --- a/arch/xtensa/include/asm/spinlock.h +++ b/arch/xtensa/include/asm/spinlock.h | |||
@@ -11,6 +11,192 @@ | |||
11 | #ifndef _XTENSA_SPINLOCK_H | 11 | #ifndef _XTENSA_SPINLOCK_H |
12 | #define _XTENSA_SPINLOCK_H | 12 | #define _XTENSA_SPINLOCK_H |
13 | 13 | ||
14 | #include <linux/spinlock.h> | 14 | /* |
15 | * spinlock | ||
16 | * | ||
17 | * There is at most one owner of a spinlock. There are not different | ||
18 | * types of spinlock owners like there are for rwlocks (see below). | ||
19 | * | ||
20 | * When trying to obtain a spinlock, the function "spins" forever, or busy- | ||
21 | * waits, until the lock is obtained. When spinning, presumably some other | ||
22 | * owner will soon give up the spinlock making it available to others. Use | ||
23 | * the trylock functions to avoid spinning forever. | ||
24 | * | ||
25 | * possible values: | ||
26 | * | ||
27 | * 0 nobody owns the spinlock | ||
28 | * 1 somebody owns the spinlock | ||
29 | */ | ||
30 | |||
31 | #define __raw_spin_is_locked(x) ((x)->slock != 0) | ||
32 | #define __raw_spin_unlock_wait(lock) \ | ||
33 | do { while (__raw_spin_is_locked(lock)) cpu_relax(); } while (0) | ||
34 | |||
35 | #define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock) | ||
36 | |||
37 | static inline void __raw_spin_lock(raw_spinlock_t *lock) | ||
38 | { | ||
39 | unsigned long tmp; | ||
40 | |||
41 | __asm__ __volatile__( | ||
42 | " movi %0, 0\n" | ||
43 | " wsr %0, scompare1\n" | ||
44 | "1: movi %0, 1\n" | ||
45 | " s32c1i %0, %1, 0\n" | ||
46 | " bnez %0, 1b\n" | ||
47 | : "=&a" (tmp) | ||
48 | : "a" (&lock->slock) | ||
49 | : "memory"); | ||
50 | } | ||
51 | |||
52 | /* Returns 1 if the lock is obtained, 0 otherwise. */ | ||
53 | |||
54 | static inline int __raw_spin_trylock(raw_spinlock_t *lock) | ||
55 | { | ||
56 | unsigned long tmp; | ||
57 | |||
58 | __asm__ __volatile__( | ||
59 | " movi %0, 0\n" | ||
60 | " wsr %0, scompare1\n" | ||
61 | " movi %0, 1\n" | ||
62 | " s32c1i %0, %1, 0\n" | ||
63 | : "=&a" (tmp) | ||
64 | : "a" (&lock->slock) | ||
65 | : "memory"); | ||
66 | |||
67 | return tmp == 0 ? 1 : 0; | ||
68 | } | ||
69 | |||
70 | static inline void __raw_spin_unlock(raw_spinlock_t *lock) | ||
71 | { | ||
72 | unsigned long tmp; | ||
73 | |||
74 | __asm__ __volatile__( | ||
75 | " movi %0, 0\n" | ||
76 | " s32ri %0, %1, 0\n" | ||
77 | : "=&a" (tmp) | ||
78 | : "a" (&lock->slock) | ||
79 | : "memory"); | ||
80 | } | ||
81 | |||
82 | /* | ||
83 | * rwlock | ||
84 | * | ||
85 | * Read-write locks are really a more flexible spinlock. They allow | ||
86 | * multiple readers but only one writer. Write ownership is exclusive | ||
87 | * (i.e., all other readers and writers are blocked from ownership while | ||
88 | * there is a write owner). These rwlocks are unfair to writers. Writers | ||
89 | * can be starved for an indefinite time by readers. | ||
90 | * | ||
91 | * possible values: | ||
92 | * | ||
93 | * 0 nobody owns the rwlock | ||
94 | * >0 one or more readers own the rwlock | ||
95 | * (the positive value is the actual number of readers) | ||
96 | * 0x80000000 one writer owns the rwlock, no other writers, no readers | ||
97 | */ | ||
98 | |||
99 | #define __raw_write_can_lock(x) ((x)->lock == 0) | ||
100 | |||
101 | static inline void __raw_write_lock(raw_rwlock_t *rw) | ||
102 | { | ||
103 | unsigned long tmp; | ||
104 | |||
105 | __asm__ __volatile__( | ||
106 | " movi %0, 0\n" | ||
107 | " wsr %0, scompare1\n" | ||
108 | "1: movi %0, 1\n" | ||
109 | " slli %0, %0, 31\n" | ||
110 | " s32c1i %0, %1, 0\n" | ||
111 | " bnez %0, 1b\n" | ||
112 | : "=&a" (tmp) | ||
113 | : "a" (&rw->lock) | ||
114 | : "memory"); | ||
115 | } | ||
116 | |||
117 | /* Returns 1 if the lock is obtained, 0 otherwise. */ | ||
118 | |||
119 | static inline int __raw_write_trylock(raw_rwlock_t *rw) | ||
120 | { | ||
121 | unsigned long tmp; | ||
122 | |||
123 | __asm__ __volatile__( | ||
124 | " movi %0, 0\n" | ||
125 | " wsr %0, scompare1\n" | ||
126 | " movi %0, 1\n" | ||
127 | " slli %0, %0, 31\n" | ||
128 | " s32c1i %0, %1, 0\n" | ||
129 | : "=&a" (tmp) | ||
130 | : "a" (&rw->lock) | ||
131 | : "memory"); | ||
132 | |||
133 | return tmp == 0 ? 1 : 0; | ||
134 | } | ||
135 | |||
136 | static inline void __raw_write_unlock(raw_rwlock_t *rw) | ||
137 | { | ||
138 | unsigned long tmp; | ||
139 | |||
140 | __asm__ __volatile__( | ||
141 | " movi %0, 0\n" | ||
142 | " s32ri %0, %1, 0\n" | ||
143 | : "=&a" (tmp) | ||
144 | : "a" (&rw->lock) | ||
145 | : "memory"); | ||
146 | } | ||
147 | |||
148 | static inline void __raw_read_lock(raw_rwlock_t *rw) | ||
149 | { | ||
150 | unsigned long tmp; | ||
151 | unsigned long result; | ||
152 | |||
153 | __asm__ __volatile__( | ||
154 | "1: l32i %1, %2, 0\n" | ||
155 | " bltz %1, 1b\n" | ||
156 | " wsr %1, scompare1\n" | ||
157 | " addi %0, %1, 1\n" | ||
158 | " s32c1i %0, %2, 0\n" | ||
159 | " bne %0, %1, 1b\n" | ||
160 | : "=&a" (result), "=&a" (tmp) | ||
161 | : "a" (&rw->lock) | ||
162 | : "memory"); | ||
163 | } | ||
164 | |||
165 | /* Returns 1 if the lock is obtained, 0 otherwise. */ | ||
166 | |||
167 | static inline int __raw_read_trylock(raw_rwlock_t *rw) | ||
168 | { | ||
169 | unsigned long result; | ||
170 | unsigned long tmp; | ||
171 | |||
172 | __asm__ __volatile__( | ||
173 | " l32i %1, %2, 0\n" | ||
174 | " addi %0, %1, 1\n" | ||
175 | " bltz %0, 1f\n" | ||
176 | " wsr %1, scompare1\n" | ||
177 | " s32c1i %0, %2, 0\n" | ||
178 | " sub %0, %0, %1\n" | ||
179 | "1:\n" | ||
180 | : "=&a" (result), "=&a" (tmp) | ||
181 | : "a" (&rw->lock) | ||
182 | : "memory"); | ||
183 | |||
184 | return result == 0; | ||
185 | } | ||
186 | |||
187 | static inline void __raw_read_unlock(raw_rwlock_t *rw) | ||
188 | { | ||
189 | unsigned long tmp1, tmp2; | ||
190 | |||
191 | __asm__ __volatile__( | ||
192 | "1: l32i %1, %2, 0\n" | ||
193 | " addi %0, %1, -1\n" | ||
194 | " wsr %1, scompare1\n" | ||
195 | " s32c1i %0, %2, 0\n" | ||
196 | " bne %0, %1, 1b\n" | ||
197 | : "=&a" (tmp1), "=&a" (tmp2) | ||
198 | : "a" (&rw->lock) | ||
199 | : "memory"); | ||
200 | } | ||
15 | 201 | ||
16 | #endif /* _XTENSA_SPINLOCK_H */ | 202 | #endif /* _XTENSA_SPINLOCK_H */ |
diff --git a/arch/xtensa/include/asm/syscall.h b/arch/xtensa/include/asm/syscall.h index c1dacca312f3..8d5e47fad095 100644 --- a/arch/xtensa/include/asm/syscall.h +++ b/arch/xtensa/include/asm/syscall.h | |||
@@ -10,8 +10,6 @@ | |||
10 | 10 | ||
11 | struct pt_regs; | 11 | struct pt_regs; |
12 | struct sigaction; | 12 | struct sigaction; |
13 | asmlinkage long xtensa_execve(char*, char**, char**, struct pt_regs*); | ||
14 | asmlinkage long xtensa_clone(unsigned long, unsigned long, struct pt_regs*); | ||
15 | asmlinkage long xtensa_ptrace(long, long, long, long); | 13 | asmlinkage long xtensa_ptrace(long, long, long, long); |
16 | asmlinkage long xtensa_sigreturn(struct pt_regs*); | 14 | asmlinkage long xtensa_sigreturn(struct pt_regs*); |
17 | asmlinkage long xtensa_rt_sigreturn(struct pt_regs*); | 15 | asmlinkage long xtensa_rt_sigreturn(struct pt_regs*); |
@@ -27,9 +25,10 @@ asmlinkage long xtensa_fadvise64_64(int, int, | |||
27 | /* Should probably move to linux/syscalls.h */ | 25 | /* Should probably move to linux/syscalls.h */ |
28 | struct pollfd; | 26 | struct pollfd; |
29 | asmlinkage long sys_pselect6(int n, fd_set __user *inp, fd_set __user *outp, | 27 | asmlinkage long sys_pselect6(int n, fd_set __user *inp, fd_set __user *outp, |
30 | fd_set __user *exp, struct timespec __user *tsp, void __user *sig); | 28 | fd_set __user *exp, struct timespec __user *tsp, |
29 | void __user *sig); | ||
31 | asmlinkage long sys_ppoll(struct pollfd __user *ufds, unsigned int nfds, | 30 | asmlinkage long sys_ppoll(struct pollfd __user *ufds, unsigned int nfds, |
32 | struct timespec __user *tsp, const sigset_t __user *sigmask, | 31 | struct timespec __user *tsp, |
33 | size_t sigsetsize); | 32 | const sigset_t __user *sigmask, |
34 | asmlinkage long sys_rt_sigsuspend(sigset_t __user *unewset, | 33 | size_t sigsetsize); |
35 | size_t sigsetsize); | 34 | asmlinkage long sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize); |
diff --git a/arch/xtensa/include/asm/traps.h b/arch/xtensa/include/asm/traps.h new file mode 100644 index 000000000000..54f70440185e --- /dev/null +++ b/arch/xtensa/include/asm/traps.h | |||
@@ -0,0 +1,23 @@ | |||
1 | /* | ||
2 | * arch/xtensa/include/asm/traps.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) 2012 Tensilica Inc. | ||
9 | */ | ||
10 | #ifndef _XTENSA_TRAPS_H | ||
11 | #define _XTENSA_TRAPS_H | ||
12 | |||
13 | #include <asm/ptrace.h> | ||
14 | |||
15 | /* | ||
16 | * handler must be either of the following: | ||
17 | * void (*)(struct pt_regs *regs); | ||
18 | * void (*)(struct pt_regs *regs, unsigned long exccause); | ||
19 | */ | ||
20 | extern void * __init trap_set_handler(int cause, void *handler); | ||
21 | extern void do_unhandled(struct pt_regs *regs, unsigned long exccause); | ||
22 | |||
23 | #endif /* _XTENSA_TRAPS_H */ | ||
diff --git a/arch/xtensa/include/asm/uaccess.h b/arch/xtensa/include/asm/uaccess.h index 6e4bb3b791ab..fd686dc45d1a 100644 --- a/arch/xtensa/include/asm/uaccess.h +++ b/arch/xtensa/include/asm/uaccess.h | |||
@@ -180,7 +180,8 @@ | |||
180 | #define segment_eq(a,b) ((a).seg == (b).seg) | 180 | #define segment_eq(a,b) ((a).seg == (b).seg) |
181 | 181 | ||
182 | #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS)) | 182 | #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS)) |
183 | #define __user_ok(addr,size) (((size) <= TASK_SIZE)&&((addr) <= TASK_SIZE-(size))) | 183 | #define __user_ok(addr,size) \ |
184 | (((size) <= TASK_SIZE)&&((addr) <= TASK_SIZE-(size))) | ||
184 | #define __access_ok(addr,size) (__kernel_ok || __user_ok((addr),(size))) | 185 | #define __access_ok(addr,size) (__kernel_ok || __user_ok((addr),(size))) |
185 | #define access_ok(type,addr,size) __access_ok((unsigned long)(addr),(size)) | 186 | #define access_ok(type,addr,size) __access_ok((unsigned long)(addr),(size)) |
186 | 187 | ||
@@ -234,10 +235,10 @@ do { \ | |||
234 | int __cb; \ | 235 | int __cb; \ |
235 | retval = 0; \ | 236 | retval = 0; \ |
236 | switch (size) { \ | 237 | switch (size) { \ |
237 | case 1: __put_user_asm(x,ptr,retval,1,"s8i",__cb); break; \ | 238 | case 1: __put_user_asm(x,ptr,retval,1,"s8i",__cb); break; \ |
238 | case 2: __put_user_asm(x,ptr,retval,2,"s16i",__cb); break; \ | 239 | case 2: __put_user_asm(x,ptr,retval,2,"s16i",__cb); break; \ |
239 | case 4: __put_user_asm(x,ptr,retval,4,"s32i",__cb); break; \ | 240 | case 4: __put_user_asm(x,ptr,retval,4,"s32i",__cb); break; \ |
240 | case 8: { \ | 241 | case 8: { \ |
241 | __typeof__(*ptr) __v64 = x; \ | 242 | __typeof__(*ptr) __v64 = x; \ |
242 | retval = __copy_to_user(ptr,&__v64,8); \ | 243 | retval = __copy_to_user(ptr,&__v64,8); \ |
243 | break; \ | 244 | break; \ |
@@ -291,7 +292,7 @@ do { \ | |||
291 | * __check_align_* macros still work. | 292 | * __check_align_* macros still work. |
292 | */ | 293 | */ |
293 | #define __put_user_asm(x, addr, err, align, insn, cb) \ | 294 | #define __put_user_asm(x, addr, err, align, insn, cb) \ |
294 | __asm__ __volatile__( \ | 295 | __asm__ __volatile__( \ |
295 | __check_align_##align \ | 296 | __check_align_##align \ |
296 | "1: "insn" %2, %3, 0 \n" \ | 297 | "1: "insn" %2, %3, 0 \n" \ |
297 | "2: \n" \ | 298 | "2: \n" \ |
@@ -301,8 +302,8 @@ do { \ | |||
301 | " .long 2b \n" \ | 302 | " .long 2b \n" \ |
302 | "5: \n" \ | 303 | "5: \n" \ |
303 | " l32r %1, 4b \n" \ | 304 | " l32r %1, 4b \n" \ |
304 | " movi %0, %4 \n" \ | 305 | " movi %0, %4 \n" \ |
305 | " jx %1 \n" \ | 306 | " jx %1 \n" \ |
306 | " .previous \n" \ | 307 | " .previous \n" \ |
307 | " .section __ex_table,\"a\" \n" \ | 308 | " .section __ex_table,\"a\" \n" \ |
308 | " .long 1b, 5b \n" \ | 309 | " .long 1b, 5b \n" \ |
@@ -334,13 +335,13 @@ extern long __get_user_bad(void); | |||
334 | do { \ | 335 | do { \ |
335 | int __cb; \ | 336 | int __cb; \ |
336 | retval = 0; \ | 337 | retval = 0; \ |
337 | switch (size) { \ | 338 | switch (size) { \ |
338 | case 1: __get_user_asm(x,ptr,retval,1,"l8ui",__cb); break; \ | 339 | case 1: __get_user_asm(x,ptr,retval,1,"l8ui",__cb); break; \ |
339 | case 2: __get_user_asm(x,ptr,retval,2,"l16ui",__cb); break; \ | 340 | case 2: __get_user_asm(x,ptr,retval,2,"l16ui",__cb); break; \ |
340 | case 4: __get_user_asm(x,ptr,retval,4,"l32i",__cb); break; \ | 341 | case 4: __get_user_asm(x,ptr,retval,4,"l32i",__cb); break; \ |
341 | case 8: retval = __copy_from_user(&x,ptr,8); break; \ | 342 | case 8: retval = __copy_from_user(&x,ptr,8); break; \ |
342 | default: (x) = __get_user_bad(); \ | 343 | default: (x) = __get_user_bad(); \ |
343 | } \ | 344 | } \ |
344 | } while (0) | 345 | } while (0) |
345 | 346 | ||
346 | 347 | ||
@@ -349,7 +350,7 @@ do { \ | |||
349 | * __check_align_* macros still work. | 350 | * __check_align_* macros still work. |
350 | */ | 351 | */ |
351 | #define __get_user_asm(x, addr, err, align, insn, cb) \ | 352 | #define __get_user_asm(x, addr, err, align, insn, cb) \ |
352 | __asm__ __volatile__( \ | 353 | __asm__ __volatile__( \ |
353 | __check_align_##align \ | 354 | __check_align_##align \ |
354 | "1: "insn" %2, %3, 0 \n" \ | 355 | "1: "insn" %2, %3, 0 \n" \ |
355 | "2: \n" \ | 356 | "2: \n" \ |
@@ -360,8 +361,8 @@ do { \ | |||
360 | "5: \n" \ | 361 | "5: \n" \ |
361 | " l32r %1, 4b \n" \ | 362 | " l32r %1, 4b \n" \ |
362 | " movi %2, 0 \n" \ | 363 | " movi %2, 0 \n" \ |
363 | " movi %0, %4 \n" \ | 364 | " movi %0, %4 \n" \ |
364 | " jx %1 \n" \ | 365 | " jx %1 \n" \ |
365 | " .previous \n" \ | 366 | " .previous \n" \ |
366 | " .section __ex_table,\"a\" \n" \ | 367 | " .section __ex_table,\"a\" \n" \ |
367 | " .long 1b, 5b \n" \ | 368 | " .long 1b, 5b \n" \ |
@@ -421,8 +422,10 @@ __generic_copy_from_user(void *to, const void *from, unsigned long n) | |||
421 | 422 | ||
422 | #define copy_to_user(to,from,n) __generic_copy_to_user((to),(from),(n)) | 423 | #define copy_to_user(to,from,n) __generic_copy_to_user((to),(from),(n)) |
423 | #define copy_from_user(to,from,n) __generic_copy_from_user((to),(from),(n)) | 424 | #define copy_from_user(to,from,n) __generic_copy_from_user((to),(from),(n)) |
424 | #define __copy_to_user(to,from,n) __generic_copy_to_user_nocheck((to),(from),(n)) | 425 | #define __copy_to_user(to,from,n) \ |
425 | #define __copy_from_user(to,from,n) __generic_copy_from_user_nocheck((to),(from),(n)) | 426 | __generic_copy_to_user_nocheck((to),(from),(n)) |
427 | #define __copy_from_user(to,from,n) \ | ||
428 | __generic_copy_from_user_nocheck((to),(from),(n)) | ||
426 | #define __copy_to_user_inatomic __copy_to_user | 429 | #define __copy_to_user_inatomic __copy_to_user |
427 | #define __copy_from_user_inatomic __copy_from_user | 430 | #define __copy_from_user_inatomic __copy_from_user |
428 | 431 | ||
diff --git a/arch/xtensa/include/asm/unistd.h b/arch/xtensa/include/asm/unistd.h index 9ef1c31d2c83..eb63ea87815c 100644 --- a/arch/xtensa/include/asm/unistd.h +++ b/arch/xtensa/include/asm/unistd.h | |||
@@ -1,16 +1,9 @@ | |||
1 | /* | 1 | #ifndef _XTENSA_UNISTD_H |
2 | * include/asm-xtensa/unistd.h | 2 | #define _XTENSA_UNISTD_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) 2001 - 2005 Tensilica Inc. | ||
9 | */ | ||
10 | 3 | ||
4 | #define __ARCH_WANT_SYS_CLONE | ||
11 | #include <uapi/asm/unistd.h> | 5 | #include <uapi/asm/unistd.h> |
12 | 6 | ||
13 | |||
14 | /* | 7 | /* |
15 | * "Conditional" syscalls | 8 | * "Conditional" syscalls |
16 | * | 9 | * |
@@ -37,3 +30,5 @@ | |||
37 | #define __IGNORE_mmap /* use mmap2 */ | 30 | #define __IGNORE_mmap /* use mmap2 */ |
38 | #define __IGNORE_vfork /* use clone */ | 31 | #define __IGNORE_vfork /* use clone */ |
39 | #define __IGNORE_fadvise64 /* use fadvise64_64 */ | 32 | #define __IGNORE_fadvise64 /* use fadvise64_64 */ |
33 | |||
34 | #endif /* _XTENSA_UNISTD_H */ | ||
diff --git a/arch/xtensa/include/uapi/asm/ioctls.h b/arch/xtensa/include/uapi/asm/ioctls.h index 2aa4cd9f0cec..b4cb1100c0fb 100644 --- a/arch/xtensa/include/uapi/asm/ioctls.h +++ b/arch/xtensa/include/uapi/asm/ioctls.h | |||
@@ -101,6 +101,9 @@ | |||
101 | #define TIOCGDEV _IOR('T',0x32, unsigned int) /* Get primary device node of /dev/console */ | 101 | #define TIOCGDEV _IOR('T',0x32, unsigned int) /* Get primary device node of /dev/console */ |
102 | #define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ | 102 | #define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ |
103 | #define TIOCVHANGUP _IO('T', 0x37) | 103 | #define TIOCVHANGUP _IO('T', 0x37) |
104 | #define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */ | ||
105 | #define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */ | ||
106 | #define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */ | ||
104 | 107 | ||
105 | #define TIOCSERCONFIG _IO('T', 83) | 108 | #define TIOCSERCONFIG _IO('T', 83) |
106 | #define TIOCSERGWILD _IOR('T', 84, int) | 109 | #define TIOCSERGWILD _IOR('T', 84, int) |
diff --git a/arch/xtensa/include/uapi/asm/mman.h b/arch/xtensa/include/uapi/asm/mman.h index 25bc6c1309c3..00eed6786d7e 100644 --- a/arch/xtensa/include/uapi/asm/mman.h +++ b/arch/xtensa/include/uapi/asm/mman.h | |||
@@ -93,4 +93,15 @@ | |||
93 | /* compatibility flags */ | 93 | /* compatibility flags */ |
94 | #define MAP_FILE 0 | 94 | #define MAP_FILE 0 |
95 | 95 | ||
96 | /* | ||
97 | * When MAP_HUGETLB is set bits [26:31] encode the log2 of the huge page size. | ||
98 | * This gives us 6 bits, which is enough until someone invents 128 bit address | ||
99 | * spaces. | ||
100 | * | ||
101 | * Assume these are all power of twos. | ||
102 | * When 0 use the default page size. | ||
103 | */ | ||
104 | #define MAP_HUGE_SHIFT 26 | ||
105 | #define MAP_HUGE_MASK 0x3f | ||
106 | |||
96 | #endif /* _XTENSA_MMAN_H */ | 107 | #endif /* _XTENSA_MMAN_H */ |
diff --git a/arch/xtensa/include/uapi/asm/signal.h b/arch/xtensa/include/uapi/asm/signal.h index b88ce96f2af9..dacf716dd3e0 100644 --- a/arch/xtensa/include/uapi/asm/signal.h +++ b/arch/xtensa/include/uapi/asm/signal.h | |||
@@ -97,12 +97,6 @@ typedef struct { | |||
97 | 97 | ||
98 | #define SA_RESTORER 0x04000000 | 98 | #define SA_RESTORER 0x04000000 |
99 | 99 | ||
100 | /* | ||
101 | * sigaltstack controls | ||
102 | */ | ||
103 | #define SS_ONSTACK 1 | ||
104 | #define SS_DISABLE 2 | ||
105 | |||
106 | #define MINSIGSTKSZ 2048 | 100 | #define MINSIGSTKSZ 2048 |
107 | #define SIGSTKSZ 8192 | 101 | #define SIGSTKSZ 8192 |
108 | 102 | ||
diff --git a/arch/xtensa/include/uapi/asm/socket.h b/arch/xtensa/include/uapi/asm/socket.h index e36c68184920..38079be1cf1e 100644 --- a/arch/xtensa/include/uapi/asm/socket.h +++ b/arch/xtensa/include/uapi/asm/socket.h | |||
@@ -52,6 +52,7 @@ | |||
52 | 52 | ||
53 | #define SO_ATTACH_FILTER 26 | 53 | #define SO_ATTACH_FILTER 26 |
54 | #define SO_DETACH_FILTER 27 | 54 | #define SO_DETACH_FILTER 27 |
55 | #define SO_GET_FILTER SO_ATTACH_FILTER | ||
55 | 56 | ||
56 | #define SO_PEERNAME 28 | 57 | #define SO_PEERNAME 28 |
57 | #define SO_TIMESTAMP 29 | 58 | #define SO_TIMESTAMP 29 |
diff --git a/arch/xtensa/include/uapi/asm/unistd.h b/arch/xtensa/include/uapi/asm/unistd.h index 479abaea5aae..5162418c5d90 100644 --- a/arch/xtensa/include/uapi/asm/unistd.h +++ b/arch/xtensa/include/uapi/asm/unistd.h | |||
@@ -1,14 +1,4 @@ | |||
1 | /* | 1 | #if !defined(_UAPI_XTENSA_UNISTD_H) || defined(__SYSCALL) |
2 | * include/asm-xtensa/unistd.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) 2001 - 2012 Tensilica Inc. | ||
9 | */ | ||
10 | |||
11 | #ifndef _UAPI_XTENSA_UNISTD_H | ||
12 | #define _UAPI_XTENSA_UNISTD_H | 2 | #define _UAPI_XTENSA_UNISTD_H |
13 | 3 | ||
14 | #ifndef __SYSCALL | 4 | #ifndef __SYSCALL |
@@ -270,9 +260,9 @@ __SYSCALL(115, sys_sendmmsg, 4) | |||
270 | /* Process Operations */ | 260 | /* Process Operations */ |
271 | 261 | ||
272 | #define __NR_clone 116 | 262 | #define __NR_clone 116 |
273 | __SYSCALL(116, xtensa_clone, 5) | 263 | __SYSCALL(116, sys_clone, 5) |
274 | #define __NR_execve 117 | 264 | #define __NR_execve 117 |
275 | __SYSCALL(117, xtensa_execve, 3) | 265 | __SYSCALL(117, sys_execve, 3) |
276 | #define __NR_exit 118 | 266 | #define __NR_exit 118 |
277 | __SYSCALL(118, sys_exit, 1) | 267 | __SYSCALL(118, sys_exit, 1) |
278 | #define __NR_exit_group 119 | 268 | #define __NR_exit_group 119 |
@@ -759,4 +749,6 @@ __SYSCALL(331, sys_kcmp, 5) | |||
759 | 749 | ||
760 | #define SYS_XTENSA_COUNT 5 /* count */ | 750 | #define SYS_XTENSA_COUNT 5 /* count */ |
761 | 751 | ||
752 | #undef __SYSCALL | ||
753 | |||
762 | #endif /* _UAPI_XTENSA_UNISTD_H */ | 754 | #endif /* _UAPI_XTENSA_UNISTD_H */ |
diff --git a/arch/xtensa/kernel/Makefile b/arch/xtensa/kernel/Makefile index f36cef5a62ff..c3a59d992ac0 100644 --- a/arch/xtensa/kernel/Makefile +++ b/arch/xtensa/kernel/Makefile | |||
@@ -23,13 +23,13 @@ obj-$(CONFIG_MODULES) += xtensa_ksyms.o module.o | |||
23 | # | 23 | # |
24 | # Replicate rules in scripts/Makefile.build | 24 | # Replicate rules in scripts/Makefile.build |
25 | 25 | ||
26 | sed-y = -e 's/\*(\(\.[a-z]*it\|\.ref\|\)\.text)/*(\1.literal \1.text)/g' \ | 26 | sed-y = -e 's/\*(\(\.[a-z]*it\|\.ref\|\)\.text)/*(\1.literal \1.text)/g' \ |
27 | -e 's/\.text\.unlikely/.literal.unlikely .text.unlikely/g' \ | 27 | -e 's/\.text\.unlikely/.literal.unlikely .text.unlikely/g' \ |
28 | -e 's/\*(\(\.text\.[a-z]*\))/*(\1.literal \1)/g' | 28 | -e 's/\*(\(\.text\.[a-z]*\))/*(\1.literal \1)/g' |
29 | 29 | ||
30 | quiet_cmd__cpp_lds_S = LDS $@ | 30 | quiet_cmd__cpp_lds_S = LDS $@ |
31 | cmd__cpp_lds_S = $(CPP) $(cpp_flags) -P -C -Uxtensa -D__ASSEMBLY__ $< \ | 31 | cmd__cpp_lds_S = $(CPP) $(cpp_flags) -P -C -Uxtensa -D__ASSEMBLY__ $< \ |
32 | | sed $(sed-y) >$@ | 32 | | sed $(sed-y) >$@ |
33 | 33 | ||
34 | $(obj)/vmlinux.lds: $(src)/vmlinux.lds.S FORCE | 34 | $(obj)/vmlinux.lds: $(src)/vmlinux.lds.S FORCE |
35 | $(call if_changed_dep,_cpp_lds_S) | 35 | $(call if_changed_dep,_cpp_lds_S) |
diff --git a/arch/xtensa/kernel/align.S b/arch/xtensa/kernel/align.S index 934ae58e2c79..aa2e87b8566a 100644 --- a/arch/xtensa/kernel/align.S +++ b/arch/xtensa/kernel/align.S | |||
@@ -442,7 +442,7 @@ ENTRY(fast_unaligned) | |||
442 | mov a1, a2 | 442 | mov a1, a2 |
443 | 443 | ||
444 | rsr a0, ps | 444 | rsr a0, ps |
445 | bbsi.l a2, PS_UM_BIT, 1f # jump if user mode | 445 | bbsi.l a2, PS_UM_BIT, 1f # jump if user mode |
446 | 446 | ||
447 | movi a0, _kernel_exception | 447 | movi a0, _kernel_exception |
448 | jx a0 | 448 | jx a0 |
@@ -450,6 +450,6 @@ ENTRY(fast_unaligned) | |||
450 | 1: movi a0, _user_exception | 450 | 1: movi a0, _user_exception |
451 | jx a0 | 451 | jx a0 |
452 | 452 | ||
453 | ENDPROC(fast_unaligned) | ||
453 | 454 | ||
454 | #endif /* XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION */ | 455 | #endif /* XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION */ |
455 | |||
diff --git a/arch/xtensa/kernel/asm-offsets.c b/arch/xtensa/kernel/asm-offsets.c index 7dc3f9157185..0701fad170db 100644 --- a/arch/xtensa/kernel/asm-offsets.c +++ b/arch/xtensa/kernel/asm-offsets.c | |||
@@ -41,6 +41,7 @@ int main(void) | |||
41 | DEFINE(PT_SAR, offsetof (struct pt_regs, sar)); | 41 | DEFINE(PT_SAR, offsetof (struct pt_regs, sar)); |
42 | DEFINE(PT_ICOUNTLEVEL, offsetof (struct pt_regs, icountlevel)); | 42 | DEFINE(PT_ICOUNTLEVEL, offsetof (struct pt_regs, icountlevel)); |
43 | DEFINE(PT_SYSCALL, offsetof (struct pt_regs, syscall)); | 43 | DEFINE(PT_SYSCALL, offsetof (struct pt_regs, syscall)); |
44 | DEFINE(PT_SCOMPARE1, offsetof(struct pt_regs, scompare1)); | ||
44 | DEFINE(PT_AREG, offsetof (struct pt_regs, areg[0])); | 45 | DEFINE(PT_AREG, offsetof (struct pt_regs, areg[0])); |
45 | DEFINE(PT_AREG0, offsetof (struct pt_regs, areg[0])); | 46 | DEFINE(PT_AREG0, offsetof (struct pt_regs, areg[0])); |
46 | DEFINE(PT_AREG1, offsetof (struct pt_regs, areg[1])); | 47 | DEFINE(PT_AREG1, offsetof (struct pt_regs, areg[1])); |
@@ -91,7 +92,8 @@ int main(void) | |||
91 | #endif | 92 | #endif |
92 | DEFINE(THREAD_XTREGS_USER, offsetof (struct thread_info, xtregs_user)); | 93 | DEFINE(THREAD_XTREGS_USER, offsetof (struct thread_info, xtregs_user)); |
93 | DEFINE(XTREGS_USER_SIZE, sizeof(xtregs_user_t)); | 94 | DEFINE(XTREGS_USER_SIZE, sizeof(xtregs_user_t)); |
94 | DEFINE(THREAD_CURRENT_DS, offsetof (struct task_struct, thread.current_ds)); | 95 | DEFINE(THREAD_CURRENT_DS, offsetof (struct task_struct, \ |
96 | thread.current_ds)); | ||
95 | 97 | ||
96 | /* struct mm_struct */ | 98 | /* struct mm_struct */ |
97 | DEFINE(MM_USERS, offsetof(struct mm_struct, mm_users)); | 99 | DEFINE(MM_USERS, offsetof(struct mm_struct, mm_users)); |
@@ -108,4 +110,3 @@ int main(void) | |||
108 | 110 | ||
109 | return 0; | 111 | return 0; |
110 | } | 112 | } |
111 | |||
diff --git a/arch/xtensa/kernel/coprocessor.S b/arch/xtensa/kernel/coprocessor.S index 54c3be313bfa..647657484866 100644 --- a/arch/xtensa/kernel/coprocessor.S +++ b/arch/xtensa/kernel/coprocessor.S | |||
@@ -43,10 +43,13 @@ | |||
43 | /* IO protection is currently unsupported. */ | 43 | /* IO protection is currently unsupported. */ |
44 | 44 | ||
45 | ENTRY(fast_io_protect) | 45 | ENTRY(fast_io_protect) |
46 | |||
46 | wsr a0, excsave1 | 47 | wsr a0, excsave1 |
47 | movi a0, unrecoverable_exception | 48 | movi a0, unrecoverable_exception |
48 | callx0 a0 | 49 | callx0 a0 |
49 | 50 | ||
51 | ENDPROC(fast_io_protect) | ||
52 | |||
50 | #if XTENSA_HAVE_COPROCESSORS | 53 | #if XTENSA_HAVE_COPROCESSORS |
51 | 54 | ||
52 | /* | 55 | /* |
@@ -139,6 +142,7 @@ ENTRY(fast_io_protect) | |||
139 | */ | 142 | */ |
140 | 143 | ||
141 | ENTRY(coprocessor_save) | 144 | ENTRY(coprocessor_save) |
145 | |||
142 | entry a1, 32 | 146 | entry a1, 32 |
143 | s32i a0, a1, 0 | 147 | s32i a0, a1, 0 |
144 | movi a0, .Lsave_cp_regs_jump_table | 148 | movi a0, .Lsave_cp_regs_jump_table |
@@ -150,7 +154,10 @@ ENTRY(coprocessor_save) | |||
150 | 1: l32i a0, a1, 0 | 154 | 1: l32i a0, a1, 0 |
151 | retw | 155 | retw |
152 | 156 | ||
157 | ENDPROC(coprocessor_save) | ||
158 | |||
153 | ENTRY(coprocessor_load) | 159 | ENTRY(coprocessor_load) |
160 | |||
154 | entry a1, 32 | 161 | entry a1, 32 |
155 | s32i a0, a1, 0 | 162 | s32i a0, a1, 0 |
156 | movi a0, .Lload_cp_regs_jump_table | 163 | movi a0, .Lload_cp_regs_jump_table |
@@ -162,8 +169,10 @@ ENTRY(coprocessor_load) | |||
162 | 1: l32i a0, a1, 0 | 169 | 1: l32i a0, a1, 0 |
163 | retw | 170 | retw |
164 | 171 | ||
172 | ENDPROC(coprocessor_load) | ||
173 | |||
165 | /* | 174 | /* |
166 | * coprocessor_flush(struct task_info*, index) | 175 | * coprocessor_flush(struct task_info*, index) |
167 | * a2 a3 | 176 | * a2 a3 |
168 | * coprocessor_restore(struct task_info*, index) | 177 | * coprocessor_restore(struct task_info*, index) |
169 | * a2 a3 | 178 | * a2 a3 |
@@ -178,6 +187,7 @@ ENTRY(coprocessor_load) | |||
178 | 187 | ||
179 | 188 | ||
180 | ENTRY(coprocessor_flush) | 189 | ENTRY(coprocessor_flush) |
190 | |||
181 | entry a1, 32 | 191 | entry a1, 32 |
182 | s32i a0, a1, 0 | 192 | s32i a0, a1, 0 |
183 | movi a0, .Lsave_cp_regs_jump_table | 193 | movi a0, .Lsave_cp_regs_jump_table |
@@ -191,6 +201,8 @@ ENTRY(coprocessor_flush) | |||
191 | 1: l32i a0, a1, 0 | 201 | 1: l32i a0, a1, 0 |
192 | retw | 202 | retw |
193 | 203 | ||
204 | ENDPROC(coprocessor_flush) | ||
205 | |||
194 | ENTRY(coprocessor_restore) | 206 | ENTRY(coprocessor_restore) |
195 | entry a1, 32 | 207 | entry a1, 32 |
196 | s32i a0, a1, 0 | 208 | s32i a0, a1, 0 |
@@ -205,6 +217,8 @@ ENTRY(coprocessor_restore) | |||
205 | 1: l32i a0, a1, 0 | 217 | 1: l32i a0, a1, 0 |
206 | retw | 218 | retw |
207 | 219 | ||
220 | ENDPROC(coprocessor_restore) | ||
221 | |||
208 | /* | 222 | /* |
209 | * Entry condition: | 223 | * Entry condition: |
210 | * | 224 | * |
@@ -220,10 +234,12 @@ ENTRY(coprocessor_restore) | |||
220 | */ | 234 | */ |
221 | 235 | ||
222 | ENTRY(fast_coprocessor_double) | 236 | ENTRY(fast_coprocessor_double) |
237 | |||
223 | wsr a0, excsave1 | 238 | wsr a0, excsave1 |
224 | movi a0, unrecoverable_exception | 239 | movi a0, unrecoverable_exception |
225 | callx0 a0 | 240 | callx0 a0 |
226 | 241 | ||
242 | ENDPROC(fast_coprocessor_double) | ||
227 | 243 | ||
228 | ENTRY(fast_coprocessor) | 244 | ENTRY(fast_coprocessor) |
229 | 245 | ||
@@ -327,9 +343,14 @@ ENTRY(fast_coprocessor) | |||
327 | 343 | ||
328 | rfe | 344 | rfe |
329 | 345 | ||
346 | ENDPROC(fast_coprocessor) | ||
347 | |||
330 | .data | 348 | .data |
349 | |||
331 | ENTRY(coprocessor_owner) | 350 | ENTRY(coprocessor_owner) |
351 | |||
332 | .fill XCHAL_CP_MAX, 4, 0 | 352 | .fill XCHAL_CP_MAX, 4, 0 |
333 | 353 | ||
334 | #endif /* XTENSA_HAVE_COPROCESSORS */ | 354 | END(coprocessor_owner) |
335 | 355 | ||
356 | #endif /* XTENSA_HAVE_COPROCESSORS */ | ||
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S index 18453067c258..3777fec85e7c 100644 --- a/arch/xtensa/kernel/entry.S +++ b/arch/xtensa/kernel/entry.S | |||
@@ -219,6 +219,7 @@ _user_exception: | |||
219 | 219 | ||
220 | j common_exception | 220 | j common_exception |
221 | 221 | ||
222 | ENDPROC(user_exception) | ||
222 | 223 | ||
223 | /* | 224 | /* |
224 | * First-level exit handler for kernel exceptions | 225 | * First-level exit handler for kernel exceptions |
@@ -371,6 +372,13 @@ common_exception: | |||
371 | s32i a2, a1, PT_LBEG | 372 | s32i a2, a1, PT_LBEG |
372 | s32i a3, a1, PT_LEND | 373 | s32i a3, a1, PT_LEND |
373 | 374 | ||
375 | /* Save SCOMPARE1 */ | ||
376 | |||
377 | #if XCHAL_HAVE_S32C1I | ||
378 | rsr a2, scompare1 | ||
379 | s32i a2, a1, PT_SCOMPARE1 | ||
380 | #endif | ||
381 | |||
374 | /* Save optional registers. */ | 382 | /* Save optional registers. */ |
375 | 383 | ||
376 | save_xtregs_opt a1 a2 a4 a5 a6 a7 PT_XTREGS_OPT | 384 | save_xtregs_opt a1 a2 a4 a5 a6 a7 PT_XTREGS_OPT |
@@ -432,6 +440,12 @@ common_exception_return: | |||
432 | 440 | ||
433 | load_xtregs_opt a1 a2 a4 a5 a6 a7 PT_XTREGS_OPT | 441 | load_xtregs_opt a1 a2 a4 a5 a6 a7 PT_XTREGS_OPT |
434 | 442 | ||
443 | /* Restore SCOMPARE1 */ | ||
444 | |||
445 | #if XCHAL_HAVE_S32C1I | ||
446 | l32i a2, a1, PT_SCOMPARE1 | ||
447 | wsr a2, scompare1 | ||
448 | #endif | ||
435 | wsr a3, ps /* disable interrupts */ | 449 | wsr a3, ps /* disable interrupts */ |
436 | 450 | ||
437 | _bbci.l a3, PS_UM_BIT, kernel_exception_exit | 451 | _bbci.l a3, PS_UM_BIT, kernel_exception_exit |
@@ -641,6 +655,8 @@ common_exception_exit: | |||
641 | l32i a1, a1, PT_AREG1 | 655 | l32i a1, a1, PT_AREG1 |
642 | rfde | 656 | rfde |
643 | 657 | ||
658 | ENDPROC(kernel_exception) | ||
659 | |||
644 | /* | 660 | /* |
645 | * Debug exception handler. | 661 | * Debug exception handler. |
646 | * | 662 | * |
@@ -701,6 +717,7 @@ ENTRY(debug_exception) | |||
701 | /* Debug exception while in exception mode. */ | 717 | /* Debug exception while in exception mode. */ |
702 | 1: j 1b // FIXME!! | 718 | 1: j 1b // FIXME!! |
703 | 719 | ||
720 | ENDPROC(debug_exception) | ||
704 | 721 | ||
705 | /* | 722 | /* |
706 | * We get here in case of an unrecoverable exception. | 723 | * We get here in case of an unrecoverable exception. |
@@ -751,6 +768,7 @@ ENTRY(unrecoverable_exception) | |||
751 | 768 | ||
752 | 1: j 1b | 769 | 1: j 1b |
753 | 770 | ||
771 | ENDPROC(unrecoverable_exception) | ||
754 | 772 | ||
755 | /* -------------------------- FAST EXCEPTION HANDLERS ----------------------- */ | 773 | /* -------------------------- FAST EXCEPTION HANDLERS ----------------------- */ |
756 | 774 | ||
@@ -856,7 +874,7 @@ ENTRY(fast_alloca) | |||
856 | 874 | ||
857 | _bnei a0, 1, 1f # no 'movsp a1, ax': jump | 875 | _bnei a0, 1, 1f # no 'movsp a1, ax': jump |
858 | 876 | ||
859 | /* Move the save area. This implies the use of the L32E | 877 | /* Move the save area. This implies the use of the L32E |
860 | * and S32E instructions, because this move must be done with | 878 | * and S32E instructions, because this move must be done with |
861 | * the user's PS.RING privilege levels, not with ring 0 | 879 | * the user's PS.RING privilege levels, not with ring 0 |
862 | * (kernel's) privileges currently active with PS.EXCM | 880 | * (kernel's) privileges currently active with PS.EXCM |
@@ -929,6 +947,7 @@ ENTRY(fast_alloca) | |||
929 | l32i a2, a2, PT_AREG2 | 947 | l32i a2, a2, PT_AREG2 |
930 | rfe | 948 | rfe |
931 | 949 | ||
950 | ENDPROC(fast_alloca) | ||
932 | 951 | ||
933 | /* | 952 | /* |
934 | * fast system calls. | 953 | * fast system calls. |
@@ -966,6 +985,8 @@ ENTRY(fast_syscall_kernel) | |||
966 | 985 | ||
967 | j kernel_exception | 986 | j kernel_exception |
968 | 987 | ||
988 | ENDPROC(fast_syscall_kernel) | ||
989 | |||
969 | ENTRY(fast_syscall_user) | 990 | ENTRY(fast_syscall_user) |
970 | 991 | ||
971 | /* Skip syscall. */ | 992 | /* Skip syscall. */ |
@@ -983,19 +1004,21 @@ ENTRY(fast_syscall_user) | |||
983 | 1004 | ||
984 | j user_exception | 1005 | j user_exception |
985 | 1006 | ||
986 | ENTRY(fast_syscall_unrecoverable) | 1007 | ENDPROC(fast_syscall_user) |
987 | 1008 | ||
988 | /* Restore all states. */ | 1009 | ENTRY(fast_syscall_unrecoverable) |
989 | 1010 | ||
990 | l32i a0, a2, PT_AREG0 # restore a0 | 1011 | /* Restore all states. */ |
991 | xsr a2, depc # restore a2, depc | ||
992 | rsr a3, excsave1 | ||
993 | 1012 | ||
994 | wsr a0, excsave1 | 1013 | l32i a0, a2, PT_AREG0 # restore a0 |
995 | movi a0, unrecoverable_exception | 1014 | xsr a2, depc # restore a2, depc |
996 | callx0 a0 | 1015 | rsr a3, excsave1 |
997 | 1016 | ||
1017 | wsr a0, excsave1 | ||
1018 | movi a0, unrecoverable_exception | ||
1019 | callx0 a0 | ||
998 | 1020 | ||
1021 | ENDPROC(fast_syscall_unrecoverable) | ||
999 | 1022 | ||
1000 | /* | 1023 | /* |
1001 | * sysxtensa syscall handler | 1024 | * sysxtensa syscall handler |
@@ -1101,7 +1124,7 @@ CATCH | |||
1101 | movi a2, -EINVAL | 1124 | movi a2, -EINVAL |
1102 | rfe | 1125 | rfe |
1103 | 1126 | ||
1104 | 1127 | ENDPROC(fast_syscall_xtensa) | |
1105 | 1128 | ||
1106 | 1129 | ||
1107 | /* fast_syscall_spill_registers. | 1130 | /* fast_syscall_spill_registers. |
@@ -1160,6 +1183,8 @@ ENTRY(fast_syscall_spill_registers) | |||
1160 | movi a2, 0 | 1183 | movi a2, 0 |
1161 | rfe | 1184 | rfe |
1162 | 1185 | ||
1186 | ENDPROC(fast_syscall_spill_registers) | ||
1187 | |||
1163 | /* Fixup handler. | 1188 | /* Fixup handler. |
1164 | * | 1189 | * |
1165 | * We get here if the spill routine causes an exception, e.g. tlb miss. | 1190 | * We get here if the spill routine causes an exception, e.g. tlb miss. |
@@ -1228,9 +1253,9 @@ fast_syscall_spill_registers_fixup: | |||
1228 | 1253 | ||
1229 | movi a3, exc_table | 1254 | movi a3, exc_table |
1230 | rsr a0, exccause | 1255 | rsr a0, exccause |
1231 | addx4 a0, a0, a3 # find entry in table | 1256 | addx4 a0, a0, a3 # find entry in table |
1232 | l32i a0, a0, EXC_TABLE_FAST_USER # load handler | 1257 | l32i a0, a0, EXC_TABLE_FAST_USER # load handler |
1233 | jx a0 | 1258 | jx a0 |
1234 | 1259 | ||
1235 | fast_syscall_spill_registers_fixup_return: | 1260 | fast_syscall_spill_registers_fixup_return: |
1236 | 1261 | ||
@@ -1432,7 +1457,7 @@ ENTRY(_spill_registers) | |||
1432 | rsr a0, ps | 1457 | rsr a0, ps |
1433 | _bbci.l a0, PS_UM_BIT, 1f | 1458 | _bbci.l a0, PS_UM_BIT, 1f |
1434 | 1459 | ||
1435 | /* User space: Setup a dummy frame and kill application. | 1460 | /* User space: Setup a dummy frame and kill application. |
1436 | * Note: We assume EXC_TABLE_KSTK contains a valid stack pointer. | 1461 | * Note: We assume EXC_TABLE_KSTK contains a valid stack pointer. |
1437 | */ | 1462 | */ |
1438 | 1463 | ||
@@ -1464,6 +1489,8 @@ ENTRY(_spill_registers) | |||
1464 | callx0 a0 # should not return | 1489 | callx0 a0 # should not return |
1465 | 1: j 1b | 1490 | 1: j 1b |
1466 | 1491 | ||
1492 | ENDPROC(_spill_registers) | ||
1493 | |||
1467 | #ifdef CONFIG_MMU | 1494 | #ifdef CONFIG_MMU |
1468 | /* | 1495 | /* |
1469 | * We should never get here. Bail out! | 1496 | * We should never get here. Bail out! |
@@ -1475,6 +1502,8 @@ ENTRY(fast_second_level_miss_double_kernel) | |||
1475 | callx0 a0 # should not return | 1502 | callx0 a0 # should not return |
1476 | 1: j 1b | 1503 | 1: j 1b |
1477 | 1504 | ||
1505 | ENDPROC(fast_second_level_miss_double_kernel) | ||
1506 | |||
1478 | /* First-level entry handler for user, kernel, and double 2nd-level | 1507 | /* First-level entry handler for user, kernel, and double 2nd-level |
1479 | * TLB miss exceptions. Note that for now, user and kernel miss | 1508 | * TLB miss exceptions. Note that for now, user and kernel miss |
1480 | * exceptions share the same entry point and are handled identically. | 1509 | * exceptions share the same entry point and are handled identically. |
@@ -1682,6 +1711,7 @@ ENTRY(fast_second_level_miss) | |||
1682 | j _kernel_exception | 1711 | j _kernel_exception |
1683 | 1: j _user_exception | 1712 | 1: j _user_exception |
1684 | 1713 | ||
1714 | ENDPROC(fast_second_level_miss) | ||
1685 | 1715 | ||
1686 | /* | 1716 | /* |
1687 | * StoreProhibitedException | 1717 | * StoreProhibitedException |
@@ -1777,6 +1807,9 @@ ENTRY(fast_store_prohibited) | |||
1777 | bbsi.l a2, PS_UM_BIT, 1f | 1807 | bbsi.l a2, PS_UM_BIT, 1f |
1778 | j _kernel_exception | 1808 | j _kernel_exception |
1779 | 1: j _user_exception | 1809 | 1: j _user_exception |
1810 | |||
1811 | ENDPROC(fast_store_prohibited) | ||
1812 | |||
1780 | #endif /* CONFIG_MMU */ | 1813 | #endif /* CONFIG_MMU */ |
1781 | 1814 | ||
1782 | /* | 1815 | /* |
@@ -1787,6 +1820,7 @@ ENTRY(fast_store_prohibited) | |||
1787 | */ | 1820 | */ |
1788 | 1821 | ||
1789 | ENTRY(system_call) | 1822 | ENTRY(system_call) |
1823 | |||
1790 | entry a1, 32 | 1824 | entry a1, 32 |
1791 | 1825 | ||
1792 | /* regs->syscall = regs->areg[2] */ | 1826 | /* regs->syscall = regs->areg[2] */ |
@@ -1831,50 +1865,8 @@ ENTRY(system_call) | |||
1831 | callx4 a4 | 1865 | callx4 a4 |
1832 | retw | 1866 | retw |
1833 | 1867 | ||
1868 | ENDPROC(system_call) | ||
1834 | 1869 | ||
1835 | /* | ||
1836 | * Create a kernel thread | ||
1837 | * | ||
1838 | * int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) | ||
1839 | * a2 a2 a3 a4 | ||
1840 | */ | ||
1841 | |||
1842 | ENTRY(kernel_thread) | ||
1843 | entry a1, 16 | ||
1844 | |||
1845 | mov a5, a2 # preserve fn over syscall | ||
1846 | mov a7, a3 # preserve args over syscall | ||
1847 | |||
1848 | movi a3, _CLONE_VM | _CLONE_UNTRACED | ||
1849 | movi a2, __NR_clone | ||
1850 | or a6, a4, a3 # arg0: flags | ||
1851 | mov a3, a1 # arg1: sp | ||
1852 | syscall | ||
1853 | |||
1854 | beq a3, a1, 1f # branch if parent | ||
1855 | mov a6, a7 # args | ||
1856 | callx4 a5 # fn(args) | ||
1857 | |||
1858 | movi a2, __NR_exit | ||
1859 | syscall # return value of fn(args) still in a6 | ||
1860 | |||
1861 | 1: retw | ||
1862 | |||
1863 | /* | ||
1864 | * Do a system call from kernel instead of calling sys_execve, so we end up | ||
1865 | * with proper pt_regs. | ||
1866 | * | ||
1867 | * int kernel_execve(const char *fname, char *const argv[], charg *const envp[]) | ||
1868 | * a2 a2 a3 a4 | ||
1869 | */ | ||
1870 | |||
1871 | ENTRY(kernel_execve) | ||
1872 | entry a1, 16 | ||
1873 | mov a6, a2 # arg0 is in a6 | ||
1874 | movi a2, __NR_execve | ||
1875 | syscall | ||
1876 | |||
1877 | retw | ||
1878 | 1870 | ||
1879 | /* | 1871 | /* |
1880 | * Task switch. | 1872 | * Task switch. |
@@ -1943,6 +1935,7 @@ ENTRY(_switch_to) | |||
1943 | 1935 | ||
1944 | retw | 1936 | retw |
1945 | 1937 | ||
1938 | ENDPROC(_switch_to) | ||
1946 | 1939 | ||
1947 | ENTRY(ret_from_fork) | 1940 | ENTRY(ret_from_fork) |
1948 | 1941 | ||
@@ -1958,3 +1951,18 @@ ENTRY(ret_from_fork) | |||
1958 | 1951 | ||
1959 | j common_exception_return | 1952 | j common_exception_return |
1960 | 1953 | ||
1954 | ENDPROC(ret_from_fork) | ||
1955 | |||
1956 | /* | ||
1957 | * Kernel thread creation helper | ||
1958 | * On entry, set up by copy_thread: a2 = thread_fn, a3 = thread_fn arg | ||
1959 | * left from _switch_to: a6 = prev | ||
1960 | */ | ||
1961 | ENTRY(ret_from_kernel_thread) | ||
1962 | |||
1963 | call4 schedule_tail | ||
1964 | mov a6, a3 | ||
1965 | callx4 a2 | ||
1966 | j common_exception_return | ||
1967 | |||
1968 | ENDPROC(ret_from_kernel_thread) | ||
diff --git a/arch/xtensa/kernel/head.S b/arch/xtensa/kernel/head.S index bdc50788f35e..91d9095284de 100644 --- a/arch/xtensa/kernel/head.S +++ b/arch/xtensa/kernel/head.S | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <asm/processor.h> | 18 | #include <asm/processor.h> |
19 | #include <asm/page.h> | 19 | #include <asm/page.h> |
20 | #include <asm/cacheasm.h> | 20 | #include <asm/cacheasm.h> |
21 | #include <asm/initialize_mmu.h> | ||
21 | 22 | ||
22 | #include <linux/init.h> | 23 | #include <linux/init.h> |
23 | #include <linux/linkage.h> | 24 | #include <linux/linkage.h> |
@@ -47,16 +48,19 @@ | |||
47 | */ | 48 | */ |
48 | 49 | ||
49 | __HEAD | 50 | __HEAD |
50 | .globl _start | 51 | ENTRY(_start) |
51 | _start: _j 2f | 52 | |
53 | _j 2f | ||
52 | .align 4 | 54 | .align 4 |
53 | 1: .word _startup | 55 | 1: .word _startup |
54 | 2: l32r a0, 1b | 56 | 2: l32r a0, 1b |
55 | jx a0 | 57 | jx a0 |
56 | 58 | ||
59 | ENDPROC(_start) | ||
60 | |||
57 | .section .init.text, "ax" | 61 | .section .init.text, "ax" |
58 | .align 4 | 62 | |
59 | _startup: | 63 | ENTRY(_startup) |
60 | 64 | ||
61 | /* Disable interrupts and exceptions. */ | 65 | /* Disable interrupts and exceptions. */ |
62 | 66 | ||
@@ -107,7 +111,7 @@ _startup: | |||
107 | /* Disable all timers. */ | 111 | /* Disable all timers. */ |
108 | 112 | ||
109 | .set _index, 0 | 113 | .set _index, 0 |
110 | .rept XCHAL_NUM_TIMERS - 1 | 114 | .rept XCHAL_NUM_TIMERS |
111 | wsr a0, SREG_CCOMPARE + _index | 115 | wsr a0, SREG_CCOMPARE + _index |
112 | .set _index, _index + 1 | 116 | .set _index, _index + 1 |
113 | .endr | 117 | .endr |
@@ -120,7 +124,7 @@ _startup: | |||
120 | 124 | ||
121 | /* Disable coprocessors. */ | 125 | /* Disable coprocessors. */ |
122 | 126 | ||
123 | #if XCHAL_CP_NUM > 0 | 127 | #if XCHAL_HAVE_CP |
124 | wsr a0, cpenable | 128 | wsr a0, cpenable |
125 | #endif | 129 | #endif |
126 | 130 | ||
@@ -152,6 +156,8 @@ _startup: | |||
152 | 156 | ||
153 | isync | 157 | isync |
154 | 158 | ||
159 | initialize_mmu | ||
160 | |||
155 | /* Unpack data sections | 161 | /* Unpack data sections |
156 | * | 162 | * |
157 | * The linker script used to build the Linux kernel image | 163 | * The linker script used to build the Linux kernel image |
@@ -230,6 +236,7 @@ _startup: | |||
230 | should_never_return: | 236 | should_never_return: |
231 | j should_never_return | 237 | j should_never_return |
232 | 238 | ||
239 | ENDPROC(_startup) | ||
233 | 240 | ||
234 | /* | 241 | /* |
235 | * BSS section | 242 | * BSS section |
@@ -239,6 +246,8 @@ __PAGE_ALIGNED_BSS | |||
239 | #ifdef CONFIG_MMU | 246 | #ifdef CONFIG_MMU |
240 | ENTRY(swapper_pg_dir) | 247 | ENTRY(swapper_pg_dir) |
241 | .fill PAGE_SIZE, 1, 0 | 248 | .fill PAGE_SIZE, 1, 0 |
249 | END(swapper_pg_dir) | ||
242 | #endif | 250 | #endif |
243 | ENTRY(empty_zero_page) | 251 | ENTRY(empty_zero_page) |
244 | .fill PAGE_SIZE, 1, 0 | 252 | .fill PAGE_SIZE, 1, 0 |
253 | END(empty_zero_page) | ||
diff --git a/arch/xtensa/kernel/irq.c b/arch/xtensa/kernel/irq.c index a6ce3e563739..6f4f9749cff7 100644 --- a/arch/xtensa/kernel/irq.c +++ b/arch/xtensa/kernel/irq.c | |||
@@ -18,6 +18,8 @@ | |||
18 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
19 | #include <linux/irq.h> | 19 | #include <linux/irq.h> |
20 | #include <linux/kernel_stat.h> | 20 | #include <linux/kernel_stat.h> |
21 | #include <linux/irqdomain.h> | ||
22 | #include <linux/of.h> | ||
21 | 23 | ||
22 | #include <asm/uaccess.h> | 24 | #include <asm/uaccess.h> |
23 | #include <asm/platform.h> | 25 | #include <asm/platform.h> |
@@ -26,19 +28,22 @@ static unsigned int cached_irq_mask; | |||
26 | 28 | ||
27 | atomic_t irq_err_count; | 29 | atomic_t irq_err_count; |
28 | 30 | ||
31 | static struct irq_domain *root_domain; | ||
32 | |||
29 | /* | 33 | /* |
30 | * do_IRQ handles all normal device IRQ's (the special | 34 | * do_IRQ handles all normal device IRQ's (the special |
31 | * SMP cross-CPU interrupts have their own specific | 35 | * SMP cross-CPU interrupts have their own specific |
32 | * handlers). | 36 | * handlers). |
33 | */ | 37 | */ |
34 | 38 | ||
35 | asmlinkage void do_IRQ(int irq, struct pt_regs *regs) | 39 | asmlinkage void do_IRQ(int hwirq, struct pt_regs *regs) |
36 | { | 40 | { |
37 | struct pt_regs *old_regs = set_irq_regs(regs); | 41 | struct pt_regs *old_regs = set_irq_regs(regs); |
42 | int irq = irq_find_mapping(root_domain, hwirq); | ||
38 | 43 | ||
39 | if (irq >= NR_IRQS) { | 44 | if (hwirq >= NR_IRQS) { |
40 | printk(KERN_EMERG "%s: cannot handle IRQ %d\n", | 45 | printk(KERN_EMERG "%s: cannot handle IRQ %d\n", |
41 | __func__, irq); | 46 | __func__, hwirq); |
42 | } | 47 | } |
43 | 48 | ||
44 | irq_enter(); | 49 | irq_enter(); |
@@ -71,40 +76,39 @@ int arch_show_interrupts(struct seq_file *p, int prec) | |||
71 | 76 | ||
72 | static void xtensa_irq_mask(struct irq_data *d) | 77 | static void xtensa_irq_mask(struct irq_data *d) |
73 | { | 78 | { |
74 | cached_irq_mask &= ~(1 << d->irq); | 79 | cached_irq_mask &= ~(1 << d->hwirq); |
75 | set_sr (cached_irq_mask, intenable); | 80 | set_sr (cached_irq_mask, intenable); |
76 | } | 81 | } |
77 | 82 | ||
78 | static void xtensa_irq_unmask(struct irq_data *d) | 83 | static void xtensa_irq_unmask(struct irq_data *d) |
79 | { | 84 | { |
80 | cached_irq_mask |= 1 << d->irq; | 85 | cached_irq_mask |= 1 << d->hwirq; |
81 | set_sr (cached_irq_mask, intenable); | 86 | set_sr (cached_irq_mask, intenable); |
82 | } | 87 | } |
83 | 88 | ||
84 | static void xtensa_irq_enable(struct irq_data *d) | 89 | static void xtensa_irq_enable(struct irq_data *d) |
85 | { | 90 | { |
86 | variant_irq_enable(d->irq); | 91 | variant_irq_enable(d->hwirq); |
87 | xtensa_irq_unmask(d); | 92 | xtensa_irq_unmask(d); |
88 | } | 93 | } |
89 | 94 | ||
90 | static void xtensa_irq_disable(struct irq_data *d) | 95 | static void xtensa_irq_disable(struct irq_data *d) |
91 | { | 96 | { |
92 | xtensa_irq_mask(d); | 97 | xtensa_irq_mask(d); |
93 | variant_irq_disable(d->irq); | 98 | variant_irq_disable(d->hwirq); |
94 | } | 99 | } |
95 | 100 | ||
96 | static void xtensa_irq_ack(struct irq_data *d) | 101 | static void xtensa_irq_ack(struct irq_data *d) |
97 | { | 102 | { |
98 | set_sr(1 << d->irq, intclear); | 103 | set_sr(1 << d->hwirq, intclear); |
99 | } | 104 | } |
100 | 105 | ||
101 | static int xtensa_irq_retrigger(struct irq_data *d) | 106 | static int xtensa_irq_retrigger(struct irq_data *d) |
102 | { | 107 | { |
103 | set_sr (1 << d->irq, INTSET); | 108 | set_sr(1 << d->hwirq, intset); |
104 | return 1; | 109 | return 1; |
105 | } | 110 | } |
106 | 111 | ||
107 | |||
108 | static struct irq_chip xtensa_irq_chip = { | 112 | static struct irq_chip xtensa_irq_chip = { |
109 | .name = "xtensa", | 113 | .name = "xtensa", |
110 | .irq_enable = xtensa_irq_enable, | 114 | .irq_enable = xtensa_irq_enable, |
@@ -115,37 +119,99 @@ static struct irq_chip xtensa_irq_chip = { | |||
115 | .irq_retrigger = xtensa_irq_retrigger, | 119 | .irq_retrigger = xtensa_irq_retrigger, |
116 | }; | 120 | }; |
117 | 121 | ||
118 | void __init init_IRQ(void) | 122 | static int xtensa_irq_map(struct irq_domain *d, unsigned int irq, |
123 | irq_hw_number_t hw) | ||
119 | { | 124 | { |
120 | int index; | 125 | u32 mask = 1 << hw; |
121 | 126 | ||
122 | for (index = 0; index < XTENSA_NR_IRQS; index++) { | 127 | if (mask & XCHAL_INTTYPE_MASK_SOFTWARE) { |
123 | int mask = 1 << index; | 128 | irq_set_chip_and_handler_name(irq, &xtensa_irq_chip, |
124 | 129 | handle_simple_irq, "level"); | |
125 | if (mask & XCHAL_INTTYPE_MASK_SOFTWARE) | 130 | irq_set_status_flags(irq, IRQ_LEVEL); |
126 | irq_set_chip_and_handler(index, &xtensa_irq_chip, | 131 | } else if (mask & XCHAL_INTTYPE_MASK_EXTERN_EDGE) { |
127 | handle_simple_irq); | 132 | irq_set_chip_and_handler_name(irq, &xtensa_irq_chip, |
133 | handle_edge_irq, "edge"); | ||
134 | irq_clear_status_flags(irq, IRQ_LEVEL); | ||
135 | } else if (mask & XCHAL_INTTYPE_MASK_EXTERN_LEVEL) { | ||
136 | irq_set_chip_and_handler_name(irq, &xtensa_irq_chip, | ||
137 | handle_level_irq, "level"); | ||
138 | irq_set_status_flags(irq, IRQ_LEVEL); | ||
139 | } else if (mask & XCHAL_INTTYPE_MASK_TIMER) { | ||
140 | irq_set_chip_and_handler_name(irq, &xtensa_irq_chip, | ||
141 | handle_edge_irq, "edge"); | ||
142 | irq_clear_status_flags(irq, IRQ_LEVEL); | ||
143 | } else {/* XCHAL_INTTYPE_MASK_WRITE_ERROR */ | ||
144 | /* XCHAL_INTTYPE_MASK_NMI */ | ||
145 | |||
146 | irq_set_chip_and_handler_name(irq, &xtensa_irq_chip, | ||
147 | handle_level_irq, "level"); | ||
148 | irq_set_status_flags(irq, IRQ_LEVEL); | ||
149 | } | ||
150 | return 0; | ||
151 | } | ||
128 | 152 | ||
129 | else if (mask & XCHAL_INTTYPE_MASK_EXTERN_EDGE) | 153 | static unsigned map_ext_irq(unsigned ext_irq) |
130 | irq_set_chip_and_handler(index, &xtensa_irq_chip, | 154 | { |
131 | handle_edge_irq); | 155 | unsigned mask = XCHAL_INTTYPE_MASK_EXTERN_EDGE | |
156 | XCHAL_INTTYPE_MASK_EXTERN_LEVEL; | ||
157 | unsigned i; | ||
132 | 158 | ||
133 | else if (mask & XCHAL_INTTYPE_MASK_EXTERN_LEVEL) | 159 | for (i = 0; mask; ++i, mask >>= 1) { |
134 | irq_set_chip_and_handler(index, &xtensa_irq_chip, | 160 | if ((mask & 1) && ext_irq-- == 0) |
135 | handle_level_irq); | 161 | return i; |
162 | } | ||
163 | return XCHAL_NUM_INTERRUPTS; | ||
164 | } | ||
136 | 165 | ||
137 | else if (mask & XCHAL_INTTYPE_MASK_TIMER) | 166 | /* |
138 | irq_set_chip_and_handler(index, &xtensa_irq_chip, | 167 | * Device Tree IRQ specifier translation function which works with one or |
139 | handle_edge_irq); | 168 | * two cell bindings. First cell value maps directly to the hwirq number. |
169 | * Second cell if present specifies whether hwirq number is external (1) or | ||
170 | * internal (0). | ||
171 | */ | ||
172 | int xtensa_irq_domain_xlate(struct irq_domain *d, struct device_node *ctrlr, | ||
173 | const u32 *intspec, unsigned int intsize, | ||
174 | unsigned long *out_hwirq, unsigned int *out_type) | ||
175 | { | ||
176 | if (WARN_ON(intsize < 1 || intsize > 2)) | ||
177 | return -EINVAL; | ||
178 | if (intsize == 2 && intspec[1] == 1) { | ||
179 | unsigned int_irq = map_ext_irq(intspec[0]); | ||
180 | if (int_irq < XCHAL_NUM_INTERRUPTS) | ||
181 | *out_hwirq = int_irq; | ||
182 | else | ||
183 | return -EINVAL; | ||
184 | } else { | ||
185 | *out_hwirq = intspec[0]; | ||
186 | } | ||
187 | *out_type = IRQ_TYPE_NONE; | ||
188 | return 0; | ||
189 | } | ||
140 | 190 | ||
141 | else /* XCHAL_INTTYPE_MASK_WRITE_ERROR */ | 191 | static const struct irq_domain_ops xtensa_irq_domain_ops = { |
142 | /* XCHAL_INTTYPE_MASK_NMI */ | 192 | .xlate = xtensa_irq_domain_xlate, |
193 | .map = xtensa_irq_map, | ||
194 | }; | ||
143 | 195 | ||
144 | irq_set_chip_and_handler(index, &xtensa_irq_chip, | 196 | void __init init_IRQ(void) |
145 | handle_level_irq); | 197 | { |
146 | } | 198 | struct device_node *intc = NULL; |
147 | 199 | ||
148 | cached_irq_mask = 0; | 200 | cached_irq_mask = 0; |
201 | set_sr(~0, intclear); | ||
202 | |||
203 | #ifdef CONFIG_OF | ||
204 | /* The interrupt controller device node is mandatory */ | ||
205 | intc = of_find_compatible_node(NULL, NULL, "xtensa,pic"); | ||
206 | BUG_ON(!intc); | ||
207 | |||
208 | root_domain = irq_domain_add_linear(intc, NR_IRQS, | ||
209 | &xtensa_irq_domain_ops, NULL); | ||
210 | #else | ||
211 | root_domain = irq_domain_add_legacy(intc, NR_IRQS, 0, 0, | ||
212 | &xtensa_irq_domain_ops, NULL); | ||
213 | #endif | ||
214 | irq_set_default_host(root_domain); | ||
149 | 215 | ||
150 | variant_init_irq(); | 216 | variant_init_irq(); |
151 | } | 217 | } |
diff --git a/arch/xtensa/kernel/module.c b/arch/xtensa/kernel/module.c index 451dda928c93..b715237bae61 100644 --- a/arch/xtensa/kernel/module.c +++ b/arch/xtensa/kernel/module.c | |||
@@ -53,7 +53,7 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, | |||
53 | struct module *mod) | 53 | struct module *mod) |
54 | { | 54 | { |
55 | unsigned int i; | 55 | unsigned int i; |
56 | Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr; | 56 | Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr; |
57 | Elf32_Sym *sym; | 57 | Elf32_Sym *sym; |
58 | unsigned char *location; | 58 | unsigned char *location; |
59 | uint32_t value; | 59 | uint32_t value; |
diff --git a/arch/xtensa/kernel/platform.c b/arch/xtensa/kernel/platform.c index 97230e46cbe7..44bf21c3769a 100644 --- a/arch/xtensa/kernel/platform.c +++ b/arch/xtensa/kernel/platform.c | |||
@@ -44,4 +44,3 @@ _F(void, calibrate_ccount, (void), | |||
44 | ccount_per_jiffy = 10 * (1000000UL/HZ); | 44 | ccount_per_jiffy = 10 * (1000000UL/HZ); |
45 | }); | 45 | }); |
46 | #endif | 46 | #endif |
47 | |||
diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c index 1908f6642d31..0dd5784416d3 100644 --- a/arch/xtensa/kernel/process.c +++ b/arch/xtensa/kernel/process.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include <asm/regs.h> | 45 | #include <asm/regs.h> |
46 | 46 | ||
47 | extern void ret_from_fork(void); | 47 | extern void ret_from_fork(void); |
48 | extern void ret_from_kernel_thread(void); | ||
48 | 49 | ||
49 | struct task_struct *current_set[NR_CPUS] = {&init_task, }; | 50 | struct task_struct *current_set[NR_CPUS] = {&init_task, }; |
50 | 51 | ||
@@ -107,7 +108,7 @@ void coprocessor_flush_all(struct thread_info *ti) | |||
107 | 108 | ||
108 | void cpu_idle(void) | 109 | void cpu_idle(void) |
109 | { | 110 | { |
110 | local_irq_enable(); | 111 | local_irq_enable(); |
111 | 112 | ||
112 | /* endless idle loop with no priority at all */ | 113 | /* endless idle loop with no priority at all */ |
113 | while (1) { | 114 | while (1) { |
@@ -158,18 +159,30 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) | |||
158 | /* | 159 | /* |
159 | * Copy thread. | 160 | * Copy thread. |
160 | * | 161 | * |
162 | * There are two modes in which this function is called: | ||
163 | * 1) Userspace thread creation, | ||
164 | * regs != NULL, usp_thread_fn is userspace stack pointer. | ||
165 | * It is expected to copy parent regs (in case CLONE_VM is not set | ||
166 | * in the clone_flags) and set up passed usp in the childregs. | ||
167 | * 2) Kernel thread creation, | ||
168 | * regs == NULL, usp_thread_fn is the function to run in the new thread | ||
169 | * and thread_fn_arg is its parameter. | ||
170 | * childregs are not used for the kernel threads. | ||
171 | * | ||
161 | * The stack layout for the new thread looks like this: | 172 | * The stack layout for the new thread looks like this: |
162 | * | 173 | * |
163 | * +------------------------+ <- sp in childregs (= tos) | 174 | * +------------------------+ |
164 | * | childregs | | 175 | * | childregs | |
165 | * +------------------------+ <- thread.sp = sp in dummy-frame | 176 | * +------------------------+ <- thread.sp = sp in dummy-frame |
166 | * | dummy-frame | (saved in dummy-frame spill-area) | 177 | * | dummy-frame | (saved in dummy-frame spill-area) |
167 | * +------------------------+ | 178 | * +------------------------+ |
168 | * | 179 | * |
169 | * We create a dummy frame to return to ret_from_fork: | 180 | * We create a dummy frame to return to either ret_from_fork or |
170 | * a0 points to ret_from_fork (simulating a call4) | 181 | * ret_from_kernel_thread: |
182 | * a0 points to ret_from_fork/ret_from_kernel_thread (simulating a call4) | ||
171 | * sp points to itself (thread.sp) | 183 | * sp points to itself (thread.sp) |
172 | * a2, a3 are unused. | 184 | * a2, a3 are unused for userspace threads, |
185 | * a2 points to thread_fn, a3 holds thread_fn arg for kernel threads. | ||
173 | * | 186 | * |
174 | * Note: This is a pristine frame, so we don't need any spill region on top of | 187 | * Note: This is a pristine frame, so we don't need any spill region on top of |
175 | * childregs. | 188 | * childregs. |
@@ -185,43 +198,62 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) | |||
185 | * involved. Much simpler to just not copy those live frames across. | 198 | * involved. Much simpler to just not copy those live frames across. |
186 | */ | 199 | */ |
187 | 200 | ||
188 | int copy_thread(unsigned long clone_flags, unsigned long usp, | 201 | int copy_thread(unsigned long clone_flags, unsigned long usp_thread_fn, |
189 | unsigned long unused, | 202 | unsigned long thread_fn_arg, struct task_struct *p) |
190 | struct task_struct * p, struct pt_regs * regs) | ||
191 | { | 203 | { |
192 | struct pt_regs *childregs; | 204 | struct pt_regs *childregs = task_pt_regs(p); |
193 | unsigned long tos; | ||
194 | int user_mode = user_mode(regs); | ||
195 | 205 | ||
196 | #if (XTENSA_HAVE_COPROCESSORS || XTENSA_HAVE_IO_PORTS) | 206 | #if (XTENSA_HAVE_COPROCESSORS || XTENSA_HAVE_IO_PORTS) |
197 | struct thread_info *ti; | 207 | struct thread_info *ti; |
198 | #endif | 208 | #endif |
199 | 209 | ||
200 | /* Set up new TSS. */ | ||
201 | tos = (unsigned long)task_stack_page(p) + THREAD_SIZE; | ||
202 | if (user_mode) | ||
203 | childregs = (struct pt_regs*)(tos - PT_USER_SIZE); | ||
204 | else | ||
205 | childregs = (struct pt_regs*)tos - 1; | ||
206 | |||
207 | /* This does not copy all the regs. In a bout of brilliance or madness, | ||
208 | ARs beyond a0-a15 exist past the end of the struct. */ | ||
209 | *childregs = *regs; | ||
210 | |||
211 | /* Create a call4 dummy-frame: a0 = 0, a1 = childregs. */ | 210 | /* Create a call4 dummy-frame: a0 = 0, a1 = childregs. */ |
212 | *((int*)childregs - 3) = (unsigned long)childregs; | 211 | *((int*)childregs - 3) = (unsigned long)childregs; |
213 | *((int*)childregs - 4) = 0; | 212 | *((int*)childregs - 4) = 0; |
214 | 213 | ||
215 | childregs->areg[2] = 0; | ||
216 | p->set_child_tid = p->clear_child_tid = NULL; | ||
217 | p->thread.ra = MAKE_RA_FOR_CALL((unsigned long)ret_from_fork, 0x1); | ||
218 | p->thread.sp = (unsigned long)childregs; | 214 | p->thread.sp = (unsigned long)childregs; |
219 | 215 | ||
220 | if (user_mode(regs)) { | 216 | if (!(p->flags & PF_KTHREAD)) { |
217 | struct pt_regs *regs = current_pt_regs(); | ||
218 | unsigned long usp = usp_thread_fn ? | ||
219 | usp_thread_fn : regs->areg[1]; | ||
220 | |||
221 | p->thread.ra = MAKE_RA_FOR_CALL( | ||
222 | (unsigned long)ret_from_fork, 0x1); | ||
221 | 223 | ||
224 | /* This does not copy all the regs. | ||
225 | * In a bout of brilliance or madness, | ||
226 | * ARs beyond a0-a15 exist past the end of the struct. | ||
227 | */ | ||
228 | *childregs = *regs; | ||
222 | childregs->areg[1] = usp; | 229 | childregs->areg[1] = usp; |
230 | childregs->areg[2] = 0; | ||
231 | |||
232 | /* When sharing memory with the parent thread, the child | ||
233 | usually starts on a pristine stack, so we have to reset | ||
234 | windowbase, windowstart and wmask. | ||
235 | (Note that such a new thread is required to always create | ||
236 | an initial call4 frame) | ||
237 | The exception is vfork, where the new thread continues to | ||
238 | run on the parent's stack until it calls execve. This could | ||
239 | be a call8 or call12, which requires a legal stack frame | ||
240 | of the previous caller for the overflow handlers to work. | ||
241 | (Note that it's always legal to overflow live registers). | ||
242 | In this case, ensure to spill at least the stack pointer | ||
243 | of that frame. */ | ||
244 | |||
223 | if (clone_flags & CLONE_VM) { | 245 | if (clone_flags & CLONE_VM) { |
224 | childregs->wmask = 1; /* can't share live windows */ | 246 | /* check that caller window is live and same stack */ |
247 | int len = childregs->wmask & ~0xf; | ||
248 | if (regs->areg[1] == usp && len != 0) { | ||
249 | int callinc = (regs->areg[0] >> 30) & 3; | ||
250 | int caller_ars = XCHAL_NUM_AREGS - callinc * 4; | ||
251 | put_user(regs->areg[caller_ars+1], | ||
252 | (unsigned __user*)(usp - 12)); | ||
253 | } | ||
254 | childregs->wmask = 1; | ||
255 | childregs->windowstart = 1; | ||
256 | childregs->windowbase = 0; | ||
225 | } else { | 257 | } else { |
226 | int len = childregs->wmask & ~0xf; | 258 | int len = childregs->wmask & ~0xf; |
227 | memcpy(&childregs->areg[XCHAL_NUM_AREGS - len/4], | 259 | memcpy(&childregs->areg[XCHAL_NUM_AREGS - len/4], |
@@ -230,11 +262,19 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, | |||
230 | // FIXME: we need to set THREADPTR in thread_info... | 262 | // FIXME: we need to set THREADPTR in thread_info... |
231 | if (clone_flags & CLONE_SETTLS) | 263 | if (clone_flags & CLONE_SETTLS) |
232 | childregs->areg[2] = childregs->areg[6]; | 264 | childregs->areg[2] = childregs->areg[6]; |
233 | |||
234 | } else { | 265 | } else { |
235 | /* In kernel space, we start a new thread with a new stack. */ | 266 | p->thread.ra = MAKE_RA_FOR_CALL( |
236 | childregs->wmask = 1; | 267 | (unsigned long)ret_from_kernel_thread, 1); |
237 | childregs->areg[1] = tos; | 268 | |
269 | /* pass parameters to ret_from_kernel_thread: | ||
270 | * a2 = thread_fn, a3 = thread_fn arg | ||
271 | */ | ||
272 | *((int *)childregs - 1) = thread_fn_arg; | ||
273 | *((int *)childregs - 2) = usp_thread_fn; | ||
274 | |||
275 | /* Childregs are only used when we're going to userspace | ||
276 | * in which case start_thread will set them up. | ||
277 | */ | ||
238 | } | 278 | } |
239 | 279 | ||
240 | #if (XTENSA_HAVE_COPROCESSORS || XTENSA_HAVE_IO_PORTS) | 280 | #if (XTENSA_HAVE_COPROCESSORS || XTENSA_HAVE_IO_PORTS) |
@@ -323,39 +363,3 @@ int dump_fpu(void) | |||
323 | { | 363 | { |
324 | return 0; | 364 | return 0; |
325 | } | 365 | } |
326 | |||
327 | asmlinkage | ||
328 | long xtensa_clone(unsigned long clone_flags, unsigned long newsp, | ||
329 | void __user *parent_tid, void *child_tls, | ||
330 | void __user *child_tid, long a5, | ||
331 | struct pt_regs *regs) | ||
332 | { | ||
333 | if (!newsp) | ||
334 | newsp = regs->areg[1]; | ||
335 | return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid); | ||
336 | } | ||
337 | |||
338 | /* | ||
339 | * xtensa_execve() executes a new program. | ||
340 | */ | ||
341 | |||
342 | asmlinkage | ||
343 | long xtensa_execve(const char __user *name, | ||
344 | const char __user *const __user *argv, | ||
345 | const char __user *const __user *envp, | ||
346 | long a3, long a4, long a5, | ||
347 | struct pt_regs *regs) | ||
348 | { | ||
349 | long error; | ||
350 | struct filename *filename; | ||
351 | |||
352 | filename = getname(name); | ||
353 | error = PTR_ERR(filename); | ||
354 | if (IS_ERR(filename)) | ||
355 | goto out; | ||
356 | error = do_execve(filename->name, argv, envp, regs); | ||
357 | putname(filename); | ||
358 | out: | ||
359 | return error; | ||
360 | } | ||
361 | |||
diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c index 33eea4c16f12..61fb2e9e9035 100644 --- a/arch/xtensa/kernel/ptrace.c +++ b/arch/xtensa/kernel/ptrace.c | |||
@@ -154,7 +154,7 @@ int ptrace_setxregs(struct task_struct *child, void __user *uregs) | |||
154 | coprocessor_flush_all(ti); | 154 | coprocessor_flush_all(ti); |
155 | coprocessor_release_all(ti); | 155 | coprocessor_release_all(ti); |
156 | 156 | ||
157 | ret |= __copy_from_user(&ti->xtregs_cp, &xtregs->cp0, | 157 | ret |= __copy_from_user(&ti->xtregs_cp, &xtregs->cp0, |
158 | sizeof(xtregs_coprocessor_t)); | 158 | sizeof(xtregs_coprocessor_t)); |
159 | #endif | 159 | #endif |
160 | ret |= __copy_from_user(®s->xtregs_opt, &xtregs->opt, | 160 | ret |= __copy_from_user(®s->xtregs_opt, &xtregs->opt, |
@@ -343,4 +343,3 @@ void do_syscall_trace_leave(struct pt_regs *regs) | |||
343 | && (current->ptrace & PT_PTRACED)) | 343 | && (current->ptrace & PT_PTRACED)) |
344 | do_syscall_trace(); | 344 | do_syscall_trace(); |
345 | } | 345 | } |
346 | |||
diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c index b237988ba6d7..24c1a57abb40 100644 --- a/arch/xtensa/kernel/setup.c +++ b/arch/xtensa/kernel/setup.c | |||
@@ -22,6 +22,11 @@ | |||
22 | #include <linux/bootmem.h> | 22 | #include <linux/bootmem.h> |
23 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
24 | 24 | ||
25 | #ifdef CONFIG_OF | ||
26 | #include <linux/of_fdt.h> | ||
27 | #include <linux/of_platform.h> | ||
28 | #endif | ||
29 | |||
25 | #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE) | 30 | #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE) |
26 | # include <linux/console.h> | 31 | # include <linux/console.h> |
27 | #endif | 32 | #endif |
@@ -42,6 +47,7 @@ | |||
42 | #include <asm/page.h> | 47 | #include <asm/page.h> |
43 | #include <asm/setup.h> | 48 | #include <asm/setup.h> |
44 | #include <asm/param.h> | 49 | #include <asm/param.h> |
50 | #include <asm/traps.h> | ||
45 | 51 | ||
46 | #include <platform/hardware.h> | 52 | #include <platform/hardware.h> |
47 | 53 | ||
@@ -64,6 +70,11 @@ int initrd_is_mapped = 0; | |||
64 | extern int initrd_below_start_ok; | 70 | extern int initrd_below_start_ok; |
65 | #endif | 71 | #endif |
66 | 72 | ||
73 | #ifdef CONFIG_OF | ||
74 | extern u32 __dtb_start[]; | ||
75 | void *dtb_start = __dtb_start; | ||
76 | #endif | ||
77 | |||
67 | unsigned char aux_device_present; | 78 | unsigned char aux_device_present; |
68 | extern unsigned long loops_per_jiffy; | 79 | extern unsigned long loops_per_jiffy; |
69 | 80 | ||
@@ -83,6 +94,8 @@ extern void init_mmu(void); | |||
83 | static inline void init_mmu(void) { } | 94 | static inline void init_mmu(void) { } |
84 | #endif | 95 | #endif |
85 | 96 | ||
97 | extern int mem_reserve(unsigned long, unsigned long, int); | ||
98 | extern void bootmem_init(void); | ||
86 | extern void zones_init(void); | 99 | extern void zones_init(void); |
87 | 100 | ||
88 | /* | 101 | /* |
@@ -104,28 +117,33 @@ typedef struct tagtable { | |||
104 | 117 | ||
105 | /* parse current tag */ | 118 | /* parse current tag */ |
106 | 119 | ||
107 | static int __init parse_tag_mem(const bp_tag_t *tag) | 120 | static int __init add_sysmem_bank(unsigned long type, unsigned long start, |
121 | unsigned long end) | ||
108 | { | 122 | { |
109 | meminfo_t *mi = (meminfo_t*)(tag->data); | ||
110 | |||
111 | if (mi->type != MEMORY_TYPE_CONVENTIONAL) | ||
112 | return -1; | ||
113 | |||
114 | if (sysmem.nr_banks >= SYSMEM_BANKS_MAX) { | 123 | if (sysmem.nr_banks >= SYSMEM_BANKS_MAX) { |
115 | printk(KERN_WARNING | 124 | printk(KERN_WARNING |
116 | "Ignoring memory bank 0x%08lx size %ldKB\n", | 125 | "Ignoring memory bank 0x%08lx size %ldKB\n", |
117 | (unsigned long)mi->start, | 126 | start, end - start); |
118 | (unsigned long)mi->end - (unsigned long)mi->start); | ||
119 | return -EINVAL; | 127 | return -EINVAL; |
120 | } | 128 | } |
121 | sysmem.bank[sysmem.nr_banks].type = mi->type; | 129 | sysmem.bank[sysmem.nr_banks].type = type; |
122 | sysmem.bank[sysmem.nr_banks].start = PAGE_ALIGN(mi->start); | 130 | sysmem.bank[sysmem.nr_banks].start = PAGE_ALIGN(start); |
123 | sysmem.bank[sysmem.nr_banks].end = mi->end & PAGE_MASK; | 131 | sysmem.bank[sysmem.nr_banks].end = end & PAGE_MASK; |
124 | sysmem.nr_banks++; | 132 | sysmem.nr_banks++; |
125 | 133 | ||
126 | return 0; | 134 | return 0; |
127 | } | 135 | } |
128 | 136 | ||
137 | static int __init parse_tag_mem(const bp_tag_t *tag) | ||
138 | { | ||
139 | meminfo_t *mi = (meminfo_t *)(tag->data); | ||
140 | |||
141 | if (mi->type != MEMORY_TYPE_CONVENTIONAL) | ||
142 | return -1; | ||
143 | |||
144 | return add_sysmem_bank(mi->type, mi->start, mi->end); | ||
145 | } | ||
146 | |||
129 | __tagtable(BP_TAG_MEMORY, parse_tag_mem); | 147 | __tagtable(BP_TAG_MEMORY, parse_tag_mem); |
130 | 148 | ||
131 | #ifdef CONFIG_BLK_DEV_INITRD | 149 | #ifdef CONFIG_BLK_DEV_INITRD |
@@ -142,12 +160,31 @@ static int __init parse_tag_initrd(const bp_tag_t* tag) | |||
142 | 160 | ||
143 | __tagtable(BP_TAG_INITRD, parse_tag_initrd); | 161 | __tagtable(BP_TAG_INITRD, parse_tag_initrd); |
144 | 162 | ||
163 | #ifdef CONFIG_OF | ||
164 | |||
165 | static int __init parse_tag_fdt(const bp_tag_t *tag) | ||
166 | { | ||
167 | dtb_start = (void *)(tag->data[0]); | ||
168 | return 0; | ||
169 | } | ||
170 | |||
171 | __tagtable(BP_TAG_FDT, parse_tag_fdt); | ||
172 | |||
173 | void __init early_init_dt_setup_initrd_arch(unsigned long start, | ||
174 | unsigned long end) | ||
175 | { | ||
176 | initrd_start = (void *)__va(start); | ||
177 | initrd_end = (void *)__va(end); | ||
178 | initrd_below_start_ok = 1; | ||
179 | } | ||
180 | |||
181 | #endif /* CONFIG_OF */ | ||
182 | |||
145 | #endif /* CONFIG_BLK_DEV_INITRD */ | 183 | #endif /* CONFIG_BLK_DEV_INITRD */ |
146 | 184 | ||
147 | static int __init parse_tag_cmdline(const bp_tag_t* tag) | 185 | static int __init parse_tag_cmdline(const bp_tag_t* tag) |
148 | { | 186 | { |
149 | strncpy(command_line, (char*)(tag->data), COMMAND_LINE_SIZE); | 187 | strlcpy(command_line, (char *)(tag->data), COMMAND_LINE_SIZE); |
150 | command_line[COMMAND_LINE_SIZE - 1] = '\0'; | ||
151 | return 0; | 188 | return 0; |
152 | } | 189 | } |
153 | 190 | ||
@@ -185,6 +222,58 @@ static int __init parse_bootparam(const bp_tag_t* tag) | |||
185 | return 0; | 222 | return 0; |
186 | } | 223 | } |
187 | 224 | ||
225 | #ifdef CONFIG_OF | ||
226 | |||
227 | void __init early_init_dt_add_memory_arch(u64 base, u64 size) | ||
228 | { | ||
229 | size &= PAGE_MASK; | ||
230 | add_sysmem_bank(MEMORY_TYPE_CONVENTIONAL, base, base + size); | ||
231 | } | ||
232 | |||
233 | void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) | ||
234 | { | ||
235 | return __alloc_bootmem(size, align, 0); | ||
236 | } | ||
237 | |||
238 | void __init early_init_devtree(void *params) | ||
239 | { | ||
240 | /* Setup flat device-tree pointer */ | ||
241 | initial_boot_params = params; | ||
242 | |||
243 | /* Retrieve various informations from the /chosen node of the | ||
244 | * device-tree, including the platform type, initrd location and | ||
245 | * size, TCE reserve, and more ... | ||
246 | */ | ||
247 | if (!command_line[0]) | ||
248 | of_scan_flat_dt(early_init_dt_scan_chosen, command_line); | ||
249 | |||
250 | /* Scan memory nodes and rebuild MEMBLOCKs */ | ||
251 | of_scan_flat_dt(early_init_dt_scan_root, NULL); | ||
252 | if (sysmem.nr_banks == 0) | ||
253 | of_scan_flat_dt(early_init_dt_scan_memory, NULL); | ||
254 | } | ||
255 | |||
256 | static void __init copy_devtree(void) | ||
257 | { | ||
258 | void *alloc = early_init_dt_alloc_memory_arch( | ||
259 | be32_to_cpu(initial_boot_params->totalsize), 0); | ||
260 | if (alloc) { | ||
261 | memcpy(alloc, initial_boot_params, | ||
262 | be32_to_cpu(initial_boot_params->totalsize)); | ||
263 | initial_boot_params = alloc; | ||
264 | } | ||
265 | } | ||
266 | |||
267 | static int __init xtensa_device_probe(void) | ||
268 | { | ||
269 | of_platform_populate(NULL, NULL, NULL, NULL); | ||
270 | return 0; | ||
271 | } | ||
272 | |||
273 | device_initcall(xtensa_device_probe); | ||
274 | |||
275 | #endif /* CONFIG_OF */ | ||
276 | |||
188 | /* | 277 | /* |
189 | * Initialize architecture. (Early stage) | 278 | * Initialize architecture. (Early stage) |
190 | */ | 279 | */ |
@@ -193,14 +282,14 @@ void __init init_arch(bp_tag_t *bp_start) | |||
193 | { | 282 | { |
194 | sysmem.nr_banks = 0; | 283 | sysmem.nr_banks = 0; |
195 | 284 | ||
196 | #ifdef CONFIG_CMDLINE_BOOL | ||
197 | strcpy(command_line, default_command_line); | ||
198 | #endif | ||
199 | |||
200 | /* Parse boot parameters */ | 285 | /* Parse boot parameters */ |
201 | 286 | ||
202 | if (bp_start) | 287 | if (bp_start) |
203 | parse_bootparam(bp_start); | 288 | parse_bootparam(bp_start); |
289 | |||
290 | #ifdef CONFIG_OF | ||
291 | early_init_devtree(dtb_start); | ||
292 | #endif | ||
204 | 293 | ||
205 | if (sysmem.nr_banks == 0) { | 294 | if (sysmem.nr_banks == 0) { |
206 | sysmem.nr_banks = 1; | 295 | sysmem.nr_banks = 1; |
@@ -209,6 +298,11 @@ void __init init_arch(bp_tag_t *bp_start) | |||
209 | + PLATFORM_DEFAULT_MEM_SIZE; | 298 | + PLATFORM_DEFAULT_MEM_SIZE; |
210 | } | 299 | } |
211 | 300 | ||
301 | #ifdef CONFIG_CMDLINE_BOOL | ||
302 | if (!command_line[0]) | ||
303 | strlcpy(command_line, default_command_line, COMMAND_LINE_SIZE); | ||
304 | #endif | ||
305 | |||
212 | /* Early hook for platforms */ | 306 | /* Early hook for platforms */ |
213 | 307 | ||
214 | platform_init(bp_start); | 308 | platform_init(bp_start); |
@@ -235,15 +329,130 @@ extern char _UserExceptionVector_text_end; | |||
235 | extern char _DoubleExceptionVector_literal_start; | 329 | extern char _DoubleExceptionVector_literal_start; |
236 | extern char _DoubleExceptionVector_text_end; | 330 | extern char _DoubleExceptionVector_text_end; |
237 | 331 | ||
238 | void __init setup_arch(char **cmdline_p) | 332 | |
333 | #ifdef CONFIG_S32C1I_SELFTEST | ||
334 | #if XCHAL_HAVE_S32C1I | ||
335 | |||
336 | static int __initdata rcw_word, rcw_probe_pc, rcw_exc; | ||
337 | |||
338 | /* | ||
339 | * Basic atomic compare-and-swap, that records PC of S32C1I for probing. | ||
340 | * | ||
341 | * If *v == cmp, set *v = set. Return previous *v. | ||
342 | */ | ||
343 | static inline int probed_compare_swap(int *v, int cmp, int set) | ||
344 | { | ||
345 | int tmp; | ||
346 | |||
347 | __asm__ __volatile__( | ||
348 | " movi %1, 1f\n" | ||
349 | " s32i %1, %4, 0\n" | ||
350 | " wsr %2, scompare1\n" | ||
351 | "1: s32c1i %0, %3, 0\n" | ||
352 | : "=a" (set), "=&a" (tmp) | ||
353 | : "a" (cmp), "a" (v), "a" (&rcw_probe_pc), "0" (set) | ||
354 | : "memory" | ||
355 | ); | ||
356 | return set; | ||
357 | } | ||
358 | |||
359 | /* Handle probed exception */ | ||
360 | |||
361 | void __init do_probed_exception(struct pt_regs *regs, unsigned long exccause) | ||
362 | { | ||
363 | if (regs->pc == rcw_probe_pc) { /* exception on s32c1i ? */ | ||
364 | regs->pc += 3; /* skip the s32c1i instruction */ | ||
365 | rcw_exc = exccause; | ||
366 | } else { | ||
367 | do_unhandled(regs, exccause); | ||
368 | } | ||
369 | } | ||
370 | |||
371 | /* Simple test of S32C1I (soc bringup assist) */ | ||
372 | |||
373 | void __init check_s32c1i(void) | ||
374 | { | ||
375 | int n, cause1, cause2; | ||
376 | void *handbus, *handdata, *handaddr; /* temporarily saved handlers */ | ||
377 | |||
378 | rcw_probe_pc = 0; | ||
379 | handbus = trap_set_handler(EXCCAUSE_LOAD_STORE_ERROR, | ||
380 | do_probed_exception); | ||
381 | handdata = trap_set_handler(EXCCAUSE_LOAD_STORE_DATA_ERROR, | ||
382 | do_probed_exception); | ||
383 | handaddr = trap_set_handler(EXCCAUSE_LOAD_STORE_ADDR_ERROR, | ||
384 | do_probed_exception); | ||
385 | |||
386 | /* First try an S32C1I that does not store: */ | ||
387 | rcw_exc = 0; | ||
388 | rcw_word = 1; | ||
389 | n = probed_compare_swap(&rcw_word, 0, 2); | ||
390 | cause1 = rcw_exc; | ||
391 | |||
392 | /* took exception? */ | ||
393 | if (cause1 != 0) { | ||
394 | /* unclean exception? */ | ||
395 | if (n != 2 || rcw_word != 1) | ||
396 | panic("S32C1I exception error"); | ||
397 | } else if (rcw_word != 1 || n != 1) { | ||
398 | panic("S32C1I compare error"); | ||
399 | } | ||
400 | |||
401 | /* Then an S32C1I that stores: */ | ||
402 | rcw_exc = 0; | ||
403 | rcw_word = 0x1234567; | ||
404 | n = probed_compare_swap(&rcw_word, 0x1234567, 0xabcde); | ||
405 | cause2 = rcw_exc; | ||
406 | |||
407 | if (cause2 != 0) { | ||
408 | /* unclean exception? */ | ||
409 | if (n != 0xabcde || rcw_word != 0x1234567) | ||
410 | panic("S32C1I exception error (b)"); | ||
411 | } else if (rcw_word != 0xabcde || n != 0x1234567) { | ||
412 | panic("S32C1I store error"); | ||
413 | } | ||
414 | |||
415 | /* Verify consistency of exceptions: */ | ||
416 | if (cause1 || cause2) { | ||
417 | pr_warn("S32C1I took exception %d, %d\n", cause1, cause2); | ||
418 | /* If emulation of S32C1I upon bus error gets implemented, | ||
419 | we can get rid of this panic for single core (not SMP) */ | ||
420 | panic("S32C1I exceptions not currently supported"); | ||
421 | } | ||
422 | if (cause1 != cause2) | ||
423 | panic("inconsistent S32C1I exceptions"); | ||
424 | |||
425 | trap_set_handler(EXCCAUSE_LOAD_STORE_ERROR, handbus); | ||
426 | trap_set_handler(EXCCAUSE_LOAD_STORE_DATA_ERROR, handdata); | ||
427 | trap_set_handler(EXCCAUSE_LOAD_STORE_ADDR_ERROR, handaddr); | ||
428 | } | ||
429 | |||
430 | #else /* XCHAL_HAVE_S32C1I */ | ||
431 | |||
432 | /* This condition should not occur with a commercially deployed processor. | ||
433 | Display reminder for early engr test or demo chips / FPGA bitstreams */ | ||
434 | void __init check_s32c1i(void) | ||
435 | { | ||
436 | pr_warn("Processor configuration lacks atomic compare-and-swap support!\n"); | ||
437 | } | ||
438 | |||
439 | #endif /* XCHAL_HAVE_S32C1I */ | ||
440 | #else /* CONFIG_S32C1I_SELFTEST */ | ||
441 | |||
442 | void __init check_s32c1i(void) | ||
239 | { | 443 | { |
240 | extern int mem_reserve(unsigned long, unsigned long, int); | 444 | } |
241 | extern void bootmem_init(void); | 445 | |
446 | #endif /* CONFIG_S32C1I_SELFTEST */ | ||
242 | 447 | ||
243 | memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); | 448 | |
244 | boot_command_line[COMMAND_LINE_SIZE-1] = '\0'; | 449 | void __init setup_arch(char **cmdline_p) |
450 | { | ||
451 | strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); | ||
245 | *cmdline_p = command_line; | 452 | *cmdline_p = command_line; |
246 | 453 | ||
454 | check_s32c1i(); | ||
455 | |||
247 | /* Reserve some memory regions */ | 456 | /* Reserve some memory regions */ |
248 | 457 | ||
249 | #ifdef CONFIG_BLK_DEV_INITRD | 458 | #ifdef CONFIG_BLK_DEV_INITRD |
@@ -251,7 +460,7 @@ void __init setup_arch(char **cmdline_p) | |||
251 | initrd_is_mapped = mem_reserve(__pa(initrd_start), | 460 | initrd_is_mapped = mem_reserve(__pa(initrd_start), |
252 | __pa(initrd_end), 0); | 461 | __pa(initrd_end), 0); |
253 | initrd_below_start_ok = 1; | 462 | initrd_below_start_ok = 1; |
254 | } else { | 463 | } else { |
255 | initrd_start = 0; | 464 | initrd_start = 0; |
256 | } | 465 | } |
257 | #endif | 466 | #endif |
@@ -275,8 +484,12 @@ void __init setup_arch(char **cmdline_p) | |||
275 | 484 | ||
276 | bootmem_init(); | 485 | bootmem_init(); |
277 | 486 | ||
278 | platform_setup(cmdline_p); | 487 | #ifdef CONFIG_OF |
488 | copy_devtree(); | ||
489 | unflatten_device_tree(); | ||
490 | #endif | ||
279 | 491 | ||
492 | platform_setup(cmdline_p); | ||
280 | 493 | ||
281 | paging_init(); | 494 | paging_init(); |
282 | zones_init(); | 495 | zones_init(); |
@@ -326,7 +539,7 @@ c_show(struct seq_file *f, void *slot) | |||
326 | "core ID\t\t: " XCHAL_CORE_ID "\n" | 539 | "core ID\t\t: " XCHAL_CORE_ID "\n" |
327 | "build ID\t: 0x%x\n" | 540 | "build ID\t: 0x%x\n" |
328 | "byte order\t: %s\n" | 541 | "byte order\t: %s\n" |
329 | "cpu MHz\t\t: %lu.%02lu\n" | 542 | "cpu MHz\t\t: %lu.%02lu\n" |
330 | "bogomips\t: %lu.%02lu\n", | 543 | "bogomips\t: %lu.%02lu\n", |
331 | XCHAL_BUILD_UNIQUE_ID, | 544 | XCHAL_BUILD_UNIQUE_ID, |
332 | XCHAL_HAVE_BE ? "big" : "little", | 545 | XCHAL_HAVE_BE ? "big" : "little", |
@@ -381,6 +594,9 @@ c_show(struct seq_file *f, void *slot) | |||
381 | #if XCHAL_HAVE_FP | 594 | #if XCHAL_HAVE_FP |
382 | "fpu " | 595 | "fpu " |
383 | #endif | 596 | #endif |
597 | #if XCHAL_HAVE_S32C1I | ||
598 | "s32c1i " | ||
599 | #endif | ||
384 | "\n"); | 600 | "\n"); |
385 | 601 | ||
386 | /* Registers. */ | 602 | /* Registers. */ |
@@ -412,7 +628,7 @@ c_show(struct seq_file *f, void *slot) | |||
412 | "icache size\t: %d\n" | 628 | "icache size\t: %d\n" |
413 | "icache flags\t: " | 629 | "icache flags\t: " |
414 | #if XCHAL_ICACHE_LINE_LOCKABLE | 630 | #if XCHAL_ICACHE_LINE_LOCKABLE |
415 | "lock" | 631 | "lock " |
416 | #endif | 632 | #endif |
417 | "\n" | 633 | "\n" |
418 | "dcache line size: %d\n" | 634 | "dcache line size: %d\n" |
@@ -420,10 +636,10 @@ c_show(struct seq_file *f, void *slot) | |||
420 | "dcache size\t: %d\n" | 636 | "dcache size\t: %d\n" |
421 | "dcache flags\t: " | 637 | "dcache flags\t: " |
422 | #if XCHAL_DCACHE_IS_WRITEBACK | 638 | #if XCHAL_DCACHE_IS_WRITEBACK |
423 | "writeback" | 639 | "writeback " |
424 | #endif | 640 | #endif |
425 | #if XCHAL_DCACHE_LINE_LOCKABLE | 641 | #if XCHAL_DCACHE_LINE_LOCKABLE |
426 | "lock" | 642 | "lock " |
427 | #endif | 643 | #endif |
428 | "\n", | 644 | "\n", |
429 | XCHAL_ICACHE_LINESIZE, | 645 | XCHAL_ICACHE_LINESIZE, |
@@ -465,4 +681,3 @@ const struct seq_operations cpuinfo_op = | |||
465 | }; | 681 | }; |
466 | 682 | ||
467 | #endif /* CONFIG_PROC_FS */ | 683 | #endif /* CONFIG_PROC_FS */ |
468 | |||
diff --git a/arch/xtensa/kernel/signal.c b/arch/xtensa/kernel/signal.c index 63c566f627bc..de34d6be91cd 100644 --- a/arch/xtensa/kernel/signal.c +++ b/arch/xtensa/kernel/signal.c | |||
@@ -212,7 +212,7 @@ restore_sigcontext(struct pt_regs *regs, struct rt_sigframe __user *frame) | |||
212 | if (err) | 212 | if (err) |
213 | return err; | 213 | return err; |
214 | 214 | ||
215 | /* The signal handler may have used coprocessors in which | 215 | /* The signal handler may have used coprocessors in which |
216 | * case they are still enabled. We disable them to force a | 216 | * case they are still enabled. We disable them to force a |
217 | * reloading of the original task's CP state by the lazy | 217 | * reloading of the original task's CP state by the lazy |
218 | * context-switching mechanisms of CP exception handling. | 218 | * context-switching mechanisms of CP exception handling. |
@@ -396,7 +396,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
396 | */ | 396 | */ |
397 | 397 | ||
398 | /* Set up registers for signal handler */ | 398 | /* Set up registers for signal handler */ |
399 | start_thread(regs, (unsigned long) ka->sa.sa_handler, | 399 | start_thread(regs, (unsigned long) ka->sa.sa_handler, |
400 | (unsigned long) frame); | 400 | (unsigned long) frame); |
401 | 401 | ||
402 | /* Set up a stack frame for a call4 | 402 | /* Set up a stack frame for a call4 |
@@ -424,9 +424,9 @@ give_sigsegv: | |||
424 | return -EFAULT; | 424 | return -EFAULT; |
425 | } | 425 | } |
426 | 426 | ||
427 | asmlinkage long xtensa_sigaltstack(const stack_t __user *uss, | 427 | asmlinkage long xtensa_sigaltstack(const stack_t __user *uss, |
428 | stack_t __user *uoss, | 428 | stack_t __user *uoss, |
429 | long a2, long a3, long a4, long a5, | 429 | long a2, long a3, long a4, long a5, |
430 | struct pt_regs *regs) | 430 | struct pt_regs *regs) |
431 | { | 431 | { |
432 | return do_sigaltstack(uss, uoss, regs->areg[1]); | 432 | return do_sigaltstack(uss, uoss, regs->areg[1]); |
diff --git a/arch/xtensa/kernel/syscall.c b/arch/xtensa/kernel/syscall.c index a5c01e74d5d5..54fa8425cee2 100644 --- a/arch/xtensa/kernel/syscall.c +++ b/arch/xtensa/kernel/syscall.c | |||
@@ -32,10 +32,8 @@ typedef void (*syscall_t)(void); | |||
32 | syscall_t sys_call_table[__NR_syscall_count] /* FIXME __cacheline_aligned */= { | 32 | syscall_t sys_call_table[__NR_syscall_count] /* FIXME __cacheline_aligned */= { |
33 | [0 ... __NR_syscall_count - 1] = (syscall_t)&sys_ni_syscall, | 33 | [0 ... __NR_syscall_count - 1] = (syscall_t)&sys_ni_syscall, |
34 | 34 | ||
35 | #undef __SYSCALL | ||
36 | #define __SYSCALL(nr,symbol,nargs) [ nr ] = (syscall_t)symbol, | 35 | #define __SYSCALL(nr,symbol,nargs) [ nr ] = (syscall_t)symbol, |
37 | #undef __KERNEL_SYSCALLS__ | 36 | #include <uapi/asm/unistd.h> |
38 | #include <asm/unistd.h> | ||
39 | }; | 37 | }; |
40 | 38 | ||
41 | asmlinkage long xtensa_shmat(int shmid, char __user *shmaddr, int shmflg) | 39 | asmlinkage long xtensa_shmat(int shmid, char __user *shmaddr, int shmflg) |
@@ -49,8 +47,8 @@ asmlinkage long xtensa_shmat(int shmid, char __user *shmaddr, int shmflg) | |||
49 | return (long)ret; | 47 | return (long)ret; |
50 | } | 48 | } |
51 | 49 | ||
52 | asmlinkage long xtensa_fadvise64_64(int fd, int advice, unsigned long long offset, unsigned long long len) | 50 | asmlinkage long xtensa_fadvise64_64(int fd, int advice, |
51 | unsigned long long offset, unsigned long long len) | ||
53 | { | 52 | { |
54 | return sys_fadvise64_64(fd, offset, len, advice); | 53 | return sys_fadvise64_64(fd, offset, len, advice); |
55 | } | 54 | } |
56 | |||
diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c index ac62f9cf1e10..ffb474104311 100644 --- a/arch/xtensa/kernel/time.c +++ b/arch/xtensa/kernel/time.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/irq.h> | 22 | #include <linux/irq.h> |
23 | #include <linux/profile.h> | 23 | #include <linux/profile.h> |
24 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
25 | #include <linux/irqdomain.h> | ||
25 | 26 | ||
26 | #include <asm/timex.h> | 27 | #include <asm/timex.h> |
27 | #include <asm/platform.h> | 28 | #include <asm/platform.h> |
@@ -31,7 +32,7 @@ unsigned long ccount_per_jiffy; /* per 1/HZ */ | |||
31 | unsigned long nsec_per_ccount; /* nsec per ccount increment */ | 32 | unsigned long nsec_per_ccount; /* nsec per ccount increment */ |
32 | #endif | 33 | #endif |
33 | 34 | ||
34 | static cycle_t ccount_read(void) | 35 | static cycle_t ccount_read(struct clocksource *cs) |
35 | { | 36 | { |
36 | return (cycle_t)get_ccount(); | 37 | return (cycle_t)get_ccount(); |
37 | } | 38 | } |
@@ -52,6 +53,7 @@ static struct irqaction timer_irqaction = { | |||
52 | 53 | ||
53 | void __init time_init(void) | 54 | void __init time_init(void) |
54 | { | 55 | { |
56 | unsigned int irq; | ||
55 | #ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT | 57 | #ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT |
56 | printk("Calibrating CPU frequency "); | 58 | printk("Calibrating CPU frequency "); |
57 | platform_calibrate_ccount(); | 59 | platform_calibrate_ccount(); |
@@ -62,7 +64,8 @@ void __init time_init(void) | |||
62 | 64 | ||
63 | /* Initialize the linux timer interrupt. */ | 65 | /* Initialize the linux timer interrupt. */ |
64 | 66 | ||
65 | setup_irq(LINUX_TIMER_INT, &timer_irqaction); | 67 | irq = irq_create_mapping(NULL, LINUX_TIMER_INT); |
68 | setup_irq(irq, &timer_irqaction); | ||
66 | set_linux_timer(get_ccount() + CCOUNT_PER_JIFFY); | 69 | set_linux_timer(get_ccount() + CCOUNT_PER_JIFFY); |
67 | } | 70 | } |
68 | 71 | ||
diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c index 5caf2b64d43a..01e0111bf787 100644 --- a/arch/xtensa/kernel/traps.c +++ b/arch/xtensa/kernel/traps.c | |||
@@ -293,6 +293,17 @@ do_debug(struct pt_regs *regs) | |||
293 | } | 293 | } |
294 | 294 | ||
295 | 295 | ||
296 | /* Set exception C handler - for temporary use when probing exceptions */ | ||
297 | |||
298 | void * __init trap_set_handler(int cause, void *handler) | ||
299 | { | ||
300 | unsigned long *entry = &exc_table[EXC_TABLE_DEFAULT / 4 + cause]; | ||
301 | void *previous = (void *)*entry; | ||
302 | *entry = (unsigned long)handler; | ||
303 | return previous; | ||
304 | } | ||
305 | |||
306 | |||
296 | /* | 307 | /* |
297 | * Initialize dispatch tables. | 308 | * Initialize dispatch tables. |
298 | * | 309 | * |
@@ -397,7 +408,8 @@ static inline void spill_registers(void) | |||
397 | "wsr a13, sar\n\t" | 408 | "wsr a13, sar\n\t" |
398 | "wsr a14, ps\n\t" | 409 | "wsr a14, ps\n\t" |
399 | :: "a" (&a0), "a" (&ps) | 410 | :: "a" (&a0), "a" (&ps) |
400 | : "a2", "a3", "a4", "a7", "a11", "a12", "a13", "a14", "a15", "memory"); | 411 | : "a2", "a3", "a4", "a7", "a11", "a12", "a13", "a14", "a15", |
412 | "memory"); | ||
401 | } | 413 | } |
402 | 414 | ||
403 | void show_trace(struct task_struct *task, unsigned long *sp) | 415 | void show_trace(struct task_struct *task, unsigned long *sp) |
@@ -452,7 +464,7 @@ void show_stack(struct task_struct *task, unsigned long *sp) | |||
452 | 464 | ||
453 | if (!sp) | 465 | if (!sp) |
454 | sp = stack_pointer(task); | 466 | sp = stack_pointer(task); |
455 | stack = sp; | 467 | stack = sp; |
456 | 468 | ||
457 | printk("\nStack: "); | 469 | printk("\nStack: "); |
458 | 470 | ||
@@ -523,5 +535,3 @@ void die(const char * str, struct pt_regs * regs, long err) | |||
523 | 535 | ||
524 | do_exit(err); | 536 | do_exit(err); |
525 | } | 537 | } |
526 | |||
527 | |||
diff --git a/arch/xtensa/kernel/vectors.S b/arch/xtensa/kernel/vectors.S index 4462c1e595c2..68df35f66ce3 100644 --- a/arch/xtensa/kernel/vectors.S +++ b/arch/xtensa/kernel/vectors.S | |||
@@ -79,6 +79,8 @@ ENTRY(_UserExceptionVector) | |||
79 | l32i a0, a0, EXC_TABLE_FAST_USER # load handler | 79 | l32i a0, a0, EXC_TABLE_FAST_USER # load handler |
80 | jx a0 | 80 | jx a0 |
81 | 81 | ||
82 | ENDPROC(_UserExceptionVector) | ||
83 | |||
82 | /* | 84 | /* |
83 | * Kernel exception vector. (Exceptions with PS.UM == 0, PS.EXCM == 0) | 85 | * Kernel exception vector. (Exceptions with PS.UM == 0, PS.EXCM == 0) |
84 | * | 86 | * |
@@ -103,6 +105,7 @@ ENTRY(_KernelExceptionVector) | |||
103 | l32i a0, a0, EXC_TABLE_FAST_KERNEL # load handler address | 105 | l32i a0, a0, EXC_TABLE_FAST_KERNEL # load handler address |
104 | jx a0 | 106 | jx a0 |
105 | 107 | ||
108 | ENDPROC(_KernelExceptionVector) | ||
106 | 109 | ||
107 | /* | 110 | /* |
108 | * Double exception vector (Exceptions with PS.EXCM == 1) | 111 | * Double exception vector (Exceptions with PS.EXCM == 1) |
@@ -225,7 +228,13 @@ ENTRY(_DoubleExceptionVector) | |||
225 | /* Window overflow/underflow exception. Get stack pointer. */ | 228 | /* Window overflow/underflow exception. Get stack pointer. */ |
226 | 229 | ||
227 | mov a3, a2 | 230 | mov a3, a2 |
228 | movi a2, exc_table | 231 | /* This explicit literal and the following references to it are made |
232 | * in order to fit DoubleExceptionVector.literals into the available | ||
233 | * 16-byte gap before DoubleExceptionVector.text in the absence of | ||
234 | * link time relaxation. See kernel/vmlinux.lds.S | ||
235 | */ | ||
236 | .literal .Lexc_table, exc_table | ||
237 | l32r a2, .Lexc_table | ||
229 | l32i a2, a2, EXC_TABLE_KSTK | 238 | l32i a2, a2, EXC_TABLE_KSTK |
230 | 239 | ||
231 | /* Check for overflow/underflow exception, jump if overflow. */ | 240 | /* Check for overflow/underflow exception, jump if overflow. */ |
@@ -255,7 +264,7 @@ ENTRY(_DoubleExceptionVector) | |||
255 | s32i a0, a2, PT_AREG0 | 264 | s32i a0, a2, PT_AREG0 |
256 | 265 | ||
257 | wsr a3, excsave1 # save a3 | 266 | wsr a3, excsave1 # save a3 |
258 | movi a3, exc_table | 267 | l32r a3, .Lexc_table |
259 | 268 | ||
260 | rsr a0, exccause | 269 | rsr a0, exccause |
261 | s32i a0, a2, PT_DEPC # mark it as a regular exception | 270 | s32i a0, a2, PT_DEPC # mark it as a regular exception |
@@ -267,7 +276,7 @@ ENTRY(_DoubleExceptionVector) | |||
267 | 276 | ||
268 | /* a0: depc, a1: a1, a2: a2, a3: trashed, depc: a0, excsave1: a3 */ | 277 | /* a0: depc, a1: a1, a2: a2, a3: trashed, depc: a0, excsave1: a3 */ |
269 | 278 | ||
270 | movi a3, exc_table | 279 | l32r a3, .Lexc_table |
271 | s32i a2, a3, EXC_TABLE_DOUBLE_SAVE # temporary variable | 280 | s32i a2, a3, EXC_TABLE_DOUBLE_SAVE # temporary variable |
272 | 281 | ||
273 | /* Enter critical section. */ | 282 | /* Enter critical section. */ |
@@ -296,7 +305,7 @@ ENTRY(_DoubleExceptionVector) | |||
296 | 305 | ||
297 | /* a0: avail, a1: a1, a2: kstk, a3: avail, depc: a2, excsave: a3 */ | 306 | /* a0: avail, a1: a1, a2: kstk, a3: avail, depc: a2, excsave: a3 */ |
298 | 307 | ||
299 | movi a3, exc_table | 308 | l32r a3, .Lexc_table |
300 | rsr a0, exccause | 309 | rsr a0, exccause |
301 | addx4 a0, a0, a3 | 310 | addx4 a0, a0, a3 |
302 | l32i a0, a0, EXC_TABLE_FAST_USER | 311 | l32i a0, a0, EXC_TABLE_FAST_USER |
@@ -338,6 +347,7 @@ ENTRY(_DoubleExceptionVector) | |||
338 | 347 | ||
339 | .end literal_prefix | 348 | .end literal_prefix |
340 | 349 | ||
350 | ENDPROC(_DoubleExceptionVector) | ||
341 | 351 | ||
342 | /* | 352 | /* |
343 | * Debug interrupt vector | 353 | * Debug interrupt vector |
@@ -349,9 +359,11 @@ ENTRY(_DoubleExceptionVector) | |||
349 | .section .DebugInterruptVector.text, "ax" | 359 | .section .DebugInterruptVector.text, "ax" |
350 | 360 | ||
351 | ENTRY(_DebugInterruptVector) | 361 | ENTRY(_DebugInterruptVector) |
362 | |||
352 | xsr a0, SREG_EXCSAVE + XCHAL_DEBUGLEVEL | 363 | xsr a0, SREG_EXCSAVE + XCHAL_DEBUGLEVEL |
353 | jx a0 | 364 | jx a0 |
354 | 365 | ||
366 | ENDPROC(_DebugInterruptVector) | ||
355 | 367 | ||
356 | 368 | ||
357 | /* Window overflow and underflow handlers. | 369 | /* Window overflow and underflow handlers. |
@@ -363,38 +375,43 @@ ENTRY(_DebugInterruptVector) | |||
363 | * we try to access any page that would cause a page fault early. | 375 | * we try to access any page that would cause a page fault early. |
364 | */ | 376 | */ |
365 | 377 | ||
378 | #define ENTRY_ALIGN64(name) \ | ||
379 | .globl name; \ | ||
380 | .align 64; \ | ||
381 | name: | ||
382 | |||
366 | .section .WindowVectors.text, "ax" | 383 | .section .WindowVectors.text, "ax" |
367 | 384 | ||
368 | 385 | ||
369 | /* 4-Register Window Overflow Vector (Handler) */ | 386 | /* 4-Register Window Overflow Vector (Handler) */ |
370 | 387 | ||
371 | .align 64 | 388 | ENTRY_ALIGN64(_WindowOverflow4) |
372 | .global _WindowOverflow4 | 389 | |
373 | _WindowOverflow4: | ||
374 | s32e a0, a5, -16 | 390 | s32e a0, a5, -16 |
375 | s32e a1, a5, -12 | 391 | s32e a1, a5, -12 |
376 | s32e a2, a5, -8 | 392 | s32e a2, a5, -8 |
377 | s32e a3, a5, -4 | 393 | s32e a3, a5, -4 |
378 | rfwo | 394 | rfwo |
379 | 395 | ||
396 | ENDPROC(_WindowOverflow4) | ||
397 | |||
380 | 398 | ||
381 | /* 4-Register Window Underflow Vector (Handler) */ | 399 | /* 4-Register Window Underflow Vector (Handler) */ |
382 | 400 | ||
383 | .align 64 | 401 | ENTRY_ALIGN64(_WindowUnderflow4) |
384 | .global _WindowUnderflow4 | 402 | |
385 | _WindowUnderflow4: | ||
386 | l32e a0, a5, -16 | 403 | l32e a0, a5, -16 |
387 | l32e a1, a5, -12 | 404 | l32e a1, a5, -12 |
388 | l32e a2, a5, -8 | 405 | l32e a2, a5, -8 |
389 | l32e a3, a5, -4 | 406 | l32e a3, a5, -4 |
390 | rfwu | 407 | rfwu |
391 | 408 | ||
409 | ENDPROC(_WindowUnderflow4) | ||
392 | 410 | ||
393 | /* 8-Register Window Overflow Vector (Handler) */ | 411 | /* 8-Register Window Overflow Vector (Handler) */ |
394 | 412 | ||
395 | .align 64 | 413 | ENTRY_ALIGN64(_WindowOverflow8) |
396 | .global _WindowOverflow8 | 414 | |
397 | _WindowOverflow8: | ||
398 | s32e a0, a9, -16 | 415 | s32e a0, a9, -16 |
399 | l32e a0, a1, -12 | 416 | l32e a0, a1, -12 |
400 | s32e a2, a9, -8 | 417 | s32e a2, a9, -8 |
@@ -406,11 +423,12 @@ _WindowOverflow8: | |||
406 | s32e a7, a0, -20 | 423 | s32e a7, a0, -20 |
407 | rfwo | 424 | rfwo |
408 | 425 | ||
426 | ENDPROC(_WindowOverflow8) | ||
427 | |||
409 | /* 8-Register Window Underflow Vector (Handler) */ | 428 | /* 8-Register Window Underflow Vector (Handler) */ |
410 | 429 | ||
411 | .align 64 | 430 | ENTRY_ALIGN64(_WindowUnderflow8) |
412 | .global _WindowUnderflow8 | 431 | |
413 | _WindowUnderflow8: | ||
414 | l32e a1, a9, -12 | 432 | l32e a1, a9, -12 |
415 | l32e a0, a9, -16 | 433 | l32e a0, a9, -16 |
416 | l32e a7, a1, -12 | 434 | l32e a7, a1, -12 |
@@ -422,12 +440,12 @@ _WindowUnderflow8: | |||
422 | l32e a7, a7, -20 | 440 | l32e a7, a7, -20 |
423 | rfwu | 441 | rfwu |
424 | 442 | ||
443 | ENDPROC(_WindowUnderflow8) | ||
425 | 444 | ||
426 | /* 12-Register Window Overflow Vector (Handler) */ | 445 | /* 12-Register Window Overflow Vector (Handler) */ |
427 | 446 | ||
428 | .align 64 | 447 | ENTRY_ALIGN64(_WindowOverflow12) |
429 | .global _WindowOverflow12 | 448 | |
430 | _WindowOverflow12: | ||
431 | s32e a0, a13, -16 | 449 | s32e a0, a13, -16 |
432 | l32e a0, a1, -12 | 450 | l32e a0, a1, -12 |
433 | s32e a1, a13, -12 | 451 | s32e a1, a13, -12 |
@@ -443,11 +461,12 @@ _WindowOverflow12: | |||
443 | s32e a11, a0, -20 | 461 | s32e a11, a0, -20 |
444 | rfwo | 462 | rfwo |
445 | 463 | ||
464 | ENDPROC(_WindowOverflow12) | ||
465 | |||
446 | /* 12-Register Window Underflow Vector (Handler) */ | 466 | /* 12-Register Window Underflow Vector (Handler) */ |
447 | 467 | ||
448 | .align 64 | 468 | ENTRY_ALIGN64(_WindowUnderflow12) |
449 | .global _WindowUnderflow12 | 469 | |
450 | _WindowUnderflow12: | ||
451 | l32e a1, a13, -12 | 470 | l32e a1, a13, -12 |
452 | l32e a0, a13, -16 | 471 | l32e a0, a13, -16 |
453 | l32e a11, a1, -12 | 472 | l32e a11, a1, -12 |
@@ -463,6 +482,6 @@ _WindowUnderflow12: | |||
463 | l32e a11, a11, -20 | 482 | l32e a11, a11, -20 |
464 | rfwu | 483 | rfwu |
465 | 484 | ||
466 | .text | 485 | ENDPROC(_WindowUnderflow12) |
467 | |||
468 | 486 | ||
487 | .text | ||
diff --git a/arch/xtensa/kernel/xtensa_ksyms.c b/arch/xtensa/kernel/xtensa_ksyms.c index a8b9f1fd1e17..afe058b24e6e 100644 --- a/arch/xtensa/kernel/xtensa_ksyms.c +++ b/arch/xtensa/kernel/xtensa_ksyms.c | |||
@@ -43,7 +43,6 @@ EXPORT_SYMBOL(__strncpy_user); | |||
43 | EXPORT_SYMBOL(clear_page); | 43 | EXPORT_SYMBOL(clear_page); |
44 | EXPORT_SYMBOL(copy_page); | 44 | EXPORT_SYMBOL(copy_page); |
45 | 45 | ||
46 | EXPORT_SYMBOL(kernel_thread); | ||
47 | EXPORT_SYMBOL(empty_zero_page); | 46 | EXPORT_SYMBOL(empty_zero_page); |
48 | 47 | ||
49 | /* | 48 | /* |
diff --git a/arch/xtensa/lib/checksum.S b/arch/xtensa/lib/checksum.S index df397f932d0e..4eb573d2720e 100644 --- a/arch/xtensa/lib/checksum.S +++ b/arch/xtensa/lib/checksum.S | |||
@@ -41,10 +41,11 @@ | |||
41 | 41 | ||
42 | .text | 42 | .text |
43 | ENTRY(csum_partial) | 43 | ENTRY(csum_partial) |
44 | /* | 44 | |
45 | * Experiments with Ethernet and SLIP connections show that buf | 45 | /* |
46 | * is aligned on either a 2-byte or 4-byte boundary. | 46 | * Experiments with Ethernet and SLIP connections show that buf |
47 | */ | 47 | * is aligned on either a 2-byte or 4-byte boundary. |
48 | */ | ||
48 | entry sp, 32 | 49 | entry sp, 32 |
49 | extui a5, a2, 0, 2 | 50 | extui a5, a2, 0, 2 |
50 | bnez a5, 8f /* branch if 2-byte aligned */ | 51 | bnez a5, 8f /* branch if 2-byte aligned */ |
@@ -170,7 +171,7 @@ ENTRY(csum_partial) | |||
170 | 3: | 171 | 3: |
171 | j 5b /* branch to handle the remaining byte */ | 172 | j 5b /* branch to handle the remaining byte */ |
172 | 173 | ||
173 | 174 | ENDPROC(csum_partial) | |
174 | 175 | ||
175 | /* | 176 | /* |
176 | * Copy from ds while checksumming, otherwise like csum_partial | 177 | * Copy from ds while checksumming, otherwise like csum_partial |
@@ -211,6 +212,7 @@ unsigned int csum_partial_copy_generic (const char *src, char *dst, int len, | |||
211 | */ | 212 | */ |
212 | 213 | ||
213 | ENTRY(csum_partial_copy_generic) | 214 | ENTRY(csum_partial_copy_generic) |
215 | |||
214 | entry sp, 32 | 216 | entry sp, 32 |
215 | mov a12, a3 | 217 | mov a12, a3 |
216 | mov a11, a4 | 218 | mov a11, a4 |
@@ -367,6 +369,8 @@ DST( s8i a8, a3, 1 ) | |||
367 | 6: | 369 | 6: |
368 | j 4b /* process the possible trailing odd byte */ | 370 | j 4b /* process the possible trailing odd byte */ |
369 | 371 | ||
372 | ENDPROC(csum_partial_copy_generic) | ||
373 | |||
370 | 374 | ||
371 | # Exception handler: | 375 | # Exception handler: |
372 | .section .fixup, "ax" | 376 | .section .fixup, "ax" |
@@ -406,4 +410,3 @@ DST( s8i a8, a3, 1 ) | |||
406 | retw | 410 | retw |
407 | 411 | ||
408 | .previous | 412 | .previous |
409 | |||
diff --git a/arch/xtensa/lib/memcopy.S b/arch/xtensa/lib/memcopy.S index c48b80acb5f0..b1c219acabe7 100644 --- a/arch/xtensa/lib/memcopy.S +++ b/arch/xtensa/lib/memcopy.S | |||
@@ -210,8 +210,10 @@ memcpy: | |||
210 | _beqz a4, .Ldone # avoid loading anything for zero-length copies | 210 | _beqz a4, .Ldone # avoid loading anything for zero-length copies |
211 | # copy 16 bytes per iteration for word-aligned dst and unaligned src | 211 | # copy 16 bytes per iteration for word-aligned dst and unaligned src |
212 | ssa8 a3 # set shift amount from byte offset | 212 | ssa8 a3 # set shift amount from byte offset |
213 | #define SIM_CHECKS_ALIGNMENT 1 /* set to 1 when running on ISS (simulator) with the | 213 | |
214 | lint or ferret client, or 0 to save a few cycles */ | 214 | /* set to 1 when running on ISS (simulator) with the |
215 | lint or ferret client, or 0 to save a few cycles */ | ||
216 | #define SIM_CHECKS_ALIGNMENT 1 | ||
215 | #if XCHAL_UNALIGNED_LOAD_EXCEPTION || SIM_CHECKS_ALIGNMENT | 217 | #if XCHAL_UNALIGNED_LOAD_EXCEPTION || SIM_CHECKS_ALIGNMENT |
216 | and a11, a3, a8 # save unalignment offset for below | 218 | and a11, a3, a8 # save unalignment offset for below |
217 | sub a3, a3, a11 # align a3 | 219 | sub a3, a3, a11 # align a3 |
diff --git a/arch/xtensa/lib/pci-auto.c b/arch/xtensa/lib/pci-auto.c index a71733ae1193..34d05abbd921 100644 --- a/arch/xtensa/lib/pci-auto.c +++ b/arch/xtensa/lib/pci-auto.c | |||
@@ -241,8 +241,8 @@ int __init pciauto_bus_scan(struct pci_controller *pci_ctrl, int current_bus) | |||
241 | unsigned char header_type; | 241 | unsigned char header_type; |
242 | struct pci_dev *dev = &pciauto_dev; | 242 | struct pci_dev *dev = &pciauto_dev; |
243 | 243 | ||
244 | pciauto_dev.bus = &pciauto_bus; | 244 | pciauto_dev.bus = &pciauto_bus; |
245 | pciauto_dev.sysdata = pci_ctrl; | 245 | pciauto_dev.sysdata = pci_ctrl; |
246 | pciauto_bus.ops = pci_ctrl->ops; | 246 | pciauto_bus.ops = pci_ctrl->ops; |
247 | 247 | ||
248 | /* | 248 | /* |
@@ -345,8 +345,3 @@ int __init pciauto_bus_scan(struct pci_controller *pci_ctrl, int current_bus) | |||
345 | } | 345 | } |
346 | return sub_bus; | 346 | return sub_bus; |
347 | } | 347 | } |
348 | |||
349 | |||
350 | |||
351 | |||
352 | |||
diff --git a/arch/xtensa/lib/strncpy_user.S b/arch/xtensa/lib/strncpy_user.S index 9f603cdaaa68..1ad0ecf45368 100644 --- a/arch/xtensa/lib/strncpy_user.S +++ b/arch/xtensa/lib/strncpy_user.S | |||
@@ -166,7 +166,7 @@ __strncpy_user: | |||
166 | retw | 166 | retw |
167 | .Lz1: # byte 1 is zero | 167 | .Lz1: # byte 1 is zero |
168 | #ifdef __XTENSA_EB__ | 168 | #ifdef __XTENSA_EB__ |
169 | extui a9, a9, 16, 16 | 169 | extui a9, a9, 16, 16 |
170 | #endif /* __XTENSA_EB__ */ | 170 | #endif /* __XTENSA_EB__ */ |
171 | EX(s16i, a9, a11, 0, fixup_s) | 171 | EX(s16i, a9, a11, 0, fixup_s) |
172 | addi a11, a11, 1 # advance dst pointer | 172 | addi a11, a11, 1 # advance dst pointer |
@@ -174,7 +174,7 @@ __strncpy_user: | |||
174 | retw | 174 | retw |
175 | .Lz2: # byte 2 is zero | 175 | .Lz2: # byte 2 is zero |
176 | #ifdef __XTENSA_EB__ | 176 | #ifdef __XTENSA_EB__ |
177 | extui a9, a9, 16, 16 | 177 | extui a9, a9, 16, 16 |
178 | #endif /* __XTENSA_EB__ */ | 178 | #endif /* __XTENSA_EB__ */ |
179 | EX(s16i, a9, a11, 0, fixup_s) | 179 | EX(s16i, a9, a11, 0, fixup_s) |
180 | movi a9, 0 | 180 | movi a9, 0 |
diff --git a/arch/xtensa/lib/strnlen_user.S b/arch/xtensa/lib/strnlen_user.S index 23f2a89816a1..4c03b1e581e9 100644 --- a/arch/xtensa/lib/strnlen_user.S +++ b/arch/xtensa/lib/strnlen_user.S | |||
@@ -145,4 +145,3 @@ __strnlen_user: | |||
145 | lenfixup: | 145 | lenfixup: |
146 | movi a2, 0 | 146 | movi a2, 0 |
147 | retw | 147 | retw |
148 | |||
diff --git a/arch/xtensa/lib/usercopy.S b/arch/xtensa/lib/usercopy.S index 46d60314bb16..ace1892a875e 100644 --- a/arch/xtensa/lib/usercopy.S +++ b/arch/xtensa/lib/usercopy.S | |||
@@ -318,4 +318,3 @@ l_fixup: | |||
318 | /* Ignore memset return value in a6. */ | 318 | /* Ignore memset return value in a6. */ |
319 | /* a2 still contains bytes not copied. */ | 319 | /* a2 still contains bytes not copied. */ |
320 | retw | 320 | retw |
321 | |||
diff --git a/arch/xtensa/mm/cache.c b/arch/xtensa/mm/cache.c index 85df4655d326..81edeab82d17 100644 --- a/arch/xtensa/mm/cache.c +++ b/arch/xtensa/mm/cache.c | |||
@@ -118,7 +118,7 @@ void flush_dcache_page(struct page *page) | |||
118 | * For now, flush the whole cache. FIXME?? | 118 | * For now, flush the whole cache. FIXME?? |
119 | */ | 119 | */ |
120 | 120 | ||
121 | void flush_cache_range(struct vm_area_struct* vma, | 121 | void flush_cache_range(struct vm_area_struct* vma, |
122 | unsigned long start, unsigned long end) | 122 | unsigned long start, unsigned long end) |
123 | { | 123 | { |
124 | __flush_invalidate_dcache_all(); | 124 | __flush_invalidate_dcache_all(); |
@@ -133,7 +133,7 @@ void flush_cache_range(struct vm_area_struct* vma, | |||
133 | */ | 133 | */ |
134 | 134 | ||
135 | void flush_cache_page(struct vm_area_struct* vma, unsigned long address, | 135 | void flush_cache_page(struct vm_area_struct* vma, unsigned long address, |
136 | unsigned long pfn) | 136 | unsigned long pfn) |
137 | { | 137 | { |
138 | /* Note that we have to use the 'alias' address to avoid multi-hit */ | 138 | /* Note that we have to use the 'alias' address to avoid multi-hit */ |
139 | 139 | ||
@@ -166,14 +166,14 @@ update_mmu_cache(struct vm_area_struct * vma, unsigned long addr, pte_t *ptep) | |||
166 | 166 | ||
167 | if (!PageReserved(page) && test_bit(PG_arch_1, &page->flags)) { | 167 | if (!PageReserved(page) && test_bit(PG_arch_1, &page->flags)) { |
168 | 168 | ||
169 | unsigned long vaddr = TLBTEMP_BASE_1 + (addr & DCACHE_ALIAS_MASK); | ||
170 | unsigned long paddr = (unsigned long) page_address(page); | 169 | unsigned long paddr = (unsigned long) page_address(page); |
171 | unsigned long phys = page_to_phys(page); | 170 | unsigned long phys = page_to_phys(page); |
171 | unsigned long tmp = TLBTEMP_BASE_1 + (addr & DCACHE_ALIAS_MASK); | ||
172 | 172 | ||
173 | __flush_invalidate_dcache_page(paddr); | 173 | __flush_invalidate_dcache_page(paddr); |
174 | 174 | ||
175 | __flush_invalidate_dcache_page_alias(vaddr, phys); | 175 | __flush_invalidate_dcache_page_alias(tmp, phys); |
176 | __invalidate_icache_page_alias(vaddr, phys); | 176 | __invalidate_icache_page_alias(tmp, phys); |
177 | 177 | ||
178 | clear_bit(PG_arch_1, &page->flags); | 178 | clear_bit(PG_arch_1, &page->flags); |
179 | } | 179 | } |
@@ -195,7 +195,7 @@ update_mmu_cache(struct vm_area_struct * vma, unsigned long addr, pte_t *ptep) | |||
195 | 195 | ||
196 | #if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK | 196 | #if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK |
197 | 197 | ||
198 | void copy_to_user_page(struct vm_area_struct *vma, struct page *page, | 198 | void copy_to_user_page(struct vm_area_struct *vma, struct page *page, |
199 | unsigned long vaddr, void *dst, const void *src, | 199 | unsigned long vaddr, void *dst, const void *src, |
200 | unsigned long len) | 200 | unsigned long len) |
201 | { | 201 | { |
@@ -205,8 +205,8 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page, | |||
205 | /* Flush and invalidate user page if aliased. */ | 205 | /* Flush and invalidate user page if aliased. */ |
206 | 206 | ||
207 | if (alias) { | 207 | if (alias) { |
208 | unsigned long temp = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK); | 208 | unsigned long t = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK); |
209 | __flush_invalidate_dcache_page_alias(temp, phys); | 209 | __flush_invalidate_dcache_page_alias(t, phys); |
210 | } | 210 | } |
211 | 211 | ||
212 | /* Copy data */ | 212 | /* Copy data */ |
@@ -219,12 +219,11 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page, | |||
219 | */ | 219 | */ |
220 | 220 | ||
221 | if (alias) { | 221 | if (alias) { |
222 | unsigned long temp = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK); | 222 | unsigned long t = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK); |
223 | 223 | ||
224 | __flush_invalidate_dcache_range((unsigned long) dst, len); | 224 | __flush_invalidate_dcache_range((unsigned long) dst, len); |
225 | if ((vma->vm_flags & VM_EXEC) != 0) { | 225 | if ((vma->vm_flags & VM_EXEC) != 0) |
226 | __invalidate_icache_page_alias(temp, phys); | 226 | __invalidate_icache_page_alias(t, phys); |
227 | } | ||
228 | 227 | ||
229 | } else if ((vma->vm_flags & VM_EXEC) != 0) { | 228 | } else if ((vma->vm_flags & VM_EXEC) != 0) { |
230 | __flush_dcache_range((unsigned long)dst,len); | 229 | __flush_dcache_range((unsigned long)dst,len); |
@@ -245,8 +244,8 @@ extern void copy_from_user_page(struct vm_area_struct *vma, struct page *page, | |||
245 | */ | 244 | */ |
246 | 245 | ||
247 | if (alias) { | 246 | if (alias) { |
248 | unsigned long temp = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK); | 247 | unsigned long t = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK); |
249 | __flush_invalidate_dcache_page_alias(temp, phys); | 248 | __flush_invalidate_dcache_page_alias(t, phys); |
250 | } | 249 | } |
251 | 250 | ||
252 | memcpy(dst, src, len); | 251 | memcpy(dst, src, len); |
diff --git a/arch/xtensa/mm/fault.c b/arch/xtensa/mm/fault.c index 245b08f7eaf4..4b7bc8db170f 100644 --- a/arch/xtensa/mm/fault.c +++ b/arch/xtensa/mm/fault.c | |||
@@ -254,4 +254,3 @@ bad_page_fault(struct pt_regs *regs, unsigned long address, int sig) | |||
254 | die("Oops", regs, sig); | 254 | die("Oops", regs, sig); |
255 | do_exit(sig); | 255 | do_exit(sig); |
256 | } | 256 | } |
257 | |||
diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c index db955179da2d..7a5156ffebb6 100644 --- a/arch/xtensa/mm/init.c +++ b/arch/xtensa/mm/init.c | |||
@@ -75,15 +75,15 @@ int __init mem_reserve(unsigned long start, unsigned long end, int must_exist) | |||
75 | sysmem.nr_banks++; | 75 | sysmem.nr_banks++; |
76 | } | 76 | } |
77 | sysmem.bank[i].end = start; | 77 | sysmem.bank[i].end = start; |
78 | |||
79 | } else if (end < sysmem.bank[i].end) { | ||
80 | sysmem.bank[i].start = end; | ||
81 | |||
78 | } else { | 82 | } else { |
79 | if (end < sysmem.bank[i].end) | 83 | /* remove entry */ |
80 | sysmem.bank[i].start = end; | 84 | sysmem.nr_banks--; |
81 | else { | 85 | sysmem.bank[i].start = sysmem.bank[sysmem.nr_banks].start; |
82 | /* remove entry */ | 86 | sysmem.bank[i].end = sysmem.bank[sysmem.nr_banks].end; |
83 | sysmem.nr_banks--; | ||
84 | sysmem.bank[i].start = sysmem.bank[sysmem.nr_banks].start; | ||
85 | sysmem.bank[i].end = sysmem.bank[sysmem.nr_banks].end; | ||
86 | } | ||
87 | } | 87 | } |
88 | return -1; | 88 | return -1; |
89 | } | 89 | } |
diff --git a/arch/xtensa/mm/misc.S b/arch/xtensa/mm/misc.S index b048406d8756..d97ed1ba7b0a 100644 --- a/arch/xtensa/mm/misc.S +++ b/arch/xtensa/mm/misc.S | |||
@@ -29,6 +29,7 @@ | |||
29 | */ | 29 | */ |
30 | 30 | ||
31 | ENTRY(clear_page) | 31 | ENTRY(clear_page) |
32 | |||
32 | entry a1, 16 | 33 | entry a1, 16 |
33 | 34 | ||
34 | movi a3, 0 | 35 | movi a3, 0 |
@@ -45,6 +46,8 @@ ENTRY(clear_page) | |||
45 | 46 | ||
46 | retw | 47 | retw |
47 | 48 | ||
49 | ENDPROC(clear_page) | ||
50 | |||
48 | /* | 51 | /* |
49 | * copy_page and copy_user_page are the same for non-cache-aliased configs. | 52 | * copy_page and copy_user_page are the same for non-cache-aliased configs. |
50 | * | 53 | * |
@@ -53,6 +56,7 @@ ENTRY(clear_page) | |||
53 | */ | 56 | */ |
54 | 57 | ||
55 | ENTRY(copy_page) | 58 | ENTRY(copy_page) |
59 | |||
56 | entry a1, 16 | 60 | entry a1, 16 |
57 | 61 | ||
58 | __loopi a2, a4, PAGE_SIZE, 32 | 62 | __loopi a2, a4, PAGE_SIZE, 32 |
@@ -84,6 +88,8 @@ ENTRY(copy_page) | |||
84 | 88 | ||
85 | retw | 89 | retw |
86 | 90 | ||
91 | ENDPROC(copy_page) | ||
92 | |||
87 | #ifdef CONFIG_MMU | 93 | #ifdef CONFIG_MMU |
88 | /* | 94 | /* |
89 | * If we have to deal with cache aliasing, we use temporary memory mappings | 95 | * If we have to deal with cache aliasing, we use temporary memory mappings |
@@ -109,6 +115,7 @@ ENTRY(__tlbtemp_mapping_start) | |||
109 | */ | 115 | */ |
110 | 116 | ||
111 | ENTRY(clear_user_page) | 117 | ENTRY(clear_user_page) |
118 | |||
112 | entry a1, 32 | 119 | entry a1, 32 |
113 | 120 | ||
114 | /* Mark page dirty and determine alias. */ | 121 | /* Mark page dirty and determine alias. */ |
@@ -164,6 +171,8 @@ ENTRY(clear_user_page) | |||
164 | 171 | ||
165 | retw | 172 | retw |
166 | 173 | ||
174 | ENDPROC(clear_user_page) | ||
175 | |||
167 | /* | 176 | /* |
168 | * copy_page_user (void *to, void *from, unsigned long vaddr, struct page *page) | 177 | * copy_page_user (void *to, void *from, unsigned long vaddr, struct page *page) |
169 | * a2 a3 a4 a5 | 178 | * a2 a3 a4 a5 |
@@ -171,7 +180,7 @@ ENTRY(clear_user_page) | |||
171 | 180 | ||
172 | ENTRY(copy_user_page) | 181 | ENTRY(copy_user_page) |
173 | 182 | ||
174 | entry a1, 32 | 183 | entry a1, 32 |
175 | 184 | ||
176 | /* Mark page dirty and determine alias for destination. */ | 185 | /* Mark page dirty and determine alias for destination. */ |
177 | 186 | ||
@@ -262,6 +271,8 @@ ENTRY(copy_user_page) | |||
262 | 271 | ||
263 | retw | 272 | retw |
264 | 273 | ||
274 | ENDPROC(copy_user_page) | ||
275 | |||
265 | #endif | 276 | #endif |
266 | 277 | ||
267 | #if (DCACHE_WAY_SIZE > PAGE_SIZE) | 278 | #if (DCACHE_WAY_SIZE > PAGE_SIZE) |
@@ -272,6 +283,7 @@ ENTRY(copy_user_page) | |||
272 | */ | 283 | */ |
273 | 284 | ||
274 | ENTRY(__flush_invalidate_dcache_page_alias) | 285 | ENTRY(__flush_invalidate_dcache_page_alias) |
286 | |||
275 | entry sp, 16 | 287 | entry sp, 16 |
276 | 288 | ||
277 | movi a7, 0 # required for exception handler | 289 | movi a7, 0 # required for exception handler |
@@ -287,6 +299,7 @@ ENTRY(__flush_invalidate_dcache_page_alias) | |||
287 | 299 | ||
288 | retw | 300 | retw |
289 | 301 | ||
302 | ENDPROC(__flush_invalidate_dcache_page_alias) | ||
290 | #endif | 303 | #endif |
291 | 304 | ||
292 | ENTRY(__tlbtemp_mapping_itlb) | 305 | ENTRY(__tlbtemp_mapping_itlb) |
@@ -294,6 +307,7 @@ ENTRY(__tlbtemp_mapping_itlb) | |||
294 | #if (ICACHE_WAY_SIZE > PAGE_SIZE) | 307 | #if (ICACHE_WAY_SIZE > PAGE_SIZE) |
295 | 308 | ||
296 | ENTRY(__invalidate_icache_page_alias) | 309 | ENTRY(__invalidate_icache_page_alias) |
310 | |||
297 | entry sp, 16 | 311 | entry sp, 16 |
298 | 312 | ||
299 | addi a6, a3, (PAGE_KERNEL_EXEC | _PAGE_HW_WRITE) | 313 | addi a6, a3, (PAGE_KERNEL_EXEC | _PAGE_HW_WRITE) |
@@ -307,11 +321,14 @@ ENTRY(__invalidate_icache_page_alias) | |||
307 | isync | 321 | isync |
308 | retw | 322 | retw |
309 | 323 | ||
324 | ENDPROC(__invalidate_icache_page_alias) | ||
325 | |||
310 | #endif | 326 | #endif |
311 | 327 | ||
312 | /* End of special treatment in tlb miss exception */ | 328 | /* End of special treatment in tlb miss exception */ |
313 | 329 | ||
314 | ENTRY(__tlbtemp_mapping_end) | 330 | ENTRY(__tlbtemp_mapping_end) |
331 | |||
315 | #endif /* CONFIG_MMU | 332 | #endif /* CONFIG_MMU |
316 | 333 | ||
317 | /* | 334 | /* |
@@ -319,6 +336,7 @@ ENTRY(__tlbtemp_mapping_end) | |||
319 | */ | 336 | */ |
320 | 337 | ||
321 | ENTRY(__invalidate_icache_page) | 338 | ENTRY(__invalidate_icache_page) |
339 | |||
322 | entry sp, 16 | 340 | entry sp, 16 |
323 | 341 | ||
324 | ___invalidate_icache_page a2 a3 | 342 | ___invalidate_icache_page a2 a3 |
@@ -326,11 +344,14 @@ ENTRY(__invalidate_icache_page) | |||
326 | 344 | ||
327 | retw | 345 | retw |
328 | 346 | ||
347 | ENDPROC(__invalidate_icache_page) | ||
348 | |||
329 | /* | 349 | /* |
330 | * void __invalidate_dcache_page(ulong start) | 350 | * void __invalidate_dcache_page(ulong start) |
331 | */ | 351 | */ |
332 | 352 | ||
333 | ENTRY(__invalidate_dcache_page) | 353 | ENTRY(__invalidate_dcache_page) |
354 | |||
334 | entry sp, 16 | 355 | entry sp, 16 |
335 | 356 | ||
336 | ___invalidate_dcache_page a2 a3 | 357 | ___invalidate_dcache_page a2 a3 |
@@ -338,11 +359,14 @@ ENTRY(__invalidate_dcache_page) | |||
338 | 359 | ||
339 | retw | 360 | retw |
340 | 361 | ||
362 | ENDPROC(__invalidate_dcache_page) | ||
363 | |||
341 | /* | 364 | /* |
342 | * void __flush_invalidate_dcache_page(ulong start) | 365 | * void __flush_invalidate_dcache_page(ulong start) |
343 | */ | 366 | */ |
344 | 367 | ||
345 | ENTRY(__flush_invalidate_dcache_page) | 368 | ENTRY(__flush_invalidate_dcache_page) |
369 | |||
346 | entry sp, 16 | 370 | entry sp, 16 |
347 | 371 | ||
348 | ___flush_invalidate_dcache_page a2 a3 | 372 | ___flush_invalidate_dcache_page a2 a3 |
@@ -350,11 +374,14 @@ ENTRY(__flush_invalidate_dcache_page) | |||
350 | dsync | 374 | dsync |
351 | retw | 375 | retw |
352 | 376 | ||
377 | ENDPROC(__flush_invalidate_dcache_page) | ||
378 | |||
353 | /* | 379 | /* |
354 | * void __flush_dcache_page(ulong start) | 380 | * void __flush_dcache_page(ulong start) |
355 | */ | 381 | */ |
356 | 382 | ||
357 | ENTRY(__flush_dcache_page) | 383 | ENTRY(__flush_dcache_page) |
384 | |||
358 | entry sp, 16 | 385 | entry sp, 16 |
359 | 386 | ||
360 | ___flush_dcache_page a2 a3 | 387 | ___flush_dcache_page a2 a3 |
@@ -362,11 +389,14 @@ ENTRY(__flush_dcache_page) | |||
362 | dsync | 389 | dsync |
363 | retw | 390 | retw |
364 | 391 | ||
392 | ENDPROC(__flush_dcache_page) | ||
393 | |||
365 | /* | 394 | /* |
366 | * void __invalidate_icache_range(ulong start, ulong size) | 395 | * void __invalidate_icache_range(ulong start, ulong size) |
367 | */ | 396 | */ |
368 | 397 | ||
369 | ENTRY(__invalidate_icache_range) | 398 | ENTRY(__invalidate_icache_range) |
399 | |||
370 | entry sp, 16 | 400 | entry sp, 16 |
371 | 401 | ||
372 | ___invalidate_icache_range a2 a3 a4 | 402 | ___invalidate_icache_range a2 a3 a4 |
@@ -374,11 +404,14 @@ ENTRY(__invalidate_icache_range) | |||
374 | 404 | ||
375 | retw | 405 | retw |
376 | 406 | ||
407 | ENDPROC(__invalidate_icache_range) | ||
408 | |||
377 | /* | 409 | /* |
378 | * void __flush_invalidate_dcache_range(ulong start, ulong size) | 410 | * void __flush_invalidate_dcache_range(ulong start, ulong size) |
379 | */ | 411 | */ |
380 | 412 | ||
381 | ENTRY(__flush_invalidate_dcache_range) | 413 | ENTRY(__flush_invalidate_dcache_range) |
414 | |||
382 | entry sp, 16 | 415 | entry sp, 16 |
383 | 416 | ||
384 | ___flush_invalidate_dcache_range a2 a3 a4 | 417 | ___flush_invalidate_dcache_range a2 a3 a4 |
@@ -386,11 +419,14 @@ ENTRY(__flush_invalidate_dcache_range) | |||
386 | 419 | ||
387 | retw | 420 | retw |
388 | 421 | ||
422 | ENDPROC(__flush_invalidate_dcache_range) | ||
423 | |||
389 | /* | 424 | /* |
390 | * void _flush_dcache_range(ulong start, ulong size) | 425 | * void _flush_dcache_range(ulong start, ulong size) |
391 | */ | 426 | */ |
392 | 427 | ||
393 | ENTRY(__flush_dcache_range) | 428 | ENTRY(__flush_dcache_range) |
429 | |||
394 | entry sp, 16 | 430 | entry sp, 16 |
395 | 431 | ||
396 | ___flush_dcache_range a2 a3 a4 | 432 | ___flush_dcache_range a2 a3 a4 |
@@ -398,22 +434,28 @@ ENTRY(__flush_dcache_range) | |||
398 | 434 | ||
399 | retw | 435 | retw |
400 | 436 | ||
437 | ENDPROC(__flush_dcache_range) | ||
438 | |||
401 | /* | 439 | /* |
402 | * void _invalidate_dcache_range(ulong start, ulong size) | 440 | * void _invalidate_dcache_range(ulong start, ulong size) |
403 | */ | 441 | */ |
404 | 442 | ||
405 | ENTRY(__invalidate_dcache_range) | 443 | ENTRY(__invalidate_dcache_range) |
444 | |||
406 | entry sp, 16 | 445 | entry sp, 16 |
407 | 446 | ||
408 | ___invalidate_dcache_range a2 a3 a4 | 447 | ___invalidate_dcache_range a2 a3 a4 |
409 | 448 | ||
410 | retw | 449 | retw |
411 | 450 | ||
451 | ENDPROC(__invalidate_dcache_range) | ||
452 | |||
412 | /* | 453 | /* |
413 | * void _invalidate_icache_all(void) | 454 | * void _invalidate_icache_all(void) |
414 | */ | 455 | */ |
415 | 456 | ||
416 | ENTRY(__invalidate_icache_all) | 457 | ENTRY(__invalidate_icache_all) |
458 | |||
417 | entry sp, 16 | 459 | entry sp, 16 |
418 | 460 | ||
419 | ___invalidate_icache_all a2 a3 | 461 | ___invalidate_icache_all a2 a3 |
@@ -421,11 +463,14 @@ ENTRY(__invalidate_icache_all) | |||
421 | 463 | ||
422 | retw | 464 | retw |
423 | 465 | ||
466 | ENDPROC(__invalidate_icache_all) | ||
467 | |||
424 | /* | 468 | /* |
425 | * void _flush_invalidate_dcache_all(void) | 469 | * void _flush_invalidate_dcache_all(void) |
426 | */ | 470 | */ |
427 | 471 | ||
428 | ENTRY(__flush_invalidate_dcache_all) | 472 | ENTRY(__flush_invalidate_dcache_all) |
473 | |||
429 | entry sp, 16 | 474 | entry sp, 16 |
430 | 475 | ||
431 | ___flush_invalidate_dcache_all a2 a3 | 476 | ___flush_invalidate_dcache_all a2 a3 |
@@ -433,11 +478,14 @@ ENTRY(__flush_invalidate_dcache_all) | |||
433 | 478 | ||
434 | retw | 479 | retw |
435 | 480 | ||
481 | ENDPROC(__flush_invalidate_dcache_all) | ||
482 | |||
436 | /* | 483 | /* |
437 | * void _invalidate_dcache_all(void) | 484 | * void _invalidate_dcache_all(void) |
438 | */ | 485 | */ |
439 | 486 | ||
440 | ENTRY(__invalidate_dcache_all) | 487 | ENTRY(__invalidate_dcache_all) |
488 | |||
441 | entry sp, 16 | 489 | entry sp, 16 |
442 | 490 | ||
443 | ___invalidate_dcache_all a2 a3 | 491 | ___invalidate_dcache_all a2 a3 |
@@ -445,3 +493,4 @@ ENTRY(__invalidate_dcache_all) | |||
445 | 493 | ||
446 | retw | 494 | retw |
447 | 495 | ||
496 | ENDPROC(__invalidate_dcache_all) | ||
diff --git a/arch/xtensa/mm/mmu.c b/arch/xtensa/mm/mmu.c index ca81654f3ec2..0f77f9d3bb8b 100644 --- a/arch/xtensa/mm/mmu.c +++ b/arch/xtensa/mm/mmu.c | |||
@@ -37,7 +37,7 @@ void __init init_mmu(void) | |||
37 | 37 | ||
38 | /* Set rasid register to a known value. */ | 38 | /* Set rasid register to a known value. */ |
39 | 39 | ||
40 | set_rasid_register(ASID_USER_FIRST); | 40 | set_rasid_register(ASID_INSERT(ASID_USER_FIRST)); |
41 | 41 | ||
42 | /* Set PTEVADDR special register to the start of the page | 42 | /* Set PTEVADDR special register to the start of the page |
43 | * table, which is in kernel mappable space (ie. not | 43 | * table, which is in kernel mappable space (ie. not |
diff --git a/arch/xtensa/mm/tlb.c b/arch/xtensa/mm/tlb.c index e2700b21395b..5411aa67c68e 100644 --- a/arch/xtensa/mm/tlb.c +++ b/arch/xtensa/mm/tlb.c | |||
@@ -63,7 +63,7 @@ void flush_tlb_all (void) | |||
63 | void flush_tlb_mm(struct mm_struct *mm) | 63 | void flush_tlb_mm(struct mm_struct *mm) |
64 | { | 64 | { |
65 | if (mm == current->active_mm) { | 65 | if (mm == current->active_mm) { |
66 | int flags; | 66 | unsigned long flags; |
67 | local_save_flags(flags); | 67 | local_save_flags(flags); |
68 | __get_new_mmu_context(mm); | 68 | __get_new_mmu_context(mm); |
69 | __load_mmu_context(mm); | 69 | __load_mmu_context(mm); |
@@ -82,7 +82,7 @@ void flush_tlb_mm(struct mm_struct *mm) | |||
82 | #endif | 82 | #endif |
83 | 83 | ||
84 | void flush_tlb_range (struct vm_area_struct *vma, | 84 | void flush_tlb_range (struct vm_area_struct *vma, |
85 | unsigned long start, unsigned long end) | 85 | unsigned long start, unsigned long end) |
86 | { | 86 | { |
87 | struct mm_struct *mm = vma->vm_mm; | 87 | struct mm_struct *mm = vma->vm_mm; |
88 | unsigned long flags; | 88 | unsigned long flags; |
@@ -100,7 +100,7 @@ void flush_tlb_range (struct vm_area_struct *vma, | |||
100 | int oldpid = get_rasid_register(); | 100 | int oldpid = get_rasid_register(); |
101 | set_rasid_register (ASID_INSERT(mm->context)); | 101 | set_rasid_register (ASID_INSERT(mm->context)); |
102 | start &= PAGE_MASK; | 102 | start &= PAGE_MASK; |
103 | if (vma->vm_flags & VM_EXEC) | 103 | if (vma->vm_flags & VM_EXEC) |
104 | while(start < end) { | 104 | while(start < end) { |
105 | invalidate_itlb_mapping(start); | 105 | invalidate_itlb_mapping(start); |
106 | invalidate_dtlb_mapping(start); | 106 | invalidate_dtlb_mapping(start); |
@@ -130,7 +130,7 @@ void flush_tlb_page (struct vm_area_struct *vma, unsigned long page) | |||
130 | 130 | ||
131 | local_save_flags(flags); | 131 | local_save_flags(flags); |
132 | 132 | ||
133 | oldpid = get_rasid_register(); | 133 | oldpid = get_rasid_register(); |
134 | 134 | ||
135 | if (vma->vm_flags & VM_EXEC) | 135 | if (vma->vm_flags & VM_EXEC) |
136 | invalidate_itlb_mapping(page); | 136 | invalidate_itlb_mapping(page); |
@@ -140,4 +140,3 @@ void flush_tlb_page (struct vm_area_struct *vma, unsigned long page) | |||
140 | 140 | ||
141 | local_irq_restore(flags); | 141 | local_irq_restore(flags); |
142 | } | 142 | } |
143 | |||
diff --git a/arch/xtensa/platforms/iss/console.c b/arch/xtensa/platforms/iss/console.c index 7e74895eee04..8207a119eee9 100644 --- a/arch/xtensa/platforms/iss/console.c +++ b/arch/xtensa/platforms/iss/console.c | |||
@@ -221,6 +221,7 @@ static __exit void rs_exit(void) | |||
221 | printk("ISS_SERIAL: failed to unregister serial driver (%d)\n", | 221 | printk("ISS_SERIAL: failed to unregister serial driver (%d)\n", |
222 | error); | 222 | error); |
223 | put_tty_driver(serial_driver); | 223 | put_tty_driver(serial_driver); |
224 | tty_port_destroy(&serial_port); | ||
224 | } | 225 | } |
225 | 226 | ||
226 | 227 | ||
diff --git a/arch/xtensa/platforms/iss/include/platform/serial.h b/arch/xtensa/platforms/iss/include/platform/serial.h index e69de29bb2d1..16aec542d435 100644 --- a/arch/xtensa/platforms/iss/include/platform/serial.h +++ b/arch/xtensa/platforms/iss/include/platform/serial.h | |||
@@ -0,0 +1,15 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 2012 Tensilica Inc. | ||
7 | */ | ||
8 | |||
9 | #ifndef __ASM_XTENSA_ISS_SERIAL_H | ||
10 | #define __ASM_XTENSA_ISS_SERIAL_H | ||
11 | |||
12 | /* Have no meaning on ISS, but needed for 8250_early.c */ | ||
13 | #define BASE_BAUD 0 | ||
14 | |||
15 | #endif /* __ASM_XTENSA_ISS_SERIAL_H */ | ||
diff --git a/arch/xtensa/platforms/iss/include/platform/simcall.h b/arch/xtensa/platforms/iss/include/platform/simcall.h index bd78192e2fc9..b5a4edf02d76 100644 --- a/arch/xtensa/platforms/iss/include/platform/simcall.h +++ b/arch/xtensa/platforms/iss/include/platform/simcall.h | |||
@@ -74,13 +74,12 @@ static inline int __simc(int a, int b, int c, int d, int e, int f) | |||
74 | "mov %1, a3\n" | 74 | "mov %1, a3\n" |
75 | : "=a" (ret), "=a" (errno), "+r"(a1), "+r"(b1) | 75 | : "=a" (ret), "=a" (errno), "+r"(a1), "+r"(b1) |
76 | : "r"(c1), "r"(d1), "r"(e1), "r"(f1) | 76 | : "r"(c1), "r"(d1), "r"(e1), "r"(f1) |
77 | : ); | 77 | : "memory"); |
78 | return ret; | 78 | return ret; |
79 | } | 79 | } |
80 | 80 | ||
81 | static inline int simc_open(const char *file, int flags, int mode) | 81 | static inline int simc_open(const char *file, int flags, int mode) |
82 | { | 82 | { |
83 | wmb(); | ||
84 | return __simc(SYS_open, (int) file, flags, mode, 0, 0); | 83 | return __simc(SYS_open, (int) file, flags, mode, 0, 0); |
85 | } | 84 | } |
86 | 85 | ||
@@ -91,19 +90,16 @@ static inline int simc_close(int fd) | |||
91 | 90 | ||
92 | static inline int simc_ioctl(int fd, int request, void *arg) | 91 | static inline int simc_ioctl(int fd, int request, void *arg) |
93 | { | 92 | { |
94 | wmb(); | ||
95 | return __simc(SYS_ioctl, fd, request, (int) arg, 0, 0); | 93 | return __simc(SYS_ioctl, fd, request, (int) arg, 0, 0); |
96 | } | 94 | } |
97 | 95 | ||
98 | static inline int simc_read(int fd, void *buf, size_t count) | 96 | static inline int simc_read(int fd, void *buf, size_t count) |
99 | { | 97 | { |
100 | rmb(); | ||
101 | return __simc(SYS_read, fd, (int) buf, count, 0, 0); | 98 | return __simc(SYS_read, fd, (int) buf, count, 0, 0); |
102 | } | 99 | } |
103 | 100 | ||
104 | static inline int simc_write(int fd, const void *buf, size_t count) | 101 | static inline int simc_write(int fd, const void *buf, size_t count) |
105 | { | 102 | { |
106 | wmb(); | ||
107 | return __simc(SYS_write, fd, (int) buf, count, 0, 0); | 103 | return __simc(SYS_write, fd, (int) buf, count, 0, 0); |
108 | } | 104 | } |
109 | 105 | ||
@@ -111,7 +107,6 @@ static inline int simc_poll(int fd) | |||
111 | { | 107 | { |
112 | struct timeval tv = { .tv_sec = 0, .tv_usec = 0 }; | 108 | struct timeval tv = { .tv_sec = 0, .tv_usec = 0 }; |
113 | 109 | ||
114 | wmb(); | ||
115 | return __simc(SYS_select_one, fd, XTISS_SELECT_ONE_READ, (int)&tv, | 110 | return __simc(SYS_select_one, fd, XTISS_SELECT_ONE_READ, (int)&tv, |
116 | 0, 0); | 111 | 0, 0); |
117 | } | 112 | } |
diff --git a/arch/xtensa/platforms/xtfpga/Makefile b/arch/xtensa/platforms/xtfpga/Makefile new file mode 100644 index 000000000000..b9ae206340cd --- /dev/null +++ b/arch/xtensa/platforms/xtfpga/Makefile | |||
@@ -0,0 +1,9 @@ | |||
1 | # Makefile for the Tensilica xtavnet Emulation Board | ||
2 | # | ||
3 | # Note! Dependencies are done automagically by 'make dep', which also | ||
4 | # removes any old dependencies. DON'T put your own dependencies here | ||
5 | # unless it's something special (ie not a .c file). | ||
6 | # | ||
7 | # Note 2! The CFLAGS definitions are in the main makefile... | ||
8 | |||
9 | obj-y = setup.o lcd.o | ||
diff --git a/arch/xtensa/platforms/xtfpga/include/platform/hardware.h b/arch/xtensa/platforms/xtfpga/include/platform/hardware.h new file mode 100644 index 000000000000..4416773cbde5 --- /dev/null +++ b/arch/xtensa/platforms/xtfpga/include/platform/hardware.h | |||
@@ -0,0 +1,69 @@ | |||
1 | /* | ||
2 | * arch/xtensa/platform/xtavnet/include/platform/hardware.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) 2006 Tensilica Inc. | ||
9 | */ | ||
10 | |||
11 | /* | ||
12 | * This file contains the hardware configuration of the XTAVNET boards. | ||
13 | */ | ||
14 | |||
15 | #ifndef __XTENSA_XTAVNET_HARDWARE_H | ||
16 | #define __XTENSA_XTAVNET_HARDWARE_H | ||
17 | |||
18 | /* By default NO_IRQ is defined to 0 in Linux, but we use the | ||
19 | interrupt 0 for UART... */ | ||
20 | #define NO_IRQ -1 | ||
21 | |||
22 | /* Memory configuration. */ | ||
23 | |||
24 | #define PLATFORM_DEFAULT_MEM_START 0x00000000 | ||
25 | #define PLATFORM_DEFAULT_MEM_SIZE 0x04000000 | ||
26 | |||
27 | /* Interrupt configuration. */ | ||
28 | |||
29 | #define PLATFORM_NR_IRQS 10 | ||
30 | |||
31 | /* Default assignment of LX60 devices to external interrupts. */ | ||
32 | |||
33 | #ifdef CONFIG_ARCH_HAS_SMP | ||
34 | #define DUART16552_INTNUM XCHAL_EXTINT3_NUM | ||
35 | #define OETH_IRQ XCHAL_EXTINT4_NUM | ||
36 | #else | ||
37 | #define DUART16552_INTNUM XCHAL_EXTINT0_NUM | ||
38 | #define OETH_IRQ XCHAL_EXTINT1_NUM | ||
39 | #endif | ||
40 | |||
41 | /* | ||
42 | * Device addresses and parameters. | ||
43 | */ | ||
44 | |||
45 | /* UART */ | ||
46 | #define DUART16552_PADDR (XCHAL_KIO_PADDR + 0x0D050020) | ||
47 | /* LCD instruction and data addresses. */ | ||
48 | #define LCD_INSTR_ADDR ((char *)IOADDR(0x0D040000)) | ||
49 | #define LCD_DATA_ADDR ((char *)IOADDR(0x0D040004)) | ||
50 | |||
51 | /* Misc. */ | ||
52 | #define XTFPGA_FPGAREGS_VADDR IOADDR(0x0D020000) | ||
53 | /* Clock frequency in Hz (read-only): */ | ||
54 | #define XTFPGA_CLKFRQ_VADDR (XTFPGA_FPGAREGS_VADDR + 0x04) | ||
55 | /* Setting of 8 DIP switches: */ | ||
56 | #define DIP_SWITCHES_VADDR (XTFPGA_FPGAREGS_VADDR + 0x0C) | ||
57 | /* Software reset (write 0xdead): */ | ||
58 | #define XTFPGA_SWRST_VADDR (XTFPGA_FPGAREGS_VADDR + 0x10) | ||
59 | |||
60 | /* OpenCores Ethernet controller: */ | ||
61 | /* regs + RX/TX descriptors */ | ||
62 | #define OETH_REGS_PADDR (XCHAL_KIO_PADDR + 0x0D030000) | ||
63 | #define OETH_REGS_SIZE 0x1000 | ||
64 | #define OETH_SRAMBUFF_PADDR (XCHAL_KIO_PADDR + 0x0D800000) | ||
65 | |||
66 | /* 5*rx buffs + 5*tx buffs */ | ||
67 | #define OETH_SRAMBUFF_SIZE (5 * 0x600 + 5 * 0x600) | ||
68 | |||
69 | #endif /* __XTENSA_XTAVNET_HARDWARE_H */ | ||
diff --git a/arch/xtensa/platforms/xtfpga/include/platform/lcd.h b/arch/xtensa/platforms/xtfpga/include/platform/lcd.h new file mode 100644 index 000000000000..0e435645af5a --- /dev/null +++ b/arch/xtensa/platforms/xtfpga/include/platform/lcd.h | |||
@@ -0,0 +1,20 @@ | |||
1 | /* | ||
2 | * arch/xtensa/platform/xtavnet/include/platform/lcd.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) 2001, 2006 Tensilica Inc. | ||
9 | */ | ||
10 | |||
11 | #ifndef __XTENSA_XTAVNET_LCD_H | ||
12 | #define __XTENSA_XTAVNET_LCD_H | ||
13 | |||
14 | /* Display string STR at position POS on the LCD. */ | ||
15 | void lcd_disp_at_pos(char *str, unsigned char pos); | ||
16 | |||
17 | /* Shift the contents of the LCD display left or right. */ | ||
18 | void lcd_shiftleft(void); | ||
19 | void lcd_shiftright(void); | ||
20 | #endif | ||
diff --git a/arch/xtensa/platforms/xtfpga/include/platform/serial.h b/arch/xtensa/platforms/xtfpga/include/platform/serial.h new file mode 100644 index 000000000000..14d8f7beebfd --- /dev/null +++ b/arch/xtensa/platforms/xtfpga/include/platform/serial.h | |||
@@ -0,0 +1,18 @@ | |||
1 | /* | ||
2 | * arch/xtensa/platform/xtavnet/include/platform/serial.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) 2001, 2006 Tensilica Inc. | ||
9 | */ | ||
10 | |||
11 | #ifndef __ASM_XTENSA_XTAVNET_SERIAL_H | ||
12 | #define __ASM_XTENSA_XTAVNET_SERIAL_H | ||
13 | |||
14 | #include <platform/hardware.h> | ||
15 | |||
16 | #define BASE_BAUD (*(long *)XTFPGA_CLKFRQ_VADDR / 16) | ||
17 | |||
18 | #endif /* __ASM_XTENSA_XTAVNET_SERIAL_H */ | ||
diff --git a/arch/xtensa/platforms/xtfpga/lcd.c b/arch/xtensa/platforms/xtfpga/lcd.c new file mode 100644 index 000000000000..2872301598df --- /dev/null +++ b/arch/xtensa/platforms/xtfpga/lcd.c | |||
@@ -0,0 +1,76 @@ | |||
1 | /* | ||
2 | * Driver for the LCD display on the Tensilica LX60 Board. | ||
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) 2001, 2006 Tensilica Inc. | ||
9 | */ | ||
10 | |||
11 | /* | ||
12 | * | ||
13 | * FIXME: this code is from the examples from the LX60 user guide. | ||
14 | * | ||
15 | * The lcd_pause function does busy waiting, which is probably not | ||
16 | * great. Maybe the code could be changed to use kernel timers, or | ||
17 | * change the hardware to not need to wait. | ||
18 | */ | ||
19 | |||
20 | #include <linux/init.h> | ||
21 | #include <linux/io.h> | ||
22 | |||
23 | #include <platform/hardware.h> | ||
24 | #include <platform/lcd.h> | ||
25 | #include <linux/delay.h> | ||
26 | |||
27 | #define LCD_PAUSE_ITERATIONS 4000 | ||
28 | #define LCD_CLEAR 0x1 | ||
29 | #define LCD_DISPLAY_ON 0xc | ||
30 | |||
31 | /* 8bit and 2 lines display */ | ||
32 | #define LCD_DISPLAY_MODE8BIT 0x38 | ||
33 | #define LCD_DISPLAY_POS 0x80 | ||
34 | #define LCD_SHIFT_LEFT 0x18 | ||
35 | #define LCD_SHIFT_RIGHT 0x1c | ||
36 | |||
37 | static int __init lcd_init(void) | ||
38 | { | ||
39 | *LCD_INSTR_ADDR = LCD_DISPLAY_MODE8BIT; | ||
40 | mdelay(5); | ||
41 | *LCD_INSTR_ADDR = LCD_DISPLAY_MODE8BIT; | ||
42 | udelay(200); | ||
43 | *LCD_INSTR_ADDR = LCD_DISPLAY_MODE8BIT; | ||
44 | udelay(50); | ||
45 | *LCD_INSTR_ADDR = LCD_DISPLAY_ON; | ||
46 | udelay(50); | ||
47 | *LCD_INSTR_ADDR = LCD_CLEAR; | ||
48 | mdelay(10); | ||
49 | lcd_disp_at_pos("XTENSA LINUX", 0); | ||
50 | return 0; | ||
51 | } | ||
52 | |||
53 | void lcd_disp_at_pos(char *str, unsigned char pos) | ||
54 | { | ||
55 | *LCD_INSTR_ADDR = LCD_DISPLAY_POS | pos; | ||
56 | udelay(100); | ||
57 | while (*str != 0) { | ||
58 | *LCD_DATA_ADDR = *str; | ||
59 | udelay(200); | ||
60 | str++; | ||
61 | } | ||
62 | } | ||
63 | |||
64 | void lcd_shiftleft(void) | ||
65 | { | ||
66 | *LCD_INSTR_ADDR = LCD_SHIFT_LEFT; | ||
67 | udelay(50); | ||
68 | } | ||
69 | |||
70 | void lcd_shiftright(void) | ||
71 | { | ||
72 | *LCD_INSTR_ADDR = LCD_SHIFT_RIGHT; | ||
73 | udelay(50); | ||
74 | } | ||
75 | |||
76 | arch_initcall(lcd_init); | ||
diff --git a/arch/xtensa/platforms/xtfpga/setup.c b/arch/xtensa/platforms/xtfpga/setup.c new file mode 100644 index 000000000000..4b9951a4569d --- /dev/null +++ b/arch/xtensa/platforms/xtfpga/setup.c | |||
@@ -0,0 +1,301 @@ | |||
1 | /* | ||
2 | * | ||
3 | * arch/xtensa/platform/xtavnet/setup.c | ||
4 | * | ||
5 | * ... | ||
6 | * | ||
7 | * Authors: Chris Zankel <chris@zankel.net> | ||
8 | * Joe Taylor <joe@tensilica.com> | ||
9 | * | ||
10 | * Copyright 2001 - 2006 Tensilica Inc. | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify it | ||
13 | * under the terms of the GNU General Public License as published by the | ||
14 | * Free Software Foundation; either version 2 of the License, or (at your | ||
15 | * option) any later version. | ||
16 | * | ||
17 | */ | ||
18 | #include <linux/stddef.h> | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/errno.h> | ||
22 | #include <linux/reboot.h> | ||
23 | #include <linux/kdev_t.h> | ||
24 | #include <linux/types.h> | ||
25 | #include <linux/major.h> | ||
26 | #include <linux/console.h> | ||
27 | #include <linux/delay.h> | ||
28 | #include <linux/of.h> | ||
29 | |||
30 | #include <asm/timex.h> | ||
31 | #include <asm/processor.h> | ||
32 | #include <asm/platform.h> | ||
33 | #include <asm/bootparam.h> | ||
34 | #include <platform/lcd.h> | ||
35 | #include <platform/hardware.h> | ||
36 | |||
37 | void platform_halt(void) | ||
38 | { | ||
39 | lcd_disp_at_pos(" HALT ", 0); | ||
40 | local_irq_disable(); | ||
41 | while (1) | ||
42 | cpu_relax(); | ||
43 | } | ||
44 | |||
45 | void platform_power_off(void) | ||
46 | { | ||
47 | lcd_disp_at_pos("POWEROFF", 0); | ||
48 | local_irq_disable(); | ||
49 | while (1) | ||
50 | cpu_relax(); | ||
51 | } | ||
52 | |||
53 | void platform_restart(void) | ||
54 | { | ||
55 | /* Flush and reset the mmu, simulate a processor reset, and | ||
56 | * jump to the reset vector. */ | ||
57 | |||
58 | |||
59 | __asm__ __volatile__ ("movi a2, 15\n\t" | ||
60 | "wsr a2, icountlevel\n\t" | ||
61 | "movi a2, 0\n\t" | ||
62 | "wsr a2, icount\n\t" | ||
63 | "wsr a2, ibreakenable\n\t" | ||
64 | "wsr a2, lcount\n\t" | ||
65 | "movi a2, 0x1f\n\t" | ||
66 | "wsr a2, ps\n\t" | ||
67 | "isync\n\t" | ||
68 | "jx %0\n\t" | ||
69 | : | ||
70 | : "a" (XCHAL_RESET_VECTOR_VADDR) | ||
71 | : "a2" | ||
72 | ); | ||
73 | |||
74 | /* control never gets here */ | ||
75 | } | ||
76 | |||
77 | void __init platform_setup(char **cmdline) | ||
78 | { | ||
79 | } | ||
80 | |||
81 | #ifdef CONFIG_OF | ||
82 | |||
83 | static void __init update_clock_frequency(struct device_node *node) | ||
84 | { | ||
85 | struct property *newfreq; | ||
86 | u32 freq; | ||
87 | |||
88 | if (!of_property_read_u32(node, "clock-frequency", &freq) && freq != 0) | ||
89 | return; | ||
90 | |||
91 | newfreq = kzalloc(sizeof(*newfreq) + sizeof(u32), GFP_KERNEL); | ||
92 | if (!newfreq) | ||
93 | return; | ||
94 | newfreq->value = newfreq + 1; | ||
95 | newfreq->length = sizeof(freq); | ||
96 | newfreq->name = kstrdup("clock-frequency", GFP_KERNEL); | ||
97 | if (!newfreq->name) { | ||
98 | kfree(newfreq); | ||
99 | return; | ||
100 | } | ||
101 | |||
102 | *(u32 *)newfreq->value = cpu_to_be32(*(u32 *)XTFPGA_CLKFRQ_VADDR); | ||
103 | prom_update_property(node, newfreq); | ||
104 | } | ||
105 | |||
106 | #define MAC_LEN 6 | ||
107 | static void __init update_local_mac(struct device_node *node) | ||
108 | { | ||
109 | struct property *newmac; | ||
110 | const u8* macaddr; | ||
111 | int prop_len; | ||
112 | |||
113 | macaddr = of_get_property(node, "local-mac-address", &prop_len); | ||
114 | if (macaddr == NULL || prop_len != MAC_LEN) | ||
115 | return; | ||
116 | |||
117 | newmac = kzalloc(sizeof(*newmac) + MAC_LEN, GFP_KERNEL); | ||
118 | if (newmac == NULL) | ||
119 | return; | ||
120 | |||
121 | newmac->value = newmac + 1; | ||
122 | newmac->length = MAC_LEN; | ||
123 | newmac->name = kstrdup("local-mac-address", GFP_KERNEL); | ||
124 | if (newmac->name == NULL) { | ||
125 | kfree(newmac); | ||
126 | return; | ||
127 | } | ||
128 | |||
129 | memcpy(newmac->value, macaddr, MAC_LEN); | ||
130 | ((u8*)newmac->value)[5] = (*(u32*)DIP_SWITCHES_VADDR) & 0x3f; | ||
131 | prom_update_property(node, newmac); | ||
132 | } | ||
133 | |||
134 | static int __init machine_setup(void) | ||
135 | { | ||
136 | struct device_node *serial; | ||
137 | struct device_node *eth = NULL; | ||
138 | |||
139 | for_each_compatible_node(serial, NULL, "ns16550a") | ||
140 | update_clock_frequency(serial); | ||
141 | |||
142 | if ((eth = of_find_compatible_node(eth, NULL, "opencores,ethoc"))) | ||
143 | update_local_mac(eth); | ||
144 | return 0; | ||
145 | } | ||
146 | arch_initcall(machine_setup); | ||
147 | |||
148 | #endif | ||
149 | |||
150 | /* early initialization */ | ||
151 | |||
152 | void __init platform_init(bp_tag_t *first) | ||
153 | { | ||
154 | } | ||
155 | |||
156 | /* Heartbeat. */ | ||
157 | |||
158 | void platform_heartbeat(void) | ||
159 | { | ||
160 | } | ||
161 | |||
162 | #ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT | ||
163 | |||
164 | void platform_calibrate_ccount(void) | ||
165 | { | ||
166 | long clk_freq = 0; | ||
167 | #ifdef CONFIG_OF | ||
168 | struct device_node *cpu = | ||
169 | of_find_compatible_node(NULL, NULL, "xtensa,cpu"); | ||
170 | if (cpu) { | ||
171 | u32 freq; | ||
172 | update_clock_frequency(cpu); | ||
173 | if (!of_property_read_u32(cpu, "clock-frequency", &freq)) | ||
174 | clk_freq = freq; | ||
175 | } | ||
176 | #endif | ||
177 | if (!clk_freq) | ||
178 | clk_freq = *(long *)XTFPGA_CLKFRQ_VADDR; | ||
179 | |||
180 | ccount_per_jiffy = clk_freq / HZ; | ||
181 | nsec_per_ccount = 1000000000UL / clk_freq; | ||
182 | } | ||
183 | |||
184 | #endif | ||
185 | |||
186 | #ifndef CONFIG_OF | ||
187 | |||
188 | #include <linux/serial_8250.h> | ||
189 | #include <linux/if.h> | ||
190 | #include <net/ethoc.h> | ||
191 | |||
192 | /*---------------------------------------------------------------------------- | ||
193 | * Ethernet -- OpenCores Ethernet MAC (ethoc driver) | ||
194 | */ | ||
195 | |||
196 | static struct resource ethoc_res[] __initdata = { | ||
197 | [0] = { /* register space */ | ||
198 | .start = OETH_REGS_PADDR, | ||
199 | .end = OETH_REGS_PADDR + OETH_REGS_SIZE - 1, | ||
200 | .flags = IORESOURCE_MEM, | ||
201 | }, | ||
202 | [1] = { /* buffer space */ | ||
203 | .start = OETH_SRAMBUFF_PADDR, | ||
204 | .end = OETH_SRAMBUFF_PADDR + OETH_SRAMBUFF_SIZE - 1, | ||
205 | .flags = IORESOURCE_MEM, | ||
206 | }, | ||
207 | [2] = { /* IRQ number */ | ||
208 | .start = OETH_IRQ, | ||
209 | .end = OETH_IRQ, | ||
210 | .flags = IORESOURCE_IRQ, | ||
211 | }, | ||
212 | }; | ||
213 | |||
214 | static struct ethoc_platform_data ethoc_pdata __initdata = { | ||
215 | /* | ||
216 | * The MAC address for these boards is 00:50:c2:13:6f:xx. | ||
217 | * The last byte (here as zero) is read from the DIP switches on the | ||
218 | * board. | ||
219 | */ | ||
220 | .hwaddr = { 0x00, 0x50, 0xc2, 0x13, 0x6f, 0 }, | ||
221 | .phy_id = -1, | ||
222 | }; | ||
223 | |||
224 | static struct platform_device ethoc_device __initdata = { | ||
225 | .name = "ethoc", | ||
226 | .id = -1, | ||
227 | .num_resources = ARRAY_SIZE(ethoc_res), | ||
228 | .resource = ethoc_res, | ||
229 | .dev = { | ||
230 | .platform_data = ðoc_pdata, | ||
231 | }, | ||
232 | }; | ||
233 | |||
234 | /*---------------------------------------------------------------------------- | ||
235 | * UART | ||
236 | */ | ||
237 | |||
238 | static struct resource serial_resource __initdata = { | ||
239 | .start = DUART16552_PADDR, | ||
240 | .end = DUART16552_PADDR + 0x1f, | ||
241 | .flags = IORESOURCE_MEM, | ||
242 | }; | ||
243 | |||
244 | static struct plat_serial8250_port serial_platform_data[] __initdata = { | ||
245 | [0] = { | ||
246 | .mapbase = DUART16552_PADDR, | ||
247 | .irq = DUART16552_INTNUM, | ||
248 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | | ||
249 | UPF_IOREMAP, | ||
250 | .iotype = UPIO_MEM32, | ||
251 | .regshift = 2, | ||
252 | .uartclk = 0, /* set in xtavnet_init() */ | ||
253 | }, | ||
254 | { }, | ||
255 | }; | ||
256 | |||
257 | static struct platform_device xtavnet_uart __initdata = { | ||
258 | .name = "serial8250", | ||
259 | .id = PLAT8250_DEV_PLATFORM, | ||
260 | .dev = { | ||
261 | .platform_data = serial_platform_data, | ||
262 | }, | ||
263 | .num_resources = 1, | ||
264 | .resource = &serial_resource, | ||
265 | }; | ||
266 | |||
267 | /* platform devices */ | ||
268 | static struct platform_device *platform_devices[] __initdata = { | ||
269 | ðoc_device, | ||
270 | &xtavnet_uart, | ||
271 | }; | ||
272 | |||
273 | |||
274 | static int __init xtavnet_init(void) | ||
275 | { | ||
276 | /* Ethernet MAC address. */ | ||
277 | ethoc_pdata.hwaddr[5] = *(u32 *)DIP_SWITCHES_VADDR; | ||
278 | |||
279 | /* Clock rate varies among FPGA bitstreams; board specific FPGA register | ||
280 | * reports the actual clock rate. | ||
281 | */ | ||
282 | serial_platform_data[0].uartclk = *(long *)XTFPGA_CLKFRQ_VADDR; | ||
283 | |||
284 | |||
285 | /* register platform devices */ | ||
286 | platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); | ||
287 | |||
288 | /* ETHOC driver is a bit quiet; at least display Ethernet MAC, so user | ||
289 | * knows whether they set it correctly on the DIP switches. | ||
290 | */ | ||
291 | pr_info("XTFPGA: Ethernet MAC %pM\n", ethoc_pdata.hwaddr); | ||
292 | |||
293 | return 0; | ||
294 | } | ||
295 | |||
296 | /* | ||
297 | * Register to be done during do_initcalls(). | ||
298 | */ | ||
299 | arch_initcall(xtavnet_init); | ||
300 | |||
301 | #endif /* CONFIG_OF */ | ||
diff --git a/arch/xtensa/variants/s6000/gpio.c b/arch/xtensa/variants/s6000/gpio.c index b89541ba39ab..da9e85c13b08 100644 --- a/arch/xtensa/variants/s6000/gpio.c +++ b/arch/xtensa/variants/s6000/gpio.c | |||
@@ -164,7 +164,7 @@ static void demux_irqs(unsigned int irq, struct irq_desc *desc) | |||
164 | int cirq; | 164 | int cirq; |
165 | 165 | ||
166 | chip->irq_mask(&desc->irq_data); | 166 | chip->irq_mask(&desc->irq_data); |
167 | chip->irq_ack(&desc->irq_data)); | 167 | chip->irq_ack(&desc->irq_data); |
168 | pending = readb(S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_MIS) & *mask; | 168 | pending = readb(S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_MIS) & *mask; |
169 | cirq = IRQ_BASE - 1; | 169 | cirq = IRQ_BASE - 1; |
170 | while (pending) { | 170 | while (pending) { |
@@ -173,7 +173,7 @@ static void demux_irqs(unsigned int irq, struct irq_desc *desc) | |||
173 | pending >>= n; | 173 | pending >>= n; |
174 | generic_handle_irq(cirq); | 174 | generic_handle_irq(cirq); |
175 | } | 175 | } |
176 | chip->irq_unmask(&desc->irq_data)); | 176 | chip->irq_unmask(&desc->irq_data); |
177 | } | 177 | } |
178 | 178 | ||
179 | extern const signed char *platform_irq_mappings[XTENSA_NR_IRQS]; | 179 | extern const signed char *platform_irq_mappings[XTENSA_NR_IRQS]; |