diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2015-04-13 10:03:32 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2015-04-13 10:03:32 -0400 |
commit | 3e20a26b02bd4f24945c87407df51948dd488620 (patch) | |
tree | f466d3b2a47a98ec2910724e17ee2f3a93c1a49e | |
parent | 98b0429b7abd5c05efdb23f3eba02ec3f696748e (diff) | |
parent | 5306a5450824691e27d68f711758515debedeeac (diff) |
Merge branch '4.0-fixes' into mips-for-linux-next
35 files changed, 763 insertions, 383 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index b018062b9d3e..1c971be1b985 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -415,6 +415,7 @@ config MIPS_MALTA | |||
415 | select SYS_HAS_CPU_MIPS32_R1 | 415 | select SYS_HAS_CPU_MIPS32_R1 |
416 | select SYS_HAS_CPU_MIPS32_R2 | 416 | select SYS_HAS_CPU_MIPS32_R2 |
417 | select SYS_HAS_CPU_MIPS32_R3_5 | 417 | select SYS_HAS_CPU_MIPS32_R3_5 |
418 | select SYS_HAS_CPU_MIPS32_R5 | ||
418 | select SYS_HAS_CPU_MIPS32_R6 | 419 | select SYS_HAS_CPU_MIPS32_R6 |
419 | select SYS_HAS_CPU_MIPS64_R1 | 420 | select SYS_HAS_CPU_MIPS64_R1 |
420 | select SYS_HAS_CPU_MIPS64_R2 | 421 | select SYS_HAS_CPU_MIPS64_R2 |
@@ -424,6 +425,7 @@ config MIPS_MALTA | |||
424 | select SYS_SUPPORTS_32BIT_KERNEL | 425 | select SYS_SUPPORTS_32BIT_KERNEL |
425 | select SYS_SUPPORTS_64BIT_KERNEL | 426 | select SYS_SUPPORTS_64BIT_KERNEL |
426 | select SYS_SUPPORTS_BIG_ENDIAN | 427 | select SYS_SUPPORTS_BIG_ENDIAN |
428 | select SYS_SUPPORTS_HIGHMEM | ||
427 | select SYS_SUPPORTS_LITTLE_ENDIAN | 429 | select SYS_SUPPORTS_LITTLE_ENDIAN |
428 | select SYS_SUPPORTS_MICROMIPS | 430 | select SYS_SUPPORTS_MICROMIPS |
429 | select SYS_SUPPORTS_MIPS_CMP | 431 | select SYS_SUPPORTS_MIPS_CMP |
@@ -1638,6 +1640,33 @@ config CPU_MIPS32_3_5_EVA | |||
1638 | One of its primary benefits is an increase in the maximum size | 1640 | One of its primary benefits is an increase in the maximum size |
1639 | of lowmem (up to 3GB). If unsure, say 'N' here. | 1641 | of lowmem (up to 3GB). If unsure, say 'N' here. |
1640 | 1642 | ||
1643 | config CPU_MIPS32_R5_FEATURES | ||
1644 | bool "MIPS32 Release 5 Features" | ||
1645 | depends on SYS_HAS_CPU_MIPS32_R5 | ||
1646 | depends on CPU_MIPS32_R2 | ||
1647 | help | ||
1648 | Choose this option to build a kernel for release 2 or later of the | ||
1649 | MIPS32 architecture including features from release 5 such as | ||
1650 | support for Extended Physical Addressing (XPA). | ||
1651 | |||
1652 | config CPU_MIPS32_R5_XPA | ||
1653 | bool "Extended Physical Addressing (XPA)" | ||
1654 | depends on CPU_MIPS32_R5_FEATURES | ||
1655 | depends on !EVA | ||
1656 | depends on !PAGE_SIZE_4KB | ||
1657 | depends on SYS_SUPPORTS_HIGHMEM | ||
1658 | select XPA | ||
1659 | select HIGHMEM | ||
1660 | select ARCH_PHYS_ADDR_T_64BIT | ||
1661 | default n | ||
1662 | help | ||
1663 | Choose this option if you want to enable the Extended Physical | ||
1664 | Addressing (XPA) on your MIPS32 core (such as P5600 series). The | ||
1665 | benefit is to increase physical addressing equal to or greater | ||
1666 | than 40 bits. Note that this has the side effect of turning on | ||
1667 | 64-bit addressing which in turn makes the PTEs 64-bit in size. | ||
1668 | If unsure, say 'N' here. | ||
1669 | |||
1641 | if CPU_LOONGSON2F | 1670 | if CPU_LOONGSON2F |
1642 | config CPU_NOP_WORKAROUNDS | 1671 | config CPU_NOP_WORKAROUNDS |
1643 | bool | 1672 | bool |
@@ -1741,6 +1770,9 @@ config SYS_HAS_CPU_MIPS32_R2 | |||
1741 | config SYS_HAS_CPU_MIPS32_R3_5 | 1770 | config SYS_HAS_CPU_MIPS32_R3_5 |
1742 | bool | 1771 | bool |
1743 | 1772 | ||
1773 | config SYS_HAS_CPU_MIPS32_R5 | ||
1774 | bool | ||
1775 | |||
1744 | config SYS_HAS_CPU_MIPS32_R6 | 1776 | config SYS_HAS_CPU_MIPS32_R6 |
1745 | bool | 1777 | bool |
1746 | 1778 | ||
@@ -1878,6 +1910,9 @@ config CPU_MIPSR6 | |||
1878 | config EVA | 1910 | config EVA |
1879 | bool | 1911 | bool |
1880 | 1912 | ||
1913 | config XPA | ||
1914 | bool | ||
1915 | |||
1881 | config SYS_SUPPORTS_32BIT_KERNEL | 1916 | config SYS_SUPPORTS_32BIT_KERNEL |
1882 | bool | 1917 | bool |
1883 | config SYS_SUPPORTS_64BIT_KERNEL | 1918 | config SYS_SUPPORTS_64BIT_KERNEL |
@@ -2114,7 +2149,7 @@ config MIPSR2_TO_R6_EMULATOR | |||
2114 | help | 2149 | help |
2115 | Choose this option if you want to run non-R6 MIPS userland code. | 2150 | Choose this option if you want to run non-R6 MIPS userland code. |
2116 | Even if you say 'Y' here, the emulator will still be disabled by | 2151 | Even if you say 'Y' here, the emulator will still be disabled by |
2117 | default. You can enable it using the 'mipsr2emul' kernel option. | 2152 | default. You can enable it using the 'mipsr2emu' kernel option. |
2118 | The only reason this is a build-time option is to save ~14K from the | 2153 | The only reason this is a build-time option is to save ~14K from the |
2119 | final kernel image. | 2154 | final kernel image. |
2120 | comment "MIPS R2-to-R6 emulator is only available for UP kernels" | 2155 | comment "MIPS R2-to-R6 emulator is only available for UP kernels" |
@@ -2184,7 +2219,7 @@ config MIPS_CMP | |||
2184 | 2219 | ||
2185 | config MIPS_CPS | 2220 | config MIPS_CPS |
2186 | bool "MIPS Coherent Processing System support" | 2221 | bool "MIPS Coherent Processing System support" |
2187 | depends on SYS_SUPPORTS_MIPS_CPS | 2222 | depends on SYS_SUPPORTS_MIPS_CPS && !64BIT |
2188 | select MIPS_CM | 2223 | select MIPS_CM |
2189 | select MIPS_CPC | 2224 | select MIPS_CPC |
2190 | select MIPS_CPS_PM if HOTPLUG_CPU | 2225 | select MIPS_CPS_PM if HOTPLUG_CPU |
diff --git a/arch/mips/Makefile b/arch/mips/Makefile index e644ac2d6501..198fd8d120a0 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile | |||
@@ -197,11 +197,17 @@ endif | |||
197 | # Warning: the 64-bit MIPS architecture does not support the `smartmips' extension | 197 | # Warning: the 64-bit MIPS architecture does not support the `smartmips' extension |
198 | # Pass -Wa,--no-warn to disable all assembler warnings until the kernel code has | 198 | # Pass -Wa,--no-warn to disable all assembler warnings until the kernel code has |
199 | # been fixed properly. | 199 | # been fixed properly. |
200 | mips-cflags := "$(cflags-y)" | 200 | mips-cflags := $(cflags-y) |
201 | cflags-$(CONFIG_CPU_HAS_SMARTMIPS) += $(call cc-option,$(mips-cflags),-msmartmips) -Wa,--no-warn | 201 | ifeq ($(CONFIG_CPU_HAS_SMARTMIPS),y) |
202 | cflags-$(CONFIG_CPU_MICROMIPS) += $(call cc-option,$(mips-cflags),-mmicromips) | 202 | smartmips-ase := $(call cc-option-yn,$(mips-cflags) -msmartmips) |
203 | cflags-$(smartmips-ase) += -msmartmips -Wa,--no-warn | ||
204 | endif | ||
205 | ifeq ($(CONFIG_CPU_MICROMIPS),y) | ||
206 | micromips-ase := $(call cc-option-yn,$(mips-cflags) -mmicromips) | ||
207 | cflags-$(micromips-ase) += -mmicromips | ||
208 | endif | ||
203 | ifeq ($(CONFIG_CPU_HAS_MSA),y) | 209 | ifeq ($(CONFIG_CPU_HAS_MSA),y) |
204 | toolchain-msa := $(call cc-option-yn,-$(mips-cflags),mhard-float -mfp64 -Wa$(comma)-mmsa) | 210 | toolchain-msa := $(call cc-option-yn,$(mips-cflags) -mhard-float -mfp64 -Wa$(comma)-mmsa) |
205 | cflags-$(toolchain-msa) += -DTOOLCHAIN_SUPPORTS_MSA | 211 | cflags-$(toolchain-msa) += -DTOOLCHAIN_SUPPORTS_MSA |
206 | endif | 212 | endif |
207 | 213 | ||
diff --git a/arch/mips/bcm47xx/board.c b/arch/mips/bcm47xx/board.c index 41b9736c3c05..bd56415f2f3b 100644 --- a/arch/mips/bcm47xx/board.c +++ b/arch/mips/bcm47xx/board.c | |||
@@ -235,8 +235,8 @@ static __init const struct bcm47xx_board_type *bcm47xx_board_get_nvram(void) | |||
235 | } | 235 | } |
236 | 236 | ||
237 | if (bcm47xx_nvram_getenv("hardware_version", buf1, sizeof(buf1)) >= 0 && | 237 | if (bcm47xx_nvram_getenv("hardware_version", buf1, sizeof(buf1)) >= 0 && |
238 | bcm47xx_nvram_getenv("boardtype", buf2, sizeof(buf2)) >= 0) { | 238 | bcm47xx_nvram_getenv("boardnum", buf2, sizeof(buf2)) >= 0) { |
239 | for (e2 = bcm47xx_board_list_boot_hw; e2->value1; e2++) { | 239 | for (e2 = bcm47xx_board_list_hw_version_num; e2->value1; e2++) { |
240 | if (!strstarts(buf1, e2->value1) && | 240 | if (!strstarts(buf1, e2->value1) && |
241 | !strcmp(buf2, e2->value2)) | 241 | !strcmp(buf2, e2->value2)) |
242 | return &e2->board; | 242 | return &e2->board; |
diff --git a/arch/mips/bcm63xx/prom.c b/arch/mips/bcm63xx/prom.c index e1f27d653f60..7019e2967009 100644 --- a/arch/mips/bcm63xx/prom.c +++ b/arch/mips/bcm63xx/prom.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <bcm63xx_cpu.h> | 17 | #include <bcm63xx_cpu.h> |
18 | #include <bcm63xx_io.h> | 18 | #include <bcm63xx_io.h> |
19 | #include <bcm63xx_regs.h> | 19 | #include <bcm63xx_regs.h> |
20 | #include <bcm63xx_gpio.h> | ||
21 | 20 | ||
22 | void __init prom_init(void) | 21 | void __init prom_init(void) |
23 | { | 22 | { |
@@ -53,9 +52,6 @@ void __init prom_init(void) | |||
53 | reg &= ~mask; | 52 | reg &= ~mask; |
54 | bcm_perf_writel(reg, PERF_CKCTL_REG); | 53 | bcm_perf_writel(reg, PERF_CKCTL_REG); |
55 | 54 | ||
56 | /* register gpiochip */ | ||
57 | bcm63xx_gpio_init(); | ||
58 | |||
59 | /* do low level board init */ | 55 | /* do low level board init */ |
60 | board_prom_init(); | 56 | board_prom_init(); |
61 | 57 | ||
diff --git a/arch/mips/bcm63xx/setup.c b/arch/mips/bcm63xx/setup.c index 6660c7ddf87b..240fb4ffa55c 100644 --- a/arch/mips/bcm63xx/setup.c +++ b/arch/mips/bcm63xx/setup.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <bcm63xx_cpu.h> | 20 | #include <bcm63xx_cpu.h> |
21 | #include <bcm63xx_regs.h> | 21 | #include <bcm63xx_regs.h> |
22 | #include <bcm63xx_io.h> | 22 | #include <bcm63xx_io.h> |
23 | #include <bcm63xx_gpio.h> | ||
23 | 24 | ||
24 | void bcm63xx_machine_halt(void) | 25 | void bcm63xx_machine_halt(void) |
25 | { | 26 | { |
@@ -160,6 +161,9 @@ void __init plat_mem_setup(void) | |||
160 | 161 | ||
161 | int __init bcm63xx_register_devices(void) | 162 | int __init bcm63xx_register_devices(void) |
162 | { | 163 | { |
164 | /* register gpiochip */ | ||
165 | bcm63xx_gpio_init(); | ||
166 | |||
163 | return board_register_devices(); | 167 | return board_register_devices(); |
164 | } | 168 | } |
165 | 169 | ||
diff --git a/arch/mips/cavium-octeon/dma-octeon.c b/arch/mips/cavium-octeon/dma-octeon.c index 7d8987818ccf..d8960d46417b 100644 --- a/arch/mips/cavium-octeon/dma-octeon.c +++ b/arch/mips/cavium-octeon/dma-octeon.c | |||
@@ -306,7 +306,7 @@ void __init plat_swiotlb_setup(void) | |||
306 | swiotlbsize = 64 * (1<<20); | 306 | swiotlbsize = 64 * (1<<20); |
307 | } | 307 | } |
308 | #endif | 308 | #endif |
309 | #ifdef CONFIG_USB_OCTEON_OHCI | 309 | #ifdef CONFIG_USB_OHCI_HCD_PLATFORM |
310 | /* OCTEON II ohci is only 32-bit. */ | 310 | /* OCTEON II ohci is only 32-bit. */ |
311 | if (OCTEON_IS_OCTEON2() && max_addr >= 0x100000000ul) | 311 | if (OCTEON_IS_OCTEON2() && max_addr >= 0x100000000ul) |
312 | swiotlbsize = 64 * (1<<20); | 312 | swiotlbsize = 64 * (1<<20); |
diff --git a/arch/mips/include/asm/asm-eva.h b/arch/mips/include/asm/asm-eva.h index e41c56e375b1..1e38f0e1ea3e 100644 --- a/arch/mips/include/asm/asm-eva.h +++ b/arch/mips/include/asm/asm-eva.h | |||
@@ -11,6 +11,36 @@ | |||
11 | #define __ASM_ASM_EVA_H | 11 | #define __ASM_ASM_EVA_H |
12 | 12 | ||
13 | #ifndef __ASSEMBLY__ | 13 | #ifndef __ASSEMBLY__ |
14 | |||
15 | /* Kernel variants */ | ||
16 | |||
17 | #define kernel_cache(op, base) "cache " op ", " base "\n" | ||
18 | #define kernel_ll(reg, addr) "ll " reg ", " addr "\n" | ||
19 | #define kernel_sc(reg, addr) "sc " reg ", " addr "\n" | ||
20 | #define kernel_lw(reg, addr) "lw " reg ", " addr "\n" | ||
21 | #define kernel_lwl(reg, addr) "lwl " reg ", " addr "\n" | ||
22 | #define kernel_lwr(reg, addr) "lwr " reg ", " addr "\n" | ||
23 | #define kernel_lh(reg, addr) "lh " reg ", " addr "\n" | ||
24 | #define kernel_lb(reg, addr) "lb " reg ", " addr "\n" | ||
25 | #define kernel_lbu(reg, addr) "lbu " reg ", " addr "\n" | ||
26 | #define kernel_sw(reg, addr) "sw " reg ", " addr "\n" | ||
27 | #define kernel_swl(reg, addr) "swl " reg ", " addr "\n" | ||
28 | #define kernel_swr(reg, addr) "swr " reg ", " addr "\n" | ||
29 | #define kernel_sh(reg, addr) "sh " reg ", " addr "\n" | ||
30 | #define kernel_sb(reg, addr) "sb " reg ", " addr "\n" | ||
31 | |||
32 | #ifdef CONFIG_32BIT | ||
33 | /* | ||
34 | * No 'sd' or 'ld' instructions in 32-bit but the code will | ||
35 | * do the correct thing | ||
36 | */ | ||
37 | #define kernel_sd(reg, addr) user_sw(reg, addr) | ||
38 | #define kernel_ld(reg, addr) user_lw(reg, addr) | ||
39 | #else | ||
40 | #define kernel_sd(reg, addr) "sd " reg", " addr "\n" | ||
41 | #define kernel_ld(reg, addr) "ld " reg", " addr "\n" | ||
42 | #endif /* CONFIG_32BIT */ | ||
43 | |||
14 | #ifdef CONFIG_EVA | 44 | #ifdef CONFIG_EVA |
15 | 45 | ||
16 | #define __BUILD_EVA_INSN(insn, reg, addr) \ | 46 | #define __BUILD_EVA_INSN(insn, reg, addr) \ |
@@ -41,37 +71,60 @@ | |||
41 | 71 | ||
42 | #else | 72 | #else |
43 | 73 | ||
44 | #define user_cache(op, base) "cache " op ", " base "\n" | 74 | #define user_cache(op, base) kernel_cache(op, base) |
45 | #define user_ll(reg, addr) "ll " reg ", " addr "\n" | 75 | #define user_ll(reg, addr) kernel_ll(reg, addr) |
46 | #define user_sc(reg, addr) "sc " reg ", " addr "\n" | 76 | #define user_sc(reg, addr) kernel_sc(reg, addr) |
47 | #define user_lw(reg, addr) "lw " reg ", " addr "\n" | 77 | #define user_lw(reg, addr) kernel_lw(reg, addr) |
48 | #define user_lwl(reg, addr) "lwl " reg ", " addr "\n" | 78 | #define user_lwl(reg, addr) kernel_lwl(reg, addr) |
49 | #define user_lwr(reg, addr) "lwr " reg ", " addr "\n" | 79 | #define user_lwr(reg, addr) kernel_lwr(reg, addr) |
50 | #define user_lh(reg, addr) "lh " reg ", " addr "\n" | 80 | #define user_lh(reg, addr) kernel_lh(reg, addr) |
51 | #define user_lb(reg, addr) "lb " reg ", " addr "\n" | 81 | #define user_lb(reg, addr) kernel_lb(reg, addr) |
52 | #define user_lbu(reg, addr) "lbu " reg ", " addr "\n" | 82 | #define user_lbu(reg, addr) kernel_lbu(reg, addr) |
53 | #define user_sw(reg, addr) "sw " reg ", " addr "\n" | 83 | #define user_sw(reg, addr) kernel_sw(reg, addr) |
54 | #define user_swl(reg, addr) "swl " reg ", " addr "\n" | 84 | #define user_swl(reg, addr) kernel_swl(reg, addr) |
55 | #define user_swr(reg, addr) "swr " reg ", " addr "\n" | 85 | #define user_swr(reg, addr) kernel_swr(reg, addr) |
56 | #define user_sh(reg, addr) "sh " reg ", " addr "\n" | 86 | #define user_sh(reg, addr) kernel_sh(reg, addr) |
57 | #define user_sb(reg, addr) "sb " reg ", " addr "\n" | 87 | #define user_sb(reg, addr) kernel_sb(reg, addr) |
58 | 88 | ||
59 | #ifdef CONFIG_32BIT | 89 | #ifdef CONFIG_32BIT |
60 | /* | 90 | #define user_sd(reg, addr) kernel_sw(reg, addr) |
61 | * No 'sd' or 'ld' instructions in 32-bit but the code will | 91 | #define user_ld(reg, addr) kernel_lw(reg, addr) |
62 | * do the correct thing | ||
63 | */ | ||
64 | #define user_sd(reg, addr) user_sw(reg, addr) | ||
65 | #define user_ld(reg, addr) user_lw(reg, addr) | ||
66 | #else | 92 | #else |
67 | #define user_sd(reg, addr) "sd " reg", " addr "\n" | 93 | #define user_sd(reg, addr) kernel_sd(reg, addr) |
68 | #define user_ld(reg, addr) "ld " reg", " addr "\n" | 94 | #define user_ld(reg, addr) kernel_ld(reg, addr) |
69 | #endif /* CONFIG_32BIT */ | 95 | #endif /* CONFIG_32BIT */ |
70 | 96 | ||
71 | #endif /* CONFIG_EVA */ | 97 | #endif /* CONFIG_EVA */ |
72 | 98 | ||
73 | #else /* __ASSEMBLY__ */ | 99 | #else /* __ASSEMBLY__ */ |
74 | 100 | ||
101 | #define kernel_cache(op, base) cache op, base | ||
102 | #define kernel_ll(reg, addr) ll reg, addr | ||
103 | #define kernel_sc(reg, addr) sc reg, addr | ||
104 | #define kernel_lw(reg, addr) lw reg, addr | ||
105 | #define kernel_lwl(reg, addr) lwl reg, addr | ||
106 | #define kernel_lwr(reg, addr) lwr reg, addr | ||
107 | #define kernel_lh(reg, addr) lh reg, addr | ||
108 | #define kernel_lb(reg, addr) lb reg, addr | ||
109 | #define kernel_lbu(reg, addr) lbu reg, addr | ||
110 | #define kernel_sw(reg, addr) sw reg, addr | ||
111 | #define kernel_swl(reg, addr) swl reg, addr | ||
112 | #define kernel_swr(reg, addr) swr reg, addr | ||
113 | #define kernel_sh(reg, addr) sh reg, addr | ||
114 | #define kernel_sb(reg, addr) sb reg, addr | ||
115 | |||
116 | #ifdef CONFIG_32BIT | ||
117 | /* | ||
118 | * No 'sd' or 'ld' instructions in 32-bit but the code will | ||
119 | * do the correct thing | ||
120 | */ | ||
121 | #define kernel_sd(reg, addr) user_sw(reg, addr) | ||
122 | #define kernel_ld(reg, addr) user_lw(reg, addr) | ||
123 | #else | ||
124 | #define kernel_sd(reg, addr) sd reg, addr | ||
125 | #define kernel_ld(reg, addr) ld reg, addr | ||
126 | #endif /* CONFIG_32BIT */ | ||
127 | |||
75 | #ifdef CONFIG_EVA | 128 | #ifdef CONFIG_EVA |
76 | 129 | ||
77 | #define __BUILD_EVA_INSN(insn, reg, addr) \ | 130 | #define __BUILD_EVA_INSN(insn, reg, addr) \ |
@@ -101,31 +154,27 @@ | |||
101 | #define user_sd(reg, addr) user_sw(reg, addr) | 154 | #define user_sd(reg, addr) user_sw(reg, addr) |
102 | #else | 155 | #else |
103 | 156 | ||
104 | #define user_cache(op, base) cache op, base | 157 | #define user_cache(op, base) kernel_cache(op, base) |
105 | #define user_ll(reg, addr) ll reg, addr | 158 | #define user_ll(reg, addr) kernel_ll(reg, addr) |
106 | #define user_sc(reg, addr) sc reg, addr | 159 | #define user_sc(reg, addr) kernel_sc(reg, addr) |
107 | #define user_lw(reg, addr) lw reg, addr | 160 | #define user_lw(reg, addr) kernel_lw(reg, addr) |
108 | #define user_lwl(reg, addr) lwl reg, addr | 161 | #define user_lwl(reg, addr) kernel_lwl(reg, addr) |
109 | #define user_lwr(reg, addr) lwr reg, addr | 162 | #define user_lwr(reg, addr) kernel_lwr(reg, addr) |
110 | #define user_lh(reg, addr) lh reg, addr | 163 | #define user_lh(reg, addr) kernel_lh(reg, addr) |
111 | #define user_lb(reg, addr) lb reg, addr | 164 | #define user_lb(reg, addr) kernel_lb(reg, addr) |
112 | #define user_lbu(reg, addr) lbu reg, addr | 165 | #define user_lbu(reg, addr) kernel_lbu(reg, addr) |
113 | #define user_sw(reg, addr) sw reg, addr | 166 | #define user_sw(reg, addr) kernel_sw(reg, addr) |
114 | #define user_swl(reg, addr) swl reg, addr | 167 | #define user_swl(reg, addr) kernel_swl(reg, addr) |
115 | #define user_swr(reg, addr) swr reg, addr | 168 | #define user_swr(reg, addr) kernel_swr(reg, addr) |
116 | #define user_sh(reg, addr) sh reg, addr | 169 | #define user_sh(reg, addr) kernel_sh(reg, addr) |
117 | #define user_sb(reg, addr) sb reg, addr | 170 | #define user_sb(reg, addr) kernel_sb(reg, addr) |
118 | 171 | ||
119 | #ifdef CONFIG_32BIT | 172 | #ifdef CONFIG_32BIT |
120 | /* | 173 | #define user_sd(reg, addr) kernel_sw(reg, addr) |
121 | * No 'sd' or 'ld' instructions in 32-bit but the code will | 174 | #define user_ld(reg, addr) kernel_lw(reg, addr) |
122 | * do the correct thing | ||
123 | */ | ||
124 | #define user_sd(reg, addr) user_sw(reg, addr) | ||
125 | #define user_ld(reg, addr) user_lw(reg, addr) | ||
126 | #else | 175 | #else |
127 | #define user_sd(reg, addr) sd reg, addr | 176 | #define user_sd(reg, addr) kernel_sd(reg, addr) |
128 | #define user_ld(reg, addr) ld reg, addr | 177 | #define user_ld(reg, addr) kernel_sd(reg, addr) |
129 | #endif /* CONFIG_32BIT */ | 178 | #endif /* CONFIG_32BIT */ |
130 | 179 | ||
131 | #endif /* CONFIG_EVA */ | 180 | #endif /* CONFIG_EVA */ |
diff --git a/arch/mips/include/asm/cacheflush.h b/arch/mips/include/asm/cacheflush.h index e08381a37f8b..723229f4cf27 100644 --- a/arch/mips/include/asm/cacheflush.h +++ b/arch/mips/include/asm/cacheflush.h | |||
@@ -29,6 +29,20 @@ | |||
29 | * - flush_icache_all() flush the entire instruction cache | 29 | * - flush_icache_all() flush the entire instruction cache |
30 | * - flush_data_cache_page() flushes a page from the data cache | 30 | * - flush_data_cache_page() flushes a page from the data cache |
31 | */ | 31 | */ |
32 | |||
33 | /* | ||
34 | * This flag is used to indicate that the page pointed to by a pte | ||
35 | * is dirty and requires cleaning before returning it to the user. | ||
36 | */ | ||
37 | #define PG_dcache_dirty PG_arch_1 | ||
38 | |||
39 | #define Page_dcache_dirty(page) \ | ||
40 | test_bit(PG_dcache_dirty, &(page)->flags) | ||
41 | #define SetPageDcacheDirty(page) \ | ||
42 | set_bit(PG_dcache_dirty, &(page)->flags) | ||
43 | #define ClearPageDcacheDirty(page) \ | ||
44 | clear_bit(PG_dcache_dirty, &(page)->flags) | ||
45 | |||
32 | extern void (*flush_cache_all)(void); | 46 | extern void (*flush_cache_all)(void); |
33 | extern void (*__flush_cache_all)(void); | 47 | extern void (*__flush_cache_all)(void); |
34 | extern void (*flush_cache_mm)(struct mm_struct *mm); | 48 | extern void (*flush_cache_mm)(struct mm_struct *mm); |
@@ -37,13 +51,15 @@ extern void (*flush_cache_range)(struct vm_area_struct *vma, | |||
37 | unsigned long start, unsigned long end); | 51 | unsigned long start, unsigned long end); |
38 | extern void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page, unsigned long pfn); | 52 | extern void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page, unsigned long pfn); |
39 | extern void __flush_dcache_page(struct page *page); | 53 | extern void __flush_dcache_page(struct page *page); |
54 | extern void __flush_icache_page(struct vm_area_struct *vma, struct page *page); | ||
40 | 55 | ||
41 | #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 | 56 | #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 |
42 | static inline void flush_dcache_page(struct page *page) | 57 | static inline void flush_dcache_page(struct page *page) |
43 | { | 58 | { |
44 | if (cpu_has_dc_aliases || !cpu_has_ic_fills_f_dc) | 59 | if (cpu_has_dc_aliases) |
45 | __flush_dcache_page(page); | 60 | __flush_dcache_page(page); |
46 | 61 | else if (!cpu_has_ic_fills_f_dc) | |
62 | SetPageDcacheDirty(page); | ||
47 | } | 63 | } |
48 | 64 | ||
49 | #define flush_dcache_mmap_lock(mapping) do { } while (0) | 65 | #define flush_dcache_mmap_lock(mapping) do { } while (0) |
@@ -61,6 +77,11 @@ static inline void flush_anon_page(struct vm_area_struct *vma, | |||
61 | static inline void flush_icache_page(struct vm_area_struct *vma, | 77 | static inline void flush_icache_page(struct vm_area_struct *vma, |
62 | struct page *page) | 78 | struct page *page) |
63 | { | 79 | { |
80 | if (!cpu_has_ic_fills_f_dc && (vma->vm_flags & VM_EXEC) && | ||
81 | Page_dcache_dirty(page)) { | ||
82 | __flush_icache_page(vma, page); | ||
83 | ClearPageDcacheDirty(page); | ||
84 | } | ||
64 | } | 85 | } |
65 | 86 | ||
66 | extern void (*flush_icache_range)(unsigned long start, unsigned long end); | 87 | extern void (*flush_icache_range)(unsigned long start, unsigned long end); |
@@ -95,19 +116,6 @@ extern void (*flush_icache_all)(void); | |||
95 | extern void (*local_flush_data_cache_page)(void * addr); | 116 | extern void (*local_flush_data_cache_page)(void * addr); |
96 | extern void (*flush_data_cache_page)(unsigned long addr); | 117 | extern void (*flush_data_cache_page)(unsigned long addr); |
97 | 118 | ||
98 | /* | ||
99 | * This flag is used to indicate that the page pointed to by a pte | ||
100 | * is dirty and requires cleaning before returning it to the user. | ||
101 | */ | ||
102 | #define PG_dcache_dirty PG_arch_1 | ||
103 | |||
104 | #define Page_dcache_dirty(page) \ | ||
105 | test_bit(PG_dcache_dirty, &(page)->flags) | ||
106 | #define SetPageDcacheDirty(page) \ | ||
107 | set_bit(PG_dcache_dirty, &(page)->flags) | ||
108 | #define ClearPageDcacheDirty(page) \ | ||
109 | clear_bit(PG_dcache_dirty, &(page)->flags) | ||
110 | |||
111 | /* Run kernel code uncached, useful for cache probing functions. */ | 119 | /* Run kernel code uncached, useful for cache probing functions. */ |
112 | unsigned long run_uncached(void *func); | 120 | unsigned long run_uncached(void *func); |
113 | 121 | ||
diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h index fc2ad332541c..5aeaf19c26b0 100644 --- a/arch/mips/include/asm/cpu-features.h +++ b/arch/mips/include/asm/cpu-features.h | |||
@@ -140,6 +140,9 @@ | |||
140 | # endif | 140 | # endif |
141 | #endif | 141 | #endif |
142 | 142 | ||
143 | #ifndef cpu_has_xpa | ||
144 | #define cpu_has_xpa (cpu_data[0].options & MIPS_CPU_XPA) | ||
145 | #endif | ||
143 | #ifndef cpu_has_vtag_icache | 146 | #ifndef cpu_has_vtag_icache |
144 | #define cpu_has_vtag_icache (cpu_data[0].icache.flags & MIPS_CACHE_VTAG) | 147 | #define cpu_has_vtag_icache (cpu_data[0].icache.flags & MIPS_CACHE_VTAG) |
145 | #endif | 148 | #endif |
@@ -239,8 +242,39 @@ | |||
239 | /* MIPSR2 and MIPSR6 have a lot of similarities */ | 242 | /* MIPSR2 and MIPSR6 have a lot of similarities */ |
240 | #define cpu_has_mips_r2_r6 (cpu_has_mips_r2 | cpu_has_mips_r6) | 243 | #define cpu_has_mips_r2_r6 (cpu_has_mips_r2 | cpu_has_mips_r6) |
241 | 244 | ||
245 | /* | ||
246 | * cpu_has_mips_r2_exec_hazard - return if IHB is required on current processor | ||
247 | * | ||
248 | * Returns non-zero value if the current processor implementation requires | ||
249 | * an IHB instruction to deal with an instruction hazard as per MIPS R2 | ||
250 | * architecture specification, zero otherwise. | ||
251 | */ | ||
242 | #ifndef cpu_has_mips_r2_exec_hazard | 252 | #ifndef cpu_has_mips_r2_exec_hazard |
243 | #define cpu_has_mips_r2_exec_hazard (cpu_has_mips_r2 | cpu_has_mips_r6) | 253 | #define cpu_has_mips_r2_exec_hazard \ |
254 | ({ \ | ||
255 | int __res; \ | ||
256 | \ | ||
257 | switch (current_cpu_type()) { \ | ||
258 | case CPU_M14KC: \ | ||
259 | case CPU_74K: \ | ||
260 | case CPU_1074K: \ | ||
261 | case CPU_PROAPTIV: \ | ||
262 | case CPU_P5600: \ | ||
263 | case CPU_M5150: \ | ||
264 | case CPU_QEMU_GENERIC: \ | ||
265 | case CPU_CAVIUM_OCTEON: \ | ||
266 | case CPU_CAVIUM_OCTEON_PLUS: \ | ||
267 | case CPU_CAVIUM_OCTEON2: \ | ||
268 | case CPU_CAVIUM_OCTEON3: \ | ||
269 | __res = 0; \ | ||
270 | break; \ | ||
271 | \ | ||
272 | default: \ | ||
273 | __res = 1; \ | ||
274 | } \ | ||
275 | \ | ||
276 | __res; \ | ||
277 | }) | ||
244 | #endif | 278 | #endif |
245 | 279 | ||
246 | /* | 280 | /* |
diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h index fd2e893e9d9f..e3adca1d0b99 100644 --- a/arch/mips/include/asm/cpu.h +++ b/arch/mips/include/asm/cpu.h | |||
@@ -377,7 +377,8 @@ enum cpu_type_enum { | |||
377 | #define MIPS_CPU_MAAR 0x400000000ull /* MAAR(I) registers are present */ | 377 | #define MIPS_CPU_MAAR 0x400000000ull /* MAAR(I) registers are present */ |
378 | #define MIPS_CPU_FRE 0x800000000ull /* FRE & UFE bits implemented */ | 378 | #define MIPS_CPU_FRE 0x800000000ull /* FRE & UFE bits implemented */ |
379 | #define MIPS_CPU_RW_LLB 0x1000000000ull /* LLADDR/LLB writes are allowed */ | 379 | #define MIPS_CPU_RW_LLB 0x1000000000ull /* LLADDR/LLB writes are allowed */ |
380 | #define MIPS_CPU_CDMM 0x2000000000ull /* CPU has Common Device Memory Map */ | 380 | #define MIPS_CPU_XPA 0x2000000000ull /* CPU supports Extended Physical Addressing */ |
381 | #define MIPS_CPU_CDMM 0x4000000000ull /* CPU has Common Device Memory Map */ | ||
381 | 382 | ||
382 | /* | 383 | /* |
383 | * CPU ASE encodings | 384 | * CPU ASE encodings |
diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h index 612cf519bd88..9a74248e7821 100644 --- a/arch/mips/include/asm/elf.h +++ b/arch/mips/include/asm/elf.h | |||
@@ -297,6 +297,9 @@ do { \ | |||
297 | if (personality(current->personality) != PER_LINUX) \ | 297 | if (personality(current->personality) != PER_LINUX) \ |
298 | set_personality(PER_LINUX); \ | 298 | set_personality(PER_LINUX); \ |
299 | \ | 299 | \ |
300 | clear_thread_flag(TIF_HYBRID_FPREGS); \ | ||
301 | set_thread_flag(TIF_32BIT_FPREGS); \ | ||
302 | \ | ||
300 | mips_set_personality_fp(state); \ | 303 | mips_set_personality_fp(state); \ |
301 | \ | 304 | \ |
302 | current->thread.abi = &mips_abi; \ | 305 | current->thread.abi = &mips_abi; \ |
@@ -324,6 +327,8 @@ do { \ | |||
324 | do { \ | 327 | do { \ |
325 | set_thread_flag(TIF_32BIT_REGS); \ | 328 | set_thread_flag(TIF_32BIT_REGS); \ |
326 | set_thread_flag(TIF_32BIT_ADDR); \ | 329 | set_thread_flag(TIF_32BIT_ADDR); \ |
330 | clear_thread_flag(TIF_HYBRID_FPREGS); \ | ||
331 | set_thread_flag(TIF_32BIT_FPREGS); \ | ||
327 | \ | 332 | \ |
328 | mips_set_personality_fp(state); \ | 333 | mips_set_personality_fp(state); \ |
329 | \ | 334 | \ |
diff --git a/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h b/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h index fa1f3cfbae8d..d68e685cde60 100644 --- a/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h | |||
@@ -50,7 +50,6 @@ | |||
50 | #define cpu_has_mips32r2 0 | 50 | #define cpu_has_mips32r2 0 |
51 | #define cpu_has_mips64r1 0 | 51 | #define cpu_has_mips64r1 0 |
52 | #define cpu_has_mips64r2 1 | 52 | #define cpu_has_mips64r2 1 |
53 | #define cpu_has_mips_r2_exec_hazard 0 | ||
54 | #define cpu_has_dsp 0 | 53 | #define cpu_has_dsp 0 |
55 | #define cpu_has_dsp2 0 | 54 | #define cpu_has_dsp2 0 |
56 | #define cpu_has_mipsmt 0 | 55 | #define cpu_has_mipsmt 0 |
diff --git a/arch/mips/include/asm/octeon/pci-octeon.h b/arch/mips/include/asm/octeon/pci-octeon.h index 64ba56a02843..1884609741a8 100644 --- a/arch/mips/include/asm/octeon/pci-octeon.h +++ b/arch/mips/include/asm/octeon/pci-octeon.h | |||
@@ -11,9 +11,6 @@ | |||
11 | 11 | ||
12 | #include <linux/pci.h> | 12 | #include <linux/pci.h> |
13 | 13 | ||
14 | /* Some PCI cards require delays when accessing config space. */ | ||
15 | #define PCI_CONFIG_SPACE_DELAY 10000 | ||
16 | |||
17 | /* | 14 | /* |
18 | * The physical memory base mapped by BAR1. 256MB at the end of the | 15 | * The physical memory base mapped by BAR1. 256MB at the end of the |
19 | * first 4GB. | 16 | * first 4GB. |
diff --git a/arch/mips/include/asm/pgtable-32.h b/arch/mips/include/asm/pgtable-32.h index a6be006b6f75..7d56686c0e62 100644 --- a/arch/mips/include/asm/pgtable-32.h +++ b/arch/mips/include/asm/pgtable-32.h | |||
@@ -105,13 +105,16 @@ static inline void pmd_clear(pmd_t *pmdp) | |||
105 | 105 | ||
106 | #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) | 106 | #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) |
107 | #define pte_page(x) pfn_to_page(pte_pfn(x)) | 107 | #define pte_page(x) pfn_to_page(pte_pfn(x)) |
108 | #define pte_pfn(x) ((unsigned long)((x).pte_high >> 6)) | 108 | #define pte_pfn(x) (((unsigned long)((x).pte_high >> _PFN_SHIFT)) | (unsigned long)((x).pte_low << _PAGE_PRESENT_SHIFT)) |
109 | static inline pte_t | 109 | static inline pte_t |
110 | pfn_pte(unsigned long pfn, pgprot_t prot) | 110 | pfn_pte(unsigned long pfn, pgprot_t prot) |
111 | { | 111 | { |
112 | pte_t pte; | 112 | pte_t pte; |
113 | pte.pte_high = (pfn << 6) | (pgprot_val(prot) & 0x3f); | 113 | |
114 | pte.pte_low = pgprot_val(prot); | 114 | pte.pte_low = (pfn >> _PAGE_PRESENT_SHIFT) | |
115 | (pgprot_val(prot) & ~_PFNX_MASK); | ||
116 | pte.pte_high = (pfn << _PFN_SHIFT) | | ||
117 | (pgprot_val(prot) & ~_PFN_MASK); | ||
115 | return pte; | 118 | return pte; |
116 | } | 119 | } |
117 | 120 | ||
@@ -166,9 +169,9 @@ pfn_pte(unsigned long pfn, pgprot_t prot) | |||
166 | #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) | 169 | #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) |
167 | 170 | ||
168 | /* Swap entries must have VALID and GLOBAL bits cleared. */ | 171 | /* Swap entries must have VALID and GLOBAL bits cleared. */ |
169 | #define __swp_type(x) (((x).val >> 2) & 0x1f) | 172 | #define __swp_type(x) (((x).val >> 4) & 0x1f) |
170 | #define __swp_offset(x) ((x).val >> 7) | 173 | #define __swp_offset(x) ((x).val >> 9) |
171 | #define __swp_entry(type,offset) ((swp_entry_t) { ((type) << 2) | ((offset) << 7) }) | 174 | #define __swp_entry(type,offset) ((swp_entry_t) { ((type) << 4) | ((offset) << 9) }) |
172 | #define __pte_to_swp_entry(pte) ((swp_entry_t) { (pte).pte_high }) | 175 | #define __pte_to_swp_entry(pte) ((swp_entry_t) { (pte).pte_high }) |
173 | #define __swp_entry_to_pte(x) ((pte_t) { 0, (x).val }) | 176 | #define __swp_entry_to_pte(x) ((pte_t) { 0, (x).val }) |
174 | 177 | ||
diff --git a/arch/mips/include/asm/pgtable-bits.h b/arch/mips/include/asm/pgtable-bits.h index 91747c282bb3..18ae5ddef118 100644 --- a/arch/mips/include/asm/pgtable-bits.h +++ b/arch/mips/include/asm/pgtable-bits.h | |||
@@ -37,7 +37,11 @@ | |||
37 | /* | 37 | /* |
38 | * The following bits are implemented by the TLB hardware | 38 | * The following bits are implemented by the TLB hardware |
39 | */ | 39 | */ |
40 | #define _PAGE_GLOBAL_SHIFT 0 | 40 | #define _PAGE_NO_EXEC_SHIFT 0 |
41 | #define _PAGE_NO_EXEC (1 << _PAGE_NO_EXEC_SHIFT) | ||
42 | #define _PAGE_NO_READ_SHIFT (_PAGE_NO_EXEC_SHIFT + 1) | ||
43 | #define _PAGE_NO_READ (1 << _PAGE_NO_READ_SHIFT) | ||
44 | #define _PAGE_GLOBAL_SHIFT (_PAGE_NO_READ_SHIFT + 1) | ||
41 | #define _PAGE_GLOBAL (1 << _PAGE_GLOBAL_SHIFT) | 45 | #define _PAGE_GLOBAL (1 << _PAGE_GLOBAL_SHIFT) |
42 | #define _PAGE_VALID_SHIFT (_PAGE_GLOBAL_SHIFT + 1) | 46 | #define _PAGE_VALID_SHIFT (_PAGE_GLOBAL_SHIFT + 1) |
43 | #define _PAGE_VALID (1 << _PAGE_VALID_SHIFT) | 47 | #define _PAGE_VALID (1 << _PAGE_VALID_SHIFT) |
@@ -49,7 +53,7 @@ | |||
49 | /* | 53 | /* |
50 | * The following bits are implemented in software | 54 | * The following bits are implemented in software |
51 | */ | 55 | */ |
52 | #define _PAGE_PRESENT_SHIFT (_CACHE_SHIFT + 3) | 56 | #define _PAGE_PRESENT_SHIFT (24) |
53 | #define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT) | 57 | #define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT) |
54 | #define _PAGE_READ_SHIFT (_PAGE_PRESENT_SHIFT + 1) | 58 | #define _PAGE_READ_SHIFT (_PAGE_PRESENT_SHIFT + 1) |
55 | #define _PAGE_READ (1 << _PAGE_READ_SHIFT) | 59 | #define _PAGE_READ (1 << _PAGE_READ_SHIFT) |
@@ -62,6 +66,11 @@ | |||
62 | 66 | ||
63 | #define _PFN_SHIFT (PAGE_SHIFT - 12 + _CACHE_SHIFT + 3) | 67 | #define _PFN_SHIFT (PAGE_SHIFT - 12 + _CACHE_SHIFT + 3) |
64 | 68 | ||
69 | /* | ||
70 | * Bits for extended EntryLo0/EntryLo1 registers | ||
71 | */ | ||
72 | #define _PFNX_MASK 0xffffff | ||
73 | |||
65 | #elif defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) | 74 | #elif defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) |
66 | 75 | ||
67 | /* | 76 | /* |
@@ -95,11 +104,7 @@ | |||
95 | 104 | ||
96 | #else | 105 | #else |
97 | /* | 106 | /* |
98 | * When using the RI/XI bit support, we have 13 bits of flags below | 107 | * Below are the "Normal" R4K cases |
99 | * the physical address. The RI/XI bits are placed such that a SRL 5 | ||
100 | * can strip off the software bits, then a ROTR 2 can move the RI/XI | ||
101 | * into bits [63:62]. This also limits physical address to 56 bits, | ||
102 | * which is more than we need right now. | ||
103 | */ | 108 | */ |
104 | 109 | ||
105 | /* | 110 | /* |
@@ -107,38 +112,59 @@ | |||
107 | */ | 112 | */ |
108 | #define _PAGE_PRESENT_SHIFT 0 | 113 | #define _PAGE_PRESENT_SHIFT 0 |
109 | #define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT) | 114 | #define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT) |
110 | #define _PAGE_READ_SHIFT (cpu_has_rixi ? _PAGE_PRESENT_SHIFT : _PAGE_PRESENT_SHIFT + 1) | 115 | /* R2 or later cores check for RI/XI support to determine _PAGE_READ */ |
111 | #define _PAGE_READ ({BUG_ON(cpu_has_rixi); 1 << _PAGE_READ_SHIFT; }) | 116 | #ifdef CONFIG_CPU_MIPSR2 |
117 | #define _PAGE_WRITE_SHIFT (_PAGE_PRESENT_SHIFT + 1) | ||
118 | #define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT) | ||
119 | #else | ||
120 | #define _PAGE_READ_SHIFT (_PAGE_PRESENT_SHIFT + 1) | ||
121 | #define _PAGE_READ (1 << _PAGE_READ_SHIFT) | ||
112 | #define _PAGE_WRITE_SHIFT (_PAGE_READ_SHIFT + 1) | 122 | #define _PAGE_WRITE_SHIFT (_PAGE_READ_SHIFT + 1) |
113 | #define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT) | 123 | #define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT) |
124 | #endif | ||
114 | #define _PAGE_ACCESSED_SHIFT (_PAGE_WRITE_SHIFT + 1) | 125 | #define _PAGE_ACCESSED_SHIFT (_PAGE_WRITE_SHIFT + 1) |
115 | #define _PAGE_ACCESSED (1 << _PAGE_ACCESSED_SHIFT) | 126 | #define _PAGE_ACCESSED (1 << _PAGE_ACCESSED_SHIFT) |
116 | #define _PAGE_MODIFIED_SHIFT (_PAGE_ACCESSED_SHIFT + 1) | 127 | #define _PAGE_MODIFIED_SHIFT (_PAGE_ACCESSED_SHIFT + 1) |
117 | #define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT) | 128 | #define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT) |
118 | 129 | ||
119 | #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT | 130 | #if defined(CONFIG_64BIT) && defined(CONFIG_MIPS_HUGE_TLB_SUPPORT) |
120 | /* huge tlb page */ | 131 | /* Huge TLB page */ |
121 | #define _PAGE_HUGE_SHIFT (_PAGE_MODIFIED_SHIFT + 1) | 132 | #define _PAGE_HUGE_SHIFT (_PAGE_MODIFIED_SHIFT + 1) |
122 | #define _PAGE_HUGE (1 << _PAGE_HUGE_SHIFT) | 133 | #define _PAGE_HUGE (1 << _PAGE_HUGE_SHIFT) |
123 | #define _PAGE_SPLITTING_SHIFT (_PAGE_HUGE_SHIFT + 1) | 134 | #define _PAGE_SPLITTING_SHIFT (_PAGE_HUGE_SHIFT + 1) |
124 | #define _PAGE_SPLITTING (1 << _PAGE_SPLITTING_SHIFT) | 135 | #define _PAGE_SPLITTING (1 << _PAGE_SPLITTING_SHIFT) |
136 | |||
137 | /* Only R2 or newer cores have the XI bit */ | ||
138 | #ifdef CONFIG_CPU_MIPSR2 | ||
139 | #define _PAGE_NO_EXEC_SHIFT (_PAGE_SPLITTING_SHIFT + 1) | ||
125 | #else | 140 | #else |
126 | #define _PAGE_HUGE_SHIFT (_PAGE_MODIFIED_SHIFT) | 141 | #define _PAGE_GLOBAL_SHIFT (_PAGE_SPLITTING_SHIFT + 1) |
127 | #define _PAGE_HUGE ({BUG(); 1; }) /* Dummy value */ | 142 | #define _PAGE_GLOBAL (1 << _PAGE_GLOBAL_SHIFT) |
128 | #define _PAGE_SPLITTING_SHIFT (_PAGE_HUGE_SHIFT) | 143 | #endif /* CONFIG_CPU_MIPSR2 */ |
129 | #define _PAGE_SPLITTING ({BUG(); 1; }) /* Dummy value */ | ||
130 | #endif | ||
131 | 144 | ||
132 | /* Page cannot be executed */ | 145 | #endif /* CONFIG_64BIT && CONFIG_MIPS_HUGE_TLB_SUPPORT */ |
133 | #define _PAGE_NO_EXEC_SHIFT (cpu_has_rixi ? _PAGE_SPLITTING_SHIFT + 1 : _PAGE_SPLITTING_SHIFT) | ||
134 | #define _PAGE_NO_EXEC ({BUG_ON(!cpu_has_rixi); 1 << _PAGE_NO_EXEC_SHIFT; }) | ||
135 | 146 | ||
136 | /* Page cannot be read */ | 147 | #ifdef CONFIG_CPU_MIPSR2 |
137 | #define _PAGE_NO_READ_SHIFT (cpu_has_rixi ? _PAGE_NO_EXEC_SHIFT + 1 : _PAGE_NO_EXEC_SHIFT) | 148 | /* XI - page cannot be executed */ |
138 | #define _PAGE_NO_READ ({BUG_ON(!cpu_has_rixi); 1 << _PAGE_NO_READ_SHIFT; }) | 149 | #ifndef _PAGE_NO_EXEC_SHIFT |
150 | #define _PAGE_NO_EXEC_SHIFT (_PAGE_MODIFIED_SHIFT + 1) | ||
151 | #endif | ||
152 | #define _PAGE_NO_EXEC (cpu_has_rixi ? (1 << _PAGE_NO_EXEC_SHIFT) : 0) | ||
153 | |||
154 | /* RI - page cannot be read */ | ||
155 | #define _PAGE_READ_SHIFT (_PAGE_NO_EXEC_SHIFT + 1) | ||
156 | #define _PAGE_READ (cpu_has_rixi ? 0 : (1 << _PAGE_READ_SHIFT)) | ||
157 | #define _PAGE_NO_READ_SHIFT _PAGE_READ_SHIFT | ||
158 | #define _PAGE_NO_READ (cpu_has_rixi ? (1 << _PAGE_READ_SHIFT) : 0) | ||
139 | 159 | ||
140 | #define _PAGE_GLOBAL_SHIFT (_PAGE_NO_READ_SHIFT + 1) | 160 | #define _PAGE_GLOBAL_SHIFT (_PAGE_NO_READ_SHIFT + 1) |
141 | #define _PAGE_GLOBAL (1 << _PAGE_GLOBAL_SHIFT) | 161 | #define _PAGE_GLOBAL (1 << _PAGE_GLOBAL_SHIFT) |
162 | |||
163 | #else /* !CONFIG_CPU_MIPSR2 */ | ||
164 | #define _PAGE_GLOBAL_SHIFT (_PAGE_MODIFIED_SHIFT + 1) | ||
165 | #define _PAGE_GLOBAL (1 << _PAGE_GLOBAL_SHIFT) | ||
166 | #endif /* CONFIG_CPU_MIPSR2 */ | ||
167 | |||
142 | #define _PAGE_VALID_SHIFT (_PAGE_GLOBAL_SHIFT + 1) | 168 | #define _PAGE_VALID_SHIFT (_PAGE_GLOBAL_SHIFT + 1) |
143 | #define _PAGE_VALID (1 << _PAGE_VALID_SHIFT) | 169 | #define _PAGE_VALID (1 << _PAGE_VALID_SHIFT) |
144 | #define _PAGE_DIRTY_SHIFT (_PAGE_VALID_SHIFT + 1) | 170 | #define _PAGE_DIRTY_SHIFT (_PAGE_VALID_SHIFT + 1) |
@@ -150,18 +176,26 @@ | |||
150 | 176 | ||
151 | #endif /* defined(CONFIG_PHYS_ADDR_T_64BIT && defined(CONFIG_CPU_MIPS32) */ | 177 | #endif /* defined(CONFIG_PHYS_ADDR_T_64BIT && defined(CONFIG_CPU_MIPS32) */ |
152 | 178 | ||
179 | #ifndef _PAGE_NO_EXEC | ||
180 | #define _PAGE_NO_EXEC 0 | ||
181 | #endif | ||
182 | #ifndef _PAGE_NO_READ | ||
183 | #define _PAGE_NO_READ 0 | ||
184 | #endif | ||
185 | |||
153 | #define _PAGE_SILENT_READ _PAGE_VALID | 186 | #define _PAGE_SILENT_READ _PAGE_VALID |
154 | #define _PAGE_SILENT_WRITE _PAGE_DIRTY | 187 | #define _PAGE_SILENT_WRITE _PAGE_DIRTY |
155 | 188 | ||
156 | #define _PFN_MASK (~((1 << (_PFN_SHIFT)) - 1)) | 189 | #define _PFN_MASK (~((1 << (_PFN_SHIFT)) - 1)) |
157 | 190 | ||
158 | #ifndef _PAGE_NO_READ | 191 | /* |
159 | #define _PAGE_NO_READ ({BUG(); 0; }) | 192 | * The final layouts of the PTE bits are: |
160 | #define _PAGE_NO_READ_SHIFT ({BUG(); 0; }) | 193 | * |
161 | #endif | 194 | * 64-bit, R1 or earlier: CCC D V G [S H] M A W R P |
162 | #ifndef _PAGE_NO_EXEC | 195 | * 32-bit, R1 or earler: CCC D V G M A W R P |
163 | #define _PAGE_NO_EXEC ({BUG(); 0; }) | 196 | * 64-bit, R2 or later: CCC D V G RI/R XI [S H] M A W P |
164 | #endif | 197 | * 32-bit, R2 or later: CCC D V G RI/R XI M A W P |
198 | */ | ||
165 | 199 | ||
166 | 200 | ||
167 | #ifndef __ASSEMBLY__ | 201 | #ifndef __ASSEMBLY__ |
@@ -171,6 +205,7 @@ | |||
171 | */ | 205 | */ |
172 | static inline uint64_t pte_to_entrylo(unsigned long pte_val) | 206 | static inline uint64_t pte_to_entrylo(unsigned long pte_val) |
173 | { | 207 | { |
208 | #ifdef CONFIG_CPU_MIPSR2 | ||
174 | if (cpu_has_rixi) { | 209 | if (cpu_has_rixi) { |
175 | int sa; | 210 | int sa; |
176 | #ifdef CONFIG_32BIT | 211 | #ifdef CONFIG_32BIT |
@@ -186,6 +221,7 @@ static inline uint64_t pte_to_entrylo(unsigned long pte_val) | |||
186 | return (pte_val >> _PAGE_GLOBAL_SHIFT) | | 221 | return (pte_val >> _PAGE_GLOBAL_SHIFT) | |
187 | ((pte_val & (_PAGE_NO_EXEC | _PAGE_NO_READ)) << sa); | 222 | ((pte_val & (_PAGE_NO_EXEC | _PAGE_NO_READ)) << sa); |
188 | } | 223 | } |
224 | #endif | ||
189 | 225 | ||
190 | return pte_val >> _PAGE_GLOBAL_SHIFT; | 226 | return pte_val >> _PAGE_GLOBAL_SHIFT; |
191 | } | 227 | } |
@@ -245,7 +281,7 @@ static inline uint64_t pte_to_entrylo(unsigned long pte_val) | |||
245 | #define _CACHE_UNCACHED_ACCELERATED (7<<_CACHE_SHIFT) | 281 | #define _CACHE_UNCACHED_ACCELERATED (7<<_CACHE_SHIFT) |
246 | #endif | 282 | #endif |
247 | 283 | ||
248 | #define __READABLE (_PAGE_SILENT_READ | _PAGE_ACCESSED | (cpu_has_rixi ? 0 : _PAGE_READ)) | 284 | #define __READABLE (_PAGE_SILENT_READ | _PAGE_READ | _PAGE_ACCESSED) |
249 | #define __WRITEABLE (_PAGE_SILENT_WRITE | _PAGE_WRITE | _PAGE_MODIFIED) | 285 | #define __WRITEABLE (_PAGE_SILENT_WRITE | _PAGE_WRITE | _PAGE_MODIFIED) |
250 | 286 | ||
251 | #define _PAGE_CHG_MASK (_PAGE_ACCESSED | _PAGE_MODIFIED | \ | 287 | #define _PAGE_CHG_MASK (_PAGE_ACCESSED | _PAGE_MODIFIED | \ |
diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h index bef782c4a44b..819af9d057a8 100644 --- a/arch/mips/include/asm/pgtable.h +++ b/arch/mips/include/asm/pgtable.h | |||
@@ -24,17 +24,17 @@ struct mm_struct; | |||
24 | struct vm_area_struct; | 24 | struct vm_area_struct; |
25 | 25 | ||
26 | #define PAGE_NONE __pgprot(_PAGE_PRESENT | _CACHE_CACHABLE_NONCOHERENT) | 26 | #define PAGE_NONE __pgprot(_PAGE_PRESENT | _CACHE_CACHABLE_NONCOHERENT) |
27 | #define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_WRITE | (cpu_has_rixi ? 0 : _PAGE_READ) | \ | 27 | #define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_WRITE | _PAGE_READ | \ |
28 | _page_cachable_default) | 28 | _page_cachable_default) |
29 | #define PAGE_COPY __pgprot(_PAGE_PRESENT | (cpu_has_rixi ? 0 : _PAGE_READ) | \ | 29 | #define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_NO_EXEC | \ |
30 | (cpu_has_rixi ? _PAGE_NO_EXEC : 0) | _page_cachable_default) | 30 | _page_cachable_default) |
31 | #define PAGE_READONLY __pgprot(_PAGE_PRESENT | (cpu_has_rixi ? 0 : _PAGE_READ) | \ | 31 | #define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_READ | \ |
32 | _page_cachable_default) | 32 | _page_cachable_default) |
33 | #define PAGE_KERNEL __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \ | 33 | #define PAGE_KERNEL __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \ |
34 | _PAGE_GLOBAL | _page_cachable_default) | 34 | _PAGE_GLOBAL | _page_cachable_default) |
35 | #define PAGE_KERNEL_NC __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \ | 35 | #define PAGE_KERNEL_NC __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \ |
36 | _PAGE_GLOBAL | _CACHE_CACHABLE_NONCOHERENT) | 36 | _PAGE_GLOBAL | _CACHE_CACHABLE_NONCOHERENT) |
37 | #define PAGE_USERIO __pgprot(_PAGE_PRESENT | (cpu_has_rixi ? 0 : _PAGE_READ) | _PAGE_WRITE | \ | 37 | #define PAGE_USERIO __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \ |
38 | _page_cachable_default) | 38 | _page_cachable_default) |
39 | #define PAGE_KERNEL_UNCACHED __pgprot(_PAGE_PRESENT | __READABLE | \ | 39 | #define PAGE_KERNEL_UNCACHED __pgprot(_PAGE_PRESENT | __READABLE | \ |
40 | __WRITEABLE | _PAGE_GLOBAL | _CACHE_UNCACHED) | 40 | __WRITEABLE | _PAGE_GLOBAL | _CACHE_UNCACHED) |
@@ -127,13 +127,9 @@ do { \ | |||
127 | } \ | 127 | } \ |
128 | } while(0) | 128 | } while(0) |
129 | 129 | ||
130 | |||
131 | extern void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, | ||
132 | pte_t pteval); | ||
133 | |||
134 | #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) | 130 | #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) |
135 | 131 | ||
136 | #define pte_none(pte) (!(((pte).pte_low | (pte).pte_high) & ~_PAGE_GLOBAL)) | 132 | #define pte_none(pte) (!(((pte).pte_high) & ~_PAGE_GLOBAL)) |
137 | #define pte_present(pte) ((pte).pte_low & _PAGE_PRESENT) | 133 | #define pte_present(pte) ((pte).pte_low & _PAGE_PRESENT) |
138 | 134 | ||
139 | static inline void set_pte(pte_t *ptep, pte_t pte) | 135 | static inline void set_pte(pte_t *ptep, pte_t pte) |
@@ -142,18 +138,17 @@ static inline void set_pte(pte_t *ptep, pte_t pte) | |||
142 | smp_wmb(); | 138 | smp_wmb(); |
143 | ptep->pte_low = pte.pte_low; | 139 | ptep->pte_low = pte.pte_low; |
144 | 140 | ||
145 | if (pte.pte_low & _PAGE_GLOBAL) { | 141 | if (pte.pte_high & _PAGE_GLOBAL) { |
146 | pte_t *buddy = ptep_buddy(ptep); | 142 | pte_t *buddy = ptep_buddy(ptep); |
147 | /* | 143 | /* |
148 | * Make sure the buddy is global too (if it's !none, | 144 | * Make sure the buddy is global too (if it's !none, |
149 | * it better already be global) | 145 | * it better already be global) |
150 | */ | 146 | */ |
151 | if (pte_none(*buddy)) { | 147 | if (pte_none(*buddy)) |
152 | buddy->pte_low |= _PAGE_GLOBAL; | ||
153 | buddy->pte_high |= _PAGE_GLOBAL; | 148 | buddy->pte_high |= _PAGE_GLOBAL; |
154 | } | ||
155 | } | 149 | } |
156 | } | 150 | } |
151 | #define set_pte_at(mm, addr, ptep, pteval) set_pte(ptep, pteval) | ||
157 | 152 | ||
158 | static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) | 153 | static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) |
159 | { | 154 | { |
@@ -161,8 +156,8 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *pt | |||
161 | 156 | ||
162 | htw_stop(); | 157 | htw_stop(); |
163 | /* Preserve global status for the pair */ | 158 | /* Preserve global status for the pair */ |
164 | if (ptep_buddy(ptep)->pte_low & _PAGE_GLOBAL) | 159 | if (ptep_buddy(ptep)->pte_high & _PAGE_GLOBAL) |
165 | null.pte_low = null.pte_high = _PAGE_GLOBAL; | 160 | null.pte_high = _PAGE_GLOBAL; |
166 | 161 | ||
167 | set_pte_at(mm, addr, ptep, null); | 162 | set_pte_at(mm, addr, ptep, null); |
168 | htw_start(); | 163 | htw_start(); |
@@ -192,6 +187,7 @@ static inline void set_pte(pte_t *ptep, pte_t pteval) | |||
192 | } | 187 | } |
193 | #endif | 188 | #endif |
194 | } | 189 | } |
190 | #define set_pte_at(mm, addr, ptep, pteval) set_pte(ptep, pteval) | ||
195 | 191 | ||
196 | static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) | 192 | static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) |
197 | { | 193 | { |
@@ -242,21 +238,21 @@ static inline int pte_young(pte_t pte) { return pte.pte_low & _PAGE_ACCESSED; } | |||
242 | 238 | ||
243 | static inline pte_t pte_wrprotect(pte_t pte) | 239 | static inline pte_t pte_wrprotect(pte_t pte) |
244 | { | 240 | { |
245 | pte.pte_low &= ~(_PAGE_WRITE | _PAGE_SILENT_WRITE); | 241 | pte.pte_low &= ~_PAGE_WRITE; |
246 | pte.pte_high &= ~_PAGE_SILENT_WRITE; | 242 | pte.pte_high &= ~_PAGE_SILENT_WRITE; |
247 | return pte; | 243 | return pte; |
248 | } | 244 | } |
249 | 245 | ||
250 | static inline pte_t pte_mkclean(pte_t pte) | 246 | static inline pte_t pte_mkclean(pte_t pte) |
251 | { | 247 | { |
252 | pte.pte_low &= ~(_PAGE_MODIFIED | _PAGE_SILENT_WRITE); | 248 | pte.pte_low &= ~_PAGE_MODIFIED; |
253 | pte.pte_high &= ~_PAGE_SILENT_WRITE; | 249 | pte.pte_high &= ~_PAGE_SILENT_WRITE; |
254 | return pte; | 250 | return pte; |
255 | } | 251 | } |
256 | 252 | ||
257 | static inline pte_t pte_mkold(pte_t pte) | 253 | static inline pte_t pte_mkold(pte_t pte) |
258 | { | 254 | { |
259 | pte.pte_low &= ~(_PAGE_ACCESSED | _PAGE_SILENT_READ); | 255 | pte.pte_low &= ~_PAGE_ACCESSED; |
260 | pte.pte_high &= ~_PAGE_SILENT_READ; | 256 | pte.pte_high &= ~_PAGE_SILENT_READ; |
261 | return pte; | 257 | return pte; |
262 | } | 258 | } |
@@ -264,30 +260,24 @@ static inline pte_t pte_mkold(pte_t pte) | |||
264 | static inline pte_t pte_mkwrite(pte_t pte) | 260 | static inline pte_t pte_mkwrite(pte_t pte) |
265 | { | 261 | { |
266 | pte.pte_low |= _PAGE_WRITE; | 262 | pte.pte_low |= _PAGE_WRITE; |
267 | if (pte.pte_low & _PAGE_MODIFIED) { | 263 | if (pte.pte_low & _PAGE_MODIFIED) |
268 | pte.pte_low |= _PAGE_SILENT_WRITE; | ||
269 | pte.pte_high |= _PAGE_SILENT_WRITE; | 264 | pte.pte_high |= _PAGE_SILENT_WRITE; |
270 | } | ||
271 | return pte; | 265 | return pte; |
272 | } | 266 | } |
273 | 267 | ||
274 | static inline pte_t pte_mkdirty(pte_t pte) | 268 | static inline pte_t pte_mkdirty(pte_t pte) |
275 | { | 269 | { |
276 | pte.pte_low |= _PAGE_MODIFIED; | 270 | pte.pte_low |= _PAGE_MODIFIED; |
277 | if (pte.pte_low & _PAGE_WRITE) { | 271 | if (pte.pte_low & _PAGE_WRITE) |
278 | pte.pte_low |= _PAGE_SILENT_WRITE; | ||
279 | pte.pte_high |= _PAGE_SILENT_WRITE; | 272 | pte.pte_high |= _PAGE_SILENT_WRITE; |
280 | } | ||
281 | return pte; | 273 | return pte; |
282 | } | 274 | } |
283 | 275 | ||
284 | static inline pte_t pte_mkyoung(pte_t pte) | 276 | static inline pte_t pte_mkyoung(pte_t pte) |
285 | { | 277 | { |
286 | pte.pte_low |= _PAGE_ACCESSED; | 278 | pte.pte_low |= _PAGE_ACCESSED; |
287 | if (pte.pte_low & _PAGE_READ) { | 279 | if (pte.pte_low & _PAGE_READ) |
288 | pte.pte_low |= _PAGE_SILENT_READ; | ||
289 | pte.pte_high |= _PAGE_SILENT_READ; | 280 | pte.pte_high |= _PAGE_SILENT_READ; |
290 | } | ||
291 | return pte; | 281 | return pte; |
292 | } | 282 | } |
293 | #else | 283 | #else |
@@ -332,13 +322,13 @@ static inline pte_t pte_mkdirty(pte_t pte) | |||
332 | static inline pte_t pte_mkyoung(pte_t pte) | 322 | static inline pte_t pte_mkyoung(pte_t pte) |
333 | { | 323 | { |
334 | pte_val(pte) |= _PAGE_ACCESSED; | 324 | pte_val(pte) |= _PAGE_ACCESSED; |
335 | if (cpu_has_rixi) { | 325 | #ifdef CONFIG_CPU_MIPSR2 |
336 | if (!(pte_val(pte) & _PAGE_NO_READ)) | 326 | if (!(pte_val(pte) & _PAGE_NO_READ)) |
337 | pte_val(pte) |= _PAGE_SILENT_READ; | 327 | pte_val(pte) |= _PAGE_SILENT_READ; |
338 | } else { | 328 | else |
339 | if (pte_val(pte) & _PAGE_READ) | 329 | #endif |
340 | pte_val(pte) |= _PAGE_SILENT_READ; | 330 | if (pte_val(pte) & _PAGE_READ) |
341 | } | 331 | pte_val(pte) |= _PAGE_SILENT_READ; |
342 | return pte; | 332 | return pte; |
343 | } | 333 | } |
344 | 334 | ||
@@ -391,10 +381,10 @@ static inline pgprot_t pgprot_writecombine(pgprot_t _prot) | |||
391 | #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) | 381 | #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) |
392 | static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) | 382 | static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) |
393 | { | 383 | { |
394 | pte.pte_low &= _PAGE_CHG_MASK; | 384 | pte.pte_low &= (_PAGE_MODIFIED | _PAGE_ACCESSED | _PFNX_MASK); |
395 | pte.pte_high &= (_PFN_MASK | _CACHE_MASK); | 385 | pte.pte_high &= (_PFN_MASK | _CACHE_MASK); |
396 | pte.pte_low |= pgprot_val(newprot); | 386 | pte.pte_low |= pgprot_val(newprot) & ~_PFNX_MASK; |
397 | pte.pte_high |= pgprot_val(newprot) & ~(_PFN_MASK | _CACHE_MASK); | 387 | pte.pte_high |= pgprot_val(newprot) & ~_PFN_MASK; |
398 | return pte; | 388 | return pte; |
399 | } | 389 | } |
400 | #else | 390 | #else |
@@ -407,12 +397,15 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) | |||
407 | 397 | ||
408 | extern void __update_tlb(struct vm_area_struct *vma, unsigned long address, | 398 | extern void __update_tlb(struct vm_area_struct *vma, unsigned long address, |
409 | pte_t pte); | 399 | pte_t pte); |
400 | extern void __update_cache(struct vm_area_struct *vma, unsigned long address, | ||
401 | pte_t pte); | ||
410 | 402 | ||
411 | static inline void update_mmu_cache(struct vm_area_struct *vma, | 403 | static inline void update_mmu_cache(struct vm_area_struct *vma, |
412 | unsigned long address, pte_t *ptep) | 404 | unsigned long address, pte_t *ptep) |
413 | { | 405 | { |
414 | pte_t pte = *ptep; | 406 | pte_t pte = *ptep; |
415 | __update_tlb(vma, address, pte); | 407 | __update_tlb(vma, address, pte); |
408 | __update_cache(vma, address, pte); | ||
416 | } | 409 | } |
417 | 410 | ||
418 | static inline void update_mmu_cache_pmd(struct vm_area_struct *vma, | 411 | static inline void update_mmu_cache_pmd(struct vm_area_struct *vma, |
@@ -534,13 +527,13 @@ static inline pmd_t pmd_mkyoung(pmd_t pmd) | |||
534 | { | 527 | { |
535 | pmd_val(pmd) |= _PAGE_ACCESSED; | 528 | pmd_val(pmd) |= _PAGE_ACCESSED; |
536 | 529 | ||
537 | if (cpu_has_rixi) { | 530 | #ifdef CONFIG_CPU_MIPSR2 |
538 | if (!(pmd_val(pmd) & _PAGE_NO_READ)) | 531 | if (!(pmd_val(pmd) & _PAGE_NO_READ)) |
539 | pmd_val(pmd) |= _PAGE_SILENT_READ; | 532 | pmd_val(pmd) |= _PAGE_SILENT_READ; |
540 | } else { | 533 | else |
541 | if (pmd_val(pmd) & _PAGE_READ) | 534 | #endif |
542 | pmd_val(pmd) |= _PAGE_SILENT_READ; | 535 | if (pmd_val(pmd) & _PAGE_READ) |
543 | } | 536 | pmd_val(pmd) |= _PAGE_SILENT_READ; |
544 | 537 | ||
545 | return pmd; | 538 | return pmd; |
546 | } | 539 | } |
diff --git a/arch/mips/include/asm/r4kcache.h b/arch/mips/include/asm/r4kcache.h index 1b22d2da88a1..38902bf97adc 100644 --- a/arch/mips/include/asm/r4kcache.h +++ b/arch/mips/include/asm/r4kcache.h | |||
@@ -12,6 +12,8 @@ | |||
12 | #ifndef _ASM_R4KCACHE_H | 12 | #ifndef _ASM_R4KCACHE_H |
13 | #define _ASM_R4KCACHE_H | 13 | #define _ASM_R4KCACHE_H |
14 | 14 | ||
15 | #include <linux/stringify.h> | ||
16 | |||
15 | #include <asm/asm.h> | 17 | #include <asm/asm.h> |
16 | #include <asm/cacheops.h> | 18 | #include <asm/cacheops.h> |
17 | #include <asm/compiler.h> | 19 | #include <asm/compiler.h> |
@@ -344,7 +346,7 @@ static inline void invalidate_tcache_page(unsigned long addr) | |||
344 | " cache %1, 0x0a0(%0); cache %1, 0x0b0(%0)\n" \ | 346 | " cache %1, 0x0a0(%0); cache %1, 0x0b0(%0)\n" \ |
345 | " cache %1, 0x0c0(%0); cache %1, 0x0d0(%0)\n" \ | 347 | " cache %1, 0x0c0(%0); cache %1, 0x0d0(%0)\n" \ |
346 | " cache %1, 0x0e0(%0); cache %1, 0x0f0(%0)\n" \ | 348 | " cache %1, 0x0e0(%0); cache %1, 0x0f0(%0)\n" \ |
347 | " addiu $1, $0, 0x100 \n" \ | 349 | " "__stringify(LONG_ADDIU)" $1, %0, 0x100 \n" \ |
348 | " cache %1, 0x000($1); cache %1, 0x010($1)\n" \ | 350 | " cache %1, 0x000($1); cache %1, 0x010($1)\n" \ |
349 | " cache %1, 0x020($1); cache %1, 0x030($1)\n" \ | 351 | " cache %1, 0x020($1); cache %1, 0x030($1)\n" \ |
350 | " cache %1, 0x040($1); cache %1, 0x050($1)\n" \ | 352 | " cache %1, 0x040($1); cache %1, 0x050($1)\n" \ |
@@ -368,17 +370,17 @@ static inline void invalidate_tcache_page(unsigned long addr) | |||
368 | " cache %1, 0x040(%0); cache %1, 0x060(%0)\n" \ | 370 | " cache %1, 0x040(%0); cache %1, 0x060(%0)\n" \ |
369 | " cache %1, 0x080(%0); cache %1, 0x0a0(%0)\n" \ | 371 | " cache %1, 0x080(%0); cache %1, 0x0a0(%0)\n" \ |
370 | " cache %1, 0x0c0(%0); cache %1, 0x0e0(%0)\n" \ | 372 | " cache %1, 0x0c0(%0); cache %1, 0x0e0(%0)\n" \ |
371 | " addiu $1, %0, 0x100\n" \ | 373 | " "__stringify(LONG_ADDIU)" $1, %0, 0x100 \n" \ |
372 | " cache %1, 0x000($1); cache %1, 0x020($1)\n" \ | 374 | " cache %1, 0x000($1); cache %1, 0x020($1)\n" \ |
373 | " cache %1, 0x040($1); cache %1, 0x060($1)\n" \ | 375 | " cache %1, 0x040($1); cache %1, 0x060($1)\n" \ |
374 | " cache %1, 0x080($1); cache %1, 0x0a0($1)\n" \ | 376 | " cache %1, 0x080($1); cache %1, 0x0a0($1)\n" \ |
375 | " cache %1, 0x0c0($1); cache %1, 0x0e0($1)\n" \ | 377 | " cache %1, 0x0c0($1); cache %1, 0x0e0($1)\n" \ |
376 | " addiu $1, $1, 0x100\n" \ | 378 | " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \ |
377 | " cache %1, 0x000($1); cache %1, 0x020($1)\n" \ | 379 | " cache %1, 0x000($1); cache %1, 0x020($1)\n" \ |
378 | " cache %1, 0x040($1); cache %1, 0x060($1)\n" \ | 380 | " cache %1, 0x040($1); cache %1, 0x060($1)\n" \ |
379 | " cache %1, 0x080($1); cache %1, 0x0a0($1)\n" \ | 381 | " cache %1, 0x080($1); cache %1, 0x0a0($1)\n" \ |
380 | " cache %1, 0x0c0($1); cache %1, 0x0e0($1)\n" \ | 382 | " cache %1, 0x0c0($1); cache %1, 0x0e0($1)\n" \ |
381 | " addiu $1, $1, 0x100\n" \ | 383 | " "__stringify(LONG_ADDIU)" $1, $1, 0x100\n" \ |
382 | " cache %1, 0x000($1); cache %1, 0x020($1)\n" \ | 384 | " cache %1, 0x000($1); cache %1, 0x020($1)\n" \ |
383 | " cache %1, 0x040($1); cache %1, 0x060($1)\n" \ | 385 | " cache %1, 0x040($1); cache %1, 0x060($1)\n" \ |
384 | " cache %1, 0x080($1); cache %1, 0x0a0($1)\n" \ | 386 | " cache %1, 0x080($1); cache %1, 0x0a0($1)\n" \ |
@@ -396,25 +398,25 @@ static inline void invalidate_tcache_page(unsigned long addr) | |||
396 | " .set noat\n" \ | 398 | " .set noat\n" \ |
397 | " cache %1, 0x000(%0); cache %1, 0x040(%0)\n" \ | 399 | " cache %1, 0x000(%0); cache %1, 0x040(%0)\n" \ |
398 | " cache %1, 0x080(%0); cache %1, 0x0c0(%0)\n" \ | 400 | " cache %1, 0x080(%0); cache %1, 0x0c0(%0)\n" \ |
399 | " addiu $1, %0, 0x100\n" \ | 401 | " "__stringify(LONG_ADDIU)" $1, %0, 0x100 \n" \ |
400 | " cache %1, 0x000($1); cache %1, 0x040($1)\n" \ | 402 | " cache %1, 0x000($1); cache %1, 0x040($1)\n" \ |
401 | " cache %1, 0x080($1); cache %1, 0x0c0($1)\n" \ | 403 | " cache %1, 0x080($1); cache %1, 0x0c0($1)\n" \ |
402 | " addiu $1, %0, 0x100\n" \ | 404 | " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \ |
403 | " cache %1, 0x000($1); cache %1, 0x040($1)\n" \ | 405 | " cache %1, 0x000($1); cache %1, 0x040($1)\n" \ |
404 | " cache %1, 0x080($1); cache %1, 0x0c0($1)\n" \ | 406 | " cache %1, 0x080($1); cache %1, 0x0c0($1)\n" \ |
405 | " addiu $1, %0, 0x100\n" \ | 407 | " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \ |
406 | " cache %1, 0x000($1); cache %1, 0x040($1)\n" \ | 408 | " cache %1, 0x000($1); cache %1, 0x040($1)\n" \ |
407 | " cache %1, 0x080($1); cache %1, 0x0c0($1)\n" \ | 409 | " cache %1, 0x080($1); cache %1, 0x0c0($1)\n" \ |
408 | " addiu $1, %0, 0x100\n" \ | 410 | " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \ |
409 | " cache %1, 0x000($1); cache %1, 0x040($1)\n" \ | 411 | " cache %1, 0x000($1); cache %1, 0x040($1)\n" \ |
410 | " cache %1, 0x080($1); cache %1, 0x0c0($1)\n" \ | 412 | " cache %1, 0x080($1); cache %1, 0x0c0($1)\n" \ |
411 | " addiu $1, %0, 0x100\n" \ | 413 | " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \ |
412 | " cache %1, 0x000($1); cache %1, 0x040($1)\n" \ | 414 | " cache %1, 0x000($1); cache %1, 0x040($1)\n" \ |
413 | " cache %1, 0x080($1); cache %1, 0x0c0($1)\n" \ | 415 | " cache %1, 0x080($1); cache %1, 0x0c0($1)\n" \ |
414 | " addiu $1, %0, 0x100\n" \ | 416 | " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \ |
415 | " cache %1, 0x000($1); cache %1, 0x040($1)\n" \ | 417 | " cache %1, 0x000($1); cache %1, 0x040($1)\n" \ |
416 | " cache %1, 0x080($1); cache %1, 0x0c0($1)\n" \ | 418 | " cache %1, 0x080($1); cache %1, 0x0c0($1)\n" \ |
417 | " addiu $1, %0, 0x100\n" \ | 419 | " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \ |
418 | " cache %1, 0x000($1); cache %1, 0x040($1)\n" \ | 420 | " cache %1, 0x000($1); cache %1, 0x040($1)\n" \ |
419 | " cache %1, 0x080($1); cache %1, 0x0c0($1)\n" \ | 421 | " cache %1, 0x080($1); cache %1, 0x0c0($1)\n" \ |
420 | " .set pop\n" \ | 422 | " .set pop\n" \ |
@@ -429,39 +431,38 @@ static inline void invalidate_tcache_page(unsigned long addr) | |||
429 | " .set mips64r6\n" \ | 431 | " .set mips64r6\n" \ |
430 | " .set noat\n" \ | 432 | " .set noat\n" \ |
431 | " cache %1, 0x000(%0); cache %1, 0x080(%0)\n" \ | 433 | " cache %1, 0x000(%0); cache %1, 0x080(%0)\n" \ |
432 | " addiu $1, %0, 0x100\n" \ | 434 | " "__stringify(LONG_ADDIU)" $1, %0, 0x100 \n" \ |
433 | " cache %1, 0x000(%0); cache %1, 0x080(%0)\n" \ | 435 | " cache %1, 0x000($1); cache %1, 0x080($1)\n" \ |
434 | " addiu $1, %0, 0x100\n" \ | 436 | " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \ |
435 | " cache %1, 0x000(%0); cache %1, 0x080(%0)\n" \ | 437 | " cache %1, 0x000($1); cache %1, 0x080($1)\n" \ |
436 | " addiu $1, %0, 0x100\n" \ | 438 | " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \ |
437 | " cache %1, 0x000(%0); cache %1, 0x080(%0)\n" \ | 439 | " cache %1, 0x000($1); cache %1, 0x080($1)\n" \ |
438 | " addiu $1, %0, 0x100\n" \ | 440 | " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \ |
439 | " cache %1, 0x000(%0); cache %1, 0x080(%0)\n" \ | 441 | " cache %1, 0x000($1); cache %1, 0x080($1)\n" \ |
440 | " addiu $1, %0, 0x100\n" \ | 442 | " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \ |
441 | " cache %1, 0x000(%0); cache %1, 0x080(%0)\n" \ | 443 | " cache %1, 0x000($1); cache %1, 0x080($1)\n" \ |
442 | " addiu $1, %0, 0x100\n" \ | 444 | " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \ |
443 | " cache %1, 0x000(%0); cache %1, 0x080(%0)\n" \ | 445 | " cache %1, 0x000($1); cache %1, 0x080($1)\n" \ |
444 | " addiu $1, %0, 0x100\n" \ | 446 | " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \ |
445 | " cache %1, 0x000(%0); cache %1, 0x080(%0)\n" \ | 447 | " cache %1, 0x000($1); cache %1, 0x080($1)\n" \ |
446 | " addiu $1, %0, 0x100\n" \ | 448 | " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \ |
447 | " cache %1, 0x000(%0); cache %1, 0x080(%0)\n" \ | 449 | " cache %1, 0x000($1); cache %1, 0x080($1)\n" \ |
448 | " addiu $1, %0, 0x100\n" \ | 450 | " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \ |
449 | " cache %1, 0x000(%0); cache %1, 0x080(%0)\n" \ | 451 | " cache %1, 0x000($1); cache %1, 0x080($1)\n" \ |
450 | " addiu $1, %0, 0x100\n" \ | 452 | " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \ |
451 | " cache %1, 0x000(%0); cache %1, 0x080(%0)\n" \ | 453 | " cache %1, 0x000($1); cache %1, 0x080($1)\n" \ |
452 | " addiu $1, %0, 0x100\n" \ | 454 | " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \ |
453 | " cache %1, 0x000(%0); cache %1, 0x080(%0)\n" \ | 455 | " cache %1, 0x000($1); cache %1, 0x080($1)\n" \ |
454 | " addiu $1, %0, 0x100\n" \ | 456 | " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \ |
455 | " cache %1, 0x000(%0); cache %1, 0x080(%0)\n" \ | 457 | " cache %1, 0x000($1); cache %1, 0x080($1)\n" \ |
456 | " addiu $1, %0, 0x100\n" \ | 458 | " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \ |
457 | " cache %1, 0x000(%0); cache %1, 0x080(%0)\n" \ | 459 | " cache %1, 0x000($1); cache %1, 0x080($1)\n" \ |
458 | " addiu $1, %0, 0x100\n" \ | 460 | " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \ |
459 | " cache %1, 0x000(%0); cache %1, 0x080(%0)\n" \ | 461 | " cache %1, 0x000($1); cache %1, 0x080($1)\n" \ |
460 | " addiu $1, %0, 0x100\n" \ | 462 | " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \ |
461 | " cache %1, 0x000(%0); cache %1, 0x080(%0)\n" \ | 463 | " cache %1, 0x000($1); cache %1, 0x080($1)\n" \ |
462 | " addiu $1, %0, 0x100\n" \ | 464 | " "__stringify(LONG_ADDIU)" $1, $1, 0x100 \n" \ |
463 | " cache %1, 0x000(%0); cache %1, 0x080(%0)\n" \ | 465 | " cache %1, 0x000($1); cache %1, 0x080($1)\n" \ |
464 | " addiu $1, %0, 0x100\n" \ | ||
465 | " .set pop\n" \ | 466 | " .set pop\n" \ |
466 | : \ | 467 | : \ |
467 | : "r" (base), \ | 468 | : "r" (base), \ |
diff --git a/arch/mips/include/asm/spinlock.h b/arch/mips/include/asm/spinlock.h index b4548690ade9..1fca2e0793dc 100644 --- a/arch/mips/include/asm/spinlock.h +++ b/arch/mips/include/asm/spinlock.h | |||
@@ -263,7 +263,7 @@ static inline void arch_read_unlock(arch_rwlock_t *rw) | |||
263 | if (R10000_LLSC_WAR) { | 263 | if (R10000_LLSC_WAR) { |
264 | __asm__ __volatile__( | 264 | __asm__ __volatile__( |
265 | "1: ll %1, %2 # arch_read_unlock \n" | 265 | "1: ll %1, %2 # arch_read_unlock \n" |
266 | " addiu %1, 1 \n" | 266 | " addiu %1, -1 \n" |
267 | " sc %1, %0 \n" | 267 | " sc %1, %0 \n" |
268 | " beqzl %1, 1b \n" | 268 | " beqzl %1, 1b \n" |
269 | : "=" GCC_OFF_SMALL_ASM() (rw->lock), "=&r" (tmp) | 269 | : "=" GCC_OFF_SMALL_ASM() (rw->lock), "=&r" (tmp) |
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index 73ab840f13bd..e36515dcd3b2 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c | |||
@@ -600,6 +600,10 @@ static inline unsigned int decode_config5(struct cpuinfo_mips *c) | |||
600 | c->options |= MIPS_CPU_MAAR; | 600 | c->options |= MIPS_CPU_MAAR; |
601 | if (config5 & MIPS_CONF5_LLB) | 601 | if (config5 & MIPS_CONF5_LLB) |
602 | c->options |= MIPS_CPU_RW_LLB; | 602 | c->options |= MIPS_CPU_RW_LLB; |
603 | #ifdef CONFIG_XPA | ||
604 | if (config5 & MIPS_CONF5_MVH) | ||
605 | c->options |= MIPS_CPU_XPA; | ||
606 | #endif | ||
603 | 607 | ||
604 | return config5 & MIPS_CONF_M; | 608 | return config5 & MIPS_CONF_M; |
605 | } | 609 | } |
diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S index af41ba6db960..7791840cf22c 100644 --- a/arch/mips/kernel/entry.S +++ b/arch/mips/kernel/entry.S | |||
@@ -10,6 +10,7 @@ | |||
10 | 10 | ||
11 | #include <asm/asm.h> | 11 | #include <asm/asm.h> |
12 | #include <asm/asmmacro.h> | 12 | #include <asm/asmmacro.h> |
13 | #include <asm/compiler.h> | ||
13 | #include <asm/regdef.h> | 14 | #include <asm/regdef.h> |
14 | #include <asm/mipsregs.h> | 15 | #include <asm/mipsregs.h> |
15 | #include <asm/stackframe.h> | 16 | #include <asm/stackframe.h> |
@@ -185,7 +186,7 @@ syscall_exit_work: | |||
185 | * For C code use the inline version named instruction_hazard(). | 186 | * For C code use the inline version named instruction_hazard(). |
186 | */ | 187 | */ |
187 | LEAF(mips_ihb) | 188 | LEAF(mips_ihb) |
188 | .set mips32r2 | 189 | .set MIPS_ISA_LEVEL_RAW |
189 | jr.hb ra | 190 | jr.hb ra |
190 | nop | 191 | nop |
191 | END(mips_ihb) | 192 | END(mips_ihb) |
diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c index 130af7d26a9c..298b2b773d12 100644 --- a/arch/mips/kernel/proc.c +++ b/arch/mips/kernel/proc.c | |||
@@ -120,6 +120,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
120 | if (cpu_has_msa) seq_printf(m, "%s", " msa"); | 120 | if (cpu_has_msa) seq_printf(m, "%s", " msa"); |
121 | if (cpu_has_eva) seq_printf(m, "%s", " eva"); | 121 | if (cpu_has_eva) seq_printf(m, "%s", " eva"); |
122 | if (cpu_has_htw) seq_printf(m, "%s", " htw"); | 122 | if (cpu_has_htw) seq_printf(m, "%s", " htw"); |
123 | if (cpu_has_xpa) seq_printf(m, "%s", " xpa"); | ||
123 | seq_printf(m, "\n"); | 124 | seq_printf(m, "\n"); |
124 | 125 | ||
125 | if (cpu_has_mmips) { | 126 | if (cpu_has_mmips) { |
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c index bed7590e475f..d5589bedd0a4 100644 --- a/arch/mips/kernel/smp-cps.c +++ b/arch/mips/kernel/smp-cps.c | |||
@@ -88,6 +88,12 @@ static void __init cps_smp_setup(void) | |||
88 | 88 | ||
89 | /* Make core 0 coherent with everything */ | 89 | /* Make core 0 coherent with everything */ |
90 | write_gcr_cl_coherence(0xff); | 90 | write_gcr_cl_coherence(0xff); |
91 | |||
92 | #ifdef CONFIG_MIPS_MT_FPAFF | ||
93 | /* If we have an FPU, enroll ourselves in the FPU-full mask */ | ||
94 | if (cpu_has_fpu) | ||
95 | cpu_set(0, mt_fpu_cpumask); | ||
96 | #endif /* CONFIG_MIPS_MT_FPAFF */ | ||
91 | } | 97 | } |
92 | 98 | ||
93 | static void __init cps_prepare_cpus(unsigned int max_cpus) | 99 | static void __init cps_prepare_cpus(unsigned int max_cpus) |
diff --git a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c index 27af5634a69b..af84bef0c90d 100644 --- a/arch/mips/kernel/unaligned.c +++ b/arch/mips/kernel/unaligned.c | |||
@@ -107,10 +107,11 @@ static u32 unaligned_action; | |||
107 | extern void show_registers(struct pt_regs *regs); | 107 | extern void show_registers(struct pt_regs *regs); |
108 | 108 | ||
109 | #ifdef __BIG_ENDIAN | 109 | #ifdef __BIG_ENDIAN |
110 | #define LoadHW(addr, value, res) \ | 110 | #define _LoadHW(addr, value, res, type) \ |
111 | do { \ | ||
111 | __asm__ __volatile__ (".set\tnoat\n" \ | 112 | __asm__ __volatile__ (".set\tnoat\n" \ |
112 | "1:\t"user_lb("%0", "0(%2)")"\n" \ | 113 | "1:\t"type##_lb("%0", "0(%2)")"\n" \ |
113 | "2:\t"user_lbu("$1", "1(%2)")"\n\t" \ | 114 | "2:\t"type##_lbu("$1", "1(%2)")"\n\t"\ |
114 | "sll\t%0, 0x8\n\t" \ | 115 | "sll\t%0, 0x8\n\t" \ |
115 | "or\t%0, $1\n\t" \ | 116 | "or\t%0, $1\n\t" \ |
116 | "li\t%1, 0\n" \ | 117 | "li\t%1, 0\n" \ |
@@ -125,13 +126,15 @@ extern void show_registers(struct pt_regs *regs); | |||
125 | STR(PTR)"\t2b, 4b\n\t" \ | 126 | STR(PTR)"\t2b, 4b\n\t" \ |
126 | ".previous" \ | 127 | ".previous" \ |
127 | : "=&r" (value), "=r" (res) \ | 128 | : "=&r" (value), "=r" (res) \ |
128 | : "r" (addr), "i" (-EFAULT)); | 129 | : "r" (addr), "i" (-EFAULT)); \ |
130 | } while(0) | ||
129 | 131 | ||
130 | #ifndef CONFIG_CPU_MIPSR6 | 132 | #ifndef CONFIG_CPU_MIPSR6 |
131 | #define LoadW(addr, value, res) \ | 133 | #define _LoadW(addr, value, res, type) \ |
134 | do { \ | ||
132 | __asm__ __volatile__ ( \ | 135 | __asm__ __volatile__ ( \ |
133 | "1:\t"user_lwl("%0", "(%2)")"\n" \ | 136 | "1:\t"type##_lwl("%0", "(%2)")"\n" \ |
134 | "2:\t"user_lwr("%0", "3(%2)")"\n\t" \ | 137 | "2:\t"type##_lwr("%0", "3(%2)")"\n\t"\ |
135 | "li\t%1, 0\n" \ | 138 | "li\t%1, 0\n" \ |
136 | "3:\n\t" \ | 139 | "3:\n\t" \ |
137 | ".insn\n\t" \ | 140 | ".insn\n\t" \ |
@@ -144,21 +147,24 @@ extern void show_registers(struct pt_regs *regs); | |||
144 | STR(PTR)"\t2b, 4b\n\t" \ | 147 | STR(PTR)"\t2b, 4b\n\t" \ |
145 | ".previous" \ | 148 | ".previous" \ |
146 | : "=&r" (value), "=r" (res) \ | 149 | : "=&r" (value), "=r" (res) \ |
147 | : "r" (addr), "i" (-EFAULT)); | 150 | : "r" (addr), "i" (-EFAULT)); \ |
151 | } while(0) | ||
152 | |||
148 | #else | 153 | #else |
149 | /* MIPSR6 has no lwl instruction */ | 154 | /* MIPSR6 has no lwl instruction */ |
150 | #define LoadW(addr, value, res) \ | 155 | #define _LoadW(addr, value, res, type) \ |
156 | do { \ | ||
151 | __asm__ __volatile__ ( \ | 157 | __asm__ __volatile__ ( \ |
152 | ".set\tpush\n" \ | 158 | ".set\tpush\n" \ |
153 | ".set\tnoat\n\t" \ | 159 | ".set\tnoat\n\t" \ |
154 | "1:"user_lb("%0", "0(%2)")"\n\t" \ | 160 | "1:"type##_lb("%0", "0(%2)")"\n\t" \ |
155 | "2:"user_lbu("$1", "1(%2)")"\n\t" \ | 161 | "2:"type##_lbu("$1", "1(%2)")"\n\t" \ |
156 | "sll\t%0, 0x8\n\t" \ | 162 | "sll\t%0, 0x8\n\t" \ |
157 | "or\t%0, $1\n\t" \ | 163 | "or\t%0, $1\n\t" \ |
158 | "3:"user_lbu("$1", "2(%2)")"\n\t" \ | 164 | "3:"type##_lbu("$1", "2(%2)")"\n\t" \ |
159 | "sll\t%0, 0x8\n\t" \ | 165 | "sll\t%0, 0x8\n\t" \ |
160 | "or\t%0, $1\n\t" \ | 166 | "or\t%0, $1\n\t" \ |
161 | "4:"user_lbu("$1", "3(%2)")"\n\t" \ | 167 | "4:"type##_lbu("$1", "3(%2)")"\n\t" \ |
162 | "sll\t%0, 0x8\n\t" \ | 168 | "sll\t%0, 0x8\n\t" \ |
163 | "or\t%0, $1\n\t" \ | 169 | "or\t%0, $1\n\t" \ |
164 | "li\t%1, 0\n" \ | 170 | "li\t%1, 0\n" \ |
@@ -176,14 +182,17 @@ extern void show_registers(struct pt_regs *regs); | |||
176 | STR(PTR)"\t4b, 11b\n\t" \ | 182 | STR(PTR)"\t4b, 11b\n\t" \ |
177 | ".previous" \ | 183 | ".previous" \ |
178 | : "=&r" (value), "=r" (res) \ | 184 | : "=&r" (value), "=r" (res) \ |
179 | : "r" (addr), "i" (-EFAULT)); | 185 | : "r" (addr), "i" (-EFAULT)); \ |
186 | } while(0) | ||
187 | |||
180 | #endif /* CONFIG_CPU_MIPSR6 */ | 188 | #endif /* CONFIG_CPU_MIPSR6 */ |
181 | 189 | ||
182 | #define LoadHWU(addr, value, res) \ | 190 | #define _LoadHWU(addr, value, res, type) \ |
191 | do { \ | ||
183 | __asm__ __volatile__ ( \ | 192 | __asm__ __volatile__ ( \ |
184 | ".set\tnoat\n" \ | 193 | ".set\tnoat\n" \ |
185 | "1:\t"user_lbu("%0", "0(%2)")"\n" \ | 194 | "1:\t"type##_lbu("%0", "0(%2)")"\n" \ |
186 | "2:\t"user_lbu("$1", "1(%2)")"\n\t" \ | 195 | "2:\t"type##_lbu("$1", "1(%2)")"\n\t"\ |
187 | "sll\t%0, 0x8\n\t" \ | 196 | "sll\t%0, 0x8\n\t" \ |
188 | "or\t%0, $1\n\t" \ | 197 | "or\t%0, $1\n\t" \ |
189 | "li\t%1, 0\n" \ | 198 | "li\t%1, 0\n" \ |
@@ -199,13 +208,15 @@ extern void show_registers(struct pt_regs *regs); | |||
199 | STR(PTR)"\t2b, 4b\n\t" \ | 208 | STR(PTR)"\t2b, 4b\n\t" \ |
200 | ".previous" \ | 209 | ".previous" \ |
201 | : "=&r" (value), "=r" (res) \ | 210 | : "=&r" (value), "=r" (res) \ |
202 | : "r" (addr), "i" (-EFAULT)); | 211 | : "r" (addr), "i" (-EFAULT)); \ |
212 | } while(0) | ||
203 | 213 | ||
204 | #ifndef CONFIG_CPU_MIPSR6 | 214 | #ifndef CONFIG_CPU_MIPSR6 |
205 | #define LoadWU(addr, value, res) \ | 215 | #define _LoadWU(addr, value, res, type) \ |
216 | do { \ | ||
206 | __asm__ __volatile__ ( \ | 217 | __asm__ __volatile__ ( \ |
207 | "1:\t"user_lwl("%0", "(%2)")"\n" \ | 218 | "1:\t"type##_lwl("%0", "(%2)")"\n" \ |
208 | "2:\t"user_lwr("%0", "3(%2)")"\n\t" \ | 219 | "2:\t"type##_lwr("%0", "3(%2)")"\n\t"\ |
209 | "dsll\t%0, %0, 32\n\t" \ | 220 | "dsll\t%0, %0, 32\n\t" \ |
210 | "dsrl\t%0, %0, 32\n\t" \ | 221 | "dsrl\t%0, %0, 32\n\t" \ |
211 | "li\t%1, 0\n" \ | 222 | "li\t%1, 0\n" \ |
@@ -220,9 +231,11 @@ extern void show_registers(struct pt_regs *regs); | |||
220 | STR(PTR)"\t2b, 4b\n\t" \ | 231 | STR(PTR)"\t2b, 4b\n\t" \ |
221 | ".previous" \ | 232 | ".previous" \ |
222 | : "=&r" (value), "=r" (res) \ | 233 | : "=&r" (value), "=r" (res) \ |
223 | : "r" (addr), "i" (-EFAULT)); | 234 | : "r" (addr), "i" (-EFAULT)); \ |
235 | } while(0) | ||
224 | 236 | ||
225 | #define LoadDW(addr, value, res) \ | 237 | #define _LoadDW(addr, value, res) \ |
238 | do { \ | ||
226 | __asm__ __volatile__ ( \ | 239 | __asm__ __volatile__ ( \ |
227 | "1:\tldl\t%0, (%2)\n" \ | 240 | "1:\tldl\t%0, (%2)\n" \ |
228 | "2:\tldr\t%0, 7(%2)\n\t" \ | 241 | "2:\tldr\t%0, 7(%2)\n\t" \ |
@@ -238,21 +251,24 @@ extern void show_registers(struct pt_regs *regs); | |||
238 | STR(PTR)"\t2b, 4b\n\t" \ | 251 | STR(PTR)"\t2b, 4b\n\t" \ |
239 | ".previous" \ | 252 | ".previous" \ |
240 | : "=&r" (value), "=r" (res) \ | 253 | : "=&r" (value), "=r" (res) \ |
241 | : "r" (addr), "i" (-EFAULT)); | 254 | : "r" (addr), "i" (-EFAULT)); \ |
255 | } while(0) | ||
256 | |||
242 | #else | 257 | #else |
243 | /* MIPSR6 has not lwl and ldl instructions */ | 258 | /* MIPSR6 has not lwl and ldl instructions */ |
244 | #define LoadWU(addr, value, res) \ | 259 | #define _LoadWU(addr, value, res, type) \ |
260 | do { \ | ||
245 | __asm__ __volatile__ ( \ | 261 | __asm__ __volatile__ ( \ |
246 | ".set\tpush\n\t" \ | 262 | ".set\tpush\n\t" \ |
247 | ".set\tnoat\n\t" \ | 263 | ".set\tnoat\n\t" \ |
248 | "1:"user_lbu("%0", "0(%2)")"\n\t" \ | 264 | "1:"type##_lbu("%0", "0(%2)")"\n\t" \ |
249 | "2:"user_lbu("$1", "1(%2)")"\n\t" \ | 265 | "2:"type##_lbu("$1", "1(%2)")"\n\t" \ |
250 | "sll\t%0, 0x8\n\t" \ | 266 | "sll\t%0, 0x8\n\t" \ |
251 | "or\t%0, $1\n\t" \ | 267 | "or\t%0, $1\n\t" \ |
252 | "3:"user_lbu("$1", "2(%2)")"\n\t" \ | 268 | "3:"type##_lbu("$1", "2(%2)")"\n\t" \ |
253 | "sll\t%0, 0x8\n\t" \ | 269 | "sll\t%0, 0x8\n\t" \ |
254 | "or\t%0, $1\n\t" \ | 270 | "or\t%0, $1\n\t" \ |
255 | "4:"user_lbu("$1", "3(%2)")"\n\t" \ | 271 | "4:"type##_lbu("$1", "3(%2)")"\n\t" \ |
256 | "sll\t%0, 0x8\n\t" \ | 272 | "sll\t%0, 0x8\n\t" \ |
257 | "or\t%0, $1\n\t" \ | 273 | "or\t%0, $1\n\t" \ |
258 | "li\t%1, 0\n" \ | 274 | "li\t%1, 0\n" \ |
@@ -270,9 +286,11 @@ extern void show_registers(struct pt_regs *regs); | |||
270 | STR(PTR)"\t4b, 11b\n\t" \ | 286 | STR(PTR)"\t4b, 11b\n\t" \ |
271 | ".previous" \ | 287 | ".previous" \ |
272 | : "=&r" (value), "=r" (res) \ | 288 | : "=&r" (value), "=r" (res) \ |
273 | : "r" (addr), "i" (-EFAULT)); | 289 | : "r" (addr), "i" (-EFAULT)); \ |
290 | } while(0) | ||
274 | 291 | ||
275 | #define LoadDW(addr, value, res) \ | 292 | #define _LoadDW(addr, value, res) \ |
293 | do { \ | ||
276 | __asm__ __volatile__ ( \ | 294 | __asm__ __volatile__ ( \ |
277 | ".set\tpush\n\t" \ | 295 | ".set\tpush\n\t" \ |
278 | ".set\tnoat\n\t" \ | 296 | ".set\tnoat\n\t" \ |
@@ -317,16 +335,19 @@ extern void show_registers(struct pt_regs *regs); | |||
317 | STR(PTR)"\t8b, 11b\n\t" \ | 335 | STR(PTR)"\t8b, 11b\n\t" \ |
318 | ".previous" \ | 336 | ".previous" \ |
319 | : "=&r" (value), "=r" (res) \ | 337 | : "=&r" (value), "=r" (res) \ |
320 | : "r" (addr), "i" (-EFAULT)); | 338 | : "r" (addr), "i" (-EFAULT)); \ |
339 | } while(0) | ||
340 | |||
321 | #endif /* CONFIG_CPU_MIPSR6 */ | 341 | #endif /* CONFIG_CPU_MIPSR6 */ |
322 | 342 | ||
323 | 343 | ||
324 | #define StoreHW(addr, value, res) \ | 344 | #define _StoreHW(addr, value, res, type) \ |
345 | do { \ | ||
325 | __asm__ __volatile__ ( \ | 346 | __asm__ __volatile__ ( \ |
326 | ".set\tnoat\n" \ | 347 | ".set\tnoat\n" \ |
327 | "1:\t"user_sb("%1", "1(%2)")"\n" \ | 348 | "1:\t"type##_sb("%1", "1(%2)")"\n" \ |
328 | "srl\t$1, %1, 0x8\n" \ | 349 | "srl\t$1, %1, 0x8\n" \ |
329 | "2:\t"user_sb("$1", "0(%2)")"\n" \ | 350 | "2:\t"type##_sb("$1", "0(%2)")"\n" \ |
330 | ".set\tat\n\t" \ | 351 | ".set\tat\n\t" \ |
331 | "li\t%0, 0\n" \ | 352 | "li\t%0, 0\n" \ |
332 | "3:\n\t" \ | 353 | "3:\n\t" \ |
@@ -340,13 +361,15 @@ extern void show_registers(struct pt_regs *regs); | |||
340 | STR(PTR)"\t2b, 4b\n\t" \ | 361 | STR(PTR)"\t2b, 4b\n\t" \ |
341 | ".previous" \ | 362 | ".previous" \ |
342 | : "=r" (res) \ | 363 | : "=r" (res) \ |
343 | : "r" (value), "r" (addr), "i" (-EFAULT)); | 364 | : "r" (value), "r" (addr), "i" (-EFAULT));\ |
365 | } while(0) | ||
344 | 366 | ||
345 | #ifndef CONFIG_CPU_MIPSR6 | 367 | #ifndef CONFIG_CPU_MIPSR6 |
346 | #define StoreW(addr, value, res) \ | 368 | #define _StoreW(addr, value, res, type) \ |
369 | do { \ | ||
347 | __asm__ __volatile__ ( \ | 370 | __asm__ __volatile__ ( \ |
348 | "1:\t"user_swl("%1", "(%2)")"\n" \ | 371 | "1:\t"type##_swl("%1", "(%2)")"\n" \ |
349 | "2:\t"user_swr("%1", "3(%2)")"\n\t" \ | 372 | "2:\t"type##_swr("%1", "3(%2)")"\n\t"\ |
350 | "li\t%0, 0\n" \ | 373 | "li\t%0, 0\n" \ |
351 | "3:\n\t" \ | 374 | "3:\n\t" \ |
352 | ".insn\n\t" \ | 375 | ".insn\n\t" \ |
@@ -359,9 +382,11 @@ extern void show_registers(struct pt_regs *regs); | |||
359 | STR(PTR)"\t2b, 4b\n\t" \ | 382 | STR(PTR)"\t2b, 4b\n\t" \ |
360 | ".previous" \ | 383 | ".previous" \ |
361 | : "=r" (res) \ | 384 | : "=r" (res) \ |
362 | : "r" (value), "r" (addr), "i" (-EFAULT)); | 385 | : "r" (value), "r" (addr), "i" (-EFAULT)); \ |
386 | } while(0) | ||
363 | 387 | ||
364 | #define StoreDW(addr, value, res) \ | 388 | #define _StoreDW(addr, value, res) \ |
389 | do { \ | ||
365 | __asm__ __volatile__ ( \ | 390 | __asm__ __volatile__ ( \ |
366 | "1:\tsdl\t%1,(%2)\n" \ | 391 | "1:\tsdl\t%1,(%2)\n" \ |
367 | "2:\tsdr\t%1, 7(%2)\n\t" \ | 392 | "2:\tsdr\t%1, 7(%2)\n\t" \ |
@@ -377,20 +402,23 @@ extern void show_registers(struct pt_regs *regs); | |||
377 | STR(PTR)"\t2b, 4b\n\t" \ | 402 | STR(PTR)"\t2b, 4b\n\t" \ |
378 | ".previous" \ | 403 | ".previous" \ |
379 | : "=r" (res) \ | 404 | : "=r" (res) \ |
380 | : "r" (value), "r" (addr), "i" (-EFAULT)); | 405 | : "r" (value), "r" (addr), "i" (-EFAULT)); \ |
406 | } while(0) | ||
407 | |||
381 | #else | 408 | #else |
382 | /* MIPSR6 has no swl and sdl instructions */ | 409 | /* MIPSR6 has no swl and sdl instructions */ |
383 | #define StoreW(addr, value, res) \ | 410 | #define _StoreW(addr, value, res, type) \ |
411 | do { \ | ||
384 | __asm__ __volatile__ ( \ | 412 | __asm__ __volatile__ ( \ |
385 | ".set\tpush\n\t" \ | 413 | ".set\tpush\n\t" \ |
386 | ".set\tnoat\n\t" \ | 414 | ".set\tnoat\n\t" \ |
387 | "1:"user_sb("%1", "3(%2)")"\n\t" \ | 415 | "1:"type##_sb("%1", "3(%2)")"\n\t" \ |
388 | "srl\t$1, %1, 0x8\n\t" \ | 416 | "srl\t$1, %1, 0x8\n\t" \ |
389 | "2:"user_sb("$1", "2(%2)")"\n\t" \ | 417 | "2:"type##_sb("$1", "2(%2)")"\n\t" \ |
390 | "srl\t$1, $1, 0x8\n\t" \ | 418 | "srl\t$1, $1, 0x8\n\t" \ |
391 | "3:"user_sb("$1", "1(%2)")"\n\t" \ | 419 | "3:"type##_sb("$1", "1(%2)")"\n\t" \ |
392 | "srl\t$1, $1, 0x8\n\t" \ | 420 | "srl\t$1, $1, 0x8\n\t" \ |
393 | "4:"user_sb("$1", "0(%2)")"\n\t" \ | 421 | "4:"type##_sb("$1", "0(%2)")"\n\t" \ |
394 | ".set\tpop\n\t" \ | 422 | ".set\tpop\n\t" \ |
395 | "li\t%0, 0\n" \ | 423 | "li\t%0, 0\n" \ |
396 | "10:\n\t" \ | 424 | "10:\n\t" \ |
@@ -407,9 +435,11 @@ extern void show_registers(struct pt_regs *regs); | |||
407 | ".previous" \ | 435 | ".previous" \ |
408 | : "=&r" (res) \ | 436 | : "=&r" (res) \ |
409 | : "r" (value), "r" (addr), "i" (-EFAULT) \ | 437 | : "r" (value), "r" (addr), "i" (-EFAULT) \ |
410 | : "memory"); | 438 | : "memory"); \ |
439 | } while(0) | ||
411 | 440 | ||
412 | #define StoreDW(addr, value, res) \ | 441 | #define StoreDW(addr, value, res) \ |
442 | do { \ | ||
413 | __asm__ __volatile__ ( \ | 443 | __asm__ __volatile__ ( \ |
414 | ".set\tpush\n\t" \ | 444 | ".set\tpush\n\t" \ |
415 | ".set\tnoat\n\t" \ | 445 | ".set\tnoat\n\t" \ |
@@ -449,15 +479,18 @@ extern void show_registers(struct pt_regs *regs); | |||
449 | ".previous" \ | 479 | ".previous" \ |
450 | : "=&r" (res) \ | 480 | : "=&r" (res) \ |
451 | : "r" (value), "r" (addr), "i" (-EFAULT) \ | 481 | : "r" (value), "r" (addr), "i" (-EFAULT) \ |
452 | : "memory"); | 482 | : "memory"); \ |
483 | } while(0) | ||
484 | |||
453 | #endif /* CONFIG_CPU_MIPSR6 */ | 485 | #endif /* CONFIG_CPU_MIPSR6 */ |
454 | 486 | ||
455 | #else /* __BIG_ENDIAN */ | 487 | #else /* __BIG_ENDIAN */ |
456 | 488 | ||
457 | #define LoadHW(addr, value, res) \ | 489 | #define _LoadHW(addr, value, res, type) \ |
490 | do { \ | ||
458 | __asm__ __volatile__ (".set\tnoat\n" \ | 491 | __asm__ __volatile__ (".set\tnoat\n" \ |
459 | "1:\t"user_lb("%0", "1(%2)")"\n" \ | 492 | "1:\t"type##_lb("%0", "1(%2)")"\n" \ |
460 | "2:\t"user_lbu("$1", "0(%2)")"\n\t" \ | 493 | "2:\t"type##_lbu("$1", "0(%2)")"\n\t"\ |
461 | "sll\t%0, 0x8\n\t" \ | 494 | "sll\t%0, 0x8\n\t" \ |
462 | "or\t%0, $1\n\t" \ | 495 | "or\t%0, $1\n\t" \ |
463 | "li\t%1, 0\n" \ | 496 | "li\t%1, 0\n" \ |
@@ -472,13 +505,15 @@ extern void show_registers(struct pt_regs *regs); | |||
472 | STR(PTR)"\t2b, 4b\n\t" \ | 505 | STR(PTR)"\t2b, 4b\n\t" \ |
473 | ".previous" \ | 506 | ".previous" \ |
474 | : "=&r" (value), "=r" (res) \ | 507 | : "=&r" (value), "=r" (res) \ |
475 | : "r" (addr), "i" (-EFAULT)); | 508 | : "r" (addr), "i" (-EFAULT)); \ |
509 | } while(0) | ||
476 | 510 | ||
477 | #ifndef CONFIG_CPU_MIPSR6 | 511 | #ifndef CONFIG_CPU_MIPSR6 |
478 | #define LoadW(addr, value, res) \ | 512 | #define _LoadW(addr, value, res, type) \ |
513 | do { \ | ||
479 | __asm__ __volatile__ ( \ | 514 | __asm__ __volatile__ ( \ |
480 | "1:\t"user_lwl("%0", "3(%2)")"\n" \ | 515 | "1:\t"type##_lwl("%0", "3(%2)")"\n" \ |
481 | "2:\t"user_lwr("%0", "(%2)")"\n\t" \ | 516 | "2:\t"type##_lwr("%0", "(%2)")"\n\t"\ |
482 | "li\t%1, 0\n" \ | 517 | "li\t%1, 0\n" \ |
483 | "3:\n\t" \ | 518 | "3:\n\t" \ |
484 | ".insn\n\t" \ | 519 | ".insn\n\t" \ |
@@ -491,21 +526,24 @@ extern void show_registers(struct pt_regs *regs); | |||
491 | STR(PTR)"\t2b, 4b\n\t" \ | 526 | STR(PTR)"\t2b, 4b\n\t" \ |
492 | ".previous" \ | 527 | ".previous" \ |
493 | : "=&r" (value), "=r" (res) \ | 528 | : "=&r" (value), "=r" (res) \ |
494 | : "r" (addr), "i" (-EFAULT)); | 529 | : "r" (addr), "i" (-EFAULT)); \ |
530 | } while(0) | ||
531 | |||
495 | #else | 532 | #else |
496 | /* MIPSR6 has no lwl instruction */ | 533 | /* MIPSR6 has no lwl instruction */ |
497 | #define LoadW(addr, value, res) \ | 534 | #define _LoadW(addr, value, res, type) \ |
535 | do { \ | ||
498 | __asm__ __volatile__ ( \ | 536 | __asm__ __volatile__ ( \ |
499 | ".set\tpush\n" \ | 537 | ".set\tpush\n" \ |
500 | ".set\tnoat\n\t" \ | 538 | ".set\tnoat\n\t" \ |
501 | "1:"user_lb("%0", "3(%2)")"\n\t" \ | 539 | "1:"type##_lb("%0", "3(%2)")"\n\t" \ |
502 | "2:"user_lbu("$1", "2(%2)")"\n\t" \ | 540 | "2:"type##_lbu("$1", "2(%2)")"\n\t" \ |
503 | "sll\t%0, 0x8\n\t" \ | 541 | "sll\t%0, 0x8\n\t" \ |
504 | "or\t%0, $1\n\t" \ | 542 | "or\t%0, $1\n\t" \ |
505 | "3:"user_lbu("$1", "1(%2)")"\n\t" \ | 543 | "3:"type##_lbu("$1", "1(%2)")"\n\t" \ |
506 | "sll\t%0, 0x8\n\t" \ | 544 | "sll\t%0, 0x8\n\t" \ |
507 | "or\t%0, $1\n\t" \ | 545 | "or\t%0, $1\n\t" \ |
508 | "4:"user_lbu("$1", "0(%2)")"\n\t" \ | 546 | "4:"type##_lbu("$1", "0(%2)")"\n\t" \ |
509 | "sll\t%0, 0x8\n\t" \ | 547 | "sll\t%0, 0x8\n\t" \ |
510 | "or\t%0, $1\n\t" \ | 548 | "or\t%0, $1\n\t" \ |
511 | "li\t%1, 0\n" \ | 549 | "li\t%1, 0\n" \ |
@@ -523,15 +561,18 @@ extern void show_registers(struct pt_regs *regs); | |||
523 | STR(PTR)"\t4b, 11b\n\t" \ | 561 | STR(PTR)"\t4b, 11b\n\t" \ |
524 | ".previous" \ | 562 | ".previous" \ |
525 | : "=&r" (value), "=r" (res) \ | 563 | : "=&r" (value), "=r" (res) \ |
526 | : "r" (addr), "i" (-EFAULT)); | 564 | : "r" (addr), "i" (-EFAULT)); \ |
565 | } while(0) | ||
566 | |||
527 | #endif /* CONFIG_CPU_MIPSR6 */ | 567 | #endif /* CONFIG_CPU_MIPSR6 */ |
528 | 568 | ||
529 | 569 | ||
530 | #define LoadHWU(addr, value, res) \ | 570 | #define _LoadHWU(addr, value, res, type) \ |
571 | do { \ | ||
531 | __asm__ __volatile__ ( \ | 572 | __asm__ __volatile__ ( \ |
532 | ".set\tnoat\n" \ | 573 | ".set\tnoat\n" \ |
533 | "1:\t"user_lbu("%0", "1(%2)")"\n" \ | 574 | "1:\t"type##_lbu("%0", "1(%2)")"\n" \ |
534 | "2:\t"user_lbu("$1", "0(%2)")"\n\t" \ | 575 | "2:\t"type##_lbu("$1", "0(%2)")"\n\t"\ |
535 | "sll\t%0, 0x8\n\t" \ | 576 | "sll\t%0, 0x8\n\t" \ |
536 | "or\t%0, $1\n\t" \ | 577 | "or\t%0, $1\n\t" \ |
537 | "li\t%1, 0\n" \ | 578 | "li\t%1, 0\n" \ |
@@ -547,13 +588,15 @@ extern void show_registers(struct pt_regs *regs); | |||
547 | STR(PTR)"\t2b, 4b\n\t" \ | 588 | STR(PTR)"\t2b, 4b\n\t" \ |
548 | ".previous" \ | 589 | ".previous" \ |
549 | : "=&r" (value), "=r" (res) \ | 590 | : "=&r" (value), "=r" (res) \ |
550 | : "r" (addr), "i" (-EFAULT)); | 591 | : "r" (addr), "i" (-EFAULT)); \ |
592 | } while(0) | ||
551 | 593 | ||
552 | #ifndef CONFIG_CPU_MIPSR6 | 594 | #ifndef CONFIG_CPU_MIPSR6 |
553 | #define LoadWU(addr, value, res) \ | 595 | #define _LoadWU(addr, value, res, type) \ |
596 | do { \ | ||
554 | __asm__ __volatile__ ( \ | 597 | __asm__ __volatile__ ( \ |
555 | "1:\t"user_lwl("%0", "3(%2)")"\n" \ | 598 | "1:\t"type##_lwl("%0", "3(%2)")"\n" \ |
556 | "2:\t"user_lwr("%0", "(%2)")"\n\t" \ | 599 | "2:\t"type##_lwr("%0", "(%2)")"\n\t"\ |
557 | "dsll\t%0, %0, 32\n\t" \ | 600 | "dsll\t%0, %0, 32\n\t" \ |
558 | "dsrl\t%0, %0, 32\n\t" \ | 601 | "dsrl\t%0, %0, 32\n\t" \ |
559 | "li\t%1, 0\n" \ | 602 | "li\t%1, 0\n" \ |
@@ -568,9 +611,11 @@ extern void show_registers(struct pt_regs *regs); | |||
568 | STR(PTR)"\t2b, 4b\n\t" \ | 611 | STR(PTR)"\t2b, 4b\n\t" \ |
569 | ".previous" \ | 612 | ".previous" \ |
570 | : "=&r" (value), "=r" (res) \ | 613 | : "=&r" (value), "=r" (res) \ |
571 | : "r" (addr), "i" (-EFAULT)); | 614 | : "r" (addr), "i" (-EFAULT)); \ |
615 | } while(0) | ||
572 | 616 | ||
573 | #define LoadDW(addr, value, res) \ | 617 | #define _LoadDW(addr, value, res) \ |
618 | do { \ | ||
574 | __asm__ __volatile__ ( \ | 619 | __asm__ __volatile__ ( \ |
575 | "1:\tldl\t%0, 7(%2)\n" \ | 620 | "1:\tldl\t%0, 7(%2)\n" \ |
576 | "2:\tldr\t%0, (%2)\n\t" \ | 621 | "2:\tldr\t%0, (%2)\n\t" \ |
@@ -586,21 +631,24 @@ extern void show_registers(struct pt_regs *regs); | |||
586 | STR(PTR)"\t2b, 4b\n\t" \ | 631 | STR(PTR)"\t2b, 4b\n\t" \ |
587 | ".previous" \ | 632 | ".previous" \ |
588 | : "=&r" (value), "=r" (res) \ | 633 | : "=&r" (value), "=r" (res) \ |
589 | : "r" (addr), "i" (-EFAULT)); | 634 | : "r" (addr), "i" (-EFAULT)); \ |
635 | } while(0) | ||
636 | |||
590 | #else | 637 | #else |
591 | /* MIPSR6 has not lwl and ldl instructions */ | 638 | /* MIPSR6 has not lwl and ldl instructions */ |
592 | #define LoadWU(addr, value, res) \ | 639 | #define _LoadWU(addr, value, res, type) \ |
640 | do { \ | ||
593 | __asm__ __volatile__ ( \ | 641 | __asm__ __volatile__ ( \ |
594 | ".set\tpush\n\t" \ | 642 | ".set\tpush\n\t" \ |
595 | ".set\tnoat\n\t" \ | 643 | ".set\tnoat\n\t" \ |
596 | "1:"user_lbu("%0", "3(%2)")"\n\t" \ | 644 | "1:"type##_lbu("%0", "3(%2)")"\n\t" \ |
597 | "2:"user_lbu("$1", "2(%2)")"\n\t" \ | 645 | "2:"type##_lbu("$1", "2(%2)")"\n\t" \ |
598 | "sll\t%0, 0x8\n\t" \ | 646 | "sll\t%0, 0x8\n\t" \ |
599 | "or\t%0, $1\n\t" \ | 647 | "or\t%0, $1\n\t" \ |
600 | "3:"user_lbu("$1", "1(%2)")"\n\t" \ | 648 | "3:"type##_lbu("$1", "1(%2)")"\n\t" \ |
601 | "sll\t%0, 0x8\n\t" \ | 649 | "sll\t%0, 0x8\n\t" \ |
602 | "or\t%0, $1\n\t" \ | 650 | "or\t%0, $1\n\t" \ |
603 | "4:"user_lbu("$1", "0(%2)")"\n\t" \ | 651 | "4:"type##_lbu("$1", "0(%2)")"\n\t" \ |
604 | "sll\t%0, 0x8\n\t" \ | 652 | "sll\t%0, 0x8\n\t" \ |
605 | "or\t%0, $1\n\t" \ | 653 | "or\t%0, $1\n\t" \ |
606 | "li\t%1, 0\n" \ | 654 | "li\t%1, 0\n" \ |
@@ -618,9 +666,11 @@ extern void show_registers(struct pt_regs *regs); | |||
618 | STR(PTR)"\t4b, 11b\n\t" \ | 666 | STR(PTR)"\t4b, 11b\n\t" \ |
619 | ".previous" \ | 667 | ".previous" \ |
620 | : "=&r" (value), "=r" (res) \ | 668 | : "=&r" (value), "=r" (res) \ |
621 | : "r" (addr), "i" (-EFAULT)); | 669 | : "r" (addr), "i" (-EFAULT)); \ |
670 | } while(0) | ||
622 | 671 | ||
623 | #define LoadDW(addr, value, res) \ | 672 | #define _LoadDW(addr, value, res) \ |
673 | do { \ | ||
624 | __asm__ __volatile__ ( \ | 674 | __asm__ __volatile__ ( \ |
625 | ".set\tpush\n\t" \ | 675 | ".set\tpush\n\t" \ |
626 | ".set\tnoat\n\t" \ | 676 | ".set\tnoat\n\t" \ |
@@ -665,15 +715,17 @@ extern void show_registers(struct pt_regs *regs); | |||
665 | STR(PTR)"\t8b, 11b\n\t" \ | 715 | STR(PTR)"\t8b, 11b\n\t" \ |
666 | ".previous" \ | 716 | ".previous" \ |
667 | : "=&r" (value), "=r" (res) \ | 717 | : "=&r" (value), "=r" (res) \ |
668 | : "r" (addr), "i" (-EFAULT)); | 718 | : "r" (addr), "i" (-EFAULT)); \ |
719 | } while(0) | ||
669 | #endif /* CONFIG_CPU_MIPSR6 */ | 720 | #endif /* CONFIG_CPU_MIPSR6 */ |
670 | 721 | ||
671 | #define StoreHW(addr, value, res) \ | 722 | #define _StoreHW(addr, value, res, type) \ |
723 | do { \ | ||
672 | __asm__ __volatile__ ( \ | 724 | __asm__ __volatile__ ( \ |
673 | ".set\tnoat\n" \ | 725 | ".set\tnoat\n" \ |
674 | "1:\t"user_sb("%1", "0(%2)")"\n" \ | 726 | "1:\t"type##_sb("%1", "0(%2)")"\n" \ |
675 | "srl\t$1,%1, 0x8\n" \ | 727 | "srl\t$1,%1, 0x8\n" \ |
676 | "2:\t"user_sb("$1", "1(%2)")"\n" \ | 728 | "2:\t"type##_sb("$1", "1(%2)")"\n" \ |
677 | ".set\tat\n\t" \ | 729 | ".set\tat\n\t" \ |
678 | "li\t%0, 0\n" \ | 730 | "li\t%0, 0\n" \ |
679 | "3:\n\t" \ | 731 | "3:\n\t" \ |
@@ -687,12 +739,15 @@ extern void show_registers(struct pt_regs *regs); | |||
687 | STR(PTR)"\t2b, 4b\n\t" \ | 739 | STR(PTR)"\t2b, 4b\n\t" \ |
688 | ".previous" \ | 740 | ".previous" \ |
689 | : "=r" (res) \ | 741 | : "=r" (res) \ |
690 | : "r" (value), "r" (addr), "i" (-EFAULT)); | 742 | : "r" (value), "r" (addr), "i" (-EFAULT));\ |
743 | } while(0) | ||
744 | |||
691 | #ifndef CONFIG_CPU_MIPSR6 | 745 | #ifndef CONFIG_CPU_MIPSR6 |
692 | #define StoreW(addr, value, res) \ | 746 | #define _StoreW(addr, value, res, type) \ |
747 | do { \ | ||
693 | __asm__ __volatile__ ( \ | 748 | __asm__ __volatile__ ( \ |
694 | "1:\t"user_swl("%1", "3(%2)")"\n" \ | 749 | "1:\t"type##_swl("%1", "3(%2)")"\n" \ |
695 | "2:\t"user_swr("%1", "(%2)")"\n\t" \ | 750 | "2:\t"type##_swr("%1", "(%2)")"\n\t"\ |
696 | "li\t%0, 0\n" \ | 751 | "li\t%0, 0\n" \ |
697 | "3:\n\t" \ | 752 | "3:\n\t" \ |
698 | ".insn\n\t" \ | 753 | ".insn\n\t" \ |
@@ -705,9 +760,11 @@ extern void show_registers(struct pt_regs *regs); | |||
705 | STR(PTR)"\t2b, 4b\n\t" \ | 760 | STR(PTR)"\t2b, 4b\n\t" \ |
706 | ".previous" \ | 761 | ".previous" \ |
707 | : "=r" (res) \ | 762 | : "=r" (res) \ |
708 | : "r" (value), "r" (addr), "i" (-EFAULT)); | 763 | : "r" (value), "r" (addr), "i" (-EFAULT)); \ |
764 | } while(0) | ||
709 | 765 | ||
710 | #define StoreDW(addr, value, res) \ | 766 | #define _StoreDW(addr, value, res) \ |
767 | do { \ | ||
711 | __asm__ __volatile__ ( \ | 768 | __asm__ __volatile__ ( \ |
712 | "1:\tsdl\t%1, 7(%2)\n" \ | 769 | "1:\tsdl\t%1, 7(%2)\n" \ |
713 | "2:\tsdr\t%1, (%2)\n\t" \ | 770 | "2:\tsdr\t%1, (%2)\n\t" \ |
@@ -723,20 +780,23 @@ extern void show_registers(struct pt_regs *regs); | |||
723 | STR(PTR)"\t2b, 4b\n\t" \ | 780 | STR(PTR)"\t2b, 4b\n\t" \ |
724 | ".previous" \ | 781 | ".previous" \ |
725 | : "=r" (res) \ | 782 | : "=r" (res) \ |
726 | : "r" (value), "r" (addr), "i" (-EFAULT)); | 783 | : "r" (value), "r" (addr), "i" (-EFAULT)); \ |
784 | } while(0) | ||
785 | |||
727 | #else | 786 | #else |
728 | /* MIPSR6 has no swl and sdl instructions */ | 787 | /* MIPSR6 has no swl and sdl instructions */ |
729 | #define StoreW(addr, value, res) \ | 788 | #define _StoreW(addr, value, res, type) \ |
789 | do { \ | ||
730 | __asm__ __volatile__ ( \ | 790 | __asm__ __volatile__ ( \ |
731 | ".set\tpush\n\t" \ | 791 | ".set\tpush\n\t" \ |
732 | ".set\tnoat\n\t" \ | 792 | ".set\tnoat\n\t" \ |
733 | "1:"user_sb("%1", "0(%2)")"\n\t" \ | 793 | "1:"type##_sb("%1", "0(%2)")"\n\t" \ |
734 | "srl\t$1, %1, 0x8\n\t" \ | 794 | "srl\t$1, %1, 0x8\n\t" \ |
735 | "2:"user_sb("$1", "1(%2)")"\n\t" \ | 795 | "2:"type##_sb("$1", "1(%2)")"\n\t" \ |
736 | "srl\t$1, $1, 0x8\n\t" \ | 796 | "srl\t$1, $1, 0x8\n\t" \ |
737 | "3:"user_sb("$1", "2(%2)")"\n\t" \ | 797 | "3:"type##_sb("$1", "2(%2)")"\n\t" \ |
738 | "srl\t$1, $1, 0x8\n\t" \ | 798 | "srl\t$1, $1, 0x8\n\t" \ |
739 | "4:"user_sb("$1", "3(%2)")"\n\t" \ | 799 | "4:"type##_sb("$1", "3(%2)")"\n\t" \ |
740 | ".set\tpop\n\t" \ | 800 | ".set\tpop\n\t" \ |
741 | "li\t%0, 0\n" \ | 801 | "li\t%0, 0\n" \ |
742 | "10:\n\t" \ | 802 | "10:\n\t" \ |
@@ -753,9 +813,11 @@ extern void show_registers(struct pt_regs *regs); | |||
753 | ".previous" \ | 813 | ".previous" \ |
754 | : "=&r" (res) \ | 814 | : "=&r" (res) \ |
755 | : "r" (value), "r" (addr), "i" (-EFAULT) \ | 815 | : "r" (value), "r" (addr), "i" (-EFAULT) \ |
756 | : "memory"); | 816 | : "memory"); \ |
817 | } while(0) | ||
757 | 818 | ||
758 | #define StoreDW(addr, value, res) \ | 819 | #define _StoreDW(addr, value, res) \ |
820 | do { \ | ||
759 | __asm__ __volatile__ ( \ | 821 | __asm__ __volatile__ ( \ |
760 | ".set\tpush\n\t" \ | 822 | ".set\tpush\n\t" \ |
761 | ".set\tnoat\n\t" \ | 823 | ".set\tnoat\n\t" \ |
@@ -795,10 +857,28 @@ extern void show_registers(struct pt_regs *regs); | |||
795 | ".previous" \ | 857 | ".previous" \ |
796 | : "=&r" (res) \ | 858 | : "=&r" (res) \ |
797 | : "r" (value), "r" (addr), "i" (-EFAULT) \ | 859 | : "r" (value), "r" (addr), "i" (-EFAULT) \ |
798 | : "memory"); | 860 | : "memory"); \ |
861 | } while(0) | ||
862 | |||
799 | #endif /* CONFIG_CPU_MIPSR6 */ | 863 | #endif /* CONFIG_CPU_MIPSR6 */ |
800 | #endif | 864 | #endif |
801 | 865 | ||
866 | #define LoadHWU(addr, value, res) _LoadHWU(addr, value, res, kernel) | ||
867 | #define LoadHWUE(addr, value, res) _LoadHWU(addr, value, res, user) | ||
868 | #define LoadWU(addr, value, res) _LoadWU(addr, value, res, kernel) | ||
869 | #define LoadWUE(addr, value, res) _LoadWU(addr, value, res, user) | ||
870 | #define LoadHW(addr, value, res) _LoadHW(addr, value, res, kernel) | ||
871 | #define LoadHWE(addr, value, res) _LoadHW(addr, value, res, user) | ||
872 | #define LoadW(addr, value, res) _LoadW(addr, value, res, kernel) | ||
873 | #define LoadWE(addr, value, res) _LoadW(addr, value, res, user) | ||
874 | #define LoadDW(addr, value, res) _LoadDW(addr, value, res) | ||
875 | |||
876 | #define StoreHW(addr, value, res) _StoreHW(addr, value, res, kernel) | ||
877 | #define StoreHWE(addr, value, res) _StoreHW(addr, value, res, user) | ||
878 | #define StoreW(addr, value, res) _StoreW(addr, value, res, kernel) | ||
879 | #define StoreWE(addr, value, res) _StoreW(addr, value, res, user) | ||
880 | #define StoreDW(addr, value, res) _StoreDW(addr, value, res) | ||
881 | |||
802 | static void emulate_load_store_insn(struct pt_regs *regs, | 882 | static void emulate_load_store_insn(struct pt_regs *regs, |
803 | void __user *addr, unsigned int __user *pc) | 883 | void __user *addr, unsigned int __user *pc) |
804 | { | 884 | { |
@@ -870,7 +950,7 @@ static void emulate_load_store_insn(struct pt_regs *regs, | |||
870 | set_fs(seg); | 950 | set_fs(seg); |
871 | goto sigbus; | 951 | goto sigbus; |
872 | } | 952 | } |
873 | LoadHW(addr, value, res); | 953 | LoadHWE(addr, value, res); |
874 | if (res) { | 954 | if (res) { |
875 | set_fs(seg); | 955 | set_fs(seg); |
876 | goto fault; | 956 | goto fault; |
@@ -883,7 +963,7 @@ static void emulate_load_store_insn(struct pt_regs *regs, | |||
883 | set_fs(seg); | 963 | set_fs(seg); |
884 | goto sigbus; | 964 | goto sigbus; |
885 | } | 965 | } |
886 | LoadW(addr, value, res); | 966 | LoadWE(addr, value, res); |
887 | if (res) { | 967 | if (res) { |
888 | set_fs(seg); | 968 | set_fs(seg); |
889 | goto fault; | 969 | goto fault; |
@@ -896,7 +976,7 @@ static void emulate_load_store_insn(struct pt_regs *regs, | |||
896 | set_fs(seg); | 976 | set_fs(seg); |
897 | goto sigbus; | 977 | goto sigbus; |
898 | } | 978 | } |
899 | LoadHWU(addr, value, res); | 979 | LoadHWUE(addr, value, res); |
900 | if (res) { | 980 | if (res) { |
901 | set_fs(seg); | 981 | set_fs(seg); |
902 | goto fault; | 982 | goto fault; |
@@ -911,7 +991,7 @@ static void emulate_load_store_insn(struct pt_regs *regs, | |||
911 | } | 991 | } |
912 | compute_return_epc(regs); | 992 | compute_return_epc(regs); |
913 | value = regs->regs[insn.spec3_format.rt]; | 993 | value = regs->regs[insn.spec3_format.rt]; |
914 | StoreHW(addr, value, res); | 994 | StoreHWE(addr, value, res); |
915 | if (res) { | 995 | if (res) { |
916 | set_fs(seg); | 996 | set_fs(seg); |
917 | goto fault; | 997 | goto fault; |
@@ -924,7 +1004,7 @@ static void emulate_load_store_insn(struct pt_regs *regs, | |||
924 | } | 1004 | } |
925 | compute_return_epc(regs); | 1005 | compute_return_epc(regs); |
926 | value = regs->regs[insn.spec3_format.rt]; | 1006 | value = regs->regs[insn.spec3_format.rt]; |
927 | StoreW(addr, value, res); | 1007 | StoreWE(addr, value, res); |
928 | if (res) { | 1008 | if (res) { |
929 | set_fs(seg); | 1009 | set_fs(seg); |
930 | goto fault; | 1010 | goto fault; |
@@ -941,7 +1021,15 @@ static void emulate_load_store_insn(struct pt_regs *regs, | |||
941 | if (!access_ok(VERIFY_READ, addr, 2)) | 1021 | if (!access_ok(VERIFY_READ, addr, 2)) |
942 | goto sigbus; | 1022 | goto sigbus; |
943 | 1023 | ||
944 | LoadHW(addr, value, res); | 1024 | if (config_enabled(CONFIG_EVA)) { |
1025 | if (segment_eq(get_fs(), get_ds())) | ||
1026 | LoadHW(addr, value, res); | ||
1027 | else | ||
1028 | LoadHWE(addr, value, res); | ||
1029 | } else { | ||
1030 | LoadHW(addr, value, res); | ||
1031 | } | ||
1032 | |||
945 | if (res) | 1033 | if (res) |
946 | goto fault; | 1034 | goto fault; |
947 | compute_return_epc(regs); | 1035 | compute_return_epc(regs); |
@@ -952,7 +1040,15 @@ static void emulate_load_store_insn(struct pt_regs *regs, | |||
952 | if (!access_ok(VERIFY_READ, addr, 4)) | 1040 | if (!access_ok(VERIFY_READ, addr, 4)) |
953 | goto sigbus; | 1041 | goto sigbus; |
954 | 1042 | ||
955 | LoadW(addr, value, res); | 1043 | if (config_enabled(CONFIG_EVA)) { |
1044 | if (segment_eq(get_fs(), get_ds())) | ||
1045 | LoadW(addr, value, res); | ||
1046 | else | ||
1047 | LoadWE(addr, value, res); | ||
1048 | } else { | ||
1049 | LoadW(addr, value, res); | ||
1050 | } | ||
1051 | |||
956 | if (res) | 1052 | if (res) |
957 | goto fault; | 1053 | goto fault; |
958 | compute_return_epc(regs); | 1054 | compute_return_epc(regs); |
@@ -963,7 +1059,15 @@ static void emulate_load_store_insn(struct pt_regs *regs, | |||
963 | if (!access_ok(VERIFY_READ, addr, 2)) | 1059 | if (!access_ok(VERIFY_READ, addr, 2)) |
964 | goto sigbus; | 1060 | goto sigbus; |
965 | 1061 | ||
966 | LoadHWU(addr, value, res); | 1062 | if (config_enabled(CONFIG_EVA)) { |
1063 | if (segment_eq(get_fs(), get_ds())) | ||
1064 | LoadHWU(addr, value, res); | ||
1065 | else | ||
1066 | LoadHWUE(addr, value, res); | ||
1067 | } else { | ||
1068 | LoadHWU(addr, value, res); | ||
1069 | } | ||
1070 | |||
967 | if (res) | 1071 | if (res) |
968 | goto fault; | 1072 | goto fault; |
969 | compute_return_epc(regs); | 1073 | compute_return_epc(regs); |
@@ -1022,7 +1126,16 @@ static void emulate_load_store_insn(struct pt_regs *regs, | |||
1022 | 1126 | ||
1023 | compute_return_epc(regs); | 1127 | compute_return_epc(regs); |
1024 | value = regs->regs[insn.i_format.rt]; | 1128 | value = regs->regs[insn.i_format.rt]; |
1025 | StoreHW(addr, value, res); | 1129 | |
1130 | if (config_enabled(CONFIG_EVA)) { | ||
1131 | if (segment_eq(get_fs(), get_ds())) | ||
1132 | StoreHW(addr, value, res); | ||
1133 | else | ||
1134 | StoreHWE(addr, value, res); | ||
1135 | } else { | ||
1136 | StoreHW(addr, value, res); | ||
1137 | } | ||
1138 | |||
1026 | if (res) | 1139 | if (res) |
1027 | goto fault; | 1140 | goto fault; |
1028 | break; | 1141 | break; |
@@ -1033,7 +1146,16 @@ static void emulate_load_store_insn(struct pt_regs *regs, | |||
1033 | 1146 | ||
1034 | compute_return_epc(regs); | 1147 | compute_return_epc(regs); |
1035 | value = regs->regs[insn.i_format.rt]; | 1148 | value = regs->regs[insn.i_format.rt]; |
1036 | StoreW(addr, value, res); | 1149 | |
1150 | if (config_enabled(CONFIG_EVA)) { | ||
1151 | if (segment_eq(get_fs(), get_ds())) | ||
1152 | StoreW(addr, value, res); | ||
1153 | else | ||
1154 | StoreWE(addr, value, res); | ||
1155 | } else { | ||
1156 | StoreW(addr, value, res); | ||
1157 | } | ||
1158 | |||
1037 | if (res) | 1159 | if (res) |
1038 | goto fault; | 1160 | goto fault; |
1039 | break; | 1161 | break; |
diff --git a/arch/mips/loongson/loongson-3/irq.c b/arch/mips/loongson/loongson-3/irq.c index 21221edda7a9..0f75b6b3d218 100644 --- a/arch/mips/loongson/loongson-3/irq.c +++ b/arch/mips/loongson/loongson-3/irq.c | |||
@@ -44,6 +44,7 @@ void mach_irq_dispatch(unsigned int pending) | |||
44 | 44 | ||
45 | static struct irqaction cascade_irqaction = { | 45 | static struct irqaction cascade_irqaction = { |
46 | .handler = no_action, | 46 | .handler = no_action, |
47 | .flags = IRQF_NO_SUSPEND, | ||
47 | .name = "cascade", | 48 | .name = "cascade", |
48 | }; | 49 | }; |
49 | 50 | ||
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c index 7e3ea7766822..77d96db8253c 100644 --- a/arch/mips/mm/cache.c +++ b/arch/mips/mm/cache.c | |||
@@ -119,36 +119,37 @@ void __flush_anon_page(struct page *page, unsigned long vmaddr) | |||
119 | 119 | ||
120 | EXPORT_SYMBOL(__flush_anon_page); | 120 | EXPORT_SYMBOL(__flush_anon_page); |
121 | 121 | ||
122 | static void mips_flush_dcache_from_pte(pte_t pteval, unsigned long address) | 122 | void __flush_icache_page(struct vm_area_struct *vma, struct page *page) |
123 | { | ||
124 | unsigned long addr; | ||
125 | |||
126 | if (PageHighMem(page)) | ||
127 | return; | ||
128 | |||
129 | addr = (unsigned long) page_address(page); | ||
130 | flush_data_cache_page(addr); | ||
131 | } | ||
132 | EXPORT_SYMBOL_GPL(__flush_icache_page); | ||
133 | |||
134 | void __update_cache(struct vm_area_struct *vma, unsigned long address, | ||
135 | pte_t pte) | ||
123 | { | 136 | { |
124 | struct page *page; | 137 | struct page *page; |
125 | unsigned long pfn = pte_pfn(pteval); | 138 | unsigned long pfn, addr; |
139 | int exec = (vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc; | ||
126 | 140 | ||
141 | pfn = pte_pfn(pte); | ||
127 | if (unlikely(!pfn_valid(pfn))) | 142 | if (unlikely(!pfn_valid(pfn))) |
128 | return; | 143 | return; |
129 | |||
130 | page = pfn_to_page(pfn); | 144 | page = pfn_to_page(pfn); |
131 | if (page_mapping(page) && Page_dcache_dirty(page)) { | 145 | if (page_mapping(page) && Page_dcache_dirty(page)) { |
132 | unsigned long page_addr = (unsigned long) page_address(page); | 146 | addr = (unsigned long) page_address(page); |
133 | 147 | if (exec || pages_do_alias(addr, address & PAGE_MASK)) | |
134 | if (!cpu_has_ic_fills_f_dc || | 148 | flush_data_cache_page(addr); |
135 | pages_do_alias(page_addr, address & PAGE_MASK)) | ||
136 | flush_data_cache_page(page_addr); | ||
137 | ClearPageDcacheDirty(page); | 149 | ClearPageDcacheDirty(page); |
138 | } | 150 | } |
139 | } | 151 | } |
140 | 152 | ||
141 | void set_pte_at(struct mm_struct *mm, unsigned long addr, | ||
142 | pte_t *ptep, pte_t pteval) | ||
143 | { | ||
144 | if (cpu_has_dc_aliases || !cpu_has_ic_fills_f_dc) { | ||
145 | if (pte_present(pteval)) | ||
146 | mips_flush_dcache_from_pte(pteval, addr); | ||
147 | } | ||
148 | |||
149 | set_pte(ptep, pteval); | ||
150 | } | ||
151 | |||
152 | unsigned long _page_cachable_default; | 153 | unsigned long _page_cachable_default; |
153 | EXPORT_SYMBOL(_page_cachable_default); | 154 | EXPORT_SYMBOL(_page_cachable_default); |
154 | 155 | ||
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 448cde372af0..faa5c9822ecc 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c | |||
@@ -96,7 +96,7 @@ static void *__kmap_pgprot(struct page *page, unsigned long addr, pgprot_t prot) | |||
96 | vaddr = __fix_to_virt(FIX_CMAP_END - idx); | 96 | vaddr = __fix_to_virt(FIX_CMAP_END - idx); |
97 | pte = mk_pte(page, prot); | 97 | pte = mk_pte(page, prot); |
98 | #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) | 98 | #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) |
99 | entrylo = pte.pte_high; | 99 | entrylo = pte_to_entrylo(pte.pte_high); |
100 | #else | 100 | #else |
101 | entrylo = pte_to_entrylo(pte_val(pte)); | 101 | entrylo = pte_to_entrylo(pte_val(pte)); |
102 | #endif | 102 | #endif |
@@ -106,6 +106,11 @@ static void *__kmap_pgprot(struct page *page, unsigned long addr, pgprot_t prot) | |||
106 | write_c0_entryhi(vaddr & (PAGE_MASK << 1)); | 106 | write_c0_entryhi(vaddr & (PAGE_MASK << 1)); |
107 | write_c0_entrylo0(entrylo); | 107 | write_c0_entrylo0(entrylo); |
108 | write_c0_entrylo1(entrylo); | 108 | write_c0_entrylo1(entrylo); |
109 | #ifdef CONFIG_XPA | ||
110 | entrylo = (pte.pte_low & _PFNX_MASK); | ||
111 | writex_c0_entrylo0(entrylo); | ||
112 | writex_c0_entrylo1(entrylo); | ||
113 | #endif | ||
109 | tlbidx = read_c0_wired(); | 114 | tlbidx = read_c0_wired(); |
110 | write_c0_wired(tlbidx + 1); | 115 | write_c0_wired(tlbidx + 1); |
111 | write_c0_index(tlbidx); | 116 | write_c0_index(tlbidx); |
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index 37ad381c3e5f..a27a088e6f9f 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c | |||
@@ -333,9 +333,17 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) | |||
333 | ptep = pte_offset_map(pmdp, address); | 333 | ptep = pte_offset_map(pmdp, address); |
334 | 334 | ||
335 | #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) | 335 | #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) |
336 | #ifdef CONFIG_XPA | ||
337 | write_c0_entrylo0(pte_to_entrylo(ptep->pte_high)); | ||
338 | writex_c0_entrylo0(ptep->pte_low & _PFNX_MASK); | ||
339 | ptep++; | ||
340 | write_c0_entrylo1(pte_to_entrylo(ptep->pte_high)); | ||
341 | writex_c0_entrylo1(ptep->pte_low & _PFNX_MASK); | ||
342 | #else | ||
336 | write_c0_entrylo0(ptep->pte_high); | 343 | write_c0_entrylo0(ptep->pte_high); |
337 | ptep++; | 344 | ptep++; |
338 | write_c0_entrylo1(ptep->pte_high); | 345 | write_c0_entrylo1(ptep->pte_high); |
346 | #endif | ||
339 | #else | 347 | #else |
340 | write_c0_entrylo0(pte_to_entrylo(pte_val(*ptep++))); | 348 | write_c0_entrylo0(pte_to_entrylo(pte_val(*ptep++))); |
341 | write_c0_entrylo1(pte_to_entrylo(pte_val(*ptep))); | 349 | write_c0_entrylo1(pte_to_entrylo(pte_val(*ptep))); |
@@ -355,6 +363,9 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) | |||
355 | void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, | 363 | void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, |
356 | unsigned long entryhi, unsigned long pagemask) | 364 | unsigned long entryhi, unsigned long pagemask) |
357 | { | 365 | { |
366 | #ifdef CONFIG_XPA | ||
367 | panic("Broken for XPA kernels"); | ||
368 | #else | ||
358 | unsigned long flags; | 369 | unsigned long flags; |
359 | unsigned long wired; | 370 | unsigned long wired; |
360 | unsigned long old_pagemask; | 371 | unsigned long old_pagemask; |
@@ -383,6 +394,7 @@ void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, | |||
383 | write_c0_pagemask(old_pagemask); | 394 | write_c0_pagemask(old_pagemask); |
384 | local_flush_tlb_all(); | 395 | local_flush_tlb_all(); |
385 | local_irq_restore(flags); | 396 | local_irq_restore(flags); |
397 | #endif | ||
386 | } | 398 | } |
387 | 399 | ||
388 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | 400 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 7c7469f56ec3..97c87027c17f 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c | |||
@@ -35,6 +35,17 @@ | |||
35 | #include <asm/uasm.h> | 35 | #include <asm/uasm.h> |
36 | #include <asm/setup.h> | 36 | #include <asm/setup.h> |
37 | 37 | ||
38 | static int __cpuinitdata mips_xpa_disabled; | ||
39 | |||
40 | static int __init xpa_disable(char *s) | ||
41 | { | ||
42 | mips_xpa_disabled = 1; | ||
43 | |||
44 | return 1; | ||
45 | } | ||
46 | |||
47 | __setup("noxpa", xpa_disable); | ||
48 | |||
38 | /* | 49 | /* |
39 | * TLB load/store/modify handlers. | 50 | * TLB load/store/modify handlers. |
40 | * | 51 | * |
@@ -231,14 +242,14 @@ static void output_pgtable_bits_defines(void) | |||
231 | pr_define("_PAGE_HUGE_SHIFT %d\n", _PAGE_HUGE_SHIFT); | 242 | pr_define("_PAGE_HUGE_SHIFT %d\n", _PAGE_HUGE_SHIFT); |
232 | pr_define("_PAGE_SPLITTING_SHIFT %d\n", _PAGE_SPLITTING_SHIFT); | 243 | pr_define("_PAGE_SPLITTING_SHIFT %d\n", _PAGE_SPLITTING_SHIFT); |
233 | #endif | 244 | #endif |
245 | #ifdef CONFIG_CPU_MIPSR2 | ||
234 | if (cpu_has_rixi) { | 246 | if (cpu_has_rixi) { |
235 | #ifdef _PAGE_NO_EXEC_SHIFT | 247 | #ifdef _PAGE_NO_EXEC_SHIFT |
236 | pr_define("_PAGE_NO_EXEC_SHIFT %d\n", _PAGE_NO_EXEC_SHIFT); | 248 | pr_define("_PAGE_NO_EXEC_SHIFT %d\n", _PAGE_NO_EXEC_SHIFT); |
237 | #endif | ||
238 | #ifdef _PAGE_NO_READ_SHIFT | ||
239 | pr_define("_PAGE_NO_READ_SHIFT %d\n", _PAGE_NO_READ_SHIFT); | 249 | pr_define("_PAGE_NO_READ_SHIFT %d\n", _PAGE_NO_READ_SHIFT); |
240 | #endif | 250 | #endif |
241 | } | 251 | } |
252 | #endif | ||
242 | pr_define("_PAGE_GLOBAL_SHIFT %d\n", _PAGE_GLOBAL_SHIFT); | 253 | pr_define("_PAGE_GLOBAL_SHIFT %d\n", _PAGE_GLOBAL_SHIFT); |
243 | pr_define("_PAGE_VALID_SHIFT %d\n", _PAGE_VALID_SHIFT); | 254 | pr_define("_PAGE_VALID_SHIFT %d\n", _PAGE_VALID_SHIFT); |
244 | pr_define("_PAGE_DIRTY_SHIFT %d\n", _PAGE_DIRTY_SHIFT); | 255 | pr_define("_PAGE_DIRTY_SHIFT %d\n", _PAGE_DIRTY_SHIFT); |
@@ -501,26 +512,9 @@ static void build_tlb_write_entry(u32 **p, struct uasm_label **l, | |||
501 | case tlb_indexed: tlbw = uasm_i_tlbwi; break; | 512 | case tlb_indexed: tlbw = uasm_i_tlbwi; break; |
502 | } | 513 | } |
503 | 514 | ||
504 | if (cpu_has_mips_r2_exec_hazard) { | 515 | if (cpu_has_mips_r2_r6) { |
505 | /* | 516 | if (cpu_has_mips_r2_exec_hazard) |
506 | * The architecture spec says an ehb is required here, | ||
507 | * but a number of cores do not have the hazard and | ||
508 | * using an ehb causes an expensive pipeline stall. | ||
509 | */ | ||
510 | switch (current_cpu_type()) { | ||
511 | case CPU_M14KC: | ||
512 | case CPU_74K: | ||
513 | case CPU_1074K: | ||
514 | case CPU_PROAPTIV: | ||
515 | case CPU_P5600: | ||
516 | case CPU_M5150: | ||
517 | case CPU_QEMU_GENERIC: | ||
518 | break; | ||
519 | |||
520 | default: | ||
521 | uasm_i_ehb(p); | 517 | uasm_i_ehb(p); |
522 | break; | ||
523 | } | ||
524 | tlbw(p); | 518 | tlbw(p); |
525 | return; | 519 | return; |
526 | } | 520 | } |
@@ -1028,12 +1022,27 @@ static void build_update_entries(u32 **p, unsigned int tmp, unsigned int ptep) | |||
1028 | } else { | 1022 | } else { |
1029 | int pte_off_even = sizeof(pte_t) / 2; | 1023 | int pte_off_even = sizeof(pte_t) / 2; |
1030 | int pte_off_odd = pte_off_even + sizeof(pte_t); | 1024 | int pte_off_odd = pte_off_even + sizeof(pte_t); |
1025 | #ifdef CONFIG_XPA | ||
1026 | const int scratch = 1; /* Our extra working register */ | ||
1031 | 1027 | ||
1032 | /* The pte entries are pre-shifted */ | 1028 | uasm_i_addu(p, scratch, 0, ptep); |
1033 | uasm_i_lw(p, tmp, pte_off_even, ptep); /* get even pte */ | 1029 | #endif |
1034 | UASM_i_MTC0(p, tmp, C0_ENTRYLO0); /* load it */ | 1030 | uasm_i_lw(p, tmp, pte_off_even, ptep); /* even pte */ |
1035 | uasm_i_lw(p, ptep, pte_off_odd, ptep); /* get odd pte */ | 1031 | uasm_i_lw(p, ptep, pte_off_odd, ptep); /* odd pte */ |
1036 | UASM_i_MTC0(p, ptep, C0_ENTRYLO1); /* load it */ | 1032 | UASM_i_ROTR(p, tmp, tmp, ilog2(_PAGE_GLOBAL)); |
1033 | UASM_i_ROTR(p, ptep, ptep, ilog2(_PAGE_GLOBAL)); | ||
1034 | UASM_i_MTC0(p, tmp, C0_ENTRYLO0); | ||
1035 | UASM_i_MTC0(p, ptep, C0_ENTRYLO1); | ||
1036 | #ifdef CONFIG_XPA | ||
1037 | uasm_i_lw(p, tmp, 0, scratch); | ||
1038 | uasm_i_lw(p, ptep, sizeof(pte_t), scratch); | ||
1039 | uasm_i_lui(p, scratch, 0xff); | ||
1040 | uasm_i_ori(p, scratch, scratch, 0xffff); | ||
1041 | uasm_i_and(p, tmp, scratch, tmp); | ||
1042 | uasm_i_and(p, ptep, scratch, ptep); | ||
1043 | uasm_i_mthc0(p, tmp, C0_ENTRYLO0); | ||
1044 | uasm_i_mthc0(p, ptep, C0_ENTRYLO1); | ||
1045 | #endif | ||
1037 | } | 1046 | } |
1038 | #else | 1047 | #else |
1039 | UASM_i_LW(p, tmp, 0, ptep); /* get even pte */ | 1048 | UASM_i_LW(p, tmp, 0, ptep); /* get even pte */ |
@@ -1534,8 +1543,14 @@ iPTE_SW(u32 **p, struct uasm_reloc **r, unsigned int pte, unsigned int ptr, | |||
1534 | { | 1543 | { |
1535 | #ifdef CONFIG_PHYS_ADDR_T_64BIT | 1544 | #ifdef CONFIG_PHYS_ADDR_T_64BIT |
1536 | unsigned int hwmode = mode & (_PAGE_VALID | _PAGE_DIRTY); | 1545 | unsigned int hwmode = mode & (_PAGE_VALID | _PAGE_DIRTY); |
1537 | #endif | ||
1538 | 1546 | ||
1547 | if (!cpu_has_64bits) { | ||
1548 | const int scratch = 1; /* Our extra working register */ | ||
1549 | |||
1550 | uasm_i_lui(p, scratch, (mode >> 16)); | ||
1551 | uasm_i_or(p, pte, pte, scratch); | ||
1552 | } else | ||
1553 | #endif | ||
1539 | uasm_i_ori(p, pte, pte, mode); | 1554 | uasm_i_ori(p, pte, pte, mode); |
1540 | #ifdef CONFIG_SMP | 1555 | #ifdef CONFIG_SMP |
1541 | # ifdef CONFIG_PHYS_ADDR_T_64BIT | 1556 | # ifdef CONFIG_PHYS_ADDR_T_64BIT |
@@ -1599,15 +1614,17 @@ build_pte_present(u32 **p, struct uasm_reloc **r, | |||
1599 | uasm_il_bbit0(p, r, pte, ilog2(_PAGE_PRESENT), lid); | 1614 | uasm_il_bbit0(p, r, pte, ilog2(_PAGE_PRESENT), lid); |
1600 | uasm_i_nop(p); | 1615 | uasm_i_nop(p); |
1601 | } else { | 1616 | } else { |
1602 | uasm_i_andi(p, t, pte, _PAGE_PRESENT); | 1617 | uasm_i_srl(p, t, pte, _PAGE_PRESENT_SHIFT); |
1618 | uasm_i_andi(p, t, t, 1); | ||
1603 | uasm_il_beqz(p, r, t, lid); | 1619 | uasm_il_beqz(p, r, t, lid); |
1604 | if (pte == t) | 1620 | if (pte == t) |
1605 | /* You lose the SMP race :-(*/ | 1621 | /* You lose the SMP race :-(*/ |
1606 | iPTE_LW(p, pte, ptr); | 1622 | iPTE_LW(p, pte, ptr); |
1607 | } | 1623 | } |
1608 | } else { | 1624 | } else { |
1609 | uasm_i_andi(p, t, pte, _PAGE_PRESENT | _PAGE_READ); | 1625 | uasm_i_srl(p, t, pte, _PAGE_PRESENT_SHIFT); |
1610 | uasm_i_xori(p, t, t, _PAGE_PRESENT | _PAGE_READ); | 1626 | uasm_i_andi(p, t, t, 3); |
1627 | uasm_i_xori(p, t, t, 3); | ||
1611 | uasm_il_bnez(p, r, t, lid); | 1628 | uasm_il_bnez(p, r, t, lid); |
1612 | if (pte == t) | 1629 | if (pte == t) |
1613 | /* You lose the SMP race :-(*/ | 1630 | /* You lose the SMP race :-(*/ |
@@ -1636,8 +1653,9 @@ build_pte_writable(u32 **p, struct uasm_reloc **r, | |||
1636 | { | 1653 | { |
1637 | int t = scratch >= 0 ? scratch : pte; | 1654 | int t = scratch >= 0 ? scratch : pte; |
1638 | 1655 | ||
1639 | uasm_i_andi(p, t, pte, _PAGE_PRESENT | _PAGE_WRITE); | 1656 | uasm_i_srl(p, t, pte, _PAGE_PRESENT_SHIFT); |
1640 | uasm_i_xori(p, t, t, _PAGE_PRESENT | _PAGE_WRITE); | 1657 | uasm_i_andi(p, t, t, 5); |
1658 | uasm_i_xori(p, t, t, 5); | ||
1641 | uasm_il_bnez(p, r, t, lid); | 1659 | uasm_il_bnez(p, r, t, lid); |
1642 | if (pte == t) | 1660 | if (pte == t) |
1643 | /* You lose the SMP race :-(*/ | 1661 | /* You lose the SMP race :-(*/ |
@@ -1673,7 +1691,8 @@ build_pte_modifiable(u32 **p, struct uasm_reloc **r, | |||
1673 | uasm_i_nop(p); | 1691 | uasm_i_nop(p); |
1674 | } else { | 1692 | } else { |
1675 | int t = scratch >= 0 ? scratch : pte; | 1693 | int t = scratch >= 0 ? scratch : pte; |
1676 | uasm_i_andi(p, t, pte, _PAGE_WRITE); | 1694 | uasm_i_srl(p, t, pte, _PAGE_WRITE_SHIFT); |
1695 | uasm_i_andi(p, t, t, 1); | ||
1677 | uasm_il_beqz(p, r, t, lid); | 1696 | uasm_il_beqz(p, r, t, lid); |
1678 | if (pte == t) | 1697 | if (pte == t) |
1679 | /* You lose the SMP race :-(*/ | 1698 | /* You lose the SMP race :-(*/ |
@@ -2286,6 +2305,11 @@ static void config_htw_params(void) | |||
2286 | 2305 | ||
2287 | pwsize = ilog2(PTRS_PER_PGD) << MIPS_PWSIZE_GDW_SHIFT; | 2306 | pwsize = ilog2(PTRS_PER_PGD) << MIPS_PWSIZE_GDW_SHIFT; |
2288 | pwsize |= ilog2(PTRS_PER_PTE) << MIPS_PWSIZE_PTW_SHIFT; | 2307 | pwsize |= ilog2(PTRS_PER_PTE) << MIPS_PWSIZE_PTW_SHIFT; |
2308 | |||
2309 | /* If XPA has been enabled, PTEs are 64-bit in size. */ | ||
2310 | if (read_c0_pagegrain() & PG_ELPA) | ||
2311 | pwsize |= 1; | ||
2312 | |||
2289 | write_c0_pwsize(pwsize); | 2313 | write_c0_pwsize(pwsize); |
2290 | 2314 | ||
2291 | /* Make sure everything is set before we enable the HTW */ | 2315 | /* Make sure everything is set before we enable the HTW */ |
@@ -2299,6 +2323,28 @@ static void config_htw_params(void) | |||
2299 | print_htw_config(); | 2323 | print_htw_config(); |
2300 | } | 2324 | } |
2301 | 2325 | ||
2326 | static void config_xpa_params(void) | ||
2327 | { | ||
2328 | #ifdef CONFIG_XPA | ||
2329 | unsigned int pagegrain; | ||
2330 | |||
2331 | if (mips_xpa_disabled) { | ||
2332 | pr_info("Extended Physical Addressing (XPA) disabled\n"); | ||
2333 | return; | ||
2334 | } | ||
2335 | |||
2336 | pagegrain = read_c0_pagegrain(); | ||
2337 | write_c0_pagegrain(pagegrain | PG_ELPA); | ||
2338 | back_to_back_c0_hazard(); | ||
2339 | pagegrain = read_c0_pagegrain(); | ||
2340 | |||
2341 | if (pagegrain & PG_ELPA) | ||
2342 | pr_info("Extended Physical Addressing (XPA) enabled\n"); | ||
2343 | else | ||
2344 | panic("Extended Physical Addressing (XPA) disabled"); | ||
2345 | #endif | ||
2346 | } | ||
2347 | |||
2302 | void build_tlb_refill_handler(void) | 2348 | void build_tlb_refill_handler(void) |
2303 | { | 2349 | { |
2304 | /* | 2350 | /* |
@@ -2363,8 +2409,9 @@ void build_tlb_refill_handler(void) | |||
2363 | } | 2409 | } |
2364 | if (cpu_has_local_ebase) | 2410 | if (cpu_has_local_ebase) |
2365 | build_r4000_tlb_refill_handler(); | 2411 | build_r4000_tlb_refill_handler(); |
2412 | if (cpu_has_xpa) | ||
2413 | config_xpa_params(); | ||
2366 | if (cpu_has_htw) | 2414 | if (cpu_has_htw) |
2367 | config_htw_params(); | 2415 | config_htw_params(); |
2368 | |||
2369 | } | 2416 | } |
2370 | } | 2417 | } |
diff --git a/arch/mips/mti-malta/malta-memory.c b/arch/mips/mti-malta/malta-memory.c index 32c27cb8e463..b769657be4d4 100644 --- a/arch/mips/mti-malta/malta-memory.c +++ b/arch/mips/mti-malta/malta-memory.c | |||
@@ -54,6 +54,12 @@ fw_memblock_t * __init fw_getmdesc(int eva) | |||
54 | pr_warn("memsize not set in YAMON, set to default (32Mb)\n"); | 54 | pr_warn("memsize not set in YAMON, set to default (32Mb)\n"); |
55 | physical_memsize = 0x02000000; | 55 | physical_memsize = 0x02000000; |
56 | } else { | 56 | } else { |
57 | if (memsize > (256 << 20)) { /* memsize should be capped to 256M */ | ||
58 | pr_warn("Unsupported memsize value (0x%lx) detected! " | ||
59 | "Using 0x10000000 (256M) instead\n", | ||
60 | memsize); | ||
61 | memsize = 256 << 20; | ||
62 | } | ||
57 | /* If ememsize is set, then set physical_memsize to that */ | 63 | /* If ememsize is set, then set physical_memsize to that */ |
58 | physical_memsize = ememsize ? : memsize; | 64 | physical_memsize = ememsize ? : memsize; |
59 | } | 65 | } |
diff --git a/arch/mips/netlogic/xlp/ahci-init-xlp2.c b/arch/mips/netlogic/xlp/ahci-init-xlp2.c index c83dbf3689e2..7b066a44e679 100644 --- a/arch/mips/netlogic/xlp/ahci-init-xlp2.c +++ b/arch/mips/netlogic/xlp/ahci-init-xlp2.c | |||
@@ -203,6 +203,7 @@ static u8 read_phy_reg(u64 regbase, u32 addr, u32 physel) | |||
203 | static void config_sata_phy(u64 regbase) | 203 | static void config_sata_phy(u64 regbase) |
204 | { | 204 | { |
205 | u32 port, i, reg; | 205 | u32 port, i, reg; |
206 | u8 val; | ||
206 | 207 | ||
207 | for (port = 0; port < 2; port++) { | 208 | for (port = 0; port < 2; port++) { |
208 | for (i = 0, reg = RXCDRCALFOSC0; reg <= CALDUTY; reg++, i++) | 209 | for (i = 0, reg = RXCDRCALFOSC0; reg <= CALDUTY; reg++, i++) |
@@ -210,6 +211,18 @@ static void config_sata_phy(u64 regbase) | |||
210 | 211 | ||
211 | for (i = 0, reg = RXDPIF; reg <= PPMDRIFTMAX_HI; reg++, i++) | 212 | for (i = 0, reg = RXDPIF; reg <= PPMDRIFTMAX_HI; reg++, i++) |
212 | write_phy_reg(regbase, reg, port, sata_phy_config2[i]); | 213 | write_phy_reg(regbase, reg, port, sata_phy_config2[i]); |
214 | |||
215 | /* Fix for PHY link up failures at lower temperatures */ | ||
216 | write_phy_reg(regbase, 0x800F, port, 0x1f); | ||
217 | |||
218 | val = read_phy_reg(regbase, 0x0029, port); | ||
219 | write_phy_reg(regbase, 0x0029, port, val | (0x7 << 1)); | ||
220 | |||
221 | val = read_phy_reg(regbase, 0x0056, port); | ||
222 | write_phy_reg(regbase, 0x0056, port, val & ~(1 << 3)); | ||
223 | |||
224 | val = read_phy_reg(regbase, 0x0018, port); | ||
225 | write_phy_reg(regbase, 0x0018, port, val & ~(0x7 << 0)); | ||
213 | } | 226 | } |
214 | } | 227 | } |
215 | 228 | ||
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index 300591c6278d..2eda01e6e08f 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile | |||
@@ -43,7 +43,7 @@ obj-$(CONFIG_SIBYTE_BCM1x80) += pci-bcm1480.o pci-bcm1480ht.o | |||
43 | obj-$(CONFIG_SNI_RM) += fixup-sni.o ops-sni.o | 43 | obj-$(CONFIG_SNI_RM) += fixup-sni.o ops-sni.o |
44 | obj-$(CONFIG_LANTIQ) += fixup-lantiq.o | 44 | obj-$(CONFIG_LANTIQ) += fixup-lantiq.o |
45 | obj-$(CONFIG_PCI_LANTIQ) += pci-lantiq.o ops-lantiq.o | 45 | obj-$(CONFIG_PCI_LANTIQ) += pci-lantiq.o ops-lantiq.o |
46 | obj-$(CONFIG_SOC_RT2880) += pci-rt2880.o | 46 | obj-$(CONFIG_SOC_RT288X) += pci-rt2880.o |
47 | obj-$(CONFIG_SOC_RT3883) += pci-rt3883.o | 47 | obj-$(CONFIG_SOC_RT3883) += pci-rt3883.o |
48 | obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o | 48 | obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o |
49 | obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o | 49 | obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o |
diff --git a/arch/mips/pci/pci-octeon.c b/arch/mips/pci/pci-octeon.c index a04af55d89f1..c258cd406fbb 100644 --- a/arch/mips/pci/pci-octeon.c +++ b/arch/mips/pci/pci-octeon.c | |||
@@ -214,6 +214,8 @@ const char *octeon_get_pci_interrupts(void) | |||
214 | return "AAABAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; | 214 | return "AAABAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; |
215 | case CVMX_BOARD_TYPE_BBGW_REF: | 215 | case CVMX_BOARD_TYPE_BBGW_REF: |
216 | return "AABCD"; | 216 | return "AABCD"; |
217 | case CVMX_BOARD_TYPE_CUST_DSR1000N: | ||
218 | return "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"; | ||
217 | case CVMX_BOARD_TYPE_THUNDER: | 219 | case CVMX_BOARD_TYPE_THUNDER: |
218 | case CVMX_BOARD_TYPE_EBH3000: | 220 | case CVMX_BOARD_TYPE_EBH3000: |
219 | default: | 221 | default: |
@@ -271,9 +273,6 @@ static int octeon_read_config(struct pci_bus *bus, unsigned int devfn, | |||
271 | pci_addr.s.func = devfn & 0x7; | 273 | pci_addr.s.func = devfn & 0x7; |
272 | pci_addr.s.reg = reg; | 274 | pci_addr.s.reg = reg; |
273 | 275 | ||
274 | #if PCI_CONFIG_SPACE_DELAY | ||
275 | udelay(PCI_CONFIG_SPACE_DELAY); | ||
276 | #endif | ||
277 | switch (size) { | 276 | switch (size) { |
278 | case 4: | 277 | case 4: |
279 | *val = le32_to_cpu(cvmx_read64_uint32(pci_addr.u64)); | 278 | *val = le32_to_cpu(cvmx_read64_uint32(pci_addr.u64)); |
@@ -308,9 +307,6 @@ static int octeon_write_config(struct pci_bus *bus, unsigned int devfn, | |||
308 | pci_addr.s.func = devfn & 0x7; | 307 | pci_addr.s.func = devfn & 0x7; |
309 | pci_addr.s.reg = reg; | 308 | pci_addr.s.reg = reg; |
310 | 309 | ||
311 | #if PCI_CONFIG_SPACE_DELAY | ||
312 | udelay(PCI_CONFIG_SPACE_DELAY); | ||
313 | #endif | ||
314 | switch (size) { | 310 | switch (size) { |
315 | case 4: | 311 | case 4: |
316 | cvmx_write64_uint32(pci_addr.u64, cpu_to_le32(val)); | 312 | cvmx_write64_uint32(pci_addr.u64, cpu_to_le32(val)); |
diff --git a/arch/mips/pci/pcie-octeon.c b/arch/mips/pci/pcie-octeon.c index 1bb0b2bf8d6e..99f3db4f0a9b 100644 --- a/arch/mips/pci/pcie-octeon.c +++ b/arch/mips/pci/pcie-octeon.c | |||
@@ -1762,14 +1762,6 @@ static int octeon_pcie_write_config(unsigned int pcie_port, struct pci_bus *bus, | |||
1762 | default: | 1762 | default: |
1763 | return PCIBIOS_FUNC_NOT_SUPPORTED; | 1763 | return PCIBIOS_FUNC_NOT_SUPPORTED; |
1764 | } | 1764 | } |
1765 | #if PCI_CONFIG_SPACE_DELAY | ||
1766 | /* | ||
1767 | * Delay on writes so that devices have time to come up. Some | ||
1768 | * bridges need this to allow time for the secondary busses to | ||
1769 | * work | ||
1770 | */ | ||
1771 | udelay(PCI_CONFIG_SPACE_DELAY); | ||
1772 | #endif | ||
1773 | return PCIBIOS_SUCCESSFUL; | 1765 | return PCIBIOS_SUCCESSFUL; |
1774 | } | 1766 | } |
1775 | 1767 | ||
diff --git a/arch/mips/ralink/Kconfig b/arch/mips/ralink/Kconfig index b1c52ca580f9..e9bc8c96174e 100644 --- a/arch/mips/ralink/Kconfig +++ b/arch/mips/ralink/Kconfig | |||
@@ -7,6 +7,11 @@ config CLKEVT_RT3352 | |||
7 | select CLKSRC_OF | 7 | select CLKSRC_OF |
8 | select CLKSRC_MMIO | 8 | select CLKSRC_MMIO |
9 | 9 | ||
10 | config RALINK_ILL_ACC | ||
11 | bool | ||
12 | depends on SOC_RT305X | ||
13 | default y | ||
14 | |||
10 | choice | 15 | choice |
11 | prompt "Ralink SoC selection" | 16 | prompt "Ralink SoC selection" |
12 | default SOC_RT305X | 17 | default SOC_RT305X |
diff --git a/drivers/ssb/Kconfig b/drivers/ssb/Kconfig index 75b3603906c1..f0d22cdb51cd 100644 --- a/drivers/ssb/Kconfig +++ b/drivers/ssb/Kconfig | |||
@@ -130,6 +130,7 @@ config SSB_DRIVER_MIPS | |||
130 | bool "SSB Broadcom MIPS core driver" | 130 | bool "SSB Broadcom MIPS core driver" |
131 | depends on SSB && MIPS | 131 | depends on SSB && MIPS |
132 | select SSB_SERIAL | 132 | select SSB_SERIAL |
133 | select SSB_SFLASH | ||
133 | help | 134 | help |
134 | Driver for the Sonics Silicon Backplane attached | 135 | Driver for the Sonics Silicon Backplane attached |
135 | Broadcom MIPS core. | 136 | Broadcom MIPS core. |