diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-26 22:53:12 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-26 22:53:12 -0500 |
commit | 9626357371b519f2b955fef399647181034a77fe (patch) | |
tree | 232abd741e773c7d3afb4ba6b02fcba03b82214d /arch/xtensa | |
parent | 2b37e9a28afbd11f899738e912fb4a617a74b462 (diff) | |
parent | 9cf81c759b7db1db593b2ca60b74ec350d5f9205 (diff) |
Merge tag 'xtensa-next-20130225' of git://github.com/czankel/xtensa-linux
Pull xtensa update from Chris Zankel:
"Added features:
- add support for thread local storage (TLS)
- add accept4 and finit_module syscalls
- support medium-priority interrupts
- add support for dc232c processor variant
- support file-base simulated disk for ISS simulator
Bug fixes:
- fix return values returned by the str[n]cmp functions
- avoid mmap cache aliasing
- fix handling of 'windowed registers' in ptrace"
* tag 'xtensa-next-20130225' of git://github.com/czankel/xtensa-linux:
xtensa: add accept4 syscall
xtensa: add support for TLS
xtensa: add missing include asm/uaccess.h to checksum.h
xtensa: do not enable GENERIC_GPIO by default
xtensa: complete ptrace handling of register windows
xtensa: add support for oprofile
xtensa: move spill_registers to traps.h
xtensa: ISS: add host file-based simulated disk
xtensa: fix str[n]cmp return value
xtensa: avoid mmap cache aliasing
xtensa: add finit_module syscall
xtensa: pull signal definitions from signal-defs.h
xtensa: fix ipc_parse_version selection
xtensa: dispatch medium-priority interrupts
xtensa: Add config files for Diamond 233L - Rev C processor variant
xtensa: use new common dtc rule
xtensa: rename prom_update_property to of_update_property
Diffstat (limited to 'arch/xtensa')
36 files changed, 1851 insertions, 115 deletions
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index cb557be492b1..a5c0663c2cdc 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig | |||
@@ -13,9 +13,11 @@ config XTENSA | |||
13 | select GENERIC_CPU_DEVICES | 13 | select GENERIC_CPU_DEVICES |
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_IPC_PARSE_VERSION | ||
16 | select ARCH_WANT_OPTIONAL_GPIOLIB | 17 | select ARCH_WANT_OPTIONAL_GPIOLIB |
17 | select CLONE_BACKWARDS | 18 | select CLONE_BACKWARDS |
18 | select IRQ_DOMAIN | 19 | select IRQ_DOMAIN |
20 | select HAVE_OPROFILE | ||
19 | help | 21 | help |
20 | Xtensa processors are 32-bit RISC machines designed by Tensilica | 22 | Xtensa processors are 32-bit RISC machines designed by Tensilica |
21 | primarily for embedded systems. These processors are both | 23 | primarily for embedded systems. These processors are both |
@@ -31,7 +33,7 @@ config GENERIC_HWEIGHT | |||
31 | def_bool y | 33 | def_bool y |
32 | 34 | ||
33 | config GENERIC_GPIO | 35 | config GENERIC_GPIO |
34 | def_bool y | 36 | bool |
35 | 37 | ||
36 | config ARCH_HAS_ILOG2_U32 | 38 | config ARCH_HAS_ILOG2_U32 |
37 | def_bool n | 39 | def_bool n |
@@ -71,6 +73,12 @@ config XTENSA_VARIANT_DC232B | |||
71 | help | 73 | help |
72 | This variant refers to Tensilica's Diamond 232L Standard core Rev.B (LE). | 74 | This variant refers to Tensilica's Diamond 232L Standard core Rev.B (LE). |
73 | 75 | ||
76 | config XTENSA_VARIANT_DC233C | ||
77 | bool "dc233c - Diamond 233L Standard Core Rev.C (LE)" | ||
78 | select MMU | ||
79 | help | ||
80 | This variant refers to Tensilica's Diamond 233L Standard core Rev.C (LE). | ||
81 | |||
74 | config XTENSA_VARIANT_S6000 | 82 | config XTENSA_VARIANT_S6000 |
75 | bool "s6000 - Stretch software configurable processor" | 83 | bool "s6000 - Stretch software configurable processor" |
76 | select VARIANT_IRQ_SWITCH | 84 | select VARIANT_IRQ_SWITCH |
@@ -197,6 +205,42 @@ config BUILTIN_DTB | |||
197 | string "DTB to build into the kernel image" | 205 | string "DTB to build into the kernel image" |
198 | depends on OF | 206 | depends on OF |
199 | 207 | ||
208 | config BLK_DEV_SIMDISK | ||
209 | tristate "Host file-based simulated block device support" | ||
210 | default n | ||
211 | depends on XTENSA_PLATFORM_ISS | ||
212 | help | ||
213 | Create block devices that map to files in the host file system. | ||
214 | Device binding to host file may be changed at runtime via proc | ||
215 | interface provided the device is not in use. | ||
216 | |||
217 | config BLK_DEV_SIMDISK_COUNT | ||
218 | int "Number of host file-based simulated block devices" | ||
219 | range 1 10 | ||
220 | depends on BLK_DEV_SIMDISK | ||
221 | default 2 | ||
222 | help | ||
223 | This is the default minimal number of created block devices. | ||
224 | Kernel/module parameter 'simdisk_count' may be used to change this | ||
225 | value at runtime. More file names (but no more than 10) may be | ||
226 | specified as parameters, simdisk_count grows accordingly. | ||
227 | |||
228 | config SIMDISK0_FILENAME | ||
229 | string "Host filename for the first simulated device" | ||
230 | depends on BLK_DEV_SIMDISK = y | ||
231 | default "" | ||
232 | help | ||
233 | Attach a first simdisk to a host file. Conventionally, this file | ||
234 | contains a root file system. | ||
235 | |||
236 | config SIMDISK1_FILENAME | ||
237 | string "Host filename for the second simulated device" | ||
238 | depends on BLK_DEV_SIMDISK = y && BLK_DEV_SIMDISK_COUNT != 1 | ||
239 | default "" | ||
240 | help | ||
241 | Another simulated disk in a host file for a buildroot-independent | ||
242 | storage. | ||
243 | |||
200 | source "mm/Kconfig" | 244 | source "mm/Kconfig" |
201 | 245 | ||
202 | source "drivers/pcmcia/Kconfig" | 246 | source "drivers/pcmcia/Kconfig" |
diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile index 0aa72702f179..136224b74d4f 100644 --- a/arch/xtensa/Makefile +++ b/arch/xtensa/Makefile | |||
@@ -15,6 +15,7 @@ | |||
15 | 15 | ||
16 | variant-$(CONFIG_XTENSA_VARIANT_FSF) := fsf | 16 | variant-$(CONFIG_XTENSA_VARIANT_FSF) := fsf |
17 | variant-$(CONFIG_XTENSA_VARIANT_DC232B) := dc232b | 17 | variant-$(CONFIG_XTENSA_VARIANT_DC232B) := dc232b |
18 | variant-$(CONFIG_XTENSA_VARIANT_DC233C) := dc233c | ||
18 | variant-$(CONFIG_XTENSA_VARIANT_S6000) := s6000 | 19 | variant-$(CONFIG_XTENSA_VARIANT_S6000) := s6000 |
19 | variant-$(CONFIG_XTENSA_VARIANT_LINUX_CUSTOM) := custom | 20 | variant-$(CONFIG_XTENSA_VARIANT_LINUX_CUSTOM) := custom |
20 | 21 | ||
@@ -86,9 +87,10 @@ core-y += arch/xtensa/kernel/ arch/xtensa/mm/ | |||
86 | core-y += $(buildvar) $(buildplf) | 87 | core-y += $(buildvar) $(buildplf) |
87 | 88 | ||
88 | libs-y += arch/xtensa/lib/ $(LIBGCC) | 89 | libs-y += arch/xtensa/lib/ $(LIBGCC) |
90 | drivers-$(CONFIG_OPROFILE) += arch/xtensa/oprofile/ | ||
89 | 91 | ||
90 | ifneq ($(CONFIG_BUILTIN_DTB),"") | 92 | ifneq ($(CONFIG_BUILTIN_DTB),"") |
91 | core-$(CONFIG_OF) += arch/xtensa/boot/ | 93 | core-$(CONFIG_OF) += arch/xtensa/boot/dts/ |
92 | endif | 94 | endif |
93 | 95 | ||
94 | boot := arch/xtensa/boot | 96 | boot := arch/xtensa/boot |
@@ -101,7 +103,7 @@ zImage: vmlinux | |||
101 | $(Q)$(MAKE) $(build)=$(boot) $@ | 103 | $(Q)$(MAKE) $(build)=$(boot) $@ |
102 | 104 | ||
103 | %.dtb: | 105 | %.dtb: |
104 | $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ | 106 | $(Q)$(MAKE) $(build)=$(boot)/dts $(boot)/dts/$@ |
105 | 107 | ||
106 | define archhelp | 108 | define archhelp |
107 | @echo '* zImage - Compressed kernel image (arch/xtensa/boot/images/zImage.*)' | 109 | @echo '* zImage - Compressed kernel image (arch/xtensa/boot/images/zImage.*)' |
diff --git a/arch/xtensa/boot/Makefile b/arch/xtensa/boot/Makefile index 818647e815d7..64ffc4b53df6 100644 --- a/arch/xtensa/boot/Makefile +++ b/arch/xtensa/boot/Makefile | |||
@@ -25,18 +25,6 @@ bootdir-$(CONFIG_XTENSA_PLATFORM_ISS) += boot-elf | |||
25 | bootdir-$(CONFIG_XTENSA_PLATFORM_XT2000) += boot-redboot boot-elf boot-uboot | 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 | bootdir-$(CONFIG_XTENSA_PLATFORM_XTFPGA) += boot-redboot boot-elf boot-uboot |
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 | |||
40 | zImage Image: $(bootdir-y) | 28 | zImage Image: $(bootdir-y) |
41 | 29 | ||
42 | $(bootdir-y): $(addprefix $(obj)/,$(subdir-y)) \ | 30 | $(bootdir-y): $(addprefix $(obj)/,$(subdir-y)) \ |
diff --git a/arch/xtensa/boot/dts/Makefile b/arch/xtensa/boot/dts/Makefile new file mode 100644 index 000000000000..5f711bba8307 --- /dev/null +++ b/arch/xtensa/boot/dts/Makefile | |||
@@ -0,0 +1,15 @@ | |||
1 | # | ||
2 | # arch/xtensa/boot/dts/Makefile | ||
3 | # | ||
4 | # This file is subject to the terms and conditions of the GNU General Public | ||
5 | # License. See the file "COPYING" in the main directory of this archive | ||
6 | # for more details. | ||
7 | # | ||
8 | # | ||
9 | |||
10 | BUILTIN_DTB := $(patsubst "%",%,$(CONFIG_BUILTIN_DTB)).dtb.o | ||
11 | ifneq ($(CONFIG_BUILTIN_DTB),"") | ||
12 | obj-$(CONFIG_OF) += $(BUILTIN_DTB) | ||
13 | endif | ||
14 | |||
15 | clean-files := *.dtb.S | ||
diff --git a/arch/xtensa/include/asm/atomic.h b/arch/xtensa/include/asm/atomic.h index c3f289174c10..e7fb447bce8e 100644 --- a/arch/xtensa/include/asm/atomic.h +++ b/arch/xtensa/include/asm/atomic.h | |||
@@ -7,7 +7,7 @@ | |||
7 | * License. See the file "COPYING" in the main directory of this archive | 7 | * License. See the file "COPYING" in the main directory of this archive |
8 | * for more details. | 8 | * for more details. |
9 | * | 9 | * |
10 | * Copyright (C) 2001 - 2005 Tensilica Inc. | 10 | * Copyright (C) 2001 - 2008 Tensilica Inc. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #ifndef _XTENSA_ATOMIC_H | 13 | #ifndef _XTENSA_ATOMIC_H |
@@ -24,11 +24,11 @@ | |||
24 | 24 | ||
25 | /* | 25 | /* |
26 | * This Xtensa implementation assumes that the right mechanism | 26 | * This Xtensa implementation assumes that the right mechanism |
27 | * for exclusion is for locking interrupts to level 1. | 27 | * for exclusion is for locking interrupts to level EXCM_LEVEL. |
28 | * | 28 | * |
29 | * Locking interrupts looks like this: | 29 | * Locking interrupts looks like this: |
30 | * | 30 | * |
31 | * rsil a15, 1 | 31 | * rsil a15, LOCKLEVEL |
32 | * <code> | 32 | * <code> |
33 | * wsr a15, PS | 33 | * wsr a15, PS |
34 | * rsync | 34 | * rsync |
diff --git a/arch/xtensa/include/asm/checksum.h b/arch/xtensa/include/asm/checksum.h index aed7ad68ca46..0593de689b56 100644 --- a/arch/xtensa/include/asm/checksum.h +++ b/arch/xtensa/include/asm/checksum.h | |||
@@ -12,6 +12,7 @@ | |||
12 | #define _XTENSA_CHECKSUM_H | 12 | #define _XTENSA_CHECKSUM_H |
13 | 13 | ||
14 | #include <linux/in6.h> | 14 | #include <linux/in6.h> |
15 | #include <asm/uaccess.h> | ||
15 | #include <variant/core.h> | 16 | #include <variant/core.h> |
16 | 17 | ||
17 | /* | 18 | /* |
diff --git a/arch/xtensa/include/asm/elf.h b/arch/xtensa/include/asm/elf.h index 264d5fa450d8..eacb25a41718 100644 --- a/arch/xtensa/include/asm/elf.h +++ b/arch/xtensa/include/asm/elf.h | |||
@@ -84,7 +84,8 @@ typedef struct { | |||
84 | elf_greg_t sar; | 84 | elf_greg_t sar; |
85 | elf_greg_t windowstart; | 85 | elf_greg_t windowstart; |
86 | elf_greg_t windowbase; | 86 | elf_greg_t windowbase; |
87 | elf_greg_t reserved[8+48]; | 87 | elf_greg_t threadptr; |
88 | elf_greg_t reserved[7+48]; | ||
88 | elf_greg_t a[64]; | 89 | elf_greg_t a[64]; |
89 | } xtensa_gregset_t; | 90 | } xtensa_gregset_t; |
90 | 91 | ||
diff --git a/arch/xtensa/include/asm/pgtable.h b/arch/xtensa/include/asm/pgtable.h index c90ea5bfa1b4..d7546c94da52 100644 --- a/arch/xtensa/include/asm/pgtable.h +++ b/arch/xtensa/include/asm/pgtable.h | |||
@@ -410,6 +410,10 @@ typedef pte_t *pte_addr_t; | |||
410 | #define __HAVE_ARCH_PTEP_SET_WRPROTECT | 410 | #define __HAVE_ARCH_PTEP_SET_WRPROTECT |
411 | #define __HAVE_ARCH_PTEP_MKDIRTY | 411 | #define __HAVE_ARCH_PTEP_MKDIRTY |
412 | #define __HAVE_ARCH_PTE_SAME | 412 | #define __HAVE_ARCH_PTE_SAME |
413 | /* We provide our own get_unmapped_area to cope with | ||
414 | * SHM area cache aliasing for userland. | ||
415 | */ | ||
416 | #define HAVE_ARCH_UNMAPPED_AREA | ||
413 | 417 | ||
414 | #include <asm-generic/pgtable.h> | 418 | #include <asm-generic/pgtable.h> |
415 | 419 | ||
diff --git a/arch/xtensa/include/asm/processor.h b/arch/xtensa/include/asm/processor.h index e5fb6b0abdf4..7e409a5b0ec5 100644 --- a/arch/xtensa/include/asm/processor.h +++ b/arch/xtensa/include/asm/processor.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * License. See the file "COPYING" in the main directory of this archive | 5 | * License. See the file "COPYING" in the main directory of this archive |
6 | * for more details. | 6 | * for more details. |
7 | * | 7 | * |
8 | * Copyright (C) 2001 - 2005 Tensilica Inc. | 8 | * Copyright (C) 2001 - 2008 Tensilica Inc. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #ifndef _XTENSA_PROCESSOR_H | 11 | #ifndef _XTENSA_PROCESSOR_H |
@@ -68,7 +68,7 @@ | |||
68 | /* LOCKLEVEL defines the interrupt level that masks all | 68 | /* LOCKLEVEL defines the interrupt level that masks all |
69 | * general-purpose interrupts. | 69 | * general-purpose interrupts. |
70 | */ | 70 | */ |
71 | #define LOCKLEVEL 1 | 71 | #define LOCKLEVEL XCHAL_EXCM_LEVEL |
72 | 72 | ||
73 | /* WSBITS and WBBITS are the width of the WINDOWSTART and WINDOWBASE | 73 | /* WSBITS and WBBITS are the width of the WINDOWSTART and WINDOWBASE |
74 | * registers | 74 | * registers |
diff --git a/arch/xtensa/include/asm/ptrace.h b/arch/xtensa/include/asm/ptrace.h index 682b1deac1f2..81f31bc9dde0 100644 --- a/arch/xtensa/include/asm/ptrace.h +++ b/arch/xtensa/include/asm/ptrace.h | |||
@@ -38,6 +38,7 @@ struct pt_regs { | |||
38 | unsigned long syscall; /* 56 */ | 38 | unsigned long syscall; /* 56 */ |
39 | unsigned long icountlevel; /* 60 */ | 39 | unsigned long icountlevel; /* 60 */ |
40 | unsigned long scompare1; /* 64 */ | 40 | unsigned long scompare1; /* 64 */ |
41 | unsigned long threadptr; /* 68 */ | ||
41 | 42 | ||
42 | /* Additional configurable registers that are used by the compiler. */ | 43 | /* Additional configurable registers that are used by the compiler. */ |
43 | xtregs_opt_t xtregs_opt; | 44 | xtregs_opt_t xtregs_opt; |
@@ -48,7 +49,7 @@ struct pt_regs { | |||
48 | /* current register frame. | 49 | /* current register frame. |
49 | * Note: The ESF for kernel exceptions ends after 16 registers! | 50 | * Note: The ESF for kernel exceptions ends after 16 registers! |
50 | */ | 51 | */ |
51 | unsigned long areg[16]; /* 128 (64) */ | 52 | unsigned long areg[16]; |
52 | }; | 53 | }; |
53 | 54 | ||
54 | #include <variant/core.h> | 55 | #include <variant/core.h> |
diff --git a/arch/xtensa/include/asm/regs.h b/arch/xtensa/include/asm/regs.h index 76096a4e5b8d..b24de6717020 100644 --- a/arch/xtensa/include/asm/regs.h +++ b/arch/xtensa/include/asm/regs.h | |||
@@ -88,6 +88,7 @@ | |||
88 | #define PS_UM_BIT 5 | 88 | #define PS_UM_BIT 5 |
89 | #define PS_EXCM_BIT 4 | 89 | #define PS_EXCM_BIT 4 |
90 | #define PS_INTLEVEL_SHIFT 0 | 90 | #define PS_INTLEVEL_SHIFT 0 |
91 | #define PS_INTLEVEL_WIDTH 4 | ||
91 | #define PS_INTLEVEL_MASK 0x0000000F | 92 | #define PS_INTLEVEL_MASK 0x0000000F |
92 | 93 | ||
93 | /* DBREAKCn register fields. */ | 94 | /* DBREAKCn register fields. */ |
diff --git a/arch/xtensa/include/asm/string.h b/arch/xtensa/include/asm/string.h index 405a8c49ff2c..8d5d9dfadb09 100644 --- a/arch/xtensa/include/asm/string.h +++ b/arch/xtensa/include/asm/string.h | |||
@@ -74,7 +74,7 @@ static inline int strcmp(const char *__cs, const char *__ct) | |||
74 | "beqz %2, 2f\n\t" | 74 | "beqz %2, 2f\n\t" |
75 | "beq %2, %3, 1b\n" | 75 | "beq %2, %3, 1b\n" |
76 | "2:\n\t" | 76 | "2:\n\t" |
77 | "sub %2, %3, %2" | 77 | "sub %2, %2, %3" |
78 | : "=r" (__cs), "=r" (__ct), "=&r" (__res), "=&r" (__dummy) | 78 | : "=r" (__cs), "=r" (__ct), "=&r" (__res), "=&r" (__dummy) |
79 | : "0" (__cs), "1" (__ct)); | 79 | : "0" (__cs), "1" (__ct)); |
80 | 80 | ||
@@ -99,7 +99,7 @@ static inline int strncmp(const char *__cs, const char *__ct, size_t __n) | |||
99 | "beqz %3, 2f\n\t" | 99 | "beqz %3, 2f\n\t" |
100 | "beq %2, %3, 1b\n" | 100 | "beq %2, %3, 1b\n" |
101 | "2:\n\t" | 101 | "2:\n\t" |
102 | "sub %2, %3, %2" | 102 | "sub %2, %2, %3" |
103 | : "=r" (__cs), "=r" (__ct), "=&r" (__res), "=&r" (__dummy) | 103 | : "=r" (__cs), "=r" (__ct), "=&r" (__res), "=&r" (__dummy) |
104 | : "0" (__cs), "1" (__ct), "r" (__cs+__n)); | 104 | : "0" (__cs), "1" (__ct), "r" (__cs+__n)); |
105 | 105 | ||
diff --git a/arch/xtensa/include/asm/timex.h b/arch/xtensa/include/asm/timex.h index 175b3d5e1b01..9e85ce8bd8dd 100644 --- a/arch/xtensa/include/asm/timex.h +++ b/arch/xtensa/include/asm/timex.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * License. See the file "COPYING" in the main directory of this archive | 5 | * License. See the file "COPYING" in the main directory of this archive |
6 | * for more details. | 6 | * for more details. |
7 | * | 7 | * |
8 | * Copyright (C) 2001 - 2005 Tensilica Inc. | 8 | * Copyright (C) 2001 - 2008 Tensilica Inc. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #ifndef _XTENSA_TIMEX_H | 11 | #ifndef _XTENSA_TIMEX_H |
@@ -19,13 +19,13 @@ | |||
19 | #define _INTLEVEL(x) XCHAL_INT ## x ## _LEVEL | 19 | #define _INTLEVEL(x) XCHAL_INT ## x ## _LEVEL |
20 | #define INTLEVEL(x) _INTLEVEL(x) | 20 | #define INTLEVEL(x) _INTLEVEL(x) |
21 | 21 | ||
22 | #if INTLEVEL(XCHAL_TIMER0_INTERRUPT) == 1 | 22 | #if INTLEVEL(XCHAL_TIMER0_INTERRUPT) <= XCHAL_EXCM_LEVEL |
23 | # define LINUX_TIMER 0 | 23 | # define LINUX_TIMER 0 |
24 | # define LINUX_TIMER_INT XCHAL_TIMER0_INTERRUPT | 24 | # define LINUX_TIMER_INT XCHAL_TIMER0_INTERRUPT |
25 | #elif INTLEVEL(XCHAL_TIMER1_INTERRUPT) == 1 | 25 | #elif INTLEVEL(XCHAL_TIMER1_INTERRUPT) <= XCHAL_EXCM_LEVEL |
26 | # define LINUX_TIMER 1 | 26 | # define LINUX_TIMER 1 |
27 | # define LINUX_TIMER_INT XCHAL_TIMER1_INTERRUPT | 27 | # define LINUX_TIMER_INT XCHAL_TIMER1_INTERRUPT |
28 | #elif INTLEVEL(XCHAL_TIMER2_INTERRUPT) == 1 | 28 | #elif INTLEVEL(XCHAL_TIMER2_INTERRUPT) <= XCHAL_EXCM_LEVEL |
29 | # define LINUX_TIMER 2 | 29 | # define LINUX_TIMER 2 |
30 | # define LINUX_TIMER_INT XCHAL_TIMER2_INTERRUPT | 30 | # define LINUX_TIMER_INT XCHAL_TIMER2_INTERRUPT |
31 | #else | 31 | #else |
diff --git a/arch/xtensa/include/asm/traps.h b/arch/xtensa/include/asm/traps.h index 54f70440185e..b5464ef3cf66 100644 --- a/arch/xtensa/include/asm/traps.h +++ b/arch/xtensa/include/asm/traps.h | |||
@@ -20,4 +20,28 @@ | |||
20 | extern void * __init trap_set_handler(int cause, void *handler); | 20 | extern void * __init trap_set_handler(int cause, void *handler); |
21 | extern void do_unhandled(struct pt_regs *regs, unsigned long exccause); | 21 | extern void do_unhandled(struct pt_regs *regs, unsigned long exccause); |
22 | 22 | ||
23 | static inline void spill_registers(void) | ||
24 | { | ||
25 | unsigned int a0, ps; | ||
26 | |||
27 | __asm__ __volatile__ ( | ||
28 | "movi a14, " __stringify(PS_EXCM_BIT | LOCKLEVEL) "\n\t" | ||
29 | "mov a12, a0\n\t" | ||
30 | "rsr a13, sar\n\t" | ||
31 | "xsr a14, ps\n\t" | ||
32 | "movi a0, _spill_registers\n\t" | ||
33 | "rsync\n\t" | ||
34 | "callx0 a0\n\t" | ||
35 | "mov a0, a12\n\t" | ||
36 | "wsr a13, sar\n\t" | ||
37 | "wsr a14, ps\n\t" | ||
38 | : : "a" (&a0), "a" (&ps) | ||
39 | #if defined(CONFIG_FRAME_POINTER) | ||
40 | : "a2", "a3", "a4", "a11", "a12", "a13", "a14", "a15", | ||
41 | #else | ||
42 | : "a2", "a3", "a4", "a7", "a11", "a12", "a13", "a14", "a15", | ||
43 | #endif | ||
44 | "memory"); | ||
45 | } | ||
46 | |||
23 | #endif /* _XTENSA_TRAPS_H */ | 47 | #endif /* _XTENSA_TRAPS_H */ |
diff --git a/arch/xtensa/include/uapi/asm/signal.h b/arch/xtensa/include/uapi/asm/signal.h index dacf716dd3e0..586756ee267a 100644 --- a/arch/xtensa/include/uapi/asm/signal.h +++ b/arch/xtensa/include/uapi/asm/signal.h | |||
@@ -102,16 +102,7 @@ typedef struct { | |||
102 | 102 | ||
103 | #ifndef __ASSEMBLY__ | 103 | #ifndef __ASSEMBLY__ |
104 | 104 | ||
105 | #define SIG_BLOCK 0 /* for blocking signals */ | 105 | #include <asm-generic/signal-defs.h> |
106 | #define SIG_UNBLOCK 1 /* for unblocking signals */ | ||
107 | #define SIG_SETMASK 2 /* for setting the signal mask */ | ||
108 | |||
109 | /* Type of a signal handler. */ | ||
110 | typedef void (*__sighandler_t)(int); | ||
111 | |||
112 | #define SIG_DFL ((__sighandler_t)0) /* default signal handling */ | ||
113 | #define SIG_IGN ((__sighandler_t)1) /* ignore signal */ | ||
114 | #define SIG_ERR ((__sighandler_t)-1) /* error return from signal */ | ||
115 | 106 | ||
116 | #ifndef __KERNEL__ | 107 | #ifndef __KERNEL__ |
117 | 108 | ||
diff --git a/arch/xtensa/include/uapi/asm/unistd.h b/arch/xtensa/include/uapi/asm/unistd.h index 19fac3f543a2..51940fec6990 100644 --- a/arch/xtensa/include/uapi/asm/unistd.h +++ b/arch/xtensa/include/uapi/asm/unistd.h | |||
@@ -728,8 +728,13 @@ __SYSCALL(330, sys_prlimit64, 4) | |||
728 | #define __NR_kcmp 331 | 728 | #define __NR_kcmp 331 |
729 | __SYSCALL(331, sys_kcmp, 5) | 729 | __SYSCALL(331, sys_kcmp, 5) |
730 | 730 | ||
731 | #define __NR_finit_module 332 | ||
732 | __SYSCALL(332, sys_finit_module, 3) | ||
731 | 733 | ||
732 | #define __NR_syscall_count 332 | 734 | #define __NR_accept4 333 |
735 | __SYSCALL(333, sys_accept4, 4) | ||
736 | |||
737 | #define __NR_syscall_count 334 | ||
733 | 738 | ||
734 | /* | 739 | /* |
735 | * sysxtensa syscall handler | 740 | * sysxtensa syscall handler |
diff --git a/arch/xtensa/kernel/asm-offsets.c b/arch/xtensa/kernel/asm-offsets.c index 0701fad170db..1915c7c889ba 100644 --- a/arch/xtensa/kernel/asm-offsets.c +++ b/arch/xtensa/kernel/asm-offsets.c | |||
@@ -42,6 +42,7 @@ int main(void) | |||
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_SCOMPARE1, offsetof(struct pt_regs, scompare1)); |
45 | DEFINE(PT_THREADPTR, offsetof(struct pt_regs, threadptr)); | ||
45 | DEFINE(PT_AREG, offsetof (struct pt_regs, areg[0])); | 46 | DEFINE(PT_AREG, offsetof (struct pt_regs, areg[0])); |
46 | DEFINE(PT_AREG0, offsetof (struct pt_regs, areg[0])); | 47 | DEFINE(PT_AREG0, offsetof (struct pt_regs, areg[0])); |
47 | DEFINE(PT_AREG1, offsetof (struct pt_regs, areg[1])); | 48 | DEFINE(PT_AREG1, offsetof (struct pt_regs, areg[1])); |
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S index 3777fec85e7c..63845f950792 100644 --- a/arch/xtensa/kernel/entry.S +++ b/arch/xtensa/kernel/entry.S | |||
@@ -7,7 +7,7 @@ | |||
7 | * License. See the file "COPYING" in the main directory of this archive | 7 | * License. See the file "COPYING" in the main directory of this archive |
8 | * for more details. | 8 | * for more details. |
9 | * | 9 | * |
10 | * Copyright (C) 2004-2007 by Tensilica Inc. | 10 | * Copyright (C) 2004 - 2008 by Tensilica Inc. |
11 | * | 11 | * |
12 | * Chris Zankel <chris@zankel.net> | 12 | * Chris Zankel <chris@zankel.net> |
13 | * | 13 | * |
@@ -130,6 +130,11 @@ _user_exception: | |||
130 | s32i a3, a1, PT_SAR | 130 | s32i a3, a1, PT_SAR |
131 | s32i a2, a1, PT_ICOUNTLEVEL | 131 | s32i a2, a1, PT_ICOUNTLEVEL |
132 | 132 | ||
133 | #if XCHAL_HAVE_THREADPTR | ||
134 | rur a2, threadptr | ||
135 | s32i a2, a1, PT_THREADPTR | ||
136 | #endif | ||
137 | |||
133 | /* Rotate ws so that the current windowbase is at bit0. */ | 138 | /* Rotate ws so that the current windowbase is at bit0. */ |
134 | /* Assume ws = xxwww1yyyy. Rotate ws right, so that a2 = yyyyxxwww1 */ | 139 | /* Assume ws = xxwww1yyyy. Rotate ws right, so that a2 = yyyyxxwww1 */ |
135 | 140 | ||
@@ -349,15 +354,16 @@ common_exception: | |||
349 | * so we can allow exceptions and interrupts (*) again. | 354 | * so we can allow exceptions and interrupts (*) again. |
350 | * Set PS(EXCM = 0, UM = 0, RING = 0, OWB = 0, WOE = 1, INTLEVEL = X) | 355 | * Set PS(EXCM = 0, UM = 0, RING = 0, OWB = 0, WOE = 1, INTLEVEL = X) |
351 | * | 356 | * |
352 | * (*) We only allow interrupts if PS.INTLEVEL was not set to 1 before | 357 | * (*) We only allow interrupts of higher priority than current IRQ |
353 | * (interrupts disabled) and if this exception is not an interrupt. | ||
354 | */ | 358 | */ |
355 | 359 | ||
356 | rsr a3, ps | 360 | rsr a3, ps |
357 | addi a0, a0, -4 | 361 | addi a0, a0, -4 |
358 | movi a2, 1 | 362 | movi a2, 1 |
359 | extui a3, a3, 0, 1 # a3 = PS.INTLEVEL[0] | 363 | extui a3, a3, PS_INTLEVEL_SHIFT, PS_INTLEVEL_WIDTH |
360 | moveqz a3, a2, a0 # a3 = 1 iff interrupt exception | 364 | # a3 = PS.INTLEVEL |
365 | movnez a2, a3, a3 # a2 = 1: level-1, > 1: high priority | ||
366 | moveqz a3, a2, a0 # a3 = IRQ level iff interrupt | ||
361 | movi a2, 1 << PS_WOE_BIT | 367 | movi a2, 1 << PS_WOE_BIT |
362 | or a3, a3, a2 | 368 | or a3, a3, a2 |
363 | rsr a0, exccause | 369 | rsr a0, exccause |
@@ -398,7 +404,7 @@ common_exception: | |||
398 | callx4 a4 | 404 | callx4 a4 |
399 | 405 | ||
400 | /* Jump here for exception exit */ | 406 | /* Jump here for exception exit */ |
401 | 407 | .global common_exception_return | |
402 | common_exception_return: | 408 | common_exception_return: |
403 | 409 | ||
404 | /* Jump if we are returning from kernel exceptions. */ | 410 | /* Jump if we are returning from kernel exceptions. */ |
@@ -509,6 +515,11 @@ user_exception_exit: | |||
509 | * (if we have restored WSBITS-1 frames). | 515 | * (if we have restored WSBITS-1 frames). |
510 | */ | 516 | */ |
511 | 517 | ||
518 | #if XCHAL_HAVE_THREADPTR | ||
519 | l32i a3, a1, PT_THREADPTR | ||
520 | wur a3, threadptr | ||
521 | #endif | ||
522 | |||
512 | 2: j common_exception_exit | 523 | 2: j common_exception_exit |
513 | 524 | ||
514 | /* This is the kernel exception exit. | 525 | /* This is the kernel exception exit. |
@@ -641,19 +652,51 @@ common_exception_exit: | |||
641 | 652 | ||
642 | l32i a0, a1, PT_DEPC | 653 | l32i a0, a1, PT_DEPC |
643 | l32i a3, a1, PT_AREG3 | 654 | l32i a3, a1, PT_AREG3 |
655 | _bltui a0, VALID_DOUBLE_EXCEPTION_ADDRESS, 1f | ||
656 | |||
657 | wsr a0, depc | ||
644 | l32i a2, a1, PT_AREG2 | 658 | l32i a2, a1, PT_AREG2 |
645 | _bgeui a0, VALID_DOUBLE_EXCEPTION_ADDRESS, 1f | 659 | l32i a0, a1, PT_AREG0 |
660 | l32i a1, a1, PT_AREG1 | ||
661 | rfde | ||
646 | 662 | ||
663 | 1: | ||
647 | /* Restore a0...a3 and return */ | 664 | /* Restore a0...a3 and return */ |
648 | 665 | ||
666 | rsr a0, ps | ||
667 | extui a2, a0, PS_INTLEVEL_SHIFT, PS_INTLEVEL_WIDTH | ||
668 | movi a0, 2f | ||
669 | slli a2, a2, 4 | ||
670 | add a0, a2, a0 | ||
671 | l32i a2, a1, PT_AREG2 | ||
672 | jx a0 | ||
673 | |||
674 | .macro irq_exit_level level | ||
675 | .align 16 | ||
676 | .if XCHAL_EXCM_LEVEL >= \level | ||
677 | l32i a0, a1, PT_PC | ||
678 | wsr a0, epc\level | ||
649 | l32i a0, a1, PT_AREG0 | 679 | l32i a0, a1, PT_AREG0 |
650 | l32i a1, a1, PT_AREG1 | 680 | l32i a1, a1, PT_AREG1 |
651 | rfe | 681 | rfi \level |
682 | .endif | ||
683 | .endm | ||
652 | 684 | ||
653 | 1: wsr a0, depc | 685 | .align 16 |
686 | 2: | ||
654 | l32i a0, a1, PT_AREG0 | 687 | l32i a0, a1, PT_AREG0 |
655 | l32i a1, a1, PT_AREG1 | 688 | l32i a1, a1, PT_AREG1 |
656 | rfde | 689 | rfe |
690 | |||
691 | .align 16 | ||
692 | /* no rfi for level-1 irq, handled by rfe above*/ | ||
693 | nop | ||
694 | |||
695 | irq_exit_level 2 | ||
696 | irq_exit_level 3 | ||
697 | irq_exit_level 4 | ||
698 | irq_exit_level 5 | ||
699 | irq_exit_level 6 | ||
657 | 700 | ||
658 | ENDPROC(kernel_exception) | 701 | ENDPROC(kernel_exception) |
659 | 702 | ||
@@ -753,7 +796,7 @@ ENTRY(unrecoverable_exception) | |||
753 | wsr a1, windowbase | 796 | wsr a1, windowbase |
754 | rsync | 797 | rsync |
755 | 798 | ||
756 | movi a1, (1 << PS_WOE_BIT) | 1 | 799 | movi a1, (1 << PS_WOE_BIT) | LOCKLEVEL |
757 | wsr a1, ps | 800 | wsr a1, ps |
758 | rsync | 801 | rsync |
759 | 802 | ||
@@ -1474,7 +1517,7 @@ ENTRY(_spill_registers) | |||
1474 | l32i a1, a3, EXC_TABLE_KSTK | 1517 | l32i a1, a3, EXC_TABLE_KSTK |
1475 | wsr a3, excsave1 | 1518 | wsr a3, excsave1 |
1476 | 1519 | ||
1477 | movi a4, (1 << PS_WOE_BIT) | 1 | 1520 | movi a4, (1 << PS_WOE_BIT) | LOCKLEVEL |
1478 | wsr a4, ps | 1521 | wsr a4, ps |
1479 | rsync | 1522 | rsync |
1480 | 1523 | ||
@@ -1922,7 +1965,7 @@ ENTRY(_switch_to) | |||
1922 | s32i a6, a3, EXC_TABLE_FIXUP | 1965 | s32i a6, a3, EXC_TABLE_FIXUP |
1923 | s32i a7, a3, EXC_TABLE_KSTK | 1966 | s32i a7, a3, EXC_TABLE_KSTK |
1924 | 1967 | ||
1925 | /* restore context of the task that 'next' addresses */ | 1968 | /* restore context of the task 'next' */ |
1926 | 1969 | ||
1927 | l32i a0, a13, THREAD_RA # restore return address | 1970 | l32i a0, a13, THREAD_RA # restore return address |
1928 | l32i a1, a13, THREAD_SP # restore stack pointer | 1971 | l32i a1, a13, THREAD_SP # restore stack pointer |
diff --git a/arch/xtensa/kernel/head.S b/arch/xtensa/kernel/head.S index 91d9095284de..df88f98737f4 100644 --- a/arch/xtensa/kernel/head.S +++ b/arch/xtensa/kernel/head.S | |||
@@ -7,7 +7,7 @@ | |||
7 | * License. See the file "COPYING" in the main directory of this archive | 7 | * License. See the file "COPYING" in the main directory of this archive |
8 | * for more details. | 8 | * for more details. |
9 | * | 9 | * |
10 | * Copyright (C) 2001 - 2005 Tensilica Inc. | 10 | * Copyright (C) 2001 - 2008 Tensilica Inc. |
11 | * | 11 | * |
12 | * Chris Zankel <chris@zankel.net> | 12 | * Chris Zankel <chris@zankel.net> |
13 | * Marc Gauthier <marc@tensilica.com, marc@alumni.uwaterloo.ca> | 13 | * Marc Gauthier <marc@tensilica.com, marc@alumni.uwaterloo.ca> |
@@ -128,14 +128,14 @@ ENTRY(_startup) | |||
128 | wsr a0, cpenable | 128 | wsr a0, cpenable |
129 | #endif | 129 | #endif |
130 | 130 | ||
131 | /* Set PS.INTLEVEL=1, PS.WOE=0, kernel stack, PS.EXCM=0 | 131 | /* Set PS.INTLEVEL=LOCKLEVEL, PS.WOE=0, kernel stack, PS.EXCM=0 |
132 | * | 132 | * |
133 | * Note: PS.EXCM must be cleared before using any loop | 133 | * Note: PS.EXCM must be cleared before using any loop |
134 | * instructions; otherwise, they are silently disabled, and | 134 | * instructions; otherwise, they are silently disabled, and |
135 | * at most one iteration of the loop is executed. | 135 | * at most one iteration of the loop is executed. |
136 | */ | 136 | */ |
137 | 137 | ||
138 | movi a1, 1 | 138 | movi a1, LOCKLEVEL |
139 | wsr a1, ps | 139 | wsr a1, ps |
140 | rsync | 140 | rsync |
141 | 141 | ||
@@ -211,7 +211,8 @@ ENTRY(_startup) | |||
211 | movi a1, init_thread_union | 211 | movi a1, init_thread_union |
212 | addi a1, a1, KERNEL_STACK_SIZE | 212 | addi a1, a1, KERNEL_STACK_SIZE |
213 | 213 | ||
214 | movi a2, 0x00040001 # WOE=1, INTLEVEL=1, UM=0 | 214 | movi a2, (1 << PS_WOE_BIT) | LOCKLEVEL |
215 | # WOE=1, INTLEVEL=LOCKLEVEL, UM=0 | ||
215 | wsr a2, ps # (enable reg-windows; progmode stack) | 216 | wsr a2, ps # (enable reg-windows; progmode stack) |
216 | rsync | 217 | rsync |
217 | 218 | ||
diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c index 0dd5784416d3..5cd82e9f601c 100644 --- a/arch/xtensa/kernel/process.c +++ b/arch/xtensa/kernel/process.c | |||
@@ -259,9 +259,10 @@ int copy_thread(unsigned long clone_flags, unsigned long usp_thread_fn, | |||
259 | memcpy(&childregs->areg[XCHAL_NUM_AREGS - len/4], | 259 | memcpy(&childregs->areg[XCHAL_NUM_AREGS - len/4], |
260 | ®s->areg[XCHAL_NUM_AREGS - len/4], len); | 260 | ®s->areg[XCHAL_NUM_AREGS - len/4], len); |
261 | } | 261 | } |
262 | // FIXME: we need to set THREADPTR in thread_info... | 262 | |
263 | /* The thread pointer is passed in the '4th argument' (= a5) */ | ||
263 | if (clone_flags & CLONE_SETTLS) | 264 | if (clone_flags & CLONE_SETTLS) |
264 | childregs->areg[2] = childregs->areg[6]; | 265 | childregs->threadptr = childregs->areg[5]; |
265 | } else { | 266 | } else { |
266 | p->thread.ra = MAKE_RA_FOR_CALL( | 267 | p->thread.ra = MAKE_RA_FOR_CALL( |
267 | (unsigned long)ret_from_kernel_thread, 1); | 268 | (unsigned long)ret_from_kernel_thread, 1); |
diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c index 61fb2e9e9035..562fac664751 100644 --- a/arch/xtensa/kernel/ptrace.c +++ b/arch/xtensa/kernel/ptrace.c | |||
@@ -53,9 +53,8 @@ int ptrace_getregs(struct task_struct *child, void __user *uregs) | |||
53 | { | 53 | { |
54 | struct pt_regs *regs = task_pt_regs(child); | 54 | struct pt_regs *regs = task_pt_regs(child); |
55 | xtensa_gregset_t __user *gregset = uregs; | 55 | xtensa_gregset_t __user *gregset = uregs; |
56 | unsigned long wm = regs->wmask; | ||
57 | unsigned long wb = regs->windowbase; | 56 | unsigned long wb = regs->windowbase; |
58 | int live, i; | 57 | int i; |
59 | 58 | ||
60 | if (!access_ok(VERIFY_WRITE, uregs, sizeof(xtensa_gregset_t))) | 59 | if (!access_ok(VERIFY_WRITE, uregs, sizeof(xtensa_gregset_t))) |
61 | return -EIO; | 60 | return -EIO; |
@@ -67,13 +66,11 @@ int ptrace_getregs(struct task_struct *child, void __user *uregs) | |||
67 | __put_user(regs->lcount, &gregset->lcount); | 66 | __put_user(regs->lcount, &gregset->lcount); |
68 | __put_user(regs->windowstart, &gregset->windowstart); | 67 | __put_user(regs->windowstart, &gregset->windowstart); |
69 | __put_user(regs->windowbase, &gregset->windowbase); | 68 | __put_user(regs->windowbase, &gregset->windowbase); |
69 | __put_user(regs->threadptr, &gregset->threadptr); | ||
70 | 70 | ||
71 | live = (wm & 2) ? 4 : (wm & 4) ? 8 : (wm & 8) ? 12 : 16; | 71 | for (i = 0; i < XCHAL_NUM_AREGS; i++) |
72 | 72 | __put_user(regs->areg[i], | |
73 | for (i = 0; i < live; i++) | 73 | gregset->a + ((wb * 4 + i) % XCHAL_NUM_AREGS)); |
74 | __put_user(regs->areg[i],gregset->a+((wb*4+i)%XCHAL_NUM_AREGS)); | ||
75 | for (i = XCHAL_NUM_AREGS - (wm >> 4) * 4; i < XCHAL_NUM_AREGS; i++) | ||
76 | __put_user(regs->areg[i],gregset->a+((wb*4+i)%XCHAL_NUM_AREGS)); | ||
77 | 74 | ||
78 | return 0; | 75 | return 0; |
79 | } | 76 | } |
@@ -84,7 +81,7 @@ int ptrace_setregs(struct task_struct *child, void __user *uregs) | |||
84 | xtensa_gregset_t *gregset = uregs; | 81 | xtensa_gregset_t *gregset = uregs; |
85 | const unsigned long ps_mask = PS_CALLINC_MASK | PS_OWB_MASK; | 82 | const unsigned long ps_mask = PS_CALLINC_MASK | PS_OWB_MASK; |
86 | unsigned long ps; | 83 | unsigned long ps; |
87 | unsigned long wb; | 84 | unsigned long wb, ws; |
88 | 85 | ||
89 | if (!access_ok(VERIFY_WRITE, uregs, sizeof(xtensa_gregset_t))) | 86 | if (!access_ok(VERIFY_WRITE, uregs, sizeof(xtensa_gregset_t))) |
90 | return -EIO; | 87 | return -EIO; |
@@ -94,21 +91,33 @@ int ptrace_setregs(struct task_struct *child, void __user *uregs) | |||
94 | __get_user(regs->lbeg, &gregset->lbeg); | 91 | __get_user(regs->lbeg, &gregset->lbeg); |
95 | __get_user(regs->lend, &gregset->lend); | 92 | __get_user(regs->lend, &gregset->lend); |
96 | __get_user(regs->lcount, &gregset->lcount); | 93 | __get_user(regs->lcount, &gregset->lcount); |
97 | __get_user(regs->windowstart, &gregset->windowstart); | 94 | __get_user(ws, &gregset->windowstart); |
98 | __get_user(wb, &gregset->windowbase); | 95 | __get_user(wb, &gregset->windowbase); |
96 | __get_user(regs->threadptr, &gregset->threadptr); | ||
99 | 97 | ||
100 | regs->ps = (regs->ps & ~ps_mask) | (ps & ps_mask) | (1 << PS_EXCM_BIT); | 98 | regs->ps = (regs->ps & ~ps_mask) | (ps & ps_mask) | (1 << PS_EXCM_BIT); |
101 | 99 | ||
102 | if (wb >= XCHAL_NUM_AREGS / 4) | 100 | if (wb >= XCHAL_NUM_AREGS / 4) |
103 | return -EFAULT; | 101 | return -EFAULT; |
104 | 102 | ||
105 | regs->windowbase = wb; | 103 | if (wb != regs->windowbase || ws != regs->windowstart) { |
104 | unsigned long rotws, wmask; | ||
105 | |||
106 | rotws = (((ws | (ws << WSBITS)) >> wb) & | ||
107 | ((1 << WSBITS) - 1)) & ~1; | ||
108 | wmask = ((rotws ? WSBITS + 1 - ffs(rotws) : 0) << 4) | | ||
109 | (rotws & 0xF) | 1; | ||
110 | regs->windowbase = wb; | ||
111 | regs->windowstart = ws; | ||
112 | regs->wmask = wmask; | ||
113 | } | ||
106 | 114 | ||
107 | if (wb != 0 && __copy_from_user(regs->areg + XCHAL_NUM_AREGS - wb * 4, | 115 | if (wb != 0 && __copy_from_user(regs->areg + XCHAL_NUM_AREGS - wb * 4, |
108 | gregset->a, wb * 16)) | 116 | gregset->a, wb * 16)) |
109 | return -EFAULT; | 117 | return -EFAULT; |
110 | 118 | ||
111 | if (__copy_from_user(regs->areg, gregset->a + wb*4, (WSBITS-wb) * 16)) | 119 | if (__copy_from_user(regs->areg, gregset->a + wb * 4, |
120 | (WSBITS - wb) * 16)) | ||
112 | return -EFAULT; | 121 | return -EFAULT; |
113 | 122 | ||
114 | return 0; | 123 | return 0; |
diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c index 24c1a57abb40..6dd25ecde3f5 100644 --- a/arch/xtensa/kernel/setup.c +++ b/arch/xtensa/kernel/setup.c | |||
@@ -328,6 +328,27 @@ extern char _UserExceptionVector_literal_start; | |||
328 | extern char _UserExceptionVector_text_end; | 328 | extern char _UserExceptionVector_text_end; |
329 | extern char _DoubleExceptionVector_literal_start; | 329 | extern char _DoubleExceptionVector_literal_start; |
330 | extern char _DoubleExceptionVector_text_end; | 330 | extern char _DoubleExceptionVector_text_end; |
331 | #if XCHAL_EXCM_LEVEL >= 2 | ||
332 | extern char _Level2InterruptVector_text_start; | ||
333 | extern char _Level2InterruptVector_text_end; | ||
334 | #endif | ||
335 | #if XCHAL_EXCM_LEVEL >= 3 | ||
336 | extern char _Level3InterruptVector_text_start; | ||
337 | extern char _Level3InterruptVector_text_end; | ||
338 | #endif | ||
339 | #if XCHAL_EXCM_LEVEL >= 4 | ||
340 | extern char _Level4InterruptVector_text_start; | ||
341 | extern char _Level4InterruptVector_text_end; | ||
342 | #endif | ||
343 | #if XCHAL_EXCM_LEVEL >= 5 | ||
344 | extern char _Level5InterruptVector_text_start; | ||
345 | extern char _Level5InterruptVector_text_end; | ||
346 | #endif | ||
347 | #if XCHAL_EXCM_LEVEL >= 6 | ||
348 | extern char _Level6InterruptVector_text_start; | ||
349 | extern char _Level6InterruptVector_text_end; | ||
350 | #endif | ||
351 | |||
331 | 352 | ||
332 | 353 | ||
333 | #ifdef CONFIG_S32C1I_SELFTEST | 354 | #ifdef CONFIG_S32C1I_SELFTEST |
@@ -482,6 +503,27 @@ void __init setup_arch(char **cmdline_p) | |||
482 | mem_reserve(__pa(&_DoubleExceptionVector_literal_start), | 503 | mem_reserve(__pa(&_DoubleExceptionVector_literal_start), |
483 | __pa(&_DoubleExceptionVector_text_end), 0); | 504 | __pa(&_DoubleExceptionVector_text_end), 0); |
484 | 505 | ||
506 | #if XCHAL_EXCM_LEVEL >= 2 | ||
507 | mem_reserve(__pa(&_Level2InterruptVector_text_start), | ||
508 | __pa(&_Level2InterruptVector_text_end), 0); | ||
509 | #endif | ||
510 | #if XCHAL_EXCM_LEVEL >= 3 | ||
511 | mem_reserve(__pa(&_Level3InterruptVector_text_start), | ||
512 | __pa(&_Level3InterruptVector_text_end), 0); | ||
513 | #endif | ||
514 | #if XCHAL_EXCM_LEVEL >= 4 | ||
515 | mem_reserve(__pa(&_Level4InterruptVector_text_start), | ||
516 | __pa(&_Level4InterruptVector_text_end), 0); | ||
517 | #endif | ||
518 | #if XCHAL_EXCM_LEVEL >= 5 | ||
519 | mem_reserve(__pa(&_Level5InterruptVector_text_start), | ||
520 | __pa(&_Level5InterruptVector_text_end), 0); | ||
521 | #endif | ||
522 | #if XCHAL_EXCM_LEVEL >= 6 | ||
523 | mem_reserve(__pa(&_Level6InterruptVector_text_start), | ||
524 | __pa(&_Level6InterruptVector_text_end), 0); | ||
525 | #endif | ||
526 | |||
485 | bootmem_init(); | 527 | bootmem_init(); |
486 | 528 | ||
487 | #ifdef CONFIG_OF | 529 | #ifdef CONFIG_OF |
diff --git a/arch/xtensa/kernel/signal.c b/arch/xtensa/kernel/signal.c index d7590dddd084..718eca1850bd 100644 --- a/arch/xtensa/kernel/signal.c +++ b/arch/xtensa/kernel/signal.c | |||
@@ -337,7 +337,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
337 | struct rt_sigframe *frame; | 337 | struct rt_sigframe *frame; |
338 | int err = 0; | 338 | int err = 0; |
339 | int signal; | 339 | int signal; |
340 | unsigned long sp, ra; | 340 | unsigned long sp, ra, tp; |
341 | 341 | ||
342 | sp = regs->areg[1]; | 342 | sp = regs->areg[1]; |
343 | 343 | ||
@@ -391,7 +391,8 @@ static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
391 | * Return context not modified until this point. | 391 | * Return context not modified until this point. |
392 | */ | 392 | */ |
393 | 393 | ||
394 | /* Set up registers for signal handler */ | 394 | /* Set up registers for signal handler; preserve the threadptr */ |
395 | tp = regs->threadptr; | ||
395 | start_thread(regs, (unsigned long) ka->sa.sa_handler, | 396 | start_thread(regs, (unsigned long) ka->sa.sa_handler, |
396 | (unsigned long) frame); | 397 | (unsigned long) frame); |
397 | 398 | ||
@@ -402,6 +403,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
402 | regs->areg[6] = (unsigned long) signal; | 403 | regs->areg[6] = (unsigned long) signal; |
403 | regs->areg[7] = (unsigned long) &frame->info; | 404 | regs->areg[7] = (unsigned long) &frame->info; |
404 | regs->areg[8] = (unsigned long) &frame->uc; | 405 | regs->areg[8] = (unsigned long) &frame->uc; |
406 | regs->threadptr = tp; | ||
405 | 407 | ||
406 | /* Set access mode to USER_DS. Nomenclature is outdated, but | 408 | /* Set access mode to USER_DS. Nomenclature is outdated, but |
407 | * functionality is used in uaccess.h | 409 | * functionality is used in uaccess.h |
diff --git a/arch/xtensa/kernel/syscall.c b/arch/xtensa/kernel/syscall.c index 54fa8425cee2..5d3f7a119ed1 100644 --- a/arch/xtensa/kernel/syscall.c +++ b/arch/xtensa/kernel/syscall.c | |||
@@ -36,6 +36,10 @@ syscall_t sys_call_table[__NR_syscall_count] /* FIXME __cacheline_aligned */= { | |||
36 | #include <uapi/asm/unistd.h> | 36 | #include <uapi/asm/unistd.h> |
37 | }; | 37 | }; |
38 | 38 | ||
39 | #define COLOUR_ALIGN(addr, pgoff) \ | ||
40 | ((((addr) + SHMLBA - 1) & ~(SHMLBA - 1)) + \ | ||
41 | (((pgoff) << PAGE_SHIFT) & (SHMLBA - 1))) | ||
42 | |||
39 | asmlinkage long xtensa_shmat(int shmid, char __user *shmaddr, int shmflg) | 43 | asmlinkage long xtensa_shmat(int shmid, char __user *shmaddr, int shmflg) |
40 | { | 44 | { |
41 | unsigned long ret; | 45 | unsigned long ret; |
@@ -52,3 +56,40 @@ asmlinkage long xtensa_fadvise64_64(int fd, int advice, | |||
52 | { | 56 | { |
53 | return sys_fadvise64_64(fd, offset, len, advice); | 57 | return sys_fadvise64_64(fd, offset, len, advice); |
54 | } | 58 | } |
59 | |||
60 | unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, | ||
61 | unsigned long len, unsigned long pgoff, unsigned long flags) | ||
62 | { | ||
63 | struct vm_area_struct *vmm; | ||
64 | |||
65 | if (flags & MAP_FIXED) { | ||
66 | /* We do not accept a shared mapping if it would violate | ||
67 | * cache aliasing constraints. | ||
68 | */ | ||
69 | if ((flags & MAP_SHARED) && | ||
70 | ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1))) | ||
71 | return -EINVAL; | ||
72 | return addr; | ||
73 | } | ||
74 | |||
75 | if (len > TASK_SIZE) | ||
76 | return -ENOMEM; | ||
77 | if (!addr) | ||
78 | addr = TASK_UNMAPPED_BASE; | ||
79 | |||
80 | if (flags & MAP_SHARED) | ||
81 | addr = COLOUR_ALIGN(addr, pgoff); | ||
82 | else | ||
83 | addr = PAGE_ALIGN(addr); | ||
84 | |||
85 | for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) { | ||
86 | /* At this point: (!vmm || addr < vmm->vm_end). */ | ||
87 | if (TASK_SIZE - len < addr) | ||
88 | return -ENOMEM; | ||
89 | if (!vmm || addr + len <= vmm->vm_start) | ||
90 | return addr; | ||
91 | addr = vmm->vm_end; | ||
92 | if (flags & MAP_SHARED) | ||
93 | addr = COLOUR_ALIGN(addr, pgoff); | ||
94 | } | ||
95 | } | ||
diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c index ded955d45155..923db5c15278 100644 --- a/arch/xtensa/kernel/traps.c +++ b/arch/xtensa/kernel/traps.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <asm/uaccess.h> | 37 | #include <asm/uaccess.h> |
38 | #include <asm/pgtable.h> | 38 | #include <asm/pgtable.h> |
39 | #include <asm/processor.h> | 39 | #include <asm/processor.h> |
40 | #include <asm/traps.h> | ||
40 | 41 | ||
41 | #ifdef CONFIG_KGDB | 42 | #ifdef CONFIG_KGDB |
42 | extern int gdb_enter; | 43 | extern int gdb_enter; |
@@ -193,28 +194,49 @@ void do_multihit(struct pt_regs *regs, unsigned long exccause) | |||
193 | } | 194 | } |
194 | 195 | ||
195 | /* | 196 | /* |
196 | * Level-1 interrupt. | 197 | * IRQ handler. |
197 | * We currently have no priority encoding. | 198 | * PS.INTLEVEL is the current IRQ priority level. |
198 | */ | 199 | */ |
199 | 200 | ||
200 | unsigned long ignored_level1_interrupts; | ||
201 | extern void do_IRQ(int, struct pt_regs *); | 201 | extern void do_IRQ(int, struct pt_regs *); |
202 | 202 | ||
203 | void do_interrupt (struct pt_regs *regs) | 203 | void do_interrupt(struct pt_regs *regs) |
204 | { | 204 | { |
205 | unsigned long intread = get_sr (interrupt); | 205 | static const unsigned int_level_mask[] = { |
206 | unsigned long intenable = get_sr (intenable); | 206 | 0, |
207 | int i, mask; | 207 | XCHAL_INTLEVEL1_MASK, |
208 | 208 | XCHAL_INTLEVEL2_MASK, | |
209 | /* Handle all interrupts (no priorities). | 209 | XCHAL_INTLEVEL3_MASK, |
210 | * (Clear the interrupt before processing, in case it's | 210 | XCHAL_INTLEVEL4_MASK, |
211 | * edge-triggered or software-generated) | 211 | XCHAL_INTLEVEL5_MASK, |
212 | */ | 212 | XCHAL_INTLEVEL6_MASK, |
213 | XCHAL_INTLEVEL7_MASK, | ||
214 | }; | ||
215 | unsigned level = get_sr(ps) & PS_INTLEVEL_MASK; | ||
216 | |||
217 | if (WARN_ON_ONCE(level >= ARRAY_SIZE(int_level_mask))) | ||
218 | return; | ||
213 | 219 | ||
214 | for (i=0, mask = 1; i < XCHAL_NUM_INTERRUPTS; i++, mask <<= 1) { | 220 | for (;;) { |
215 | if (mask & (intread & intenable)) { | 221 | unsigned intread = get_sr(interrupt); |
216 | set_sr (mask, intclear); | 222 | unsigned intenable = get_sr(intenable); |
217 | do_IRQ (i,regs); | 223 | unsigned int_at_level = intread & intenable & |
224 | int_level_mask[level]; | ||
225 | |||
226 | if (!int_at_level) | ||
227 | return; | ||
228 | |||
229 | /* | ||
230 | * Clear the interrupt before processing, in case it's | ||
231 | * edge-triggered or software-generated | ||
232 | */ | ||
233 | while (int_at_level) { | ||
234 | unsigned i = __ffs(int_at_level); | ||
235 | unsigned mask = 1 << i; | ||
236 | |||
237 | int_at_level ^= mask; | ||
238 | set_sr(mask, intclear); | ||
239 | do_IRQ(i, regs); | ||
218 | } | 240 | } |
219 | } | 241 | } |
220 | } | 242 | } |
@@ -392,26 +414,6 @@ static __always_inline unsigned long *stack_pointer(struct task_struct *task) | |||
392 | return sp; | 414 | return sp; |
393 | } | 415 | } |
394 | 416 | ||
395 | static inline void spill_registers(void) | ||
396 | { | ||
397 | unsigned int a0, ps; | ||
398 | |||
399 | __asm__ __volatile__ ( | ||
400 | "movi a14, " __stringify(PS_EXCM_BIT | 1) "\n\t" | ||
401 | "mov a12, a0\n\t" | ||
402 | "rsr a13, sar\n\t" | ||
403 | "xsr a14, ps\n\t" | ||
404 | "movi a0, _spill_registers\n\t" | ||
405 | "rsync\n\t" | ||
406 | "callx0 a0\n\t" | ||
407 | "mov a0, a12\n\t" | ||
408 | "wsr a13, sar\n\t" | ||
409 | "wsr a14, ps\n\t" | ||
410 | :: "a" (&a0), "a" (&ps) | ||
411 | : "a2", "a3", "a4", "a7", "a11", "a12", "a13", "a14", "a15", | ||
412 | "memory"); | ||
413 | } | ||
414 | |||
415 | void show_trace(struct task_struct *task, unsigned long *sp) | 417 | void show_trace(struct task_struct *task, unsigned long *sp) |
416 | { | 418 | { |
417 | unsigned long a0, a1, pc; | 419 | unsigned long a0, a1, pc; |
diff --git a/arch/xtensa/kernel/vectors.S b/arch/xtensa/kernel/vectors.S index 68df35f66ce3..82109b42e240 100644 --- a/arch/xtensa/kernel/vectors.S +++ b/arch/xtensa/kernel/vectors.S | |||
@@ -10,7 +10,7 @@ | |||
10 | * Public License. See the file "COPYING" in the main directory of | 10 | * Public License. See the file "COPYING" in the main directory of |
11 | * this archive for more details. | 11 | * this archive for more details. |
12 | * | 12 | * |
13 | * Copyright (C) 2005 Tensilica, Inc. | 13 | * Copyright (C) 2005 - 2008 Tensilica, Inc. |
14 | * | 14 | * |
15 | * Chris Zankel <chris@zankel.net> | 15 | * Chris Zankel <chris@zankel.net> |
16 | * | 16 | * |
@@ -366,6 +366,41 @@ ENTRY(_DebugInterruptVector) | |||
366 | ENDPROC(_DebugInterruptVector) | 366 | ENDPROC(_DebugInterruptVector) |
367 | 367 | ||
368 | 368 | ||
369 | |||
370 | /* | ||
371 | * Medium priority level interrupt vectors | ||
372 | * | ||
373 | * Each takes less than 16 (0x10) bytes, no literals, by placing | ||
374 | * the extra 8 bytes that would otherwise be required in the window | ||
375 | * vectors area where there is space. With relocatable vectors, | ||
376 | * all vectors are within ~ 4 kB range of each other, so we can | ||
377 | * simply jump (J) to another vector without having to use JX. | ||
378 | * | ||
379 | * common_exception code gets current IRQ level in PS.INTLEVEL | ||
380 | * and preserves it for the IRQ handling time. | ||
381 | */ | ||
382 | |||
383 | .macro irq_entry_level level | ||
384 | |||
385 | .if XCHAL_EXCM_LEVEL >= \level | ||
386 | .section .Level\level\()InterruptVector.text, "ax" | ||
387 | ENTRY(_Level\level\()InterruptVector) | ||
388 | wsr a0, epc1 | ||
389 | rsr a0, epc\level | ||
390 | xsr a0, epc1 | ||
391 | # branch to user or kernel vector | ||
392 | j _SimulateUserKernelVectorException | ||
393 | .endif | ||
394 | |||
395 | .endm | ||
396 | |||
397 | irq_entry_level 2 | ||
398 | irq_entry_level 3 | ||
399 | irq_entry_level 4 | ||
400 | irq_entry_level 5 | ||
401 | irq_entry_level 6 | ||
402 | |||
403 | |||
369 | /* Window overflow and underflow handlers. | 404 | /* Window overflow and underflow handlers. |
370 | * The handlers must be 64 bytes apart, first starting with the underflow | 405 | * The handlers must be 64 bytes apart, first starting with the underflow |
371 | * handlers underflow-4 to underflow-12, then the overflow handlers | 406 | * handlers underflow-4 to underflow-12, then the overflow handlers |
@@ -396,6 +431,26 @@ ENTRY_ALIGN64(_WindowOverflow4) | |||
396 | ENDPROC(_WindowOverflow4) | 431 | ENDPROC(_WindowOverflow4) |
397 | 432 | ||
398 | 433 | ||
434 | #if XCHAL_EXCM_LEVEL >= 2 | ||
435 | /* Not a window vector - but a convenient location | ||
436 | * (where we know there's space) for continuation of | ||
437 | * medium priority interrupt dispatch code. | ||
438 | * On entry here, a0 contains PS, and EPC2 contains saved a0: | ||
439 | */ | ||
440 | .align 4 | ||
441 | _SimulateUserKernelVectorException: | ||
442 | wsr a0, excsave2 | ||
443 | movi a0, 4 # LEVEL1_INTERRUPT cause | ||
444 | wsr a0, exccause | ||
445 | rsr a0, ps | ||
446 | bbsi.l a0, PS_UM_BIT, 1f # branch if user mode | ||
447 | rsr a0, excsave2 # restore a0 | ||
448 | j _KernelExceptionVector # simulate kernel vector exception | ||
449 | 1: rsr a0, excsave2 # restore a0 | ||
450 | j _UserExceptionVector # simulate user vector exception | ||
451 | #endif | ||
452 | |||
453 | |||
399 | /* 4-Register Window Underflow Vector (Handler) */ | 454 | /* 4-Register Window Underflow Vector (Handler) */ |
400 | 455 | ||
401 | ENTRY_ALIGN64(_WindowUnderflow4) | 456 | ENTRY_ALIGN64(_WindowUnderflow4) |
diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S index 255154f820b7..14695240536d 100644 --- a/arch/xtensa/kernel/vmlinux.lds.S +++ b/arch/xtensa/kernel/vmlinux.lds.S | |||
@@ -7,7 +7,7 @@ | |||
7 | * License. See the file "COPYING" in the main directory of this archive | 7 | * License. See the file "COPYING" in the main directory of this archive |
8 | * for more details. | 8 | * for more details. |
9 | * | 9 | * |
10 | * Copyright (C) 2001 - 2005 Tensilica Inc. | 10 | * Copyright (C) 2001 - 2008 Tensilica Inc. |
11 | * | 11 | * |
12 | * Chris Zankel <chris@zankel.net> | 12 | * Chris Zankel <chris@zankel.net> |
13 | * Marc Gauthier <marc@tensilica.com, marc@alumni.uwaterloo.ca> | 13 | * Marc Gauthier <marc@tensilica.com, marc@alumni.uwaterloo.ca> |
@@ -134,6 +134,26 @@ SECTIONS | |||
134 | 134 | ||
135 | RELOCATE_ENTRY(_WindowVectors_text, | 135 | RELOCATE_ENTRY(_WindowVectors_text, |
136 | .WindowVectors.text); | 136 | .WindowVectors.text); |
137 | #if XCHAL_EXCM_LEVEL >= 2 | ||
138 | RELOCATE_ENTRY(_Level2InterruptVector_text, | ||
139 | .Level2InterruptVector.text); | ||
140 | #endif | ||
141 | #if XCHAL_EXCM_LEVEL >= 3 | ||
142 | RELOCATE_ENTRY(_Level3InterruptVector_text, | ||
143 | .Level3InterruptVector.text); | ||
144 | #endif | ||
145 | #if XCHAL_EXCM_LEVEL >= 4 | ||
146 | RELOCATE_ENTRY(_Level4InterruptVector_text, | ||
147 | .Level4InterruptVector.text); | ||
148 | #endif | ||
149 | #if XCHAL_EXCM_LEVEL >= 5 | ||
150 | RELOCATE_ENTRY(_Level5InterruptVector_text, | ||
151 | .Level5InterruptVector.text); | ||
152 | #endif | ||
153 | #if XCHAL_EXCM_LEVEL >= 6 | ||
154 | RELOCATE_ENTRY(_Level6InterruptVector_text, | ||
155 | .Level6InterruptVector.text); | ||
156 | #endif | ||
137 | RELOCATE_ENTRY(_KernelExceptionVector_text, | 157 | RELOCATE_ENTRY(_KernelExceptionVector_text, |
138 | .KernelExceptionVector.text); | 158 | .KernelExceptionVector.text); |
139 | RELOCATE_ENTRY(_UserExceptionVector_text, | 159 | RELOCATE_ENTRY(_UserExceptionVector_text, |
@@ -177,11 +197,53 @@ SECTIONS | |||
177 | XCHAL_DEBUG_VECTOR_VADDR, | 197 | XCHAL_DEBUG_VECTOR_VADDR, |
178 | 4, | 198 | 4, |
179 | .DebugInterruptVector.literal) | 199 | .DebugInterruptVector.literal) |
200 | #undef LAST | ||
201 | #define LAST .DebugInterruptVector.text | ||
202 | #if XCHAL_EXCM_LEVEL >= 2 | ||
203 | SECTION_VECTOR (_Level2InterruptVector_text, | ||
204 | .Level2InterruptVector.text, | ||
205 | XCHAL_INTLEVEL2_VECTOR_VADDR, | ||
206 | SIZEOF(LAST), LAST) | ||
207 | # undef LAST | ||
208 | # define LAST .Level2InterruptVector.text | ||
209 | #endif | ||
210 | #if XCHAL_EXCM_LEVEL >= 3 | ||
211 | SECTION_VECTOR (_Level3InterruptVector_text, | ||
212 | .Level3InterruptVector.text, | ||
213 | XCHAL_INTLEVEL3_VECTOR_VADDR, | ||
214 | SIZEOF(LAST), LAST) | ||
215 | # undef LAST | ||
216 | # define LAST .Level3InterruptVector.text | ||
217 | #endif | ||
218 | #if XCHAL_EXCM_LEVEL >= 4 | ||
219 | SECTION_VECTOR (_Level4InterruptVector_text, | ||
220 | .Level4InterruptVector.text, | ||
221 | XCHAL_INTLEVEL4_VECTOR_VADDR, | ||
222 | SIZEOF(LAST), LAST) | ||
223 | # undef LAST | ||
224 | # define LAST .Level4InterruptVector.text | ||
225 | #endif | ||
226 | #if XCHAL_EXCM_LEVEL >= 5 | ||
227 | SECTION_VECTOR (_Level5InterruptVector_text, | ||
228 | .Level5InterruptVector.text, | ||
229 | XCHAL_INTLEVEL5_VECTOR_VADDR, | ||
230 | SIZEOF(LAST), LAST) | ||
231 | # undef LAST | ||
232 | # define LAST .Level5InterruptVector.text | ||
233 | #endif | ||
234 | #if XCHAL_EXCM_LEVEL >= 6 | ||
235 | SECTION_VECTOR (_Level6InterruptVector_text, | ||
236 | .Level6InterruptVector.text, | ||
237 | XCHAL_INTLEVEL6_VECTOR_VADDR, | ||
238 | SIZEOF(LAST), LAST) | ||
239 | # undef LAST | ||
240 | # define LAST .Level6InterruptVector.text | ||
241 | #endif | ||
180 | SECTION_VECTOR (_KernelExceptionVector_literal, | 242 | SECTION_VECTOR (_KernelExceptionVector_literal, |
181 | .KernelExceptionVector.literal, | 243 | .KernelExceptionVector.literal, |
182 | XCHAL_KERNEL_VECTOR_VADDR - 4, | 244 | XCHAL_KERNEL_VECTOR_VADDR - 4, |
183 | SIZEOF(.DebugInterruptVector.text), | 245 | SIZEOF(LAST), LAST) |
184 | .DebugInterruptVector.text) | 246 | #undef LAST |
185 | SECTION_VECTOR (_KernelExceptionVector_text, | 247 | SECTION_VECTOR (_KernelExceptionVector_text, |
186 | .KernelExceptionVector.text, | 248 | .KernelExceptionVector.text, |
187 | XCHAL_KERNEL_VECTOR_VADDR, | 249 | XCHAL_KERNEL_VECTOR_VADDR, |
diff --git a/arch/xtensa/oprofile/Makefile b/arch/xtensa/oprofile/Makefile new file mode 100644 index 000000000000..69ffbe80f184 --- /dev/null +++ b/arch/xtensa/oprofile/Makefile | |||
@@ -0,0 +1,9 @@ | |||
1 | obj-$(CONFIG_OPROFILE) += oprofile.o | ||
2 | |||
3 | DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ | ||
4 | oprof.o cpu_buffer.o buffer_sync.o \ | ||
5 | event_buffer.o oprofile_files.o \ | ||
6 | oprofilefs.o oprofile_stats.o \ | ||
7 | timer_int.o ) | ||
8 | |||
9 | oprofile-y := $(DRIVER_OBJS) init.o backtrace.o | ||
diff --git a/arch/xtensa/oprofile/backtrace.c b/arch/xtensa/oprofile/backtrace.c new file mode 100644 index 000000000000..66f32ee2c982 --- /dev/null +++ b/arch/xtensa/oprofile/backtrace.c | |||
@@ -0,0 +1,171 @@ | |||
1 | /** | ||
2 | * @file backtrace.c | ||
3 | * | ||
4 | * @remark Copyright 2008 Tensilica Inc. | ||
5 | * @remark Read the file COPYING | ||
6 | * | ||
7 | */ | ||
8 | |||
9 | #include <linux/oprofile.h> | ||
10 | #include <linux/sched.h> | ||
11 | #include <linux/mm.h> | ||
12 | #include <asm/ptrace.h> | ||
13 | #include <asm/uaccess.h> | ||
14 | #include <asm/traps.h> | ||
15 | |||
16 | /* Address of common_exception_return, used to check the | ||
17 | * transition from kernel to user space. | ||
18 | */ | ||
19 | extern int common_exception_return; | ||
20 | |||
21 | /* A struct that maps to the part of the frame containing the a0 and | ||
22 | * a1 registers. | ||
23 | */ | ||
24 | struct frame_start { | ||
25 | unsigned long a0; | ||
26 | unsigned long a1; | ||
27 | }; | ||
28 | |||
29 | static void xtensa_backtrace_user(struct pt_regs *regs, unsigned int depth) | ||
30 | { | ||
31 | unsigned long windowstart = regs->windowstart; | ||
32 | unsigned long windowbase = regs->windowbase; | ||
33 | unsigned long a0 = regs->areg[0]; | ||
34 | unsigned long a1 = regs->areg[1]; | ||
35 | unsigned long pc = MAKE_PC_FROM_RA(a0, regs->pc); | ||
36 | int index; | ||
37 | |||
38 | /* First add the current PC to the trace. */ | ||
39 | if (pc != 0 && pc <= TASK_SIZE) | ||
40 | oprofile_add_trace(pc); | ||
41 | else | ||
42 | return; | ||
43 | |||
44 | /* Two steps: | ||
45 | * | ||
46 | * 1. Look through the register window for the | ||
47 | * previous PCs in the call trace. | ||
48 | * | ||
49 | * 2. Look on the stack. | ||
50 | */ | ||
51 | |||
52 | /* Step 1. */ | ||
53 | /* Rotate WINDOWSTART to move the bit corresponding to | ||
54 | * the current window to the bit #0. | ||
55 | */ | ||
56 | windowstart = (windowstart << WSBITS | windowstart) >> windowbase; | ||
57 | |||
58 | /* Look for bits that are set, they correspond to | ||
59 | * valid windows. | ||
60 | */ | ||
61 | for (index = WSBITS - 1; (index > 0) && depth; depth--, index--) | ||
62 | if (windowstart & (1 << index)) { | ||
63 | /* Read a0 and a1 from the | ||
64 | * corresponding position in AREGs. | ||
65 | */ | ||
66 | a0 = regs->areg[index * 4]; | ||
67 | a1 = regs->areg[index * 4 + 1]; | ||
68 | /* Get the PC from a0 and a1. */ | ||
69 | pc = MAKE_PC_FROM_RA(a0, pc); | ||
70 | |||
71 | /* Add the PC to the trace. */ | ||
72 | if (pc != 0 && pc <= TASK_SIZE) | ||
73 | oprofile_add_trace(pc); | ||
74 | else | ||
75 | return; | ||
76 | } | ||
77 | |||
78 | /* Step 2. */ | ||
79 | /* We are done with the register window, we need to | ||
80 | * look through the stack. | ||
81 | */ | ||
82 | if (depth > 0) { | ||
83 | /* Start from the a1 register. */ | ||
84 | /* a1 = regs->areg[1]; */ | ||
85 | while (a0 != 0 && depth--) { | ||
86 | |||
87 | struct frame_start frame_start; | ||
88 | /* Get the location for a1, a0 for the | ||
89 | * previous frame from the current a1. | ||
90 | */ | ||
91 | unsigned long *psp = (unsigned long *)a1; | ||
92 | psp -= 4; | ||
93 | |||
94 | /* Check if the region is OK to access. */ | ||
95 | if (!access_ok(VERIFY_READ, psp, sizeof(frame_start))) | ||
96 | return; | ||
97 | /* Copy a1, a0 from user space stack frame. */ | ||
98 | if (__copy_from_user_inatomic(&frame_start, psp, | ||
99 | sizeof(frame_start))) | ||
100 | return; | ||
101 | |||
102 | a0 = frame_start.a0; | ||
103 | a1 = frame_start.a1; | ||
104 | pc = MAKE_PC_FROM_RA(a0, pc); | ||
105 | |||
106 | if (pc != 0 && pc <= TASK_SIZE) | ||
107 | oprofile_add_trace(pc); | ||
108 | else | ||
109 | return; | ||
110 | } | ||
111 | } | ||
112 | } | ||
113 | |||
114 | static void xtensa_backtrace_kernel(struct pt_regs *regs, unsigned int depth) | ||
115 | { | ||
116 | unsigned long pc = regs->pc; | ||
117 | unsigned long *psp; | ||
118 | unsigned long sp_start, sp_end; | ||
119 | unsigned long a0 = regs->areg[0]; | ||
120 | unsigned long a1 = regs->areg[1]; | ||
121 | |||
122 | sp_start = a1 & ~(THREAD_SIZE-1); | ||
123 | sp_end = sp_start + THREAD_SIZE; | ||
124 | |||
125 | /* Spill the register window to the stack first. */ | ||
126 | spill_registers(); | ||
127 | |||
128 | /* Read the stack frames one by one and create the PC | ||
129 | * from the a0 and a1 registers saved there. | ||
130 | */ | ||
131 | while (a1 > sp_start && a1 < sp_end && depth--) { | ||
132 | pc = MAKE_PC_FROM_RA(a0, pc); | ||
133 | |||
134 | /* Add the PC to the trace. */ | ||
135 | if (kernel_text_address(pc)) | ||
136 | oprofile_add_trace(pc); | ||
137 | |||
138 | if (pc == (unsigned long) &common_exception_return) { | ||
139 | regs = (struct pt_regs *)a1; | ||
140 | if (user_mode(regs)) { | ||
141 | pc = regs->pc; | ||
142 | if (pc != 0 && pc <= TASK_SIZE) | ||
143 | oprofile_add_trace(pc); | ||
144 | else | ||
145 | return; | ||
146 | return xtensa_backtrace_user(regs, depth); | ||
147 | } | ||
148 | a0 = regs->areg[0]; | ||
149 | a1 = regs->areg[1]; | ||
150 | continue; | ||
151 | } | ||
152 | |||
153 | psp = (unsigned long *)a1; | ||
154 | |||
155 | a0 = *(psp - 4); | ||
156 | a1 = *(psp - 3); | ||
157 | |||
158 | if (a1 <= (unsigned long)psp) | ||
159 | return; | ||
160 | |||
161 | } | ||
162 | return; | ||
163 | } | ||
164 | |||
165 | void xtensa_backtrace(struct pt_regs * const regs, unsigned int depth) | ||
166 | { | ||
167 | if (user_mode(regs)) | ||
168 | xtensa_backtrace_user(regs, depth); | ||
169 | else | ||
170 | xtensa_backtrace_kernel(regs, depth); | ||
171 | } | ||
diff --git a/arch/xtensa/oprofile/init.c b/arch/xtensa/oprofile/init.c new file mode 100644 index 000000000000..a67eea379766 --- /dev/null +++ b/arch/xtensa/oprofile/init.c | |||
@@ -0,0 +1,26 @@ | |||
1 | /** | ||
2 | * @file init.c | ||
3 | * | ||
4 | * @remark Copyright 2008 Tensilica Inc. | ||
5 | * @remark Read the file COPYING | ||
6 | * | ||
7 | */ | ||
8 | |||
9 | #include <linux/kernel.h> | ||
10 | #include <linux/oprofile.h> | ||
11 | #include <linux/errno.h> | ||
12 | #include <linux/init.h> | ||
13 | |||
14 | |||
15 | extern void xtensa_backtrace(struct pt_regs *const regs, unsigned int depth); | ||
16 | |||
17 | int __init oprofile_arch_init(struct oprofile_operations *ops) | ||
18 | { | ||
19 | ops->backtrace = xtensa_backtrace; | ||
20 | return -ENODEV; | ||
21 | } | ||
22 | |||
23 | |||
24 | void oprofile_arch_exit(void) | ||
25 | { | ||
26 | } | ||
diff --git a/arch/xtensa/platforms/iss/Makefile b/arch/xtensa/platforms/iss/Makefile index b7d1a5c0ff7f..d2369b799c50 100644 --- a/arch/xtensa/platforms/iss/Makefile +++ b/arch/xtensa/platforms/iss/Makefile | |||
@@ -6,3 +6,4 @@ | |||
6 | 6 | ||
7 | obj-y = console.o setup.o | 7 | obj-y = console.o setup.o |
8 | obj-$(CONFIG_NET) += network.o | 8 | obj-$(CONFIG_NET) += network.o |
9 | obj-$(CONFIG_BLK_DEV_SIMDISK) += simdisk.o | ||
diff --git a/arch/xtensa/platforms/iss/simdisk.c b/arch/xtensa/platforms/iss/simdisk.c new file mode 100644 index 000000000000..f58ffc3b68a8 --- /dev/null +++ b/arch/xtensa/platforms/iss/simdisk.c | |||
@@ -0,0 +1,375 @@ | |||
1 | /* | ||
2 | * arch/xtensa/platforms/iss/simdisk.c | ||
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-2013 Tensilica Inc. | ||
9 | * Authors Victor Prupis | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/moduleparam.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/string.h> | ||
17 | #include <linux/blkdev.h> | ||
18 | #include <linux/bio.h> | ||
19 | #include <linux/proc_fs.h> | ||
20 | #include <asm/uaccess.h> | ||
21 | #include <platform/simcall.h> | ||
22 | |||
23 | #define SIMDISK_MAJOR 240 | ||
24 | #define SECTOR_SHIFT 9 | ||
25 | #define SIMDISK_MINORS 1 | ||
26 | #define MAX_SIMDISK_COUNT 10 | ||
27 | |||
28 | struct simdisk { | ||
29 | const char *filename; | ||
30 | spinlock_t lock; | ||
31 | struct request_queue *queue; | ||
32 | struct gendisk *gd; | ||
33 | struct proc_dir_entry *procfile; | ||
34 | int users; | ||
35 | unsigned long size; | ||
36 | int fd; | ||
37 | }; | ||
38 | |||
39 | |||
40 | static int simdisk_count = CONFIG_BLK_DEV_SIMDISK_COUNT; | ||
41 | module_param(simdisk_count, int, S_IRUGO); | ||
42 | MODULE_PARM_DESC(simdisk_count, "Number of simdisk units."); | ||
43 | |||
44 | static int n_files; | ||
45 | static const char *filename[MAX_SIMDISK_COUNT] = { | ||
46 | #ifdef CONFIG_SIMDISK0_FILENAME | ||
47 | CONFIG_SIMDISK0_FILENAME, | ||
48 | #ifdef CONFIG_SIMDISK1_FILENAME | ||
49 | CONFIG_SIMDISK1_FILENAME, | ||
50 | #endif | ||
51 | #endif | ||
52 | }; | ||
53 | |||
54 | static int simdisk_param_set_filename(const char *val, | ||
55 | const struct kernel_param *kp) | ||
56 | { | ||
57 | if (n_files < ARRAY_SIZE(filename)) | ||
58 | filename[n_files++] = val; | ||
59 | else | ||
60 | return -EINVAL; | ||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | static const struct kernel_param_ops simdisk_param_ops_filename = { | ||
65 | .set = simdisk_param_set_filename, | ||
66 | }; | ||
67 | module_param_cb(filename, &simdisk_param_ops_filename, &n_files, 0); | ||
68 | MODULE_PARM_DESC(filename, "Backing storage filename."); | ||
69 | |||
70 | static int simdisk_major = SIMDISK_MAJOR; | ||
71 | |||
72 | static void simdisk_transfer(struct simdisk *dev, unsigned long sector, | ||
73 | unsigned long nsect, char *buffer, int write) | ||
74 | { | ||
75 | unsigned long offset = sector << SECTOR_SHIFT; | ||
76 | unsigned long nbytes = nsect << SECTOR_SHIFT; | ||
77 | |||
78 | if (offset > dev->size || dev->size - offset < nbytes) { | ||
79 | pr_notice("Beyond-end %s (%ld %ld)\n", | ||
80 | write ? "write" : "read", offset, nbytes); | ||
81 | return; | ||
82 | } | ||
83 | |||
84 | spin_lock(&dev->lock); | ||
85 | while (nbytes > 0) { | ||
86 | unsigned long io; | ||
87 | |||
88 | __simc(SYS_lseek, dev->fd, offset, SEEK_SET, 0, 0); | ||
89 | if (write) | ||
90 | io = simc_write(dev->fd, buffer, nbytes); | ||
91 | else | ||
92 | io = simc_read(dev->fd, buffer, nbytes); | ||
93 | if (io == -1) { | ||
94 | pr_err("SIMDISK: IO error %d\n", errno); | ||
95 | break; | ||
96 | } | ||
97 | buffer += io; | ||
98 | offset += io; | ||
99 | nbytes -= io; | ||
100 | } | ||
101 | spin_unlock(&dev->lock); | ||
102 | } | ||
103 | |||
104 | static int simdisk_xfer_bio(struct simdisk *dev, struct bio *bio) | ||
105 | { | ||
106 | int i; | ||
107 | struct bio_vec *bvec; | ||
108 | sector_t sector = bio->bi_sector; | ||
109 | |||
110 | bio_for_each_segment(bvec, bio, i) { | ||
111 | char *buffer = __bio_kmap_atomic(bio, i, KM_USER0); | ||
112 | unsigned len = bvec->bv_len >> SECTOR_SHIFT; | ||
113 | |||
114 | simdisk_transfer(dev, sector, len, buffer, | ||
115 | bio_data_dir(bio) == WRITE); | ||
116 | sector += len; | ||
117 | __bio_kunmap_atomic(bio, KM_USER0); | ||
118 | } | ||
119 | return 0; | ||
120 | } | ||
121 | |||
122 | static void simdisk_make_request(struct request_queue *q, struct bio *bio) | ||
123 | { | ||
124 | struct simdisk *dev = q->queuedata; | ||
125 | int status = simdisk_xfer_bio(dev, bio); | ||
126 | bio_endio(bio, status); | ||
127 | } | ||
128 | |||
129 | |||
130 | static int simdisk_open(struct block_device *bdev, fmode_t mode) | ||
131 | { | ||
132 | struct simdisk *dev = bdev->bd_disk->private_data; | ||
133 | |||
134 | spin_lock(&dev->lock); | ||
135 | if (!dev->users) | ||
136 | check_disk_change(bdev); | ||
137 | ++dev->users; | ||
138 | spin_unlock(&dev->lock); | ||
139 | return 0; | ||
140 | } | ||
141 | |||
142 | static int simdisk_release(struct gendisk *disk, fmode_t mode) | ||
143 | { | ||
144 | struct simdisk *dev = disk->private_data; | ||
145 | spin_lock(&dev->lock); | ||
146 | --dev->users; | ||
147 | spin_unlock(&dev->lock); | ||
148 | return 0; | ||
149 | } | ||
150 | |||
151 | static const struct block_device_operations simdisk_ops = { | ||
152 | .owner = THIS_MODULE, | ||
153 | .open = simdisk_open, | ||
154 | .release = simdisk_release, | ||
155 | }; | ||
156 | |||
157 | static struct simdisk *sddev; | ||
158 | static struct proc_dir_entry *simdisk_procdir; | ||
159 | |||
160 | static int simdisk_attach(struct simdisk *dev, const char *filename) | ||
161 | { | ||
162 | int err = 0; | ||
163 | |||
164 | filename = kstrdup(filename, GFP_KERNEL); | ||
165 | if (filename == NULL) | ||
166 | return -ENOMEM; | ||
167 | |||
168 | spin_lock(&dev->lock); | ||
169 | |||
170 | if (dev->fd != -1) { | ||
171 | err = -EBUSY; | ||
172 | goto out; | ||
173 | } | ||
174 | dev->fd = simc_open(filename, O_RDWR, 0); | ||
175 | if (dev->fd == -1) { | ||
176 | pr_err("SIMDISK: Can't open %s: %d\n", filename, errno); | ||
177 | err = -ENODEV; | ||
178 | goto out; | ||
179 | } | ||
180 | dev->size = __simc(SYS_lseek, dev->fd, 0, SEEK_END, 0, 0); | ||
181 | set_capacity(dev->gd, dev->size >> SECTOR_SHIFT); | ||
182 | dev->filename = filename; | ||
183 | pr_info("SIMDISK: %s=%s\n", dev->gd->disk_name, dev->filename); | ||
184 | out: | ||
185 | if (err) | ||
186 | kfree(filename); | ||
187 | spin_unlock(&dev->lock); | ||
188 | |||
189 | return err; | ||
190 | } | ||
191 | |||
192 | static int simdisk_detach(struct simdisk *dev) | ||
193 | { | ||
194 | int err = 0; | ||
195 | |||
196 | spin_lock(&dev->lock); | ||
197 | |||
198 | if (dev->users != 0) { | ||
199 | err = -EBUSY; | ||
200 | } else if (dev->fd != -1) { | ||
201 | if (simc_close(dev->fd)) { | ||
202 | pr_err("SIMDISK: error closing %s: %d\n", | ||
203 | dev->filename, errno); | ||
204 | err = -EIO; | ||
205 | } else { | ||
206 | pr_info("SIMDISK: %s detached from %s\n", | ||
207 | dev->gd->disk_name, dev->filename); | ||
208 | dev->fd = -1; | ||
209 | kfree(dev->filename); | ||
210 | dev->filename = NULL; | ||
211 | } | ||
212 | } | ||
213 | spin_unlock(&dev->lock); | ||
214 | return err; | ||
215 | } | ||
216 | |||
217 | static int proc_read_simdisk(char *page, char **start, off_t off, | ||
218 | int count, int *eof, void *data) | ||
219 | { | ||
220 | int len; | ||
221 | struct simdisk *dev = (struct simdisk *) data; | ||
222 | len = sprintf(page, "%s\n", dev->filename ? dev->filename : ""); | ||
223 | return len; | ||
224 | } | ||
225 | |||
226 | static int proc_write_simdisk(struct file *file, const char *buffer, | ||
227 | unsigned long count, void *data) | ||
228 | { | ||
229 | char *tmp = kmalloc(count + 1, GFP_KERNEL); | ||
230 | struct simdisk *dev = (struct simdisk *) data; | ||
231 | int err; | ||
232 | |||
233 | if (tmp == NULL) | ||
234 | return -ENOMEM; | ||
235 | if (copy_from_user(tmp, buffer, count)) { | ||
236 | err = -EFAULT; | ||
237 | goto out_free; | ||
238 | } | ||
239 | |||
240 | err = simdisk_detach(dev); | ||
241 | if (err != 0) | ||
242 | goto out_free; | ||
243 | |||
244 | if (count > 0 && tmp[count - 1] == '\n') | ||
245 | tmp[count - 1] = 0; | ||
246 | else | ||
247 | tmp[count] = 0; | ||
248 | |||
249 | if (tmp[0]) | ||
250 | err = simdisk_attach(dev, tmp); | ||
251 | |||
252 | if (err == 0) | ||
253 | err = count; | ||
254 | out_free: | ||
255 | kfree(tmp); | ||
256 | return err; | ||
257 | } | ||
258 | |||
259 | static int __init simdisk_setup(struct simdisk *dev, int which, | ||
260 | struct proc_dir_entry *procdir) | ||
261 | { | ||
262 | char tmp[2] = { '0' + which, 0 }; | ||
263 | |||
264 | dev->fd = -1; | ||
265 | dev->filename = NULL; | ||
266 | spin_lock_init(&dev->lock); | ||
267 | dev->users = 0; | ||
268 | |||
269 | dev->queue = blk_alloc_queue(GFP_KERNEL); | ||
270 | if (dev->queue == NULL) { | ||
271 | pr_err("blk_alloc_queue failed\n"); | ||
272 | goto out_alloc_queue; | ||
273 | } | ||
274 | |||
275 | blk_queue_make_request(dev->queue, simdisk_make_request); | ||
276 | dev->queue->queuedata = dev; | ||
277 | |||
278 | dev->gd = alloc_disk(SIMDISK_MINORS); | ||
279 | if (dev->gd == NULL) { | ||
280 | pr_err("alloc_disk failed\n"); | ||
281 | goto out_alloc_disk; | ||
282 | } | ||
283 | dev->gd->major = simdisk_major; | ||
284 | dev->gd->first_minor = which; | ||
285 | dev->gd->fops = &simdisk_ops; | ||
286 | dev->gd->queue = dev->queue; | ||
287 | dev->gd->private_data = dev; | ||
288 | snprintf(dev->gd->disk_name, 32, "simdisk%d", which); | ||
289 | set_capacity(dev->gd, 0); | ||
290 | add_disk(dev->gd); | ||
291 | |||
292 | dev->procfile = create_proc_entry(tmp, 0644, procdir); | ||
293 | dev->procfile->data = dev; | ||
294 | dev->procfile->read_proc = proc_read_simdisk; | ||
295 | dev->procfile->write_proc = proc_write_simdisk; | ||
296 | return 0; | ||
297 | |||
298 | out_alloc_disk: | ||
299 | blk_cleanup_queue(dev->queue); | ||
300 | dev->queue = NULL; | ||
301 | out_alloc_queue: | ||
302 | simc_close(dev->fd); | ||
303 | return -EIO; | ||
304 | } | ||
305 | |||
306 | static int __init simdisk_init(void) | ||
307 | { | ||
308 | int i; | ||
309 | |||
310 | if (register_blkdev(simdisk_major, "simdisk") < 0) { | ||
311 | pr_err("SIMDISK: register_blkdev: %d\n", simdisk_major); | ||
312 | return -EIO; | ||
313 | } | ||
314 | pr_info("SIMDISK: major: %d\n", simdisk_major); | ||
315 | |||
316 | if (n_files > simdisk_count) | ||
317 | simdisk_count = n_files; | ||
318 | if (simdisk_count > MAX_SIMDISK_COUNT) | ||
319 | simdisk_count = MAX_SIMDISK_COUNT; | ||
320 | |||
321 | sddev = kmalloc(simdisk_count * sizeof(struct simdisk), | ||
322 | GFP_KERNEL); | ||
323 | if (sddev == NULL) | ||
324 | goto out_unregister; | ||
325 | |||
326 | simdisk_procdir = proc_mkdir("simdisk", 0); | ||
327 | if (simdisk_procdir == NULL) | ||
328 | goto out_free_unregister; | ||
329 | |||
330 | for (i = 0; i < simdisk_count; ++i) { | ||
331 | if (simdisk_setup(sddev + i, i, simdisk_procdir) == 0) { | ||
332 | if (filename[i] != NULL && filename[i][0] != 0 && | ||
333 | (n_files == 0 || i < n_files)) | ||
334 | simdisk_attach(sddev + i, filename[i]); | ||
335 | } | ||
336 | } | ||
337 | |||
338 | return 0; | ||
339 | |||
340 | out_free_unregister: | ||
341 | kfree(sddev); | ||
342 | out_unregister: | ||
343 | unregister_blkdev(simdisk_major, "simdisk"); | ||
344 | return -ENOMEM; | ||
345 | } | ||
346 | module_init(simdisk_init); | ||
347 | |||
348 | static void simdisk_teardown(struct simdisk *dev, int which, | ||
349 | struct proc_dir_entry *procdir) | ||
350 | { | ||
351 | char tmp[2] = { '0' + which, 0 }; | ||
352 | |||
353 | simdisk_detach(dev); | ||
354 | if (dev->gd) | ||
355 | del_gendisk(dev->gd); | ||
356 | if (dev->queue) | ||
357 | blk_cleanup_queue(dev->queue); | ||
358 | remove_proc_entry(tmp, procdir); | ||
359 | } | ||
360 | |||
361 | static void __exit simdisk_exit(void) | ||
362 | { | ||
363 | int i; | ||
364 | |||
365 | for (i = 0; i < simdisk_count; ++i) | ||
366 | simdisk_teardown(sddev + i, i, simdisk_procdir); | ||
367 | remove_proc_entry("simdisk", 0); | ||
368 | kfree(sddev); | ||
369 | unregister_blkdev(simdisk_major, "simdisk"); | ||
370 | } | ||
371 | module_exit(simdisk_exit); | ||
372 | |||
373 | MODULE_ALIAS_BLOCKDEV_MAJOR(SIMDISK_MAJOR); | ||
374 | |||
375 | MODULE_LICENSE("GPL"); | ||
diff --git a/arch/xtensa/platforms/xtfpga/setup.c b/arch/xtensa/platforms/xtfpga/setup.c index 4b9951a4569d..9d888a2a5755 100644 --- a/arch/xtensa/platforms/xtfpga/setup.c +++ b/arch/xtensa/platforms/xtfpga/setup.c | |||
@@ -100,7 +100,7 @@ static void __init update_clock_frequency(struct device_node *node) | |||
100 | } | 100 | } |
101 | 101 | ||
102 | *(u32 *)newfreq->value = cpu_to_be32(*(u32 *)XTFPGA_CLKFRQ_VADDR); | 102 | *(u32 *)newfreq->value = cpu_to_be32(*(u32 *)XTFPGA_CLKFRQ_VADDR); |
103 | prom_update_property(node, newfreq); | 103 | of_update_property(node, newfreq); |
104 | } | 104 | } |
105 | 105 | ||
106 | #define MAC_LEN 6 | 106 | #define MAC_LEN 6 |
@@ -128,7 +128,7 @@ static void __init update_local_mac(struct device_node *node) | |||
128 | 128 | ||
129 | memcpy(newmac->value, macaddr, MAC_LEN); | 129 | memcpy(newmac->value, macaddr, MAC_LEN); |
130 | ((u8*)newmac->value)[5] = (*(u32*)DIP_SWITCHES_VADDR) & 0x3f; | 130 | ((u8*)newmac->value)[5] = (*(u32*)DIP_SWITCHES_VADDR) & 0x3f; |
131 | prom_update_property(node, newmac); | 131 | of_update_property(node, newmac); |
132 | } | 132 | } |
133 | 133 | ||
134 | static int __init machine_setup(void) | 134 | static int __init machine_setup(void) |
diff --git a/arch/xtensa/variants/dc233c/include/variant/core.h b/arch/xtensa/variants/dc233c/include/variant/core.h new file mode 100644 index 000000000000..3a2e53b94930 --- /dev/null +++ b/arch/xtensa/variants/dc233c/include/variant/core.h | |||
@@ -0,0 +1,475 @@ | |||
1 | /* | ||
2 | * xtensa/config/core-isa.h -- HAL definitions that are dependent on Xtensa | ||
3 | * processor CORE configuration | ||
4 | * | ||
5 | * See <xtensa/config/core.h>, which includes this file, for more details. | ||
6 | */ | ||
7 | |||
8 | /* Xtensa processor core configuration information. | ||
9 | |||
10 | Copyright (c) 1999-2010 Tensilica Inc. | ||
11 | |||
12 | Permission is hereby granted, free of charge, to any person obtaining | ||
13 | a copy of this software and associated documentation files (the | ||
14 | "Software"), to deal in the Software without restriction, including | ||
15 | without limitation the rights to use, copy, modify, merge, publish, | ||
16 | distribute, sublicense, and/or sell copies of the Software, and to | ||
17 | permit persons to whom the Software is furnished to do so, subject to | ||
18 | the following conditions: | ||
19 | |||
20 | The above copyright notice and this permission notice shall be included | ||
21 | in all copies or substantial portions of the Software. | ||
22 | |||
23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||
26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY | ||
27 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | ||
28 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||
29 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ | ||
30 | |||
31 | #ifndef _XTENSA_CORE_CONFIGURATION_H | ||
32 | #define _XTENSA_CORE_CONFIGURATION_H | ||
33 | |||
34 | |||
35 | /**************************************************************************** | ||
36 | Parameters Useful for Any Code, USER or PRIVILEGED | ||
37 | ****************************************************************************/ | ||
38 | |||
39 | /* | ||
40 | * Note: Macros of the form XCHAL_HAVE_*** have a value of 1 if the option is | ||
41 | * configured, and a value of 0 otherwise. These macros are always defined. | ||
42 | */ | ||
43 | |||
44 | |||
45 | /*---------------------------------------------------------------------- | ||
46 | ISA | ||
47 | ----------------------------------------------------------------------*/ | ||
48 | |||
49 | #define XCHAL_HAVE_BE 0 /* big-endian byte ordering */ | ||
50 | #define XCHAL_HAVE_WINDOWED 1 /* windowed registers option */ | ||
51 | #define XCHAL_NUM_AREGS 32 /* num of physical addr regs */ | ||
52 | #define XCHAL_NUM_AREGS_LOG2 5 /* log2(XCHAL_NUM_AREGS) */ | ||
53 | #define XCHAL_MAX_INSTRUCTION_SIZE 3 /* max instr bytes (3..8) */ | ||
54 | #define XCHAL_HAVE_DEBUG 1 /* debug option */ | ||
55 | #define XCHAL_HAVE_DENSITY 1 /* 16-bit instructions */ | ||
56 | #define XCHAL_HAVE_LOOPS 1 /* zero-overhead loops */ | ||
57 | #define XCHAL_HAVE_NSA 1 /* NSA/NSAU instructions */ | ||
58 | #define XCHAL_HAVE_MINMAX 1 /* MIN/MAX instructions */ | ||
59 | #define XCHAL_HAVE_SEXT 1 /* SEXT instruction */ | ||
60 | #define XCHAL_HAVE_CLAMPS 1 /* CLAMPS instruction */ | ||
61 | #define XCHAL_HAVE_MUL16 1 /* MUL16S/MUL16U instructions */ | ||
62 | #define XCHAL_HAVE_MUL32 1 /* MULL instruction */ | ||
63 | #define XCHAL_HAVE_MUL32_HIGH 0 /* MULUH/MULSH instructions */ | ||
64 | #define XCHAL_HAVE_DIV32 1 /* QUOS/QUOU/REMS/REMU instructions */ | ||
65 | #define XCHAL_HAVE_L32R 1 /* L32R instruction */ | ||
66 | #define XCHAL_HAVE_ABSOLUTE_LITERALS 1 /* non-PC-rel (extended) L32R */ | ||
67 | #define XCHAL_HAVE_CONST16 0 /* CONST16 instruction */ | ||
68 | #define XCHAL_HAVE_ADDX 1 /* ADDX#/SUBX# instructions */ | ||
69 | #define XCHAL_HAVE_WIDE_BRANCHES 0 /* B*.W18 or B*.W15 instr's */ | ||
70 | #define XCHAL_HAVE_PREDICTED_BRANCHES 0 /* B[EQ/EQZ/NE/NEZ]T instr's */ | ||
71 | #define XCHAL_HAVE_CALL4AND12 1 /* (obsolete option) */ | ||
72 | #define XCHAL_HAVE_ABS 1 /* ABS instruction */ | ||
73 | /*#define XCHAL_HAVE_POPC 0*/ /* POPC instruction */ | ||
74 | /*#define XCHAL_HAVE_CRC 0*/ /* CRC instruction */ | ||
75 | #define XCHAL_HAVE_RELEASE_SYNC 1 /* L32AI/S32RI instructions */ | ||
76 | #define XCHAL_HAVE_S32C1I 1 /* S32C1I instruction */ | ||
77 | #define XCHAL_HAVE_SPECULATION 0 /* speculation */ | ||
78 | #define XCHAL_HAVE_FULL_RESET 1 /* all regs/state reset */ | ||
79 | #define XCHAL_NUM_CONTEXTS 1 /* */ | ||
80 | #define XCHAL_NUM_MISC_REGS 2 /* num of scratch regs (0..4) */ | ||
81 | #define XCHAL_HAVE_TAP_MASTER 0 /* JTAG TAP control instr's */ | ||
82 | #define XCHAL_HAVE_PRID 1 /* processor ID register */ | ||
83 | #define XCHAL_HAVE_EXTERN_REGS 1 /* WER/RER instructions */ | ||
84 | #define XCHAL_HAVE_MP_INTERRUPTS 0 /* interrupt distributor port */ | ||
85 | #define XCHAL_HAVE_MP_RUNSTALL 0 /* core RunStall control port */ | ||
86 | #define XCHAL_HAVE_THREADPTR 1 /* THREADPTR register */ | ||
87 | #define XCHAL_HAVE_BOOLEANS 0 /* boolean registers */ | ||
88 | #define XCHAL_HAVE_CP 1 /* CPENABLE reg (coprocessor) */ | ||
89 | #define XCHAL_CP_MAXCFG 8 /* max allowed cp id plus one */ | ||
90 | #define XCHAL_HAVE_MAC16 1 /* MAC16 package */ | ||
91 | #define XCHAL_HAVE_VECTORFPU2005 0 /* vector floating-point pkg */ | ||
92 | #define XCHAL_HAVE_FP 0 /* floating point pkg */ | ||
93 | #define XCHAL_HAVE_DFP 0 /* double precision FP pkg */ | ||
94 | #define XCHAL_HAVE_DFP_accel 0 /* double precision FP acceleration pkg */ | ||
95 | #define XCHAL_HAVE_VECTRA1 0 /* Vectra I pkg */ | ||
96 | #define XCHAL_HAVE_VECTRALX 0 /* Vectra LX pkg */ | ||
97 | #define XCHAL_HAVE_HIFIPRO 0 /* HiFiPro Audio Engine pkg */ | ||
98 | #define XCHAL_HAVE_HIFI2 0 /* HiFi2 Audio Engine pkg */ | ||
99 | #define XCHAL_HAVE_HIFI2EP 0 /* HiFi2EP */ | ||
100 | #define XCHAL_HAVE_CONNXD2 0 /* ConnX D2 pkg */ | ||
101 | #define XCHAL_HAVE_BBE16 0 /* ConnX BBE16 pkg */ | ||
102 | #define XCHAL_HAVE_BBE16_RSQRT 0 /* BBE16 & vector recip sqrt */ | ||
103 | #define XCHAL_HAVE_BBE16_VECDIV 0 /* BBE16 & vector divide */ | ||
104 | #define XCHAL_HAVE_BBE16_DESPREAD 0 /* BBE16 & despread */ | ||
105 | #define XCHAL_HAVE_BSP3 0 /* ConnX BSP3 pkg */ | ||
106 | #define XCHAL_HAVE_SSP16 0 /* ConnX SSP16 pkg */ | ||
107 | #define XCHAL_HAVE_SSP16_VITERBI 0 /* SSP16 & viterbi */ | ||
108 | #define XCHAL_HAVE_TURBO16 0 /* ConnX Turbo16 pkg */ | ||
109 | #define XCHAL_HAVE_BBP16 0 /* ConnX BBP16 pkg */ | ||
110 | |||
111 | |||
112 | /*---------------------------------------------------------------------- | ||
113 | MISC | ||
114 | ----------------------------------------------------------------------*/ | ||
115 | |||
116 | #define XCHAL_NUM_WRITEBUFFER_ENTRIES 8 /* size of write buffer */ | ||
117 | #define XCHAL_INST_FETCH_WIDTH 4 /* instr-fetch width in bytes */ | ||
118 | #define XCHAL_DATA_WIDTH 4 /* data width in bytes */ | ||
119 | /* In T1050, applies to selected core load and store instructions (see ISA): */ | ||
120 | #define XCHAL_UNALIGNED_LOAD_EXCEPTION 1 /* unaligned loads cause exc. */ | ||
121 | #define XCHAL_UNALIGNED_STORE_EXCEPTION 1 /* unaligned stores cause exc.*/ | ||
122 | #define XCHAL_UNALIGNED_LOAD_HW 0 /* unaligned loads work in hw */ | ||
123 | #define XCHAL_UNALIGNED_STORE_HW 0 /* unaligned stores work in hw*/ | ||
124 | |||
125 | #define XCHAL_SW_VERSION 900001 /* sw version of this header */ | ||
126 | |||
127 | #define XCHAL_CORE_ID "dc233c" /* alphanum core name | ||
128 | (CoreID) set in the Xtensa | ||
129 | Processor Generator */ | ||
130 | |||
131 | #define XCHAL_CORE_DESCRIPTION "dc233c" | ||
132 | #define XCHAL_BUILD_UNIQUE_ID 0x00004B21 /* 22-bit sw build ID */ | ||
133 | |||
134 | /* | ||
135 | * These definitions describe the hardware targeted by this software. | ||
136 | */ | ||
137 | #define XCHAL_HW_CONFIGID0 0xC56707FE /* ConfigID hi 32 bits*/ | ||
138 | #define XCHAL_HW_CONFIGID1 0x14404B21 /* ConfigID lo 32 bits*/ | ||
139 | #define XCHAL_HW_VERSION_NAME "LX4.0.1" /* full version name */ | ||
140 | #define XCHAL_HW_VERSION_MAJOR 2400 /* major ver# of targeted hw */ | ||
141 | #define XCHAL_HW_VERSION_MINOR 1 /* minor ver# of targeted hw */ | ||
142 | #define XCHAL_HW_VERSION 240001 /* major*100+minor */ | ||
143 | #define XCHAL_HW_REL_LX4 1 | ||
144 | #define XCHAL_HW_REL_LX4_0 1 | ||
145 | #define XCHAL_HW_REL_LX4_0_1 1 | ||
146 | #define XCHAL_HW_CONFIGID_RELIABLE 1 | ||
147 | /* If software targets a *range* of hardware versions, these are the bounds: */ | ||
148 | #define XCHAL_HW_MIN_VERSION_MAJOR 2400 /* major v of earliest tgt hw */ | ||
149 | #define XCHAL_HW_MIN_VERSION_MINOR 1 /* minor v of earliest tgt hw */ | ||
150 | #define XCHAL_HW_MIN_VERSION 240001 /* earliest targeted hw */ | ||
151 | #define XCHAL_HW_MAX_VERSION_MAJOR 2400 /* major v of latest tgt hw */ | ||
152 | #define XCHAL_HW_MAX_VERSION_MINOR 1 /* minor v of latest tgt hw */ | ||
153 | #define XCHAL_HW_MAX_VERSION 240001 /* latest targeted hw */ | ||
154 | |||
155 | |||
156 | /*---------------------------------------------------------------------- | ||
157 | CACHE | ||
158 | ----------------------------------------------------------------------*/ | ||
159 | |||
160 | #define XCHAL_ICACHE_LINESIZE 32 /* I-cache line size in bytes */ | ||
161 | #define XCHAL_DCACHE_LINESIZE 32 /* D-cache line size in bytes */ | ||
162 | #define XCHAL_ICACHE_LINEWIDTH 5 /* log2(I line size in bytes) */ | ||
163 | #define XCHAL_DCACHE_LINEWIDTH 5 /* log2(D line size in bytes) */ | ||
164 | |||
165 | #define XCHAL_ICACHE_SIZE 16384 /* I-cache size in bytes or 0 */ | ||
166 | #define XCHAL_DCACHE_SIZE 16384 /* D-cache size in bytes or 0 */ | ||
167 | |||
168 | #define XCHAL_DCACHE_IS_WRITEBACK 1 /* writeback feature */ | ||
169 | #define XCHAL_DCACHE_IS_COHERENT 0 /* MP coherence feature */ | ||
170 | |||
171 | #define XCHAL_HAVE_PREFETCH 0 /* PREFCTL register */ | ||
172 | |||
173 | |||
174 | |||
175 | |||
176 | /**************************************************************************** | ||
177 | Parameters Useful for PRIVILEGED (Supervisory or Non-Virtualized) Code | ||
178 | ****************************************************************************/ | ||
179 | |||
180 | |||
181 | #ifndef XTENSA_HAL_NON_PRIVILEGED_ONLY | ||
182 | |||
183 | /*---------------------------------------------------------------------- | ||
184 | CACHE | ||
185 | ----------------------------------------------------------------------*/ | ||
186 | |||
187 | #define XCHAL_HAVE_PIF 1 /* any outbound PIF present */ | ||
188 | |||
189 | /* If present, cache size in bytes == (ways * 2^(linewidth + setwidth)). */ | ||
190 | |||
191 | /* Number of cache sets in log2(lines per way): */ | ||
192 | #define XCHAL_ICACHE_SETWIDTH 7 | ||
193 | #define XCHAL_DCACHE_SETWIDTH 7 | ||
194 | |||
195 | /* Cache set associativity (number of ways): */ | ||
196 | #define XCHAL_ICACHE_WAYS 4 | ||
197 | #define XCHAL_DCACHE_WAYS 4 | ||
198 | |||
199 | /* Cache features: */ | ||
200 | #define XCHAL_ICACHE_LINE_LOCKABLE 1 | ||
201 | #define XCHAL_DCACHE_LINE_LOCKABLE 1 | ||
202 | #define XCHAL_ICACHE_ECC_PARITY 0 | ||
203 | #define XCHAL_DCACHE_ECC_PARITY 0 | ||
204 | |||
205 | /* Cache access size in bytes (affects operation of SICW instruction): */ | ||
206 | #define XCHAL_ICACHE_ACCESS_SIZE 4 | ||
207 | #define XCHAL_DCACHE_ACCESS_SIZE 4 | ||
208 | |||
209 | /* Number of encoded cache attr bits (see <xtensa/hal.h> for decoded bits): */ | ||
210 | #define XCHAL_CA_BITS 4 | ||
211 | |||
212 | |||
213 | /*---------------------------------------------------------------------- | ||
214 | INTERNAL I/D RAM/ROMs and XLMI | ||
215 | ----------------------------------------------------------------------*/ | ||
216 | |||
217 | #define XCHAL_NUM_INSTROM 0 /* number of core instr. ROMs */ | ||
218 | #define XCHAL_NUM_INSTRAM 0 /* number of core instr. RAMs */ | ||
219 | #define XCHAL_NUM_DATAROM 0 /* number of core data ROMs */ | ||
220 | #define XCHAL_NUM_DATARAM 0 /* number of core data RAMs */ | ||
221 | #define XCHAL_NUM_URAM 0 /* number of core unified RAMs*/ | ||
222 | #define XCHAL_NUM_XLMI 0 /* number of core XLMI ports */ | ||
223 | |||
224 | #define XCHAL_HAVE_IMEM_LOADSTORE 1 /* can load/store to IROM/IRAM*/ | ||
225 | |||
226 | |||
227 | /*---------------------------------------------------------------------- | ||
228 | INTERRUPTS and TIMERS | ||
229 | ----------------------------------------------------------------------*/ | ||
230 | |||
231 | #define XCHAL_HAVE_INTERRUPTS 1 /* interrupt option */ | ||
232 | #define XCHAL_HAVE_HIGHPRI_INTERRUPTS 1 /* med/high-pri. interrupts */ | ||
233 | #define XCHAL_HAVE_NMI 1 /* non-maskable interrupt */ | ||
234 | #define XCHAL_HAVE_CCOUNT 1 /* CCOUNT reg. (timer option) */ | ||
235 | #define XCHAL_NUM_TIMERS 3 /* number of CCOMPAREn regs */ | ||
236 | #define XCHAL_NUM_INTERRUPTS 22 /* number of interrupts */ | ||
237 | #define XCHAL_NUM_INTERRUPTS_LOG2 5 /* ceil(log2(NUM_INTERRUPTS)) */ | ||
238 | #define XCHAL_NUM_EXTINTERRUPTS 17 /* num of external interrupts */ | ||
239 | #define XCHAL_NUM_INTLEVELS 6 /* number of interrupt levels | ||
240 | (not including level zero) */ | ||
241 | #define XCHAL_EXCM_LEVEL 3 /* level masked by PS.EXCM */ | ||
242 | /* (always 1 in XEA1; levels 2 .. EXCM_LEVEL are "medium priority") */ | ||
243 | |||
244 | /* Masks of interrupts at each interrupt level: */ | ||
245 | #define XCHAL_INTLEVEL1_MASK 0x001F80FF | ||
246 | #define XCHAL_INTLEVEL2_MASK 0x00000100 | ||
247 | #define XCHAL_INTLEVEL3_MASK 0x00200E00 | ||
248 | #define XCHAL_INTLEVEL4_MASK 0x00001000 | ||
249 | #define XCHAL_INTLEVEL5_MASK 0x00002000 | ||
250 | #define XCHAL_INTLEVEL6_MASK 0x00000000 | ||
251 | #define XCHAL_INTLEVEL7_MASK 0x00004000 | ||
252 | |||
253 | /* Masks of interrupts at each range 1..n of interrupt levels: */ | ||
254 | #define XCHAL_INTLEVEL1_ANDBELOW_MASK 0x001F80FF | ||
255 | #define XCHAL_INTLEVEL2_ANDBELOW_MASK 0x001F81FF | ||
256 | #define XCHAL_INTLEVEL3_ANDBELOW_MASK 0x003F8FFF | ||
257 | #define XCHAL_INTLEVEL4_ANDBELOW_MASK 0x003F9FFF | ||
258 | #define XCHAL_INTLEVEL5_ANDBELOW_MASK 0x003FBFFF | ||
259 | #define XCHAL_INTLEVEL6_ANDBELOW_MASK 0x003FBFFF | ||
260 | #define XCHAL_INTLEVEL7_ANDBELOW_MASK 0x003FFFFF | ||
261 | |||
262 | /* Level of each interrupt: */ | ||
263 | #define XCHAL_INT0_LEVEL 1 | ||
264 | #define XCHAL_INT1_LEVEL 1 | ||
265 | #define XCHAL_INT2_LEVEL 1 | ||
266 | #define XCHAL_INT3_LEVEL 1 | ||
267 | #define XCHAL_INT4_LEVEL 1 | ||
268 | #define XCHAL_INT5_LEVEL 1 | ||
269 | #define XCHAL_INT6_LEVEL 1 | ||
270 | #define XCHAL_INT7_LEVEL 1 | ||
271 | #define XCHAL_INT8_LEVEL 2 | ||
272 | #define XCHAL_INT9_LEVEL 3 | ||
273 | #define XCHAL_INT10_LEVEL 3 | ||
274 | #define XCHAL_INT11_LEVEL 3 | ||
275 | #define XCHAL_INT12_LEVEL 4 | ||
276 | #define XCHAL_INT13_LEVEL 5 | ||
277 | #define XCHAL_INT14_LEVEL 7 | ||
278 | #define XCHAL_INT15_LEVEL 1 | ||
279 | #define XCHAL_INT16_LEVEL 1 | ||
280 | #define XCHAL_INT17_LEVEL 1 | ||
281 | #define XCHAL_INT18_LEVEL 1 | ||
282 | #define XCHAL_INT19_LEVEL 1 | ||
283 | #define XCHAL_INT20_LEVEL 1 | ||
284 | #define XCHAL_INT21_LEVEL 3 | ||
285 | #define XCHAL_DEBUGLEVEL 6 /* debug interrupt level */ | ||
286 | #define XCHAL_HAVE_DEBUG_EXTERN_INT 1 /* OCD external db interrupt */ | ||
287 | #define XCHAL_NMILEVEL 7 /* NMI "level" (for use with | ||
288 | EXCSAVE/EPS/EPC_n, RFI n) */ | ||
289 | |||
290 | /* Type of each interrupt: */ | ||
291 | #define XCHAL_INT0_TYPE XTHAL_INTTYPE_EXTERN_LEVEL | ||
292 | #define XCHAL_INT1_TYPE XTHAL_INTTYPE_EXTERN_LEVEL | ||
293 | #define XCHAL_INT2_TYPE XTHAL_INTTYPE_EXTERN_LEVEL | ||
294 | #define XCHAL_INT3_TYPE XTHAL_INTTYPE_EXTERN_LEVEL | ||
295 | #define XCHAL_INT4_TYPE XTHAL_INTTYPE_EXTERN_LEVEL | ||
296 | #define XCHAL_INT5_TYPE XTHAL_INTTYPE_EXTERN_LEVEL | ||
297 | #define XCHAL_INT6_TYPE XTHAL_INTTYPE_TIMER | ||
298 | #define XCHAL_INT7_TYPE XTHAL_INTTYPE_SOFTWARE | ||
299 | #define XCHAL_INT8_TYPE XTHAL_INTTYPE_EXTERN_LEVEL | ||
300 | #define XCHAL_INT9_TYPE XTHAL_INTTYPE_EXTERN_LEVEL | ||
301 | #define XCHAL_INT10_TYPE XTHAL_INTTYPE_TIMER | ||
302 | #define XCHAL_INT11_TYPE XTHAL_INTTYPE_SOFTWARE | ||
303 | #define XCHAL_INT12_TYPE XTHAL_INTTYPE_EXTERN_LEVEL | ||
304 | #define XCHAL_INT13_TYPE XTHAL_INTTYPE_TIMER | ||
305 | #define XCHAL_INT14_TYPE XTHAL_INTTYPE_NMI | ||
306 | #define XCHAL_INT15_TYPE XTHAL_INTTYPE_EXTERN_EDGE | ||
307 | #define XCHAL_INT16_TYPE XTHAL_INTTYPE_EXTERN_EDGE | ||
308 | #define XCHAL_INT17_TYPE XTHAL_INTTYPE_EXTERN_EDGE | ||
309 | #define XCHAL_INT18_TYPE XTHAL_INTTYPE_EXTERN_EDGE | ||
310 | #define XCHAL_INT19_TYPE XTHAL_INTTYPE_EXTERN_EDGE | ||
311 | #define XCHAL_INT20_TYPE XTHAL_INTTYPE_EXTERN_EDGE | ||
312 | #define XCHAL_INT21_TYPE XTHAL_INTTYPE_EXTERN_EDGE | ||
313 | |||
314 | /* Masks of interrupts for each type of interrupt: */ | ||
315 | #define XCHAL_INTTYPE_MASK_UNCONFIGURED 0xFFC00000 | ||
316 | #define XCHAL_INTTYPE_MASK_SOFTWARE 0x00000880 | ||
317 | #define XCHAL_INTTYPE_MASK_EXTERN_EDGE 0x003F8000 | ||
318 | #define XCHAL_INTTYPE_MASK_EXTERN_LEVEL 0x0000133F | ||
319 | #define XCHAL_INTTYPE_MASK_TIMER 0x00002440 | ||
320 | #define XCHAL_INTTYPE_MASK_NMI 0x00004000 | ||
321 | #define XCHAL_INTTYPE_MASK_WRITE_ERROR 0x00000000 | ||
322 | |||
323 | /* Interrupt numbers assigned to specific interrupt sources: */ | ||
324 | #define XCHAL_TIMER0_INTERRUPT 6 /* CCOMPARE0 */ | ||
325 | #define XCHAL_TIMER1_INTERRUPT 10 /* CCOMPARE1 */ | ||
326 | #define XCHAL_TIMER2_INTERRUPT 13 /* CCOMPARE2 */ | ||
327 | #define XCHAL_TIMER3_INTERRUPT XTHAL_TIMER_UNCONFIGURED | ||
328 | #define XCHAL_NMI_INTERRUPT 14 /* non-maskable interrupt */ | ||
329 | |||
330 | /* Interrupt numbers for levels at which only one interrupt is configured: */ | ||
331 | #define XCHAL_INTLEVEL2_NUM 8 | ||
332 | #define XCHAL_INTLEVEL4_NUM 12 | ||
333 | #define XCHAL_INTLEVEL5_NUM 13 | ||
334 | #define XCHAL_INTLEVEL7_NUM 14 | ||
335 | /* (There are many interrupts each at level(s) 1, 3.) */ | ||
336 | |||
337 | |||
338 | /* | ||
339 | * External interrupt vectors/levels. | ||
340 | * These macros describe how Xtensa processor interrupt numbers | ||
341 | * (as numbered internally, eg. in INTERRUPT and INTENABLE registers) | ||
342 | * map to external BInterrupt<n> pins, for those interrupts | ||
343 | * configured as external (level-triggered, edge-triggered, or NMI). | ||
344 | * See the Xtensa processor databook for more details. | ||
345 | */ | ||
346 | |||
347 | /* Core interrupt numbers mapped to each EXTERNAL interrupt number: */ | ||
348 | #define XCHAL_EXTINT0_NUM 0 /* (intlevel 1) */ | ||
349 | #define XCHAL_EXTINT1_NUM 1 /* (intlevel 1) */ | ||
350 | #define XCHAL_EXTINT2_NUM 2 /* (intlevel 1) */ | ||
351 | #define XCHAL_EXTINT3_NUM 3 /* (intlevel 1) */ | ||
352 | #define XCHAL_EXTINT4_NUM 4 /* (intlevel 1) */ | ||
353 | #define XCHAL_EXTINT5_NUM 5 /* (intlevel 1) */ | ||
354 | #define XCHAL_EXTINT6_NUM 8 /* (intlevel 2) */ | ||
355 | #define XCHAL_EXTINT7_NUM 9 /* (intlevel 3) */ | ||
356 | #define XCHAL_EXTINT8_NUM 12 /* (intlevel 4) */ | ||
357 | #define XCHAL_EXTINT9_NUM 14 /* (intlevel 7) */ | ||
358 | #define XCHAL_EXTINT10_NUM 15 /* (intlevel 1) */ | ||
359 | #define XCHAL_EXTINT11_NUM 16 /* (intlevel 1) */ | ||
360 | #define XCHAL_EXTINT12_NUM 17 /* (intlevel 1) */ | ||
361 | #define XCHAL_EXTINT13_NUM 18 /* (intlevel 1) */ | ||
362 | #define XCHAL_EXTINT14_NUM 19 /* (intlevel 1) */ | ||
363 | #define XCHAL_EXTINT15_NUM 20 /* (intlevel 1) */ | ||
364 | #define XCHAL_EXTINT16_NUM 21 /* (intlevel 3) */ | ||
365 | |||
366 | |||
367 | /*---------------------------------------------------------------------- | ||
368 | EXCEPTIONS and VECTORS | ||
369 | ----------------------------------------------------------------------*/ | ||
370 | |||
371 | #define XCHAL_XEA_VERSION 2 /* Xtensa Exception Architecture | ||
372 | number: 1 == XEA1 (old) | ||
373 | 2 == XEA2 (new) | ||
374 | 0 == XEAX (extern) or TX */ | ||
375 | #define XCHAL_HAVE_XEA1 0 /* Exception Architecture 1 */ | ||
376 | #define XCHAL_HAVE_XEA2 1 /* Exception Architecture 2 */ | ||
377 | #define XCHAL_HAVE_XEAX 0 /* External Exception Arch. */ | ||
378 | #define XCHAL_HAVE_EXCEPTIONS 1 /* exception option */ | ||
379 | #define XCHAL_HAVE_HALT 0 /* halt architecture option */ | ||
380 | #define XCHAL_HAVE_BOOTLOADER 0 /* boot loader (for TX) */ | ||
381 | #define XCHAL_HAVE_MEM_ECC_PARITY 0 /* local memory ECC/parity */ | ||
382 | #define XCHAL_HAVE_VECTOR_SELECT 1 /* relocatable vectors */ | ||
383 | #define XCHAL_HAVE_VECBASE 1 /* relocatable vectors */ | ||
384 | #define XCHAL_VECBASE_RESET_VADDR 0x00002000 /* VECBASE reset value */ | ||
385 | #define XCHAL_VECBASE_RESET_PADDR 0x00002000 | ||
386 | #define XCHAL_RESET_VECBASE_OVERLAP 0 | ||
387 | |||
388 | #define XCHAL_RESET_VECTOR0_VADDR 0xFE000000 | ||
389 | #define XCHAL_RESET_VECTOR0_PADDR 0xFE000000 | ||
390 | #define XCHAL_RESET_VECTOR1_VADDR 0x00001000 | ||
391 | #define XCHAL_RESET_VECTOR1_PADDR 0x00001000 | ||
392 | #define XCHAL_RESET_VECTOR_VADDR 0xFE000000 | ||
393 | #define XCHAL_RESET_VECTOR_PADDR 0xFE000000 | ||
394 | #define XCHAL_USER_VECOFS 0x00000340 | ||
395 | #define XCHAL_USER_VECTOR_VADDR 0x00002340 | ||
396 | #define XCHAL_USER_VECTOR_PADDR 0x00002340 | ||
397 | #define XCHAL_KERNEL_VECOFS 0x00000300 | ||
398 | #define XCHAL_KERNEL_VECTOR_VADDR 0x00002300 | ||
399 | #define XCHAL_KERNEL_VECTOR_PADDR 0x00002300 | ||
400 | #define XCHAL_DOUBLEEXC_VECOFS 0x000003C0 | ||
401 | #define XCHAL_DOUBLEEXC_VECTOR_VADDR 0x000023C0 | ||
402 | #define XCHAL_DOUBLEEXC_VECTOR_PADDR 0x000023C0 | ||
403 | #define XCHAL_WINDOW_OF4_VECOFS 0x00000000 | ||
404 | #define XCHAL_WINDOW_UF4_VECOFS 0x00000040 | ||
405 | #define XCHAL_WINDOW_OF8_VECOFS 0x00000080 | ||
406 | #define XCHAL_WINDOW_UF8_VECOFS 0x000000C0 | ||
407 | #define XCHAL_WINDOW_OF12_VECOFS 0x00000100 | ||
408 | #define XCHAL_WINDOW_UF12_VECOFS 0x00000140 | ||
409 | #define XCHAL_WINDOW_VECTORS_VADDR 0x00002000 | ||
410 | #define XCHAL_WINDOW_VECTORS_PADDR 0x00002000 | ||
411 | #define XCHAL_INTLEVEL2_VECOFS 0x00000180 | ||
412 | #define XCHAL_INTLEVEL2_VECTOR_VADDR 0x00002180 | ||
413 | #define XCHAL_INTLEVEL2_VECTOR_PADDR 0x00002180 | ||
414 | #define XCHAL_INTLEVEL3_VECOFS 0x000001C0 | ||
415 | #define XCHAL_INTLEVEL3_VECTOR_VADDR 0x000021C0 | ||
416 | #define XCHAL_INTLEVEL3_VECTOR_PADDR 0x000021C0 | ||
417 | #define XCHAL_INTLEVEL4_VECOFS 0x00000200 | ||
418 | #define XCHAL_INTLEVEL4_VECTOR_VADDR 0x00002200 | ||
419 | #define XCHAL_INTLEVEL4_VECTOR_PADDR 0x00002200 | ||
420 | #define XCHAL_INTLEVEL5_VECOFS 0x00000240 | ||
421 | #define XCHAL_INTLEVEL5_VECTOR_VADDR 0x00002240 | ||
422 | #define XCHAL_INTLEVEL5_VECTOR_PADDR 0x00002240 | ||
423 | #define XCHAL_INTLEVEL6_VECOFS 0x00000280 | ||
424 | #define XCHAL_INTLEVEL6_VECTOR_VADDR 0x00002280 | ||
425 | #define XCHAL_INTLEVEL6_VECTOR_PADDR 0x00002280 | ||
426 | #define XCHAL_DEBUG_VECOFS XCHAL_INTLEVEL6_VECOFS | ||
427 | #define XCHAL_DEBUG_VECTOR_VADDR XCHAL_INTLEVEL6_VECTOR_VADDR | ||
428 | #define XCHAL_DEBUG_VECTOR_PADDR XCHAL_INTLEVEL6_VECTOR_PADDR | ||
429 | #define XCHAL_NMI_VECOFS 0x000002C0 | ||
430 | #define XCHAL_NMI_VECTOR_VADDR 0x000022C0 | ||
431 | #define XCHAL_NMI_VECTOR_PADDR 0x000022C0 | ||
432 | #define XCHAL_INTLEVEL7_VECOFS XCHAL_NMI_VECOFS | ||
433 | #define XCHAL_INTLEVEL7_VECTOR_VADDR XCHAL_NMI_VECTOR_VADDR | ||
434 | #define XCHAL_INTLEVEL7_VECTOR_PADDR XCHAL_NMI_VECTOR_PADDR | ||
435 | |||
436 | |||
437 | /*---------------------------------------------------------------------- | ||
438 | DEBUG | ||
439 | ----------------------------------------------------------------------*/ | ||
440 | |||
441 | #define XCHAL_HAVE_OCD 1 /* OnChipDebug option */ | ||
442 | #define XCHAL_NUM_IBREAK 2 /* number of IBREAKn regs */ | ||
443 | #define XCHAL_NUM_DBREAK 2 /* number of DBREAKn regs */ | ||
444 | #define XCHAL_HAVE_OCD_DIR_ARRAY 1 /* faster OCD option */ | ||
445 | |||
446 | |||
447 | /*---------------------------------------------------------------------- | ||
448 | MMU | ||
449 | ----------------------------------------------------------------------*/ | ||
450 | |||
451 | /* See core-matmap.h header file for more details. */ | ||
452 | |||
453 | #define XCHAL_HAVE_TLBS 1 /* inverse of HAVE_CACHEATTR */ | ||
454 | #define XCHAL_HAVE_SPANNING_WAY 1 /* one way maps I+D 4GB vaddr */ | ||
455 | #define XCHAL_SPANNING_WAY 6 /* TLB spanning way number */ | ||
456 | #define XCHAL_HAVE_IDENTITY_MAP 0 /* vaddr == paddr always */ | ||
457 | #define XCHAL_HAVE_CACHEATTR 0 /* CACHEATTR register present */ | ||
458 | #define XCHAL_HAVE_MIMIC_CACHEATTR 0 /* region protection */ | ||
459 | #define XCHAL_HAVE_XLT_CACHEATTR 0 /* region prot. w/translation */ | ||
460 | #define XCHAL_HAVE_PTP_MMU 1 /* full MMU (with page table | ||
461 | [autorefill] and protection) | ||
462 | usable for an MMU-based OS */ | ||
463 | /* If none of the above last 4 are set, it's a custom TLB configuration. */ | ||
464 | #define XCHAL_ITLB_ARF_ENTRIES_LOG2 2 /* log2(autorefill way size) */ | ||
465 | #define XCHAL_DTLB_ARF_ENTRIES_LOG2 2 /* log2(autorefill way size) */ | ||
466 | |||
467 | #define XCHAL_MMU_ASID_BITS 8 /* number of bits in ASIDs */ | ||
468 | #define XCHAL_MMU_RINGS 4 /* number of rings (1..4) */ | ||
469 | #define XCHAL_MMU_RING_BITS 2 /* num of bits in RING field */ | ||
470 | |||
471 | #endif /* !XTENSA_HAL_NON_PRIVILEGED_ONLY */ | ||
472 | |||
473 | |||
474 | #endif /* _XTENSA_CORE_CONFIGURATION_H */ | ||
475 | |||
diff --git a/arch/xtensa/variants/dc233c/include/variant/tie-asm.h b/arch/xtensa/variants/dc233c/include/variant/tie-asm.h new file mode 100644 index 000000000000..5dbd981ea424 --- /dev/null +++ b/arch/xtensa/variants/dc233c/include/variant/tie-asm.h | |||
@@ -0,0 +1,193 @@ | |||
1 | /* | ||
2 | * tie-asm.h -- compile-time HAL assembler definitions dependent on CORE & TIE | ||
3 | * | ||
4 | * NOTE: This header file is not meant to be included directly. | ||
5 | */ | ||
6 | |||
7 | /* This header file contains assembly-language definitions (assembly | ||
8 | macros, etc.) for this specific Xtensa processor's TIE extensions | ||
9 | and options. It is customized to this Xtensa processor configuration. | ||
10 | |||
11 | Copyright (c) 1999-2010 Tensilica Inc. | ||
12 | |||
13 | Permission is hereby granted, free of charge, to any person obtaining | ||
14 | a copy of this software and associated documentation files (the | ||
15 | "Software"), to deal in the Software without restriction, including | ||
16 | without limitation the rights to use, copy, modify, merge, publish, | ||
17 | distribute, sublicense, and/or sell copies of the Software, and to | ||
18 | permit persons to whom the Software is furnished to do so, subject to | ||
19 | the following conditions: | ||
20 | |||
21 | The above copyright notice and this permission notice shall be included | ||
22 | in all copies or substantial portions of the Software. | ||
23 | |||
24 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
25 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
26 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||
27 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY | ||
28 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | ||
29 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||
30 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ | ||
31 | |||
32 | #ifndef _XTENSA_CORE_TIE_ASM_H | ||
33 | #define _XTENSA_CORE_TIE_ASM_H | ||
34 | |||
35 | /* Selection parameter values for save-area save/restore macros: */ | ||
36 | /* Option vs. TIE: */ | ||
37 | #define XTHAL_SAS_TIE 0x0001 /* custom extension or coprocessor */ | ||
38 | #define XTHAL_SAS_OPT 0x0002 /* optional (and not a coprocessor) */ | ||
39 | #define XTHAL_SAS_ANYOT 0x0003 /* both of the above */ | ||
40 | /* Whether used automatically by compiler: */ | ||
41 | #define XTHAL_SAS_NOCC 0x0004 /* not used by compiler w/o special opts/code */ | ||
42 | #define XTHAL_SAS_CC 0x0008 /* used by compiler without special opts/code */ | ||
43 | #define XTHAL_SAS_ANYCC 0x000C /* both of the above */ | ||
44 | /* ABI handling across function calls: */ | ||
45 | #define XTHAL_SAS_CALR 0x0010 /* caller-saved */ | ||
46 | #define XTHAL_SAS_CALE 0x0020 /* callee-saved */ | ||
47 | #define XTHAL_SAS_GLOB 0x0040 /* global across function calls (in thread) */ | ||
48 | #define XTHAL_SAS_ANYABI 0x0070 /* all of the above three */ | ||
49 | /* Misc */ | ||
50 | #define XTHAL_SAS_ALL 0xFFFF /* include all default NCP contents */ | ||
51 | #define XTHAL_SAS3(optie,ccuse,abi) ( ((optie) & XTHAL_SAS_ANYOT) \ | ||
52 | | ((ccuse) & XTHAL_SAS_ANYCC) \ | ||
53 | | ((abi) & XTHAL_SAS_ANYABI) ) | ||
54 | |||
55 | |||
56 | |||
57 | /* | ||
58 | * Macro to save all non-coprocessor (extra) custom TIE and optional state | ||
59 | * (not including zero-overhead loop registers). | ||
60 | * Required parameters: | ||
61 | * ptr Save area pointer address register (clobbered) | ||
62 | * (register must contain a 4 byte aligned address). | ||
63 | * at1..at4 Four temporary address registers (first XCHAL_NCP_NUM_ATMPS | ||
64 | * registers are clobbered, the remaining are unused). | ||
65 | * Optional parameters: | ||
66 | * continue If macro invoked as part of a larger store sequence, set to 1 | ||
67 | * if this is not the first in the sequence. Defaults to 0. | ||
68 | * ofs Offset from start of larger sequence (from value of first ptr | ||
69 | * in sequence) at which to store. Defaults to next available space | ||
70 | * (or 0 if <continue> is 0). | ||
71 | * select Select what category(ies) of registers to store, as a bitmask | ||
72 | * (see XTHAL_SAS_xxx constants). Defaults to all registers. | ||
73 | * alloc Select what category(ies) of registers to allocate; if any | ||
74 | * category is selected here that is not in <select>, space for | ||
75 | * the corresponding registers is skipped without doing any store. | ||
76 | */ | ||
77 | .macro xchal_ncp_store ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL alloc=0 | ||
78 | xchal_sa_start \continue, \ofs | ||
79 | // Optional global register used by default by the compiler: | ||
80 | .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_GLOB) & ~(\select) | ||
81 | xchal_sa_align \ptr, 0, 1020, 4, 4 | ||
82 | rur.THREADPTR \at1 // threadptr option | ||
83 | s32i \at1, \ptr, .Lxchal_ofs_+0 | ||
84 | .set .Lxchal_ofs_, .Lxchal_ofs_ + 4 | ||
85 | .elseif ((XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_GLOB) & ~(\alloc)) == 0 | ||
86 | xchal_sa_align \ptr, 0, 1020, 4, 4 | ||
87 | .set .Lxchal_ofs_, .Lxchal_ofs_ + 4 | ||
88 | .endif | ||
89 | // Optional caller-saved registers used by default by the compiler: | ||
90 | .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_CALR) & ~(\select) | ||
91 | xchal_sa_align \ptr, 0, 1016, 4, 4 | ||
92 | rsr \at1, ACCLO // MAC16 option | ||
93 | s32i \at1, \ptr, .Lxchal_ofs_+0 | ||
94 | rsr \at1, ACCHI // MAC16 option | ||
95 | s32i \at1, \ptr, .Lxchal_ofs_+4 | ||
96 | .set .Lxchal_ofs_, .Lxchal_ofs_ + 8 | ||
97 | .elseif ((XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_CALR) & ~(\alloc)) == 0 | ||
98 | xchal_sa_align \ptr, 0, 1016, 4, 4 | ||
99 | .set .Lxchal_ofs_, .Lxchal_ofs_ + 8 | ||
100 | .endif | ||
101 | // Optional caller-saved registers not used by default by the compiler: | ||
102 | .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~(\select) | ||
103 | xchal_sa_align \ptr, 0, 1004, 4, 4 | ||
104 | rsr \at1, M0 // MAC16 option | ||
105 | s32i \at1, \ptr, .Lxchal_ofs_+0 | ||
106 | rsr \at1, M1 // MAC16 option | ||
107 | s32i \at1, \ptr, .Lxchal_ofs_+4 | ||
108 | rsr \at1, M2 // MAC16 option | ||
109 | s32i \at1, \ptr, .Lxchal_ofs_+8 | ||
110 | rsr \at1, M3 // MAC16 option | ||
111 | s32i \at1, \ptr, .Lxchal_ofs_+12 | ||
112 | rsr \at1, SCOMPARE1 // conditional store option | ||
113 | s32i \at1, \ptr, .Lxchal_ofs_+16 | ||
114 | .set .Lxchal_ofs_, .Lxchal_ofs_ + 20 | ||
115 | .elseif ((XTHAL_SAS_OPT | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~(\alloc)) == 0 | ||
116 | xchal_sa_align \ptr, 0, 1004, 4, 4 | ||
117 | .set .Lxchal_ofs_, .Lxchal_ofs_ + 20 | ||
118 | .endif | ||
119 | .endm // xchal_ncp_store | ||
120 | |||
121 | /* | ||
122 | * Macro to restore all non-coprocessor (extra) custom TIE and optional state | ||
123 | * (not including zero-overhead loop registers). | ||
124 | * Required parameters: | ||
125 | * ptr Save area pointer address register (clobbered) | ||
126 | * (register must contain a 4 byte aligned address). | ||
127 | * at1..at4 Four temporary address registers (first XCHAL_NCP_NUM_ATMPS | ||
128 | * registers are clobbered, the remaining are unused). | ||
129 | * Optional parameters: | ||
130 | * continue If macro invoked as part of a larger load sequence, set to 1 | ||
131 | * if this is not the first in the sequence. Defaults to 0. | ||
132 | * ofs Offset from start of larger sequence (from value of first ptr | ||
133 | * in sequence) at which to load. Defaults to next available space | ||
134 | * (or 0 if <continue> is 0). | ||
135 | * select Select what category(ies) of registers to load, as a bitmask | ||
136 | * (see XTHAL_SAS_xxx constants). Defaults to all registers. | ||
137 | * alloc Select what category(ies) of registers to allocate; if any | ||
138 | * category is selected here that is not in <select>, space for | ||
139 | * the corresponding registers is skipped without doing any load. | ||
140 | */ | ||
141 | .macro xchal_ncp_load ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL alloc=0 | ||
142 | xchal_sa_start \continue, \ofs | ||
143 | // Optional global register used by default by the compiler: | ||
144 | .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_GLOB) & ~(\select) | ||
145 | xchal_sa_align \ptr, 0, 1020, 4, 4 | ||
146 | l32i \at1, \ptr, .Lxchal_ofs_+0 | ||
147 | wur.THREADPTR \at1 // threadptr option | ||
148 | .set .Lxchal_ofs_, .Lxchal_ofs_ + 4 | ||
149 | .elseif ((XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_GLOB) & ~(\alloc)) == 0 | ||
150 | xchal_sa_align \ptr, 0, 1020, 4, 4 | ||
151 | .set .Lxchal_ofs_, .Lxchal_ofs_ + 4 | ||
152 | .endif | ||
153 | // Optional caller-saved registers used by default by the compiler: | ||
154 | .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_CALR) & ~(\select) | ||
155 | xchal_sa_align \ptr, 0, 1016, 4, 4 | ||
156 | l32i \at1, \ptr, .Lxchal_ofs_+0 | ||
157 | wsr \at1, ACCLO // MAC16 option | ||
158 | l32i \at1, \ptr, .Lxchal_ofs_+4 | ||
159 | wsr \at1, ACCHI // MAC16 option | ||
160 | .set .Lxchal_ofs_, .Lxchal_ofs_ + 8 | ||
161 | .elseif ((XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_CALR) & ~(\alloc)) == 0 | ||
162 | xchal_sa_align \ptr, 0, 1016, 4, 4 | ||
163 | .set .Lxchal_ofs_, .Lxchal_ofs_ + 8 | ||
164 | .endif | ||
165 | // Optional caller-saved registers not used by default by the compiler: | ||
166 | .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~(\select) | ||
167 | xchal_sa_align \ptr, 0, 1004, 4, 4 | ||
168 | l32i \at1, \ptr, .Lxchal_ofs_+0 | ||
169 | wsr \at1, M0 // MAC16 option | ||
170 | l32i \at1, \ptr, .Lxchal_ofs_+4 | ||
171 | wsr \at1, M1 // MAC16 option | ||
172 | l32i \at1, \ptr, .Lxchal_ofs_+8 | ||
173 | wsr \at1, M2 // MAC16 option | ||
174 | l32i \at1, \ptr, .Lxchal_ofs_+12 | ||
175 | wsr \at1, M3 // MAC16 option | ||
176 | l32i \at1, \ptr, .Lxchal_ofs_+16 | ||
177 | wsr \at1, SCOMPARE1 // conditional store option | ||
178 | .set .Lxchal_ofs_, .Lxchal_ofs_ + 20 | ||
179 | .elseif ((XTHAL_SAS_OPT | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~(\alloc)) == 0 | ||
180 | xchal_sa_align \ptr, 0, 1004, 4, 4 | ||
181 | .set .Lxchal_ofs_, .Lxchal_ofs_ + 20 | ||
182 | .endif | ||
183 | .endm // xchal_ncp_load | ||
184 | |||
185 | |||
186 | #define XCHAL_NCP_NUM_ATMPS 1 | ||
187 | |||
188 | |||
189 | |||
190 | #define XCHAL_SA_NUM_ATMPS 1 | ||
191 | |||
192 | #endif /*_XTENSA_CORE_TIE_ASM_H*/ | ||
193 | |||
diff --git a/arch/xtensa/variants/dc233c/include/variant/tie.h b/arch/xtensa/variants/dc233c/include/variant/tie.h new file mode 100644 index 000000000000..815e52bc3d00 --- /dev/null +++ b/arch/xtensa/variants/dc233c/include/variant/tie.h | |||
@@ -0,0 +1,150 @@ | |||
1 | /* | ||
2 | * tie.h -- compile-time HAL definitions dependent on CORE & TIE configuration | ||
3 | * | ||
4 | * NOTE: This header file is not meant to be included directly. | ||
5 | */ | ||
6 | |||
7 | /* This header file describes this specific Xtensa processor's TIE extensions | ||
8 | that extend basic Xtensa core functionality. It is customized to this | ||
9 | Xtensa processor configuration. | ||
10 | |||
11 | Copyright (c) 1999-2010 Tensilica Inc. | ||
12 | |||
13 | Permission is hereby granted, free of charge, to any person obtaining | ||
14 | a copy of this software and associated documentation files (the | ||
15 | "Software"), to deal in the Software without restriction, including | ||
16 | without limitation the rights to use, copy, modify, merge, publish, | ||
17 | distribute, sublicense, and/or sell copies of the Software, and to | ||
18 | permit persons to whom the Software is furnished to do so, subject to | ||
19 | the following conditions: | ||
20 | |||
21 | The above copyright notice and this permission notice shall be included | ||
22 | in all copies or substantial portions of the Software. | ||
23 | |||
24 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
25 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
26 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||
27 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY | ||
28 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | ||
29 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||
30 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ | ||
31 | |||
32 | #ifndef _XTENSA_CORE_TIE_H | ||
33 | #define _XTENSA_CORE_TIE_H | ||
34 | |||
35 | #define XCHAL_CP_NUM 1 /* number of coprocessors */ | ||
36 | #define XCHAL_CP_MAX 8 /* max CP ID + 1 (0 if none) */ | ||
37 | #define XCHAL_CP_MASK 0x80 /* bitmask of all CPs by ID */ | ||
38 | #define XCHAL_CP_PORT_MASK 0x80 /* bitmask of only port CPs */ | ||
39 | |||
40 | /* Basic parameters of each coprocessor: */ | ||
41 | #define XCHAL_CP7_NAME "XTIOP" | ||
42 | #define XCHAL_CP7_IDENT XTIOP | ||
43 | #define XCHAL_CP7_SA_SIZE 0 /* size of state save area */ | ||
44 | #define XCHAL_CP7_SA_ALIGN 1 /* min alignment of save area */ | ||
45 | #define XCHAL_CP_ID_XTIOP 7 /* coprocessor ID (0..7) */ | ||
46 | |||
47 | /* Filler info for unassigned coprocessors, to simplify arrays etc: */ | ||
48 | #define XCHAL_CP0_SA_SIZE 0 | ||
49 | #define XCHAL_CP0_SA_ALIGN 1 | ||
50 | #define XCHAL_CP1_SA_SIZE 0 | ||
51 | #define XCHAL_CP1_SA_ALIGN 1 | ||
52 | #define XCHAL_CP2_SA_SIZE 0 | ||
53 | #define XCHAL_CP2_SA_ALIGN 1 | ||
54 | #define XCHAL_CP3_SA_SIZE 0 | ||
55 | #define XCHAL_CP3_SA_ALIGN 1 | ||
56 | #define XCHAL_CP4_SA_SIZE 0 | ||
57 | #define XCHAL_CP4_SA_ALIGN 1 | ||
58 | #define XCHAL_CP5_SA_SIZE 0 | ||
59 | #define XCHAL_CP5_SA_ALIGN 1 | ||
60 | #define XCHAL_CP6_SA_SIZE 0 | ||
61 | #define XCHAL_CP6_SA_ALIGN 1 | ||
62 | |||
63 | /* Save area for non-coprocessor optional and custom (TIE) state: */ | ||
64 | #define XCHAL_NCP_SA_SIZE 32 | ||
65 | #define XCHAL_NCP_SA_ALIGN 4 | ||
66 | |||
67 | /* Total save area for optional and custom state (NCP + CPn): */ | ||
68 | #define XCHAL_TOTAL_SA_SIZE 32 /* with 16-byte align padding */ | ||
69 | #define XCHAL_TOTAL_SA_ALIGN 4 /* actual minimum alignment */ | ||
70 | |||
71 | /* | ||
72 | * Detailed contents of save areas. | ||
73 | * NOTE: caller must define the XCHAL_SA_REG macro (not defined here) | ||
74 | * before expanding the XCHAL_xxx_SA_LIST() macros. | ||
75 | * | ||
76 | * XCHAL_SA_REG(s,ccused,abikind,kind,opt,name,galign,align,asize, | ||
77 | * dbnum,base,regnum,bitsz,gapsz,reset,x...) | ||
78 | * | ||
79 | * s = passed from XCHAL_*_LIST(s), eg. to select how to expand | ||
80 | * ccused = set if used by compiler without special options or code | ||
81 | * abikind = 0 (caller-saved), 1 (callee-saved), or 2 (thread-global) | ||
82 | * kind = 0 (special reg), 1 (TIE user reg), or 2 (TIE regfile reg) | ||
83 | * opt = 0 (custom TIE extension or coprocessor), or 1 (optional reg) | ||
84 | * name = lowercase reg name (no quotes) | ||
85 | * galign = group byte alignment (power of 2) (galign >= align) | ||
86 | * align = register byte alignment (power of 2) | ||
87 | * asize = allocated size in bytes (asize*8 == bitsz + gapsz + padsz) | ||
88 | * (not including any pad bytes required to galign this or next reg) | ||
89 | * dbnum = unique target number f/debug (see <xtensa-libdb-macros.h>) | ||
90 | * base = reg shortname w/o index (or sr=special, ur=TIE user reg) | ||
91 | * regnum = reg index in regfile, or special/TIE-user reg number | ||
92 | * bitsz = number of significant bits (regfile width, or ur/sr mask bits) | ||
93 | * gapsz = intervening bits, if bitsz bits not stored contiguously | ||
94 | * (padsz = pad bits at end [TIE regfile] or at msbits [ur,sr] of asize) | ||
95 | * reset = register reset value (or 0 if undefined at reset) | ||
96 | * x = reserved for future use (0 until then) | ||
97 | * | ||
98 | * To filter out certain registers, e.g. to expand only the non-global | ||
99 | * registers used by the compiler, you can do something like this: | ||
100 | * | ||
101 | * #define XCHAL_SA_REG(s,ccused,p...) SELCC##ccused(p) | ||
102 | * #define SELCC0(p...) | ||
103 | * #define SELCC1(abikind,p...) SELAK##abikind(p) | ||
104 | * #define SELAK0(p...) REG(p) | ||
105 | * #define SELAK1(p...) REG(p) | ||
106 | * #define SELAK2(p...) | ||
107 | * #define REG(kind,tie,name,galn,aln,asz,csz,dbnum,base,rnum,bsz,rst,x...) \ | ||
108 | * ...what you want to expand... | ||
109 | */ | ||
110 | |||
111 | #define XCHAL_NCP_SA_NUM 8 | ||
112 | #define XCHAL_NCP_SA_LIST(s) \ | ||
113 | XCHAL_SA_REG(s,1,2,1,1, threadptr, 4, 4, 4,0x03E7, ur,231, 32,0,0,0) \ | ||
114 | XCHAL_SA_REG(s,1,0,0,1, acclo, 4, 4, 4,0x0210, sr,16 , 32,0,0,0) \ | ||
115 | XCHAL_SA_REG(s,1,0,0,1, acchi, 4, 4, 4,0x0211, sr,17 , 8,0,0,0) \ | ||
116 | XCHAL_SA_REG(s,0,0,0,1, m0, 4, 4, 4,0x0220, sr,32 , 32,0,0,0) \ | ||
117 | XCHAL_SA_REG(s,0,0,0,1, m1, 4, 4, 4,0x0221, sr,33 , 32,0,0,0) \ | ||
118 | XCHAL_SA_REG(s,0,0,0,1, m2, 4, 4, 4,0x0222, sr,34 , 32,0,0,0) \ | ||
119 | XCHAL_SA_REG(s,0,0,0,1, m3, 4, 4, 4,0x0223, sr,35 , 32,0,0,0) \ | ||
120 | XCHAL_SA_REG(s,0,0,0,1, scompare1, 4, 4, 4,0x020C, sr,12 , 32,0,0,0) | ||
121 | |||
122 | #define XCHAL_CP0_SA_NUM 0 | ||
123 | #define XCHAL_CP0_SA_LIST(s) /* empty */ | ||
124 | |||
125 | #define XCHAL_CP1_SA_NUM 0 | ||
126 | #define XCHAL_CP1_SA_LIST(s) /* empty */ | ||
127 | |||
128 | #define XCHAL_CP2_SA_NUM 0 | ||
129 | #define XCHAL_CP2_SA_LIST(s) /* empty */ | ||
130 | |||
131 | #define XCHAL_CP3_SA_NUM 0 | ||
132 | #define XCHAL_CP3_SA_LIST(s) /* empty */ | ||
133 | |||
134 | #define XCHAL_CP4_SA_NUM 0 | ||
135 | #define XCHAL_CP4_SA_LIST(s) /* empty */ | ||
136 | |||
137 | #define XCHAL_CP5_SA_NUM 0 | ||
138 | #define XCHAL_CP5_SA_LIST(s) /* empty */ | ||
139 | |||
140 | #define XCHAL_CP6_SA_NUM 0 | ||
141 | #define XCHAL_CP6_SA_LIST(s) /* empty */ | ||
142 | |||
143 | #define XCHAL_CP7_SA_NUM 0 | ||
144 | #define XCHAL_CP7_SA_LIST(s) /* empty */ | ||
145 | |||
146 | /* Byte length of instruction from its first nibble (op0 field), per FLIX. */ | ||
147 | #define XCHAL_OP0_FORMAT_LENGTHS 3,3,3,3,3,3,3,3,2,2,2,2,2,2,3,3 | ||
148 | |||
149 | #endif /*_XTENSA_CORE_TIE_H*/ | ||
150 | |||