Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'for-linus' of git://git.linaro.org/people/rmk/linux-arm

Pull ARM updates from Russell King:
"This contains the usual updates from other people (listed below) and
the usual random muddle of miscellaneous ARM updates which cover some
low priority bug fixes and performance improvements.

I've started to put the pull request wording into the merge commits,
which are:

- NoMMU stuff:

This includes the following series sent earlier to the list:
- nommu-fixes
- R7 Support
- MPU support

I've left out the ARCH_MULTIPLATFORM/!MMU stuff that Arnd and I
were discussing today until we've reached a conclusion/that's had
some more review.

This is rebased (and re-tested) on your devel-stable branch because
otherwise there were going to be conflicts with Uwe's V7M work now
that you've merged that. I've included the fix for limiting MPU to
CPU_V7.

- Huge page support

These changes bring both HugeTLB support and Transparent HugePage
(THP) support to ARM. Only long descriptors (LPAE) are supported
in this series.

The code has been tested on an Arndale board (Exynos 5250).

- LPAE updates

Please pull these miscellaneous LPAE fixes I've been collecting for
a while now for 3.11. They've been tested and reviewed by quite a
few people, and most of the patches are pretty trivial. -- Will Deacon.

- arch_timer cleanups

Please pull these arch_timer cleanups I've been holding onto for a
while. They're the same as my last posting, but have been rebased
to v3.10-rc3.

- mpidr linearisation (multiprocessor id register - identifies which
CPU number we are in the system)

This patch series that implements MPIDR linearization through a
simple hashing algorithm and updates current cpu_{suspend}/{resume}
code to use the newly created hash structures to retrieve context
pointers. It represents a stepping stone for the implementation of
power management code on forthcoming multi-cluster ARM systems.

It has been tested on TC2 (dual cluster A15xA7 system), iMX6q,
OMAP4 and Tegra, with processors hitting low-power states requiring
warm-boot resume through the cpu_resume code path"

* 'for-linus' of git://git.linaro.org/people/rmk/linux-arm: (77 commits)
ARM: 7775/1: mm: Remove do_sect_fault from LPAE code
ARM: 7777/1: Avoid extra calls to the C compiler
ARM: 7774/1: Fix dtb dependency to use order-only prerequisites
ARM: 7770/1: remove residual ARMv2 support from decompressor
ARM: 7769/1: Cortex-A15: fix erratum 798181 implementation
ARM: 7768/1: prevent risks of out-of-bound access in ASID allocator
ARM: 7767/1: let the ASID allocator handle suspended animation
ARM: 7766/1: versatile: don't mark pen as __INIT
ARM: 7765/1: perf: Record the user-mode PC in the call chain.
ARM: 7735/2: Preserve the user r/w register TPIDRURW on context switch and fork
ARM: kernel: implement stack pointer save array through MPIDR hashing
ARM: kernel: build MPIDR hash function data structure
ARM: mpu: Ensure that MPU depends on CPU_V7
ARM: mpu: protect the vectors page with an MPU region
ARM: mpu: Allow enabling of the MPU via kconfig
ARM: 7758/1: introduce config HAS_BANDGAP
ARM: 7757/1: mm: don't flush icache in switch_mm with hardware broadcasting
ARM: 7751/1: zImage: don't overwrite ourself with a page table
ARM: 7749/1: spinlock: retry trylock operation if strex fails on free lock
ARM: 7748/1: oabi: handle faults when loading swi instruction from userspace
...

+1989 -420
+3
Documentation/devicetree/bindings/arm/l2cc.txt
··· 16 16 performs the same operation). 17 17 "marvell,"aurora-outer-cache: Marvell Controller designed to be 18 18 compatible with the ARM one with outer cache mode. 19 + "bcm,bcm11351-a2-pl310-cache": For Broadcom bcm11351 chipset where an 20 + offset needs to be added to the address before passing down to the L2 21 + cache controller 19 22 - cache-unified : Specifies the cache is a unified cache. 20 23 - cache-level : Should be set to 2 for a level 2 cache. 21 24 - reg : Physical base address and size of cache controller's memory mapped
+13 -2
arch/arm/Kconfig
··· 175 175 and that the relevant menu configurations are displayed for 176 176 it. 177 177 178 + config ARCH_HAS_BANDGAP 179 + bool 180 + 178 181 config GENERIC_HWEIGHT 179 182 bool 180 183 default y ··· 1453 1450 depends on CPU_V6K || CPU_V7 1454 1451 depends on GENERIC_CLOCKEVENTS 1455 1452 depends on HAVE_SMP 1456 - depends on MMU 1453 + depends on MMU || ARM_MPU 1457 1454 select USE_GENERIC_SMP_HELPERS 1458 1455 help 1459 1456 This enables support for systems with more than one CPU. If you have ··· 1474 1471 1475 1472 config SMP_ON_UP 1476 1473 bool "Allow booting SMP kernel on uniprocessor systems (EXPERIMENTAL)" 1477 - depends on SMP && !XIP_KERNEL 1474 + depends on SMP && !XIP_KERNEL && MMU 1478 1475 default y 1479 1476 help 1480 1477 SMP kernels contain instructions which fail on non-SMP processors. ··· 1746 1743 help 1747 1744 Enable hardware performance counter support for perf events. If 1748 1745 disabled, perf events will use software events only. 1746 + 1747 + config SYS_SUPPORTS_HUGETLBFS 1748 + def_bool y 1749 + depends on ARM_LPAE 1750 + 1751 + config HAVE_ARCH_TRANSPARENT_HUGEPAGE 1752 + def_bool y 1753 + depends on ARM_LPAE 1749 1754 1750 1755 source "mm/Kconfig" 1751 1756
+12
arch/arm/Kconfig-nommu
··· 50 50 Otherwise, say 'y' here. In this case, the kernel will require 51 51 external support to redirect the hardware exception vectors to 52 52 the writable versions located at DRAM_BASE. 53 + 54 + config ARM_MPU 55 + bool 'Use the ARM v7 PMSA Compliant MPU' 56 + depends on CPU_V7 57 + default y 58 + help 59 + Some ARM systems without an MMU have instead a Memory Protection 60 + Unit (MPU) that defines the type and permissions for regions of 61 + memory. 62 + 63 + If your CPU has an MPU then you should choose 'y' here unless you 64 + know that you do not want to use the MPU.
+9 -1
arch/arm/Kconfig.debug
··· 550 550 of the tiles using the RS1 memory map, including all new A-class 551 551 core tiles, FPGA-based SMMs and software models. 552 552 553 + config DEBUG_VEXPRESS_UART0_CRX 554 + bool "Use PL011 UART0 at 0xb0090000 (Cortex-R compliant tiles)" 555 + depends on ARCH_VEXPRESS && !MMU 556 + help 557 + This option selects UART0 at 0xb0090000. This is appropriate for 558 + Cortex-R series tiles and SMMs, such as Cortex-R5 and Cortex-R7 559 + 553 560 config DEBUG_VT8500_UART0 554 561 bool "Use UART0 on VIA/Wondermedia SoCs" 555 562 depends on ARCH_VT8500 ··· 796 789 default "debug/u300.S" if DEBUG_U300_UART 797 790 default "debug/ux500.S" if DEBUG_UX500_UART 798 791 default "debug/vexpress.S" if DEBUG_VEXPRESS_UART0_DETECT || \ 799 - DEBUG_VEXPRESS_UART0_CA9 || DEBUG_VEXPRESS_UART0_RS1 792 + DEBUG_VEXPRESS_UART0_CA9 || DEBUG_VEXPRESS_UART0_RS1 || \ 793 + DEBUG_VEXPRESS_UART0_CRX 800 794 default "debug/vt8500.S" if DEBUG_VT8500_UART0 801 795 default "debug/zynq.S" if DEBUG_ZYNQ_UART0 || DEBUG_ZYNQ_UART1 802 796 default "mach/debug-macro.S"
+34 -27
arch/arm/Makefile
··· 59 59 # Note that GCC does not numerically define an architecture version 60 60 # macro, but instead defines a whole series of macros which makes 61 61 # testing for a specific architecture or later rather impossible. 62 - arch-$(CONFIG_CPU_32v7M) :=-D__LINUX_ARM_ARCH__=7 -march=armv7-m -Wa,-march=armv7-m 63 - arch-$(CONFIG_CPU_32v7) :=-D__LINUX_ARM_ARCH__=7 $(call cc-option,-march=armv7-a,-march=armv5t -Wa$(comma)-march=armv7-a) 64 - arch-$(CONFIG_CPU_32v6) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6,-march=armv5t -Wa$(comma)-march=armv6) 62 + arch-$(CONFIG_CPU_32v7M) =-D__LINUX_ARM_ARCH__=7 -march=armv7-m -Wa,-march=armv7-m 63 + arch-$(CONFIG_CPU_32v7) =-D__LINUX_ARM_ARCH__=7 $(call cc-option,-march=armv7-a,-march=armv5t -Wa$(comma)-march=armv7-a) 64 + arch-$(CONFIG_CPU_32v6) =-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6,-march=armv5t -Wa$(comma)-march=armv6) 65 65 # Only override the compiler option if ARMv6. The ARMv6K extensions are 66 66 # always available in ARMv7 67 67 ifeq ($(CONFIG_CPU_32v6),y) 68 - arch-$(CONFIG_CPU_32v6K) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6k,-march=armv5t -Wa$(comma)-march=armv6k) 68 + arch-$(CONFIG_CPU_32v6K) =-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6k,-march=armv5t -Wa$(comma)-march=armv6k) 69 69 endif 70 - arch-$(CONFIG_CPU_32v5) :=-D__LINUX_ARM_ARCH__=5 $(call cc-option,-march=armv5te,-march=armv4t) 71 - arch-$(CONFIG_CPU_32v4T) :=-D__LINUX_ARM_ARCH__=4 -march=armv4t 72 - arch-$(CONFIG_CPU_32v4) :=-D__LINUX_ARM_ARCH__=4 -march=armv4 73 - arch-$(CONFIG_CPU_32v3) :=-D__LINUX_ARM_ARCH__=3 -march=armv3 70 + arch-$(CONFIG_CPU_32v5) =-D__LINUX_ARM_ARCH__=5 $(call cc-option,-march=armv5te,-march=armv4t) 71 + arch-$(CONFIG_CPU_32v4T) =-D__LINUX_ARM_ARCH__=4 -march=armv4t 72 + arch-$(CONFIG_CPU_32v4) =-D__LINUX_ARM_ARCH__=4 -march=armv4 73 + arch-$(CONFIG_CPU_32v3) =-D__LINUX_ARM_ARCH__=3 -march=armv3 74 + 75 + # Evaluate arch cc-option calls now 76 + arch-y := $(arch-y) 74 77 75 78 # This selects how we optimise for the processor. 76 - tune-$(CONFIG_CPU_ARM7TDMI) :=-mtune=arm7tdmi 77 - tune-$(CONFIG_CPU_ARM720T) :=-mtune=arm7tdmi 78 - tune-$(CONFIG_CPU_ARM740T) :=-mtune=arm7tdmi 79 - tune-$(CONFIG_CPU_ARM9TDMI) :=-mtune=arm9tdmi 80 - tune-$(CONFIG_CPU_ARM940T) :=-mtune=arm9tdmi 81 - tune-$(CONFIG_CPU_ARM946E) :=$(call cc-option,-mtune=arm9e,-mtune=arm9tdmi) 82 - tune-$(CONFIG_CPU_ARM920T) :=-mtune=arm9tdmi 83 - tune-$(CONFIG_CPU_ARM922T) :=-mtune=arm9tdmi 84 - tune-$(CONFIG_CPU_ARM925T) :=-mtune=arm9tdmi 85 - tune-$(CONFIG_CPU_ARM926T) :=-mtune=arm9tdmi 86 - tune-$(CONFIG_CPU_FA526) :=-mtune=arm9tdmi 87 - tune-$(CONFIG_CPU_SA110) :=-mtune=strongarm110 88 - tune-$(CONFIG_CPU_SA1100) :=-mtune=strongarm1100 89 - tune-$(CONFIG_CPU_XSCALE) :=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale 90 - tune-$(CONFIG_CPU_XSC3) :=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale 91 - tune-$(CONFIG_CPU_FEROCEON) :=$(call cc-option,-mtune=marvell-f,-mtune=xscale) 92 - tune-$(CONFIG_CPU_V6) :=$(call cc-option,-mtune=arm1136j-s,-mtune=strongarm) 93 - tune-$(CONFIG_CPU_V6K) :=$(call cc-option,-mtune=arm1136j-s,-mtune=strongarm) 79 + tune-$(CONFIG_CPU_ARM7TDMI) =-mtune=arm7tdmi 80 + tune-$(CONFIG_CPU_ARM720T) =-mtune=arm7tdmi 81 + tune-$(CONFIG_CPU_ARM740T) =-mtune=arm7tdmi 82 + tune-$(CONFIG_CPU_ARM9TDMI) =-mtune=arm9tdmi 83 + tune-$(CONFIG_CPU_ARM940T) =-mtune=arm9tdmi 84 + tune-$(CONFIG_CPU_ARM946E) =$(call cc-option,-mtune=arm9e,-mtune=arm9tdmi) 85 + tune-$(CONFIG_CPU_ARM920T) =-mtune=arm9tdmi 86 + tune-$(CONFIG_CPU_ARM922T) =-mtune=arm9tdmi 87 + tune-$(CONFIG_CPU_ARM925T) =-mtune=arm9tdmi 88 + tune-$(CONFIG_CPU_ARM926T) =-mtune=arm9tdmi 89 + tune-$(CONFIG_CPU_FA526) =-mtune=arm9tdmi 90 + tune-$(CONFIG_CPU_SA110) =-mtune=strongarm110 91 + tune-$(CONFIG_CPU_SA1100) =-mtune=strongarm1100 92 + tune-$(CONFIG_CPU_XSCALE) =$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale 93 + tune-$(CONFIG_CPU_XSC3) =$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale 94 + tune-$(CONFIG_CPU_FEROCEON) =$(call cc-option,-mtune=marvell-f,-mtune=xscale) 95 + tune-$(CONFIG_CPU_V6) =$(call cc-option,-mtune=arm1136j-s,-mtune=strongarm) 96 + tune-$(CONFIG_CPU_V6K) =$(call cc-option,-mtune=arm1136j-s,-mtune=strongarm) 97 + 98 + # Evaluate tune cc-option calls now 99 + tune-y := $(tune-y) 94 100 95 101 ifeq ($(CONFIG_AEABI),y) 96 102 CFLAGS_ABI :=-mabi=aapcs-linux -mno-thumb-interwork ··· 301 295 zinstall uinstall install: vmlinux 302 296 $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@ 303 297 304 - %.dtb: scripts 298 + %.dtb: | scripts 305 299 $(Q)$(MAKE) $(build)=$(boot)/dts MACHINE=$(MACHINE) $(boot)/dts/$@ 306 300 301 + PHONY += dtbs 307 302 dtbs: scripts 308 303 $(Q)$(MAKE) $(build)=$(boot)/dts MACHINE=$(MACHINE) dtbs 309 304
+38 -6
arch/arm/boot/compressed/atags_to_fdt.c
··· 53 53 return fdt_getprop(fdt, offset, property, len); 54 54 } 55 55 56 + static uint32_t get_cell_size(const void *fdt) 57 + { 58 + int len; 59 + uint32_t cell_size = 1; 60 + const uint32_t *size_len = getprop(fdt, "/", "#size-cells", &len); 61 + 62 + if (size_len) 63 + cell_size = fdt32_to_cpu(*size_len); 64 + return cell_size; 65 + } 66 + 56 67 static void merge_fdt_bootargs(void *fdt, const char *fdt_cmdline) 57 68 { 58 69 char cmdline[COMMAND_LINE_SIZE]; ··· 106 95 int atags_to_fdt(void *atag_list, void *fdt, int total_space) 107 96 { 108 97 struct tag *atag = atag_list; 109 - uint32_t mem_reg_property[2 * NR_BANKS]; 98 + /* In the case of 64 bits memory size, need to reserve 2 cells for 99 + * address and size for each bank */ 100 + uint32_t mem_reg_property[2 * 2 * NR_BANKS]; 110 101 int memcount = 0; 111 - int ret; 102 + int ret, memsize; 112 103 113 104 /* make sure we've got an aligned pointer */ 114 105 if ((u32)atag_list & 0x3) ··· 150 137 continue; 151 138 if (!atag->u.mem.size) 152 139 continue; 153 - mem_reg_property[memcount++] = cpu_to_fdt32(atag->u.mem.start); 154 - mem_reg_property[memcount++] = cpu_to_fdt32(atag->u.mem.size); 140 + memsize = get_cell_size(fdt); 141 + 142 + if (memsize == 2) { 143 + /* if memsize is 2, that means that 144 + * each data needs 2 cells of 32 bits, 145 + * so the data are 64 bits */ 146 + uint64_t *mem_reg_prop64 = 147 + (uint64_t *)mem_reg_property; 148 + mem_reg_prop64[memcount++] = 149 + cpu_to_fdt64(atag->u.mem.start); 150 + mem_reg_prop64[memcount++] = 151 + cpu_to_fdt64(atag->u.mem.size); 152 + } else { 153 + mem_reg_property[memcount++] = 154 + cpu_to_fdt32(atag->u.mem.start); 155 + mem_reg_property[memcount++] = 156 + cpu_to_fdt32(atag->u.mem.size); 157 + } 158 + 155 159 } else if (atag->hdr.tag == ATAG_INITRD2) { 156 160 uint32_t initrd_start, initrd_size; 157 161 initrd_start = atag->u.initrd.start; ··· 180 150 } 181 151 } 182 152 183 - if (memcount) 184 - setprop(fdt, "/memory", "reg", mem_reg_property, 4*memcount); 153 + if (memcount) { 154 + setprop(fdt, "/memory", "reg", mem_reg_property, 155 + 4 * memcount * memsize); 156 + } 185 157 186 158 return fdt_pack(fdt); 187 159 }
+30 -10
arch/arm/boot/compressed/head.S
··· 142 142 mov r7, r1 @ save architecture ID 143 143 mov r8, r2 @ save atags pointer 144 144 145 - #ifndef __ARM_ARCH_2__ 146 145 /* 147 146 * Booting from Angel - need to enter SVC mode and disable 148 147 * FIQs/IRQs (numeric definitions from angel arm.h source). ··· 157 158 safe_svcmode_maskall r0 158 159 msr spsr_cxsf, r9 @ Save the CPU boot mode in 159 160 @ SPSR 160 - #else 161 - teqp pc, #0x0c000003 @ turn off interrupts 162 - #endif 163 - 164 161 /* 165 162 * Note that some cache flushing and other stuff may 166 163 * be needed here - is there an Angel SWI call for this? ··· 178 183 ldr r4, =zreladdr 179 184 #endif 180 185 181 - bl cache_on 186 + /* 187 + * Set up a page table only if it won't overwrite ourself. 188 + * That means r4 < pc && r4 - 16k page directory > &_end. 189 + * Given that r4 > &_end is most unfrequent, we add a rough 190 + * additional 1MB of room for a possible appended DTB. 191 + */ 192 + mov r0, pc 193 + cmp r0, r4 194 + ldrcc r0, LC0+32 195 + addcc r0, r0, pc 196 + cmpcc r4, r0 197 + orrcc r4, r4, #1 @ remember we skipped cache_on 198 + blcs cache_on 182 199 183 200 restart: adr r0, LC0 184 201 ldmia r0, {r1, r2, r3, r6, r10, r11, r12} ··· 236 229 * r0 = delta 237 230 * r2 = BSS start 238 231 * r3 = BSS end 239 - * r4 = final kernel address 232 + * r4 = final kernel address (possibly with LSB set) 240 233 * r5 = appended dtb size (still unknown) 241 234 * r6 = _edata 242 235 * r7 = architecture ID ··· 284 277 */ 285 278 cmp r0, #1 286 279 sub r0, r4, #TEXT_OFFSET 280 + bic r0, r0, #1 287 281 add r0, r0, #0x100 288 282 mov r1, r6 289 283 sub r2, sp, r6 ··· 331 323 332 324 /* 333 325 * Check to see if we will overwrite ourselves. 334 - * r4 = final kernel address 326 + * r4 = final kernel address (possibly with LSB set) 335 327 * r9 = size of decompressed image 336 328 * r10 = end of this image, including bss/stack/malloc space if non XIP 337 329 * We basically want: 338 330 * r4 - 16k page directory >= r10 -> OK 339 331 * r4 + image length <= address of wont_overwrite -> OK 332 + * Note: the possible LSB in r4 is harmless here. 340 333 */ 341 334 add r10, r10, #16384 342 335 cmp r4, r10 ··· 399 390 add sp, sp, r6 400 391 #endif 401 392 402 - bl cache_clean_flush 393 + tst r4, #1 394 + bleq cache_clean_flush 403 395 404 396 adr r0, BSYM(restart) 405 397 add r0, r0, r6 ··· 412 402 * r0 = delta 413 403 * r2 = BSS start 414 404 * r3 = BSS end 415 - * r4 = kernel execution address 405 + * r4 = kernel execution address (possibly with LSB set) 416 406 * r5 = appended dtb size (0 if not present) 417 407 * r7 = architecture ID 418 408 * r8 = atags pointer ··· 475 465 cmp r2, r3 476 466 blo 1b 477 467 468 + /* 469 + * Did we skip the cache setup earlier? 470 + * That is indicated by the LSB in r4. 471 + * Do it now if so. 472 + */ 473 + tst r4, #1 474 + bic r4, r4, #1 475 + blne cache_on 476 + 478 477 /* 479 478 * The C runtime environment should now be setup sufficiently. 480 479 * Set up some pointers, and start decompressing. ··· 532 513 .word _got_start @ r11 533 514 .word _got_end @ ip 534 515 .word .L_user_stack_end @ sp 516 + .word _end - restart + 16384 + 1024*1024 535 517 .size LC0, . - LC0 536 518 537 519 #ifdef CONFIG_ARCH_RPC
+4 -4
arch/arm/boot/dts/bcm11351.dtsi
··· 50 50 }; 51 51 52 52 L2: l2-cache { 53 - compatible = "arm,pl310-cache"; 54 - reg = <0x3ff20000 0x1000>; 55 - cache-unified; 56 - cache-level = <2>; 53 + compatible = "bcm,bcm11351-a2-pl310-cache"; 54 + reg = <0x3ff20000 0x1000>; 55 + cache-unified; 56 + cache-level = <2>; 57 57 }; 58 58 59 59 timer@35006000 {
+2 -2
arch/arm/common/mcpm_head.S
··· 32 32 1901: adr r0, 1902b 33 33 bl printascii 34 34 mov r0, r9 35 - bl printhex8 35 + bl printhex2 36 36 adr r0, 1903b 37 37 bl printascii 38 38 mov r0, r10 39 - bl printhex8 39 + bl printhex2 40 40 adr r0, 1904b 41 41 bl printascii 42 42 #endif
-5
arch/arm/common/mcpm_platsmp.c
··· 19 19 #include <asm/smp.h> 20 20 #include <asm/smp_plat.h> 21 21 22 - static void __init simple_smp_init_cpus(void) 23 - { 24 - } 25 - 26 22 static int __cpuinit mcpm_boot_secondary(unsigned int cpu, struct task_struct *idle) 27 23 { 28 24 unsigned int mpidr, pcpu, pcluster, ret; ··· 70 74 #endif 71 75 72 76 static struct smp_operations __initdata mcpm_smp_ops = { 73 - .smp_init_cpus = simple_smp_init_cpus, 74 77 .smp_boot_secondary = mcpm_boot_secondary, 75 78 .smp_secondary_init = mcpm_secondary_init, 76 79 #ifdef CONFIG_HOTPLUG_CPU
-9
arch/arm/include/asm/arch_timer.h
··· 80 80 return val; 81 81 } 82 82 83 - static inline u64 arch_counter_get_cntpct(void) 84 - { 85 - u64 cval; 86 - 87 - isb(); 88 - asm volatile("mrrc p15, 0, %Q0, %R0, c14" : "=r" (cval)); 89 - return cval; 90 - } 91 - 92 83 static inline u64 arch_counter_get_cntvct(void) 93 84 { 94 85 u64 cval;
+5
arch/arm/include/asm/cp15.h
··· 23 23 #define CR_RR (1 << 14) /* Round Robin cache replacement */ 24 24 #define CR_L4 (1 << 15) /* LDR pc can set T bit */ 25 25 #define CR_DT (1 << 16) 26 + #ifdef CONFIG_MMU 27 + #define CR_HA (1 << 17) /* Hardware management of Access Flag */ 28 + #else 29 + #define CR_BR (1 << 17) /* MPU Background region enable (PMSA) */ 30 + #endif 26 31 #define CR_IT (1 << 18) 27 32 #define CR_ST (1 << 19) 28 33 #define CR_FI (1 << 21) /* Fast interrupt (lower latency mode) */
+1
arch/arm/include/asm/cputype.h
··· 8 8 #define CPUID_CACHETYPE 1 9 9 #define CPUID_TCM 2 10 10 #define CPUID_TLBTYPE 3 11 + #define CPUID_MPUIR 4 11 12 #define CPUID_MPIDR 5 12 13 13 14 #ifdef CONFIG_CPU_V7M
+1 -1
arch/arm/include/asm/div64.h
··· 46 46 __rem; \ 47 47 }) 48 48 49 - #if __GNUC__ < 4 49 + #if __GNUC__ < 4 || !defined(CONFIG_AEABI) 50 50 51 51 /* 52 52 * gcc versions earlier than 4.0 are simply too problematic for the
+9 -9
arch/arm/include/asm/glue-proc.h
··· 230 230 # endif 231 231 #endif 232 232 233 - #ifdef CONFIG_CPU_PJ4B 234 - # ifdef CPU_NAME 235 - # undef MULTI_CPU 236 - # define MULTI_CPU 237 - # else 238 - # define CPU_NAME cpu_pj4b 239 - # endif 240 - #endif 241 - 242 233 #ifdef CONFIG_CPU_V7M 243 234 # ifdef CPU_NAME 244 235 # undef MULTI_CPU 245 236 # define MULTI_CPU 246 237 # else 247 238 # define CPU_NAME cpu_v7m 239 + # endif 240 + #endif 241 + 242 + #ifdef CONFIG_CPU_PJ4B 243 + # ifdef CPU_NAME 244 + # undef MULTI_CPU 245 + # define MULTI_CPU 246 + # else 247 + # define CPU_NAME cpu_pj4b 248 248 # endif 249 249 #endif 250 250
+71
arch/arm/include/asm/hugetlb-3level.h
··· 1 + /* 2 + * arch/arm/include/asm/hugetlb-3level.h 3 + * 4 + * Copyright (C) 2012 ARM Ltd. 5 + * 6 + * Based on arch/x86/include/asm/hugetlb.h. 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + * 17 + * You should have received a copy of the GNU General Public License 18 + * along with this program; if not, write to the Free Software 19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 + */ 21 + 22 + #ifndef _ASM_ARM_HUGETLB_3LEVEL_H 23 + #define _ASM_ARM_HUGETLB_3LEVEL_H 24 + 25 + 26 + /* 27 + * If our huge pte is non-zero then mark the valid bit. 28 + * This allows pte_present(huge_ptep_get(ptep)) to return true for non-zero 29 + * ptes. 30 + * (The valid bit is automatically cleared by set_pte_at for PROT_NONE ptes). 31 + */ 32 + static inline pte_t huge_ptep_get(pte_t *ptep) 33 + { 34 + pte_t retval = *ptep; 35 + if (pte_val(retval)) 36 + pte_val(retval) |= L_PTE_VALID; 37 + return retval; 38 + } 39 + 40 + static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, 41 + pte_t *ptep, pte_t pte) 42 + { 43 + set_pte_at(mm, addr, ptep, pte); 44 + } 45 + 46 + static inline void huge_ptep_clear_flush(struct vm_area_struct *vma, 47 + unsigned long addr, pte_t *ptep) 48 + { 49 + ptep_clear_flush(vma, addr, ptep); 50 + } 51 + 52 + static inline void huge_ptep_set_wrprotect(struct mm_struct *mm, 53 + unsigned long addr, pte_t *ptep) 54 + { 55 + ptep_set_wrprotect(mm, addr, ptep); 56 + } 57 + 58 + static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm, 59 + unsigned long addr, pte_t *ptep) 60 + { 61 + return ptep_get_and_clear(mm, addr, ptep); 62 + } 63 + 64 + static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma, 65 + unsigned long addr, pte_t *ptep, 66 + pte_t pte, int dirty) 67 + { 68 + return ptep_set_access_flags(vma, addr, ptep, pte, dirty); 69 + } 70 + 71 + #endif /* _ASM_ARM_HUGETLB_3LEVEL_H */
+84
arch/arm/include/asm/hugetlb.h
··· 1 + /* 2 + * arch/arm/include/asm/hugetlb.h 3 + * 4 + * Copyright (C) 2012 ARM Ltd. 5 + * 6 + * Based on arch/x86/include/asm/hugetlb.h 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + * 17 + * You should have received a copy of the GNU General Public License 18 + * along with this program; if not, write to the Free Software 19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 + */ 21 + 22 + #ifndef _ASM_ARM_HUGETLB_H 23 + #define _ASM_ARM_HUGETLB_H 24 + 25 + #include <asm/page.h> 26 + #include <asm-generic/hugetlb.h> 27 + 28 + #include <asm/hugetlb-3level.h> 29 + 30 + static inline void hugetlb_free_pgd_range(struct mmu_gather *tlb, 31 + unsigned long addr, unsigned long end, 32 + unsigned long floor, 33 + unsigned long ceiling) 34 + { 35 + free_pgd_range(tlb, addr, end, floor, ceiling); 36 + } 37 + 38 + 39 + static inline int is_hugepage_only_range(struct mm_struct *mm, 40 + unsigned long addr, unsigned long len) 41 + { 42 + return 0; 43 + } 44 + 45 + static inline int prepare_hugepage_range(struct file *file, 46 + unsigned long addr, unsigned long len) 47 + { 48 + struct hstate *h = hstate_file(file); 49 + if (len & ~huge_page_mask(h)) 50 + return -EINVAL; 51 + if (addr & ~huge_page_mask(h)) 52 + return -EINVAL; 53 + return 0; 54 + } 55 + 56 + static inline void hugetlb_prefault_arch_hook(struct mm_struct *mm) 57 + { 58 + } 59 + 60 + static inline int huge_pte_none(pte_t pte) 61 + { 62 + return pte_none(pte); 63 + } 64 + 65 + static inline pte_t huge_pte_wrprotect(pte_t pte) 66 + { 67 + return pte_wrprotect(pte); 68 + } 69 + 70 + static inline int arch_prepare_hugepage(struct page *page) 71 + { 72 + return 0; 73 + } 74 + 75 + static inline void arch_release_hugepage(struct page *page) 76 + { 77 + } 78 + 79 + static inline void arch_clear_hugepage_flags(struct page *page) 80 + { 81 + clear_bit(PG_dcache_clean, &page->flags); 82 + } 83 + 84 + #endif /* _ASM_ARM_HUGETLB_H */
+4 -4
arch/arm/include/asm/io.h
··· 130 130 */ 131 131 extern void __iomem *__arm_ioremap_pfn_caller(unsigned long, unsigned long, 132 132 size_t, unsigned int, void *); 133 - extern void __iomem *__arm_ioremap_caller(unsigned long, size_t, unsigned int, 133 + extern void __iomem *__arm_ioremap_caller(phys_addr_t, size_t, unsigned int, 134 134 void *); 135 135 136 136 extern void __iomem *__arm_ioremap_pfn(unsigned long, unsigned long, size_t, unsigned int); 137 - extern void __iomem *__arm_ioremap(unsigned long, size_t, unsigned int); 138 - extern void __iomem *__arm_ioremap_exec(unsigned long, size_t, bool cached); 137 + extern void __iomem *__arm_ioremap(phys_addr_t, size_t, unsigned int); 138 + extern void __iomem *__arm_ioremap_exec(phys_addr_t, size_t, bool cached); 139 139 extern void __iounmap(volatile void __iomem *addr); 140 140 extern void __arm_iounmap(volatile void __iomem *addr); 141 141 142 - extern void __iomem * (*arch_ioremap_caller)(unsigned long, size_t, 142 + extern void __iomem * (*arch_ioremap_caller)(phys_addr_t, size_t, 143 143 unsigned int, void *); 144 144 extern void (*arch_iounmap)(volatile void __iomem *); 145 145
+17 -1
arch/arm/include/asm/memory.h
··· 18 18 #include <linux/types.h> 19 19 #include <linux/sizes.h> 20 20 21 + #include <asm/cache.h> 22 + 21 23 #ifdef CONFIG_NEED_MACH_MEMORY_H 22 24 #include <mach/memory.h> 23 25 #endif ··· 143 141 #define page_to_phys(page) (__pfn_to_phys(page_to_pfn(page))) 144 142 #define phys_to_page(phys) (pfn_to_page(__phys_to_pfn(phys))) 145 143 144 + /* 145 + * Minimum guaranted alignment in pgd_alloc(). The page table pointers passed 146 + * around in head.S and proc-*.S are shifted by this amount, in order to 147 + * leave spare high bits for systems with physical address extension. This 148 + * does not fully accomodate the 40-bit addressing capability of ARM LPAE, but 149 + * gives us about 38-bits or so. 150 + */ 151 + #ifdef CONFIG_ARM_LPAE 152 + #define ARCH_PGD_SHIFT L1_CACHE_SHIFT 153 + #else 154 + #define ARCH_PGD_SHIFT 0 155 + #endif 156 + #define ARCH_PGD_MASK ((1 << ARCH_PGD_SHIFT) - 1) 157 + 146 158 #ifndef __ASSEMBLY__ 147 159 148 160 /* ··· 223 207 * direct-mapped view. We assume this is the first page 224 208 * of RAM in the mem_map as well. 225 209 */ 226 - #define PHYS_PFN_OFFSET (PHYS_OFFSET >> PAGE_SHIFT) 210 + #define PHYS_PFN_OFFSET ((unsigned long)(PHYS_OFFSET >> PAGE_SHIFT)) 227 211 228 212 /* 229 213 * These are *only* valid on the kernel direct mapped RAM memory.
+18 -5
arch/arm/include/asm/mmu_context.h
··· 18 18 #include <asm/cacheflush.h> 19 19 #include <asm/cachetype.h> 20 20 #include <asm/proc-fns.h> 21 + #include <asm/smp_plat.h> 21 22 #include <asm-generic/mm_hooks.h> 22 23 23 24 void __check_vmalloc_seq(struct mm_struct *mm); ··· 28 27 void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk); 29 28 #define init_new_context(tsk,mm) ({ atomic64_set(&mm->context.id, 0); 0; }) 30 29 31 - DECLARE_PER_CPU(atomic64_t, active_asids); 30 + #ifdef CONFIG_ARM_ERRATA_798181 31 + void a15_erratum_get_cpumask(int this_cpu, struct mm_struct *mm, 32 + cpumask_t *mask); 33 + #else /* !CONFIG_ARM_ERRATA_798181 */ 34 + static inline void a15_erratum_get_cpumask(int this_cpu, struct mm_struct *mm, 35 + cpumask_t *mask) 36 + { 37 + } 38 + #endif /* CONFIG_ARM_ERRATA_798181 */ 32 39 33 40 #else /* !CONFIG_CPU_HAS_ASID */ 34 41 ··· 107 98 #ifdef CONFIG_MMU 108 99 unsigned int cpu = smp_processor_id(); 109 100 110 - #ifdef CONFIG_SMP 111 - /* check for possible thread migration */ 112 - if (!cpumask_empty(mm_cpumask(next)) && 101 + /* 102 + * __sync_icache_dcache doesn't broadcast the I-cache invalidation, 103 + * so check for possible thread migration and invalidate the I-cache 104 + * if we're new to this CPU. 105 + */ 106 + if (cache_ops_need_broadcast() && 107 + !cpumask_empty(mm_cpumask(next)) && 113 108 !cpumask_test_cpu(cpu, mm_cpumask(next))) 114 109 __flush_icache_all(); 115 - #endif 110 + 116 111 if (!cpumask_test_and_set_cpu(cpu, mm_cpumask(next)) || prev != next) { 117 112 check_and_switch_context(next, tsk); 118 113 if (cache_is_vivt())
+76
arch/arm/include/asm/mpu.h
··· 1 + #ifndef __ARM_MPU_H 2 + #define __ARM_MPU_H 3 + 4 + #ifdef CONFIG_ARM_MPU 5 + 6 + /* MPUIR layout */ 7 + #define MPUIR_nU 1 8 + #define MPUIR_DREGION 8 9 + #define MPUIR_IREGION 16 10 + #define MPUIR_DREGION_SZMASK (0xFF << MPUIR_DREGION) 11 + #define MPUIR_IREGION_SZMASK (0xFF << MPUIR_IREGION) 12 + 13 + /* ID_MMFR0 data relevant to MPU */ 14 + #define MMFR0_PMSA (0xF << 4) 15 + #define MMFR0_PMSAv7 (3 << 4) 16 + 17 + /* MPU D/I Size Register fields */ 18 + #define MPU_RSR_SZ 1 19 + #define MPU_RSR_EN 0 20 + 21 + /* The D/I RSR value for an enabled region spanning the whole of memory */ 22 + #define MPU_RSR_ALL_MEM 63 23 + 24 + /* Individual bits in the DR/IR ACR */ 25 + #define MPU_ACR_XN (1 << 12) 26 + #define MPU_ACR_SHARED (1 << 2) 27 + 28 + /* C, B and TEX[2:0] bits only have semantic meanings when grouped */ 29 + #define MPU_RGN_CACHEABLE 0xB 30 + #define MPU_RGN_SHARED_CACHEABLE (MPU_RGN_CACHEABLE | MPU_ACR_SHARED) 31 + #define MPU_RGN_STRONGLY_ORDERED 0 32 + 33 + /* Main region should only be shared for SMP */ 34 + #ifdef CONFIG_SMP 35 + #define MPU_RGN_NORMAL (MPU_RGN_CACHEABLE | MPU_ACR_SHARED) 36 + #else 37 + #define MPU_RGN_NORMAL MPU_RGN_CACHEABLE 38 + #endif 39 + 40 + /* Access permission bits of ACR (only define those that we use)*/ 41 + #define MPU_AP_PL1RW_PL0RW (0x3 << 8) 42 + #define MPU_AP_PL1RW_PL0R0 (0x2 << 8) 43 + #define MPU_AP_PL1RW_PL0NA (0x1 << 8) 44 + 45 + /* For minimal static MPU region configurations */ 46 + #define MPU_PROBE_REGION 0 47 + #define MPU_BG_REGION 1 48 + #define MPU_RAM_REGION 2 49 + #define MPU_VECTORS_REGION 3 50 + 51 + /* Maximum number of regions Linux is interested in */ 52 + #define MPU_MAX_REGIONS 16 53 + 54 + #define MPU_DATA_SIDE 0 55 + #define MPU_INSTR_SIDE 1 56 + 57 + #ifndef __ASSEMBLY__ 58 + 59 + struct mpu_rgn { 60 + /* Assume same attributes for d/i-side */ 61 + u32 drbar; 62 + u32 drsr; 63 + u32 dracr; 64 + }; 65 + 66 + struct mpu_rgn_info { 67 + u32 mpuir; 68 + struct mpu_rgn rgns[MPU_MAX_REGIONS]; 69 + }; 70 + extern struct mpu_rgn_info mpu_rgn_info; 71 + 72 + #endif /* __ASSEMBLY__ */ 73 + 74 + #endif /* CONFIG_ARM_MPU */ 75 + 76 + #endif
+1 -1
arch/arm/include/asm/page.h
··· 13 13 /* PAGE_SHIFT determines the page size */ 14 14 #define PAGE_SHIFT 12 15 15 #define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) 16 - #define PAGE_MASK (~(PAGE_SIZE-1)) 16 + #define PAGE_MASK (~((1 << PAGE_SHIFT) - 1)) 17 17 18 18 #ifndef __ASSEMBLY__ 19 19
+24
arch/arm/include/asm/pgtable-3level-hwdef.h
··· 30 30 #define PMD_TYPE_FAULT (_AT(pmdval_t, 0) << 0) 31 31 #define PMD_TYPE_TABLE (_AT(pmdval_t, 3) << 0) 32 32 #define PMD_TYPE_SECT (_AT(pmdval_t, 1) << 0) 33 + #define PMD_TABLE_BIT (_AT(pmdval_t, 1) << 1) 33 34 #define PMD_BIT4 (_AT(pmdval_t, 0)) 34 35 #define PMD_DOMAIN(x) (_AT(pmdval_t, 0)) 35 36 #define PMD_APTABLE_SHIFT (61) ··· 42 41 */ 43 42 #define PMD_SECT_BUFFERABLE (_AT(pmdval_t, 1) << 2) 44 43 #define PMD_SECT_CACHEABLE (_AT(pmdval_t, 1) << 3) 44 + #define PMD_SECT_USER (_AT(pmdval_t, 1) << 6) /* AP[1] */ 45 + #define PMD_SECT_RDONLY (_AT(pmdval_t, 1) << 7) /* AP[2] */ 45 46 #define PMD_SECT_S (_AT(pmdval_t, 3) << 8) 46 47 #define PMD_SECT_AF (_AT(pmdval_t, 1) << 10) 47 48 #define PMD_SECT_nG (_AT(pmdval_t, 1) << 11) ··· 69 66 #define PTE_TYPE_MASK (_AT(pteval_t, 3) << 0) 70 67 #define PTE_TYPE_FAULT (_AT(pteval_t, 0) << 0) 71 68 #define PTE_TYPE_PAGE (_AT(pteval_t, 3) << 0) 69 + #define PTE_TABLE_BIT (_AT(pteval_t, 1) << 1) 72 70 #define PTE_BUFFERABLE (_AT(pteval_t, 1) << 2) /* AttrIndx[0] */ 73 71 #define PTE_CACHEABLE (_AT(pteval_t, 1) << 3) /* AttrIndx[1] */ 74 72 #define PTE_EXT_SHARED (_AT(pteval_t, 3) << 8) /* SH[1:0], inner shareable */ ··· 82 78 */ 83 79 #define PHYS_MASK_SHIFT (40) 84 80 #define PHYS_MASK ((1ULL << PHYS_MASK_SHIFT) - 1) 81 + 82 + /* 83 + * TTBR0/TTBR1 split (PAGE_OFFSET): 84 + * 0x40000000: T0SZ = 2, T1SZ = 0 (not used) 85 + * 0x80000000: T0SZ = 0, T1SZ = 1 86 + * 0xc0000000: T0SZ = 0, T1SZ = 2 87 + * 88 + * Only use this feature if PHYS_OFFSET <= PAGE_OFFSET, otherwise 89 + * booting secondary CPUs would end up using TTBR1 for the identity 90 + * mapping set up in TTBR0. 91 + */ 92 + #if defined CONFIG_VMSPLIT_2G 93 + #define TTBR1_OFFSET 16 /* skip two L1 entries */ 94 + #elif defined CONFIG_VMSPLIT_3G 95 + #define TTBR1_OFFSET (4096 * (1 + 3)) /* only L2, skip pgd + 3*pmd */ 96 + #else 97 + #define TTBR1_OFFSET 0 98 + #endif 99 + 100 + #define TTBR1_SIZE (((PAGE_OFFSET >> 30) - 1) << 16) 85 101 86 102 #endif
+92 -4
arch/arm/include/asm/pgtable-3level.h
··· 33 33 #define PTRS_PER_PMD 512 34 34 #define PTRS_PER_PGD 4 35 35 36 - #define PTE_HWTABLE_PTRS (PTRS_PER_PTE) 36 + #define PTE_HWTABLE_PTRS (0) 37 37 #define PTE_HWTABLE_OFF (0) 38 38 #define PTE_HWTABLE_SIZE (PTRS_PER_PTE * sizeof(u64)) 39 39 ··· 48 48 #define PMD_SHIFT 21 49 49 50 50 #define PMD_SIZE (1UL << PMD_SHIFT) 51 - #define PMD_MASK (~(PMD_SIZE-1)) 51 + #define PMD_MASK (~((1 << PMD_SHIFT) - 1)) 52 52 #define PGDIR_SIZE (1UL << PGDIR_SHIFT) 53 - #define PGDIR_MASK (~(PGDIR_SIZE-1)) 53 + #define PGDIR_MASK (~((1 << PGDIR_SHIFT) - 1)) 54 54 55 55 /* 56 56 * section address mask and size definitions. 57 57 */ 58 58 #define SECTION_SHIFT 21 59 59 #define SECTION_SIZE (1UL << SECTION_SHIFT) 60 - #define SECTION_MASK (~(SECTION_SIZE-1)) 60 + #define SECTION_MASK (~((1 << SECTION_SHIFT) - 1)) 61 61 62 62 #define USER_PTRS_PER_PGD (PAGE_OFFSET / PGDIR_SIZE) 63 + 64 + /* 65 + * Hugetlb definitions. 66 + */ 67 + #define HPAGE_SHIFT PMD_SHIFT 68 + #define HPAGE_SIZE (_AC(1, UL) << HPAGE_SHIFT) 69 + #define HPAGE_MASK (~(HPAGE_SIZE - 1)) 70 + #define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) 63 71 64 72 /* 65 73 * "Linux" PTE definitions for LPAE. ··· 86 78 #define L_PTE_DIRTY (_AT(pteval_t, 1) << 55) /* unused */ 87 79 #define L_PTE_SPECIAL (_AT(pteval_t, 1) << 56) /* unused */ 88 80 #define L_PTE_NONE (_AT(pteval_t, 1) << 57) /* PROT_NONE */ 81 + 82 + #define PMD_SECT_VALID (_AT(pmdval_t, 1) << 0) 83 + #define PMD_SECT_DIRTY (_AT(pmdval_t, 1) << 55) 84 + #define PMD_SECT_SPLITTING (_AT(pmdval_t, 1) << 56) 85 + #define PMD_SECT_NONE (_AT(pmdval_t, 1) << 57) 89 86 90 87 /* 91 88 * To be used in assembly code with the upper page attributes. ··· 179 166 clean_pmd_entry(pmdp); \ 180 167 } while (0) 181 168 169 + /* 170 + * For 3 levels of paging the PTE_EXT_NG bit will be set for user address ptes 171 + * that are written to a page table but not for ptes created with mk_pte. 172 + * 173 + * In hugetlb_no_page, a new huge pte (new_pte) is generated and passed to 174 + * hugetlb_cow, where it is compared with an entry in a page table. 175 + * This comparison test fails erroneously leading ultimately to a memory leak. 176 + * 177 + * To correct this behaviour, we mask off PTE_EXT_NG for any pte that is 178 + * present before running the comparison. 179 + */ 180 + #define __HAVE_ARCH_PTE_SAME 181 + #define pte_same(pte_a,pte_b) ((pte_present(pte_a) ? pte_val(pte_a) & ~PTE_EXT_NG \ 182 + : pte_val(pte_a)) \ 183 + == (pte_present(pte_b) ? pte_val(pte_b) & ~PTE_EXT_NG \ 184 + : pte_val(pte_b))) 185 + 182 186 #define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,__pte(pte_val(pte)|(ext))) 187 + 188 + #define pte_huge(pte) (pte_val(pte) && !(pte_val(pte) & PTE_TABLE_BIT)) 189 + #define pte_mkhuge(pte) (__pte(pte_val(pte) & ~PTE_TABLE_BIT)) 190 + 191 + #define pmd_young(pmd) (pmd_val(pmd) & PMD_SECT_AF) 192 + 193 + #define __HAVE_ARCH_PMD_WRITE 194 + #define pmd_write(pmd) (!(pmd_val(pmd) & PMD_SECT_RDONLY)) 195 + 196 + #ifdef CONFIG_TRANSPARENT_HUGEPAGE 197 + #define pmd_trans_huge(pmd) (pmd_val(pmd) && !(pmd_val(pmd) & PMD_TABLE_BIT)) 198 + #define pmd_trans_splitting(pmd) (pmd_val(pmd) & PMD_SECT_SPLITTING) 199 + #endif 200 + 201 + #define PMD_BIT_FUNC(fn,op) \ 202 + static inline pmd_t pmd_##fn(pmd_t pmd) { pmd_val(pmd) op; return pmd; } 203 + 204 + PMD_BIT_FUNC(wrprotect, |= PMD_SECT_RDONLY); 205 + PMD_BIT_FUNC(mkold, &= ~PMD_SECT_AF); 206 + PMD_BIT_FUNC(mksplitting, |= PMD_SECT_SPLITTING); 207 + PMD_BIT_FUNC(mkwrite, &= ~PMD_SECT_RDONLY); 208 + PMD_BIT_FUNC(mkdirty, |= PMD_SECT_DIRTY); 209 + PMD_BIT_FUNC(mkyoung, |= PMD_SECT_AF); 210 + 211 + #define pmd_mkhuge(pmd) (__pmd(pmd_val(pmd) & ~PMD_TABLE_BIT)) 212 + 213 + #define pmd_pfn(pmd) (((pmd_val(pmd) & PMD_MASK) & PHYS_MASK) >> PAGE_SHIFT) 214 + #define pfn_pmd(pfn,prot) (__pmd(((phys_addr_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot))) 215 + #define mk_pmd(page,prot) pfn_pmd(page_to_pfn(page),prot) 216 + 217 + /* represent a notpresent pmd by zero, this is used by pmdp_invalidate */ 218 + #define pmd_mknotpresent(pmd) (__pmd(0)) 219 + 220 + static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot) 221 + { 222 + const pmdval_t mask = PMD_SECT_USER | PMD_SECT_XN | PMD_SECT_RDONLY | 223 + PMD_SECT_VALID | PMD_SECT_NONE; 224 + pmd_val(pmd) = (pmd_val(pmd) & ~mask) | (pgprot_val(newprot) & mask); 225 + return pmd; 226 + } 227 + 228 + static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr, 229 + pmd_t *pmdp, pmd_t pmd) 230 + { 231 + BUG_ON(addr >= TASK_SIZE); 232 + 233 + /* create a faulting entry if PROT_NONE protected */ 234 + if (pmd_val(pmd) & PMD_SECT_NONE) 235 + pmd_val(pmd) &= ~PMD_SECT_VALID; 236 + 237 + *pmdp = __pmd(pmd_val(pmd) | PMD_SECT_nG); 238 + flush_pmd_entry(pmdp); 239 + } 240 + 241 + static inline int has_transparent_hugepage(void) 242 + { 243 + return 1; 244 + } 183 245 184 246 #endif /* __ASSEMBLY__ */ 185 247
+3
arch/arm/include/asm/pgtable.h
··· 24 24 #include <asm/memory.h> 25 25 #include <asm/pgtable-hwdef.h> 26 26 27 + 28 + #include <asm/tlbflush.h> 29 + 27 30 #ifdef CONFIG_ARM_LPAE 28 31 #include <asm/pgtable-3level.h> 29 32 #else
+23 -7
arch/arm/include/asm/proc-fns.h
··· 60 60 /* 61 61 * Set the page table 62 62 */ 63 - void (*switch_mm)(unsigned long pgd_phys, struct mm_struct *mm); 63 + void (*switch_mm)(phys_addr_t pgd_phys, struct mm_struct *mm); 64 64 /* 65 65 * Set a possibly extended PTE. Non-extended PTEs should 66 66 * ignore 'ext'. ··· 82 82 extern void cpu_proc_fin(void); 83 83 extern int cpu_do_idle(void); 84 84 extern void cpu_dcache_clean_area(void *, int); 85 - extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm); 85 + extern void cpu_do_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm); 86 86 #ifdef CONFIG_ARM_LPAE 87 87 extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte); 88 88 #else ··· 116 116 #define cpu_switch_mm(pgd,mm) cpu_do_switch_mm(virt_to_phys(pgd),mm) 117 117 118 118 #ifdef CONFIG_ARM_LPAE 119 + 120 + #define cpu_get_ttbr(nr) \ 121 + ({ \ 122 + u64 ttbr; \ 123 + __asm__("mrrc p15, " #nr ", %Q0, %R0, c2" \ 124 + : "=r" (ttbr)); \ 125 + ttbr; \ 126 + }) 127 + 128 + #define cpu_set_ttbr(nr, val) \ 129 + do { \ 130 + u64 ttbr = val; \ 131 + __asm__("mcrr p15, " #nr ", %Q0, %R0, c2" \ 132 + : : "r" (ttbr)); \ 133 + } while (0) 134 + 119 135 #define cpu_get_pgd() \ 120 136 ({ \ 121 - unsigned long pg, pg2; \ 122 - __asm__("mrrc p15, 0, %0, %1, c2" \ 123 - : "=r" (pg), "=r" (pg2) \ 124 - : \ 125 - : "cc"); \ 137 + u64 pg = cpu_get_ttbr(0); \ 126 138 pg &= ~(PTRS_PER_PGD*sizeof(pgd_t)-1); \ 127 139 (pgd_t *)phys_to_virt(pg); \ 128 140 }) ··· 148 136 (pgd_t *)phys_to_virt(pg); \ 149 137 }) 150 138 #endif 139 + 140 + #else /*!CONFIG_MMU */ 141 + 142 + #define cpu_switch_mm(pgd,mm) { } 151 143 152 144 #endif 153 145
+4 -1
arch/arm/include/asm/smp.h
··· 65 65 * Initial data for bringing up a secondary CPU. 66 66 */ 67 67 struct secondary_data { 68 - unsigned long pgdir; 68 + union { 69 + unsigned long mpu_rgn_szr; 70 + unsigned long pgdir; 71 + }; 69 72 unsigned long swapper_pg_dir; 70 73 void *stack; 71 74 };
+22
arch/arm/include/asm/smp_plat.h
··· 26 26 } 27 27 28 28 /* all SMP configurations have the extended CPUID registers */ 29 + #ifndef CONFIG_MMU 30 + #define tlb_ops_need_broadcast() 0 31 + #else 29 32 static inline int tlb_ops_need_broadcast(void) 30 33 { 31 34 if (!is_smp()) ··· 36 33 37 34 return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 2; 38 35 } 36 + #endif 39 37 40 38 #if !defined(CONFIG_SMP) || __LINUX_ARM_ARCH__ >= 7 41 39 #define cache_ops_need_broadcast() 0 ··· 70 66 return -EINVAL; 71 67 } 72 68 69 + /* 70 + * NOTE ! Assembly code relies on the following 71 + * structure memory layout in order to carry out load 72 + * multiple from its base address. For more 73 + * information check arch/arm/kernel/sleep.S 74 + */ 75 + struct mpidr_hash { 76 + u32 mask; /* used by sleep.S */ 77 + u32 shift_aff[3]; /* used by sleep.S */ 78 + u32 bits; 79 + }; 80 + 81 + extern struct mpidr_hash mpidr_hash; 82 + 83 + static inline u32 mpidr_hash_size(void) 84 + { 85 + return 1 << mpidr_hash.bits; 86 + } 73 87 #endif
+13 -10
arch/arm/include/asm/spinlock.h
··· 97 97 98 98 static inline int arch_spin_trylock(arch_spinlock_t *lock) 99 99 { 100 - unsigned long tmp; 100 + unsigned long contended, res; 101 101 u32 slock; 102 102 103 - __asm__ __volatile__( 104 - " ldrex %0, [%2]\n" 105 - " subs %1, %0, %0, ror #16\n" 106 - " addeq %0, %0, %3\n" 107 - " strexeq %1, %0, [%2]" 108 - : "=&r" (slock), "=&r" (tmp) 109 - : "r" (&lock->slock), "I" (1 << TICKET_SHIFT) 110 - : "cc"); 103 + do { 104 + __asm__ __volatile__( 105 + " ldrex %0, [%3]\n" 106 + " mov %2, #0\n" 107 + " subs %1, %0, %0, ror #16\n" 108 + " addeq %0, %0, %4\n" 109 + " strexeq %2, %0, [%3]" 110 + : "=&r" (slock), "=&r" (contended), "=r" (res) 111 + : "r" (&lock->slock), "I" (1 << TICKET_SHIFT) 112 + : "cc"); 113 + } while (res); 111 114 112 - if (tmp == 0) { 115 + if (!contended) { 113 116 smp_mb(); 114 117 return 1; 115 118 } else {
+5
arch/arm/include/asm/suspend.h
··· 1 1 #ifndef __ASM_ARM_SUSPEND_H 2 2 #define __ASM_ARM_SUSPEND_H 3 3 4 + struct sleep_save_sp { 5 + u32 *save_ptr_stash; 6 + u32 save_ptr_stash_phys; 7 + }; 8 + 4 9 extern void cpu_resume(void); 5 10 extern int cpu_suspend(unsigned long, int (*)(unsigned long)); 6 11
+1 -1
arch/arm/include/asm/thread_info.h
··· 58 58 struct cpu_context_save cpu_context; /* cpu context */ 59 59 __u32 syscall; /* syscall number */ 60 60 __u8 used_cp[16]; /* thread used copro */ 61 - unsigned long tp_value; 61 + unsigned long tp_value[2]; /* TLS registers */ 62 62 #ifdef CONFIG_CRUNCH 63 63 struct crunch_state crunchstate; 64 64 #endif
+6
arch/arm/include/asm/tlb.h
··· 204 204 #endif 205 205 } 206 206 207 + static inline void 208 + tlb_remove_pmd_tlb_entry(struct mmu_gather *tlb, pmd_t *pmdp, unsigned long addr) 209 + { 210 + tlb_add_flush(tlb, addr); 211 + } 212 + 207 213 #define pte_free_tlb(tlb, ptep, addr) __pte_free_tlb(tlb, ptep, addr) 208 214 #define pmd_free_tlb(tlb, pmdp, addr) __pmd_free_tlb(tlb, pmdp, addr) 209 215 #define pud_free_tlb(tlb, pudp, addr) pud_free((tlb)->mm, pudp)
+26 -1
arch/arm/include/asm/tlbflush.h
··· 535 535 } 536 536 #endif 537 537 538 + #define update_mmu_cache_pmd(vma, address, pmd) do { } while (0) 539 + 538 540 #endif 539 541 540 - #endif /* CONFIG_MMU */ 542 + #elif defined(CONFIG_SMP) /* !CONFIG_MMU */ 543 + 544 + #ifndef __ASSEMBLY__ 545 + 546 + #include <linux/mm_types.h> 547 + 548 + static inline void local_flush_tlb_all(void) { } 549 + static inline void local_flush_tlb_mm(struct mm_struct *mm) { } 550 + static inline void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) { } 551 + static inline void local_flush_tlb_kernel_page(unsigned long kaddr) { } 552 + static inline void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) { } 553 + static inline void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) { } 554 + static inline void local_flush_bp_all(void) { } 555 + 556 + extern void flush_tlb_all(void); 557 + extern void flush_tlb_mm(struct mm_struct *mm); 558 + extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr); 559 + extern void flush_tlb_kernel_page(unsigned long kaddr); 560 + extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end); 561 + extern void flush_tlb_kernel_range(unsigned long start, unsigned long end); 562 + extern void flush_bp_all(void); 563 + #endif /* __ASSEMBLY__ */ 564 + 565 + #endif 541 566 542 567 #endif
+27 -13
arch/arm/include/asm/tls.h
··· 2 2 #define __ASMARM_TLS_H 3 3 4 4 #ifdef __ASSEMBLY__ 5 - .macro set_tls_none, tp, tmp1, tmp2 5 + #include <asm/asm-offsets.h> 6 + .macro switch_tls_none, base, tp, tpuser, tmp1, tmp2 6 7 .endm 7 8 8 - .macro set_tls_v6k, tp, tmp1, tmp2 9 + .macro switch_tls_v6k, base, tp, tpuser, tmp1, tmp2 10 + mrc p15, 0, \tmp2, c13, c0, 2 @ get the user r/w register 9 11 mcr p15, 0, \tp, c13, c0, 3 @ set TLS register 10 - mov \tmp1, #0 11 - mcr p15, 0, \tmp1, c13, c0, 2 @ clear user r/w TLS register 12 + mcr p15, 0, \tpuser, c13, c0, 2 @ and the user r/w register 13 + str \tmp2, [\base, #TI_TP_VALUE + 4] @ save it 12 14 .endm 13 15 14 - .macro set_tls_v6, tp, tmp1, tmp2 16 + .macro switch_tls_v6, base, tp, tpuser, tmp1, tmp2 15 17 ldr \tmp1, =elf_hwcap 16 18 ldr \tmp1, [\tmp1, #0] 17 19 mov \tmp2, #0xffff0fff 18 20 tst \tmp1, #HWCAP_TLS @ hardware TLS available? 19 - mcrne p15, 0, \tp, c13, c0, 3 @ yes, set TLS register 20 - movne \tmp1, #0 21 - mcrne p15, 0, \tmp1, c13, c0, 2 @ clear user r/w TLS register 22 21 streq \tp, [\tmp2, #-15] @ set TLS value at 0xffff0ff0 22 + mrcne p15, 0, \tmp2, c13, c0, 2 @ get the user r/w register 23 + mcrne p15, 0, \tp, c13, c0, 3 @ yes, set TLS register 24 + mcrne p15, 0, \tpuser, c13, c0, 2 @ set user r/w register 25 + strne \tmp2, [\base, #TI_TP_VALUE + 4] @ save it 23 26 .endm 24 27 25 - .macro set_tls_software, tp, tmp1, tmp2 28 + .macro switch_tls_software, base, tp, tpuser, tmp1, tmp2 26 29 mov \tmp1, #0xffff0fff 27 30 str \tp, [\tmp1, #-15] @ set TLS value at 0xffff0ff0 28 31 .endm ··· 34 31 #ifdef CONFIG_TLS_REG_EMUL 35 32 #define tls_emu 1 36 33 #define has_tls_reg 1 37 - #define set_tls set_tls_none 34 + #define switch_tls switch_tls_none 38 35 #elif defined(CONFIG_CPU_V6) 39 36 #define tls_emu 0 40 37 #define has_tls_reg (elf_hwcap & HWCAP_TLS) 41 - #define set_tls set_tls_v6 38 + #define switch_tls switch_tls_v6 42 39 #elif defined(CONFIG_CPU_32v6K) 43 40 #define tls_emu 0 44 41 #define has_tls_reg 1 45 - #define set_tls set_tls_v6k 42 + #define switch_tls switch_tls_v6k 46 43 #else 47 44 #define tls_emu 0 48 45 #define has_tls_reg 0 49 - #define set_tls set_tls_software 46 + #define switch_tls switch_tls_software 50 47 #endif 51 48 49 + #ifndef __ASSEMBLY__ 50 + static inline unsigned long get_tpuser(void) 51 + { 52 + unsigned long reg = 0; 53 + 54 + if (has_tls_reg && !tls_emu) 55 + __asm__("mrc p15, 0, %0, c13, c0, 2" : "=r" (reg)); 56 + 57 + return reg; 58 + } 59 + #endif 52 60 #endif /* __ASMARM_TLS_H */
+10
arch/arm/include/debug/vexpress.S
··· 16 16 #define DEBUG_LL_PHYS_BASE_RS1 0x1c000000 17 17 #define DEBUG_LL_UART_OFFSET_RS1 0x00090000 18 18 19 + #define DEBUG_LL_UART_PHYS_CRX 0xb0090000 20 + 19 21 #define DEBUG_LL_VIRT_BASE 0xf8000000 20 22 21 23 #if defined(CONFIG_DEBUG_VEXPRESS_UART0_DETECT) ··· 65 63 mov \rp, #DEBUG_LL_UART_OFFSET_RS1 66 64 orr \rv, \rp, #DEBUG_LL_VIRT_BASE 67 65 orr \rp, \rp, #DEBUG_LL_PHYS_BASE_RS1 66 + .endm 67 + 68 + #include <asm/hardware/debug-pl01x.S> 69 + 70 + #elif defined(CONFIG_DEBUG_VEXPRESS_UART0_CRX) 71 + 72 + .macro addruart,rp,tmp,tmp2 73 + ldr \rp, =DEBUG_LL_UART_PHYS_CRX 68 74 .endm 69 75 70 76 #include <asm/hardware/debug-pl01x.S>
+1 -1
arch/arm/include/uapi/asm/hwcap.h
··· 25 25 #define HWCAP_IDIVT (1 << 18) 26 26 #define HWCAP_VFPD32 (1 << 19) /* set if VFP has 32 regs (not 16) */ 27 27 #define HWCAP_IDIV (HWCAP_IDIVA | HWCAP_IDIVT) 28 - 28 + #define HWCAP_LPAE (1 << 20) 29 29 30 30 #endif /* _UAPI__ASMARM_HWCAP_H */
+4 -1
arch/arm/kernel/Makefile
··· 38 38 obj-$(CONFIG_ISA_DMA) += dma-isa.o 39 39 obj-$(CONFIG_PCI) += bios32.o isa.o 40 40 obj-$(CONFIG_ARM_CPU_SUSPEND) += sleep.o suspend.o 41 - obj-$(CONFIG_SMP) += smp.o smp_tlb.o 41 + obj-$(CONFIG_SMP) += smp.o 42 + ifdef CONFIG_MMU 43 + obj-$(CONFIG_SMP) += smp_tlb.o 44 + endif 42 45 obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o 43 46 obj-$(CONFIG_HAVE_ARM_TWD) += smp_twd.o 44 47 obj-$(CONFIG_ARM_ARCH_TIMER) += arch_timer.o
+6
arch/arm/kernel/asm-offsets.c
··· 23 23 #include <asm/thread_info.h> 24 24 #include <asm/memory.h> 25 25 #include <asm/procinfo.h> 26 + #include <asm/suspend.h> 26 27 #include <asm/hardware/cache-l2x0.h> 27 28 #include <linux/kbuild.h> 28 29 ··· 145 144 #endif 146 145 #ifdef MULTI_CACHE 147 146 DEFINE(CACHE_FLUSH_KERN_ALL, offsetof(struct cpu_cache_fns, flush_kern_all)); 147 + #endif 148 + #ifdef CONFIG_ARM_CPU_SUSPEND 149 + DEFINE(SLEEP_SAVE_SP_SZ, sizeof(struct sleep_save_sp)); 150 + DEFINE(SLEEP_SAVE_SP_PHYS, offsetof(struct sleep_save_sp, save_ptr_stash_phys)); 151 + DEFINE(SLEEP_SAVE_SP_VIRT, offsetof(struct sleep_save_sp, save_ptr_stash)); 148 152 #endif 149 153 BLANK(); 150 154 DEFINE(DMA_BIDIRECTIONAL, DMA_BIDIRECTIONAL);
+3 -2
arch/arm/kernel/entry-armv.S
··· 685 685 UNWIND(.fnstart ) 686 686 UNWIND(.cantunwind ) 687 687 add ip, r1, #TI_CPU_SAVE 688 - ldr r3, [r2, #TI_TP_VALUE] 689 688 ARM( stmia ip!, {r4 - sl, fp, sp, lr} ) @ Store most regs on stack 690 689 THUMB( stmia ip!, {r4 - sl, fp} ) @ Store most regs on stack 691 690 THUMB( str sp, [ip], #4 ) 692 691 THUMB( str lr, [ip], #4 ) 692 + ldr r4, [r2, #TI_TP_VALUE] 693 + ldr r5, [r2, #TI_TP_VALUE + 4] 693 694 #ifdef CONFIG_CPU_USE_DOMAINS 694 695 ldr r6, [r2, #TI_CPU_DOMAIN] 695 696 #endif 696 - set_tls r3, r4, r5 697 + switch_tls r1, r4, r5, r3, r7 697 698 #if defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP) 698 699 ldr r7, [r2, #TI_TASK] 699 700 ldr r8, =__stack_chk_guard
+29 -13
arch/arm/kernel/entry-common.S
··· 366 366 #endif 367 367 zero_fp 368 368 369 + #ifdef CONFIG_ALIGNMENT_TRAP 370 + ldr ip, __cr_alignment 371 + ldr ip, [ip] 372 + mcr p15, 0, ip, c1, c0 @ update control register 373 + #endif 374 + 375 + enable_irq 376 + ct_user_exit 377 + get_thread_info tsk 378 + 369 379 /* 370 380 * Get the system call number. 371 381 */ ··· 389 379 #ifdef CONFIG_ARM_THUMB 390 380 tst r8, #PSR_T_BIT 391 381 movne r10, #0 @ no thumb OABI emulation 392 - ldreq r10, [lr, #-4] @ get SWI instruction 382 + USER( ldreq r10, [lr, #-4] ) @ get SWI instruction 393 383 #else 394 - ldr r10, [lr, #-4] @ get SWI instruction 384 + USER( ldr r10, [lr, #-4] ) @ get SWI instruction 395 385 #endif 396 386 #ifdef CONFIG_CPU_ENDIAN_BE8 397 387 rev r10, r10 @ little endian instruction ··· 406 396 /* Legacy ABI only, possibly thumb mode. */ 407 397 tst r8, #PSR_T_BIT @ this is SPSR from save_user_regs 408 398 addne scno, r7, #__NR_SYSCALL_BASE @ put OS number in 409 - ldreq scno, [lr, #-4] 399 + USER( ldreq scno, [lr, #-4] ) 410 400 411 401 #else 412 402 /* Legacy ABI only. */ 413 - ldr scno, [lr, #-4] @ get SWI instruction 403 + USER( ldr scno, [lr, #-4] ) @ get SWI instruction 414 404 #endif 415 405 416 - #ifdef CONFIG_ALIGNMENT_TRAP 417 - ldr ip, __cr_alignment 418 - ldr ip, [ip] 419 - mcr p15, 0, ip, c1, c0 @ update control register 420 - #endif 421 - enable_irq 422 - ct_user_exit 423 - 424 - get_thread_info tsk 425 406 adr tbl, sys_call_table @ load syscall table pointer 426 407 427 408 #if defined(CONFIG_OABI_COMPAT) ··· 447 446 eor r0, scno, #__NR_SYSCALL_BASE @ put OS number back 448 447 bcs arm_syscall 449 448 b sys_ni_syscall @ not private func 449 + 450 + #if defined(CONFIG_OABI_COMPAT) || !defined(CONFIG_AEABI) 451 + /* 452 + * We failed to handle a fault trying to access the page 453 + * containing the swi instruction, but we're not really in a 454 + * position to return -EFAULT. Instead, return back to the 455 + * instruction and re-enter the user fault handling path trying 456 + * to page it in. This will likely result in sending SEGV to the 457 + * current task. 458 + */ 459 + 9001: 460 + sub lr, lr, #4 461 + str lr, [sp, #S_PC] 462 + b ret_fast_syscall 463 + #endif 450 464 ENDPROC(vector_swi) 451 465 452 466 /*
+156 -4
arch/arm/kernel/head-nommu.S
··· 17 17 #include <asm/assembler.h> 18 18 #include <asm/ptrace.h> 19 19 #include <asm/asm-offsets.h> 20 + #include <asm/memory.h> 20 21 #include <asm/cp15.h> 21 22 #include <asm/thread_info.h> 22 23 #include <asm/v7m.h> 24 + #include <asm/mpu.h> 25 + #include <asm/page.h> 23 26 24 27 /* 25 28 * Kernel startup entry point. ··· 66 63 movs r10, r5 @ invalid processor (r5=0)? 67 64 beq __error_p @ yes, error 'p' 68 65 69 - adr lr, BSYM(__after_proc_init) @ return (PIC) address 66 + #ifdef CONFIG_ARM_MPU 67 + /* Calculate the size of a region covering just the kernel */ 68 + ldr r5, =PHYS_OFFSET @ Region start: PHYS_OFFSET 69 + ldr r6, =(_end) @ Cover whole kernel 70 + sub r6, r6, r5 @ Minimum size of region to map 71 + clz r6, r6 @ Region size must be 2^N... 72 + rsb r6, r6, #31 @ ...so round up region size 73 + lsl r6, r6, #MPU_RSR_SZ @ Put size in right field 74 + orr r6, r6, #(1 << MPU_RSR_EN) @ Set region enabled bit 75 + bl __setup_mpu 76 + #endif 77 + ldr r13, =__mmap_switched @ address to jump to after 78 + @ initialising sctlr 79 + adr lr, BSYM(1f) @ return (PIC) address 70 80 ARM( add pc, r10, #PROCINFO_INITFUNC ) 71 81 THUMB( add r12, r10, #PROCINFO_INITFUNC ) 72 82 THUMB( mov pc, r12 ) 83 + 1: b __after_proc_init 73 84 ENDPROC(stext) 85 + 86 + #ifdef CONFIG_SMP 87 + __CPUINIT 88 + ENTRY(secondary_startup) 89 + /* 90 + * Common entry point for secondary CPUs. 91 + * 92 + * Ensure that we're in SVC mode, and IRQs are disabled. Lookup 93 + * the processor type - there is no need to check the machine type 94 + * as it has already been validated by the primary processor. 95 + */ 96 + setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 97 + #ifndef CONFIG_CPU_CP15 98 + ldr r9, =CONFIG_PROCESSOR_ID 99 + #else 100 + mrc p15, 0, r9, c0, c0 @ get processor id 101 + #endif 102 + bl __lookup_processor_type @ r5=procinfo r9=cpuid 103 + movs r10, r5 @ invalid processor? 104 + beq __error_p @ yes, error 'p' 105 + 106 + adr r4, __secondary_data 107 + ldmia r4, {r7, r12} 108 + 109 + #ifdef CONFIG_ARM_MPU 110 + /* Use MPU region info supplied by __cpu_up */ 111 + ldr r6, [r7] @ get secondary_data.mpu_szr 112 + bl __setup_mpu @ Initialize the MPU 113 + #endif 114 + 115 + adr lr, BSYM(__after_proc_init) @ return address 116 + mov r13, r12 @ __secondary_switched address 117 + ARM( add pc, r10, #PROCINFO_INITFUNC ) 118 + THUMB( add r12, r10, #PROCINFO_INITFUNC ) 119 + THUMB( mov pc, r12 ) 120 + ENDPROC(secondary_startup) 121 + 122 + ENTRY(__secondary_switched) 123 + ldr sp, [r7, #8] @ set up the stack pointer 124 + mov fp, #0 125 + b secondary_start_kernel 126 + ENDPROC(__secondary_switched) 127 + 128 + .type __secondary_data, %object 129 + __secondary_data: 130 + .long secondary_data 131 + .long __secondary_switched 132 + #endif /* CONFIG_SMP */ 74 133 75 134 /* 76 135 * Set the Control Register and Read the process ID. ··· 164 99 #endif 165 100 mcr p15, 0, r0, c1, c0, 0 @ write control reg 166 101 #endif /* CONFIG_CPU_CP15 */ 167 - 168 - b __mmap_switched @ clear the BSS and jump 169 - @ to start_kernel 102 + mov pc, r13 170 103 ENDPROC(__after_proc_init) 171 104 .ltorg 172 105 106 + #ifdef CONFIG_ARM_MPU 107 + 108 + 109 + /* Set which MPU region should be programmed */ 110 + .macro set_region_nr tmp, rgnr 111 + mov \tmp, \rgnr @ Use static region numbers 112 + mcr p15, 0, \tmp, c6, c2, 0 @ Write RGNR 113 + .endm 114 + 115 + /* Setup a single MPU region, either D or I side (D-side for unified) */ 116 + .macro setup_region bar, acr, sr, side = MPU_DATA_SIDE 117 + mcr p15, 0, \bar, c6, c1, (0 + \side) @ I/DRBAR 118 + mcr p15, 0, \acr, c6, c1, (4 + \side) @ I/DRACR 119 + mcr p15, 0, \sr, c6, c1, (2 + \side) @ I/DRSR 120 + .endm 121 + 122 + /* 123 + * Setup the MPU and initial MPU Regions. We create the following regions: 124 + * Region 0: Use this for probing the MPU details, so leave disabled. 125 + * Region 1: Background region - covers the whole of RAM as strongly ordered 126 + * Region 2: Normal, Shared, cacheable for RAM. From PHYS_OFFSET, size from r6 127 + * Region 3: Normal, shared, inaccessible from PL0 to protect the vectors page 128 + * 129 + * r6: Value to be written to DRSR (and IRSR if required) for MPU_RAM_REGION 130 + */ 131 + 132 + ENTRY(__setup_mpu) 133 + 134 + /* Probe for v7 PMSA compliance */ 135 + mrc p15, 0, r0, c0, c1, 4 @ Read ID_MMFR0 136 + and r0, r0, #(MMFR0_PMSA) @ PMSA field 137 + teq r0, #(MMFR0_PMSAv7) @ PMSA v7 138 + bne __error_p @ Fail: ARM_MPU on NOT v7 PMSA 139 + 140 + /* Determine whether the D/I-side memory map is unified. We set the 141 + * flags here and continue to use them for the rest of this function */ 142 + mrc p15, 0, r0, c0, c0, 4 @ MPUIR 143 + ands r5, r0, #MPUIR_DREGION_SZMASK @ 0 size d region => No MPU 144 + beq __error_p @ Fail: ARM_MPU and no MPU 145 + tst r0, #MPUIR_nU @ MPUIR_nU = 0 for unified 146 + 147 + /* Setup second region first to free up r6 */ 148 + set_region_nr r0, #MPU_RAM_REGION 149 + isb 150 + /* Full access from PL0, PL1, shared for CONFIG_SMP, cacheable */ 151 + ldr r0, =PHYS_OFFSET @ RAM starts at PHYS_OFFSET 152 + ldr r5,=(MPU_AP_PL1RW_PL0RW | MPU_RGN_NORMAL) 153 + 154 + setup_region r0, r5, r6, MPU_DATA_SIDE @ PHYS_OFFSET, shared, enabled 155 + beq 1f @ Memory-map not unified 156 + setup_region r0, r5, r6, MPU_INSTR_SIDE @ PHYS_OFFSET, shared, enabled 157 + 1: isb 158 + 159 + /* First/background region */ 160 + set_region_nr r0, #MPU_BG_REGION 161 + isb 162 + /* Execute Never, strongly ordered, inaccessible to PL0, rw PL1 */ 163 + mov r0, #0 @ BG region starts at 0x0 164 + ldr r5,=(MPU_ACR_XN | MPU_RGN_STRONGLY_ORDERED | MPU_AP_PL1RW_PL0NA) 165 + mov r6, #MPU_RSR_ALL_MEM @ 4GB region, enabled 166 + 167 + setup_region r0, r5, r6, MPU_DATA_SIDE @ 0x0, BG region, enabled 168 + beq 2f @ Memory-map not unified 169 + setup_region r0, r5, r6, MPU_INSTR_SIDE @ 0x0, BG region, enabled 170 + 2: isb 171 + 172 + /* Vectors region */ 173 + set_region_nr r0, #MPU_VECTORS_REGION 174 + isb 175 + /* Shared, inaccessible to PL0, rw PL1 */ 176 + mov r0, #CONFIG_VECTORS_BASE @ Cover from VECTORS_BASE 177 + ldr r5,=(MPU_AP_PL1RW_PL0NA | MPU_RGN_NORMAL) 178 + /* Writing N to bits 5:1 (RSR_SZ) --> region size 2^N+1 */ 179 + mov r6, #(((PAGE_SHIFT - 1) << MPU_RSR_SZ) | 1 << MPU_RSR_EN) 180 + 181 + setup_region r0, r5, r6, MPU_DATA_SIDE @ VECTORS_BASE, PL0 NA, enabled 182 + beq 3f @ Memory-map not unified 183 + setup_region r0, r5, r6, MPU_INSTR_SIDE @ VECTORS_BASE, PL0 NA, enabled 184 + 3: isb 185 + 186 + /* Enable the MPU */ 187 + mrc p15, 0, r0, c1, c0, 0 @ Read SCTLR 188 + bic r0, r0, #CR_BR @ Disable the 'default mem-map' 189 + orr r0, r0, #CR_M @ Set SCTRL.M (MPU on) 190 + mcr p15, 0, r0, c1, c0, 0 @ Enable MPU 191 + isb 192 + mov pc,lr 193 + ENDPROC(__setup_mpu) 194 + #endif 173 195 #include "head-common.S"
+4 -6
arch/arm/kernel/head.S
··· 156 156 * 157 157 * Returns: 158 158 * r0, r3, r5-r7 corrupted 159 - * r4 = physical page table address 159 + * r4 = page table (see ARCH_PGD_SHIFT in asm/memory.h) 160 160 */ 161 161 __create_page_tables: 162 162 pgtbl r4, r8 @ page table address ··· 331 331 #endif 332 332 #ifdef CONFIG_ARM_LPAE 333 333 sub r4, r4, #0x1000 @ point to the PGD table 334 + mov r4, r4, lsr #ARCH_PGD_SHIFT 334 335 #endif 335 336 mov pc, lr 336 337 ENDPROC(__create_page_tables) ··· 409 408 * r0 = cp#15 control register 410 409 * r1 = machine ID 411 410 * r2 = atags or dtb pointer 412 - * r4 = page table pointer 411 + * r4 = page table (see ARCH_PGD_SHIFT in asm/memory.h) 413 412 * r9 = processor ID 414 413 * r13 = *virtual* address to jump to upon completion 415 414 */ ··· 428 427 #ifdef CONFIG_CPU_ICACHE_DISABLE 429 428 bic r0, r0, #CR_I 430 429 #endif 431 - #ifdef CONFIG_ARM_LPAE 432 - mov r5, #0 433 - mcrr p15, 0, r4, r5, c2 @ load TTBR0 434 - #else 430 + #ifndef CONFIG_ARM_LPAE 435 431 mov r5, #(domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \ 436 432 domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \ 437 433 domain_val(DOMAIN_TABLE, DOMAIN_MANAGER) | \
+7
arch/arm/kernel/hyp-stub.S
··· 153 153 mrc p15, 4, r7, c14, c1, 0 @ CNTHCTL 154 154 orr r7, r7, #3 @ PL1PCEN | PL1PCTEN 155 155 mcr p15, 4, r7, c14, c1, 0 @ CNTHCTL 156 + mov r7, #0 157 + mcrr p15, 4, r7, r7, c14 @ CNTVOFF 158 + 159 + @ Disable virtual timer in case it was counting 160 + mrc p15, 0, r7, c14, c3, 1 @ CNTV_CTL 161 + bic r7, #1 @ Clear ENABLE 162 + mcr p15, 0, r7, c14, c3, 1 @ CNTV_CTL 156 163 1: 157 164 #endif 158 165
+1
arch/arm/kernel/perf_event.c
··· 569 569 return; 570 570 } 571 571 572 + perf_callchain_store(entry, regs->ARM_pc); 572 573 tail = (struct frame_tail __user *)regs->ARM_fp - 1; 573 574 574 575 while ((entry->nr < PERF_MAX_STACK_DEPTH) &&
+3 -1
arch/arm/kernel/process.c
··· 39 39 #include <asm/thread_notify.h> 40 40 #include <asm/stacktrace.h> 41 41 #include <asm/mach/time.h> 42 + #include <asm/tls.h> 42 43 43 44 #ifdef CONFIG_CC_STACKPROTECTOR 44 45 #include <linux/stackprotector.h> ··· 375 374 clear_ptrace_hw_breakpoint(p); 376 375 377 376 if (clone_flags & CLONE_SETTLS) 378 - thread->tp_value = childregs->ARM_r3; 377 + thread->tp_value[0] = childregs->ARM_r3; 378 + thread->tp_value[1] = get_tpuser(); 379 379 380 380 thread_notify(THREAD_NOTIFY_COPY, thread); 381 381
+2 -2
arch/arm/kernel/psci_smp.c
··· 68 68 /* We should never return */ 69 69 panic("psci: cpu %d failed to shutdown\n", cpu); 70 70 } 71 - #else 72 - #define psci_cpu_die NULL 73 71 #endif 74 72 75 73 bool __init psci_smp_available(void) ··· 78 80 79 81 struct smp_operations __initdata psci_smp_ops = { 80 82 .smp_boot_secondary = psci_boot_secondary, 83 + #ifdef CONFIG_HOTPLUG_CPU 81 84 .cpu_die = psci_cpu_die, 85 + #endif 82 86 };
+1 -1
arch/arm/kernel/ptrace.c
··· 849 849 #endif 850 850 851 851 case PTRACE_GET_THREAD_AREA: 852 - ret = put_user(task_thread_info(child)->tp_value, 852 + ret = put_user(task_thread_info(child)->tp_value[0], 853 853 datap); 854 854 break; 855 855
+81 -1
arch/arm/kernel/setup.c
··· 367 367 368 368 static void __init cpuid_init_hwcaps(void) 369 369 { 370 - unsigned int divide_instrs; 370 + unsigned int divide_instrs, vmsa; 371 371 372 372 if (cpu_architecture() < CPU_ARCH_ARMv7) 373 373 return; ··· 380 380 case 1: 381 381 elf_hwcap |= HWCAP_IDIVT; 382 382 } 383 + 384 + /* LPAE implies atomic ldrd/strd instructions */ 385 + vmsa = (read_cpuid_ext(CPUID_EXT_MMFR0) & 0xf) >> 0; 386 + if (vmsa >= 5) 387 + elf_hwcap |= HWCAP_LPAE; 383 388 } 384 389 385 390 static void __init feat_v6_fixup(void) ··· 475 470 for (i = 1; i < nr_cpu_ids; ++i) 476 471 cpu_logical_map(i) = i == cpu ? 0 : i; 477 472 473 + /* 474 + * clear __my_cpu_offset on boot CPU to avoid hang caused by 475 + * using percpu variable early, for example, lockdep will 476 + * access percpu variable inside lock_release 477 + */ 478 + set_my_cpu_offset(0); 479 + 478 480 printk(KERN_INFO "Booting Linux on physical CPU 0x%x\n", mpidr); 479 481 } 482 + 483 + struct mpidr_hash mpidr_hash; 484 + #ifdef CONFIG_SMP 485 + /** 486 + * smp_build_mpidr_hash - Pre-compute shifts required at each affinity 487 + * level in order to build a linear index from an 488 + * MPIDR value. Resulting algorithm is a collision 489 + * free hash carried out through shifting and ORing 490 + */ 491 + static void __init smp_build_mpidr_hash(void) 492 + { 493 + u32 i, affinity; 494 + u32 fs[3], bits[3], ls, mask = 0; 495 + /* 496 + * Pre-scan the list of MPIDRS and filter out bits that do 497 + * not contribute to affinity levels, ie they never toggle. 498 + */ 499 + for_each_possible_cpu(i) 500 + mask |= (cpu_logical_map(i) ^ cpu_logical_map(0)); 501 + pr_debug("mask of set bits 0x%x\n", mask); 502 + /* 503 + * Find and stash the last and first bit set at all affinity levels to 504 + * check how many bits are required to represent them. 505 + */ 506 + for (i = 0; i < 3; i++) { 507 + affinity = MPIDR_AFFINITY_LEVEL(mask, i); 508 + /* 509 + * Find the MSB bit and LSB bits position 510 + * to determine how many bits are required 511 + * to express the affinity level. 512 + */ 513 + ls = fls(affinity); 514 + fs[i] = affinity ? ffs(affinity) - 1 : 0; 515 + bits[i] = ls - fs[i]; 516 + } 517 + /* 518 + * An index can be created from the MPIDR by isolating the 519 + * significant bits at each affinity level and by shifting 520 + * them in order to compress the 24 bits values space to a 521 + * compressed set of values. This is equivalent to hashing 522 + * the MPIDR through shifting and ORing. It is a collision free 523 + * hash though not minimal since some levels might contain a number 524 + * of CPUs that is not an exact power of 2 and their bit 525 + * representation might contain holes, eg MPIDR[7:0] = {0x2, 0x80}. 526 + */ 527 + mpidr_hash.shift_aff[0] = fs[0]; 528 + mpidr_hash.shift_aff[1] = MPIDR_LEVEL_BITS + fs[1] - bits[0]; 529 + mpidr_hash.shift_aff[2] = 2*MPIDR_LEVEL_BITS + fs[2] - 530 + (bits[1] + bits[0]); 531 + mpidr_hash.mask = mask; 532 + mpidr_hash.bits = bits[2] + bits[1] + bits[0]; 533 + pr_debug("MPIDR hash: aff0[%u] aff1[%u] aff2[%u] mask[0x%x] bits[%u]\n", 534 + mpidr_hash.shift_aff[0], 535 + mpidr_hash.shift_aff[1], 536 + mpidr_hash.shift_aff[2], 537 + mpidr_hash.mask, 538 + mpidr_hash.bits); 539 + /* 540 + * 4x is an arbitrary value used to warn on a hash table much bigger 541 + * than expected on most systems. 542 + */ 543 + if (mpidr_hash_size() > 4 * num_possible_cpus()) 544 + pr_warn("Large number of MPIDR hash buckets detected\n"); 545 + sync_cache_w(&mpidr_hash); 546 + } 547 + #endif 480 548 481 549 static void __init setup_processor(void) 482 550 { ··· 898 820 smp_set_ops(mdesc->smp); 899 821 } 900 822 smp_init_cpus(); 823 + smp_build_mpidr_hash(); 901 824 } 902 825 #endif 903 826 ··· 971 892 "vfpv4", 972 893 "idiva", 973 894 "idivt", 895 + "lpae", 974 896 NULL 975 897 }; 976 898
+7 -2
arch/arm/kernel/signal.c
··· 392 392 if (ksig->ka.sa.sa_flags & SA_SIGINFO) 393 393 idx += 3; 394 394 395 + /* 396 + * Put the sigreturn code on the stack no matter which return 397 + * mechanism we use in order to remain ABI compliant 398 + */ 395 399 if (__put_user(sigreturn_codes[idx], rc) || 396 400 __put_user(sigreturn_codes[idx+1], rc+1)) 397 401 return 1; 398 402 399 - if (cpsr & MODE32_BIT) { 403 + if ((cpsr & MODE32_BIT) && !IS_ENABLED(CONFIG_ARM_MPU)) { 400 404 /* 401 405 * 32-bit code can use the new high-page 402 - * signal return code support. 406 + * signal return code support except when the MPU has 407 + * protected the vectors page from PL0 403 408 */ 404 409 retcode = KERN_SIGRETURN_CODE + (idx << 2) + thumb; 405 410 } else {
+79 -18
arch/arm/kernel/sleep.S
··· 7 7 .text 8 8 9 9 /* 10 + * Implementation of MPIDR hash algorithm through shifting 11 + * and OR'ing. 12 + * 13 + * @dst: register containing hash result 14 + * @rs0: register containing affinity level 0 bit shift 15 + * @rs1: register containing affinity level 1 bit shift 16 + * @rs2: register containing affinity level 2 bit shift 17 + * @mpidr: register containing MPIDR value 18 + * @mask: register containing MPIDR mask 19 + * 20 + * Pseudo C-code: 21 + * 22 + *u32 dst; 23 + * 24 + *compute_mpidr_hash(u32 rs0, u32 rs1, u32 rs2, u32 mpidr, u32 mask) { 25 + * u32 aff0, aff1, aff2; 26 + * u32 mpidr_masked = mpidr & mask; 27 + * aff0 = mpidr_masked & 0xff; 28 + * aff1 = mpidr_masked & 0xff00; 29 + * aff2 = mpidr_masked & 0xff0000; 30 + * dst = (aff0 >> rs0 | aff1 >> rs1 | aff2 >> rs2); 31 + *} 32 + * Input registers: rs0, rs1, rs2, mpidr, mask 33 + * Output register: dst 34 + * Note: input and output registers must be disjoint register sets 35 + (eg: a macro instance with mpidr = r1 and dst = r1 is invalid) 36 + */ 37 + .macro compute_mpidr_hash dst, rs0, rs1, rs2, mpidr, mask 38 + and \mpidr, \mpidr, \mask @ mask out MPIDR bits 39 + and \dst, \mpidr, #0xff @ mask=aff0 40 + ARM( mov \dst, \dst, lsr \rs0 ) @ dst=aff0>>rs0 41 + THUMB( lsr \dst, \dst, \rs0 ) 42 + and \mask, \mpidr, #0xff00 @ mask = aff1 43 + ARM( orr \dst, \dst, \mask, lsr \rs1 ) @ dst|=(aff1>>rs1) 44 + THUMB( lsr \mask, \mask, \rs1 ) 45 + THUMB( orr \dst, \dst, \mask ) 46 + and \mask, \mpidr, #0xff0000 @ mask = aff2 47 + ARM( orr \dst, \dst, \mask, lsr \rs2 ) @ dst|=(aff2>>rs2) 48 + THUMB( lsr \mask, \mask, \rs2 ) 49 + THUMB( orr \dst, \dst, \mask ) 50 + .endm 51 + 52 + /* 10 53 * Save CPU state for a suspend. This saves the CPU general purpose 11 54 * registers, and allocates space on the kernel stack to save the CPU 12 55 * specific registers and some other data for resume. ··· 72 29 mov r1, r4 @ size of save block 73 30 mov r2, r5 @ virtual SP 74 31 ldr r3, =sleep_save_sp 75 - #ifdef CONFIG_SMP 76 - ALT_SMP(mrc p15, 0, lr, c0, c0, 5) 77 - ALT_UP(mov lr, #0) 78 - and lr, lr, #15 32 + ldr r3, [r3, #SLEEP_SAVE_SP_VIRT] 33 + ALT_SMP(mrc p15, 0, r9, c0, c0, 5) 34 + ALT_UP_B(1f) 35 + ldr r8, =mpidr_hash 36 + /* 37 + * This ldmia relies on the memory layout of the mpidr_hash 38 + * struct mpidr_hash. 39 + */ 40 + ldmia r8, {r4-r7} @ r4 = mpidr mask (r5,r6,r7) = l[0,1,2] shifts 41 + compute_mpidr_hash lr, r5, r6, r7, r9, r4 79 42 add r3, r3, lr, lsl #2 80 - #endif 43 + 1: 81 44 bl __cpu_suspend_save 82 45 adr lr, BSYM(cpu_suspend_abort) 83 46 ldmfd sp!, {r0, pc} @ call suspend fn ··· 130 81 .data 131 82 .align 132 83 ENTRY(cpu_resume) 133 - #ifdef CONFIG_SMP 134 - adr r0, sleep_save_sp 135 - ALT_SMP(mrc p15, 0, r1, c0, c0, 5) 136 - ALT_UP(mov r1, #0) 137 - and r1, r1, #15 138 - ldr r0, [r0, r1, lsl #2] @ stack phys addr 139 - #else 140 - ldr r0, sleep_save_sp @ stack phys addr 141 - #endif 84 + mov r1, #0 85 + ALT_SMP(mrc p15, 0, r0, c0, c0, 5) 86 + ALT_UP_B(1f) 87 + adr r2, mpidr_hash_ptr 88 + ldr r3, [r2] 89 + add r2, r2, r3 @ r2 = struct mpidr_hash phys address 90 + /* 91 + * This ldmia relies on the memory layout of the mpidr_hash 92 + * struct mpidr_hash. 93 + */ 94 + ldmia r2, { r3-r6 } @ r3 = mpidr mask (r4,r5,r6) = l[0,1,2] shifts 95 + compute_mpidr_hash r1, r4, r5, r6, r0, r3 96 + 1: 97 + adr r0, _sleep_save_sp 98 + ldr r0, [r0, #SLEEP_SAVE_SP_PHYS] 99 + ldr r0, [r0, r1, lsl #2] 100 + 142 101 setmode PSR_I_BIT | PSR_F_BIT | SVC_MODE, r1 @ set SVC, irqs off 143 102 @ load phys pgd, stack, resume fn 144 103 ARM( ldmia r0!, {r1, sp, pc} ) ··· 155 98 THUMB( bx r3 ) 156 99 ENDPROC(cpu_resume) 157 100 158 - sleep_save_sp: 159 - .rept CONFIG_NR_CPUS 160 - .long 0 @ preserve stack phys ptr here 161 - .endr 101 + .align 2 102 + mpidr_hash_ptr: 103 + .long mpidr_hash - . @ mpidr_hash struct offset 104 + 105 + .type sleep_save_sp, #object 106 + ENTRY(sleep_save_sp) 107 + _sleep_save_sp: 108 + .space SLEEP_SAVE_SP_SZ @ struct sleep_save_sp
+17 -4
arch/arm/kernel/smp.c
··· 45 45 #include <asm/smp_plat.h> 46 46 #include <asm/virt.h> 47 47 #include <asm/mach/arch.h> 48 + #include <asm/mpu.h> 48 49 49 50 /* 50 51 * as from 2.5, kernels no longer have an init_tasks structure ··· 79 78 smp_ops = *ops; 80 79 }; 81 80 81 + static unsigned long get_arch_pgd(pgd_t *pgd) 82 + { 83 + phys_addr_t pgdir = virt_to_phys(pgd); 84 + BUG_ON(pgdir & ARCH_PGD_MASK); 85 + return pgdir >> ARCH_PGD_SHIFT; 86 + } 87 + 82 88 int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle) 83 89 { 84 90 int ret; ··· 95 87 * its stack and the page tables. 96 88 */ 97 89 secondary_data.stack = task_stack_page(idle) + THREAD_START_SP; 98 - secondary_data.pgdir = virt_to_phys(idmap_pgd); 99 - secondary_data.swapper_pg_dir = virt_to_phys(swapper_pg_dir); 90 + #ifdef CONFIG_ARM_MPU 91 + secondary_data.mpu_rgn_szr = mpu_rgn_info.rgns[MPU_RAM_REGION].drsr; 92 + #endif 93 + 94 + #ifdef CONFIG_MMU 95 + secondary_data.pgdir = get_arch_pgd(idmap_pgd); 96 + secondary_data.swapper_pg_dir = get_arch_pgd(swapper_pg_dir); 97 + #endif 100 98 __cpuc_flush_dcache_area(&secondary_data, sizeof(secondary_data)); 101 99 outer_clean_range(__pa(&secondary_data), __pa(&secondary_data + 1)); 102 100 ··· 126 112 pr_err("CPU%u: failed to boot: %d\n", cpu, ret); 127 113 } 128 114 129 - secondary_data.stack = NULL; 130 - secondary_data.pgdir = 0; 131 115 116 + memset(&secondary_data, 0, sizeof(secondary_data)); 132 117 return ret; 133 118 } 134 119
+2 -16
arch/arm/kernel/smp_tlb.c
··· 103 103 104 104 static void broadcast_tlb_mm_a15_erratum(struct mm_struct *mm) 105 105 { 106 - int cpu, this_cpu; 106 + int this_cpu; 107 107 cpumask_t mask = { CPU_BITS_NONE }; 108 108 109 109 if (!erratum_a15_798181()) ··· 111 111 112 112 dummy_flush_tlb_a15_erratum(); 113 113 this_cpu = get_cpu(); 114 - for_each_online_cpu(cpu) { 115 - if (cpu == this_cpu) 116 - continue; 117 - /* 118 - * We only need to send an IPI if the other CPUs are running 119 - * the same ASID as the one being invalidated. There is no 120 - * need for locking around the active_asids check since the 121 - * switch_mm() function has at least one dmb() (as required by 122 - * this workaround) in case a context switch happens on 123 - * another CPU after the condition below. 124 - */ 125 - if (atomic64_read(&mm->context.id) == 126 - atomic64_read(&per_cpu(active_asids, cpu))) 127 - cpumask_set_cpu(cpu, &mask); 128 - } 114 + a15_erratum_get_cpumask(this_cpu, mm, &mask); 129 115 smp_call_function_many(&mask, ipi_flush_tlb_a15_erratum, NULL, 1); 130 116 put_cpu(); 131 117 }
+52 -24
arch/arm/kernel/suspend.c
··· 1 1 #include <linux/init.h> 2 + #include <linux/slab.h> 2 3 4 + #include <asm/cacheflush.h> 3 5 #include <asm/idmap.h> 4 6 #include <asm/pgalloc.h> 5 7 #include <asm/pgtable.h> 6 8 #include <asm/memory.h> 9 + #include <asm/smp_plat.h> 7 10 #include <asm/suspend.h> 8 11 #include <asm/tlbflush.h> 9 12 10 13 extern int __cpu_suspend(unsigned long, int (*)(unsigned long)); 11 14 extern void cpu_resume_mmu(void); 15 + 16 + #ifdef CONFIG_MMU 17 + /* 18 + * Hide the first two arguments to __cpu_suspend - these are an implementation 19 + * detail which platform code shouldn't have to know about. 20 + */ 21 + int cpu_suspend(unsigned long arg, int (*fn)(unsigned long)) 22 + { 23 + struct mm_struct *mm = current->active_mm; 24 + int ret; 25 + 26 + if (!idmap_pgd) 27 + return -EINVAL; 28 + 29 + /* 30 + * Provide a temporary page table with an identity mapping for 31 + * the MMU-enable code, required for resuming. On successful 32 + * resume (indicated by a zero return code), we need to switch 33 + * back to the correct page tables. 34 + */ 35 + ret = __cpu_suspend(arg, fn); 36 + if (ret == 0) { 37 + cpu_switch_mm(mm->pgd, mm); 38 + local_flush_bp_all(); 39 + local_flush_tlb_all(); 40 + } 41 + 42 + return ret; 43 + } 44 + #else 45 + int cpu_suspend(unsigned long arg, int (*fn)(unsigned long)) 46 + { 47 + return __cpu_suspend(arg, fn); 48 + } 49 + #define idmap_pgd NULL 50 + #endif 12 51 13 52 /* 14 53 * This is called by __cpu_suspend() to save the state, and do whatever ··· 86 47 virt_to_phys(save_ptr) + sizeof(*save_ptr)); 87 48 } 88 49 89 - /* 90 - * Hide the first two arguments to __cpu_suspend - these are an implementation 91 - * detail which platform code shouldn't have to know about. 92 - */ 93 - int cpu_suspend(unsigned long arg, int (*fn)(unsigned long)) 50 + extern struct sleep_save_sp sleep_save_sp; 51 + 52 + static int cpu_suspend_alloc_sp(void) 94 53 { 95 - struct mm_struct *mm = current->active_mm; 96 - int ret; 54 + void *ctx_ptr; 55 + /* ctx_ptr is an array of physical addresses */ 56 + ctx_ptr = kcalloc(mpidr_hash_size(), sizeof(u32), GFP_KERNEL); 97 57 98 - if (!idmap_pgd) 99 - return -EINVAL; 100 - 101 - /* 102 - * Provide a temporary page table with an identity mapping for 103 - * the MMU-enable code, required for resuming. On successful 104 - * resume (indicated by a zero return code), we need to switch 105 - * back to the correct page tables. 106 - */ 107 - ret = __cpu_suspend(arg, fn); 108 - if (ret == 0) { 109 - cpu_switch_mm(mm->pgd, mm); 110 - local_flush_bp_all(); 111 - local_flush_tlb_all(); 112 - } 113 - 114 - return ret; 58 + if (WARN_ON(!ctx_ptr)) 59 + return -ENOMEM; 60 + sleep_save_sp.save_ptr_stash = ctx_ptr; 61 + sleep_save_sp.save_ptr_stash_phys = virt_to_phys(ctx_ptr); 62 + sync_cache_w(&sleep_save_sp); 63 + return 0; 115 64 } 65 + early_initcall(cpu_suspend_alloc_sp);
+2 -2
arch/arm/kernel/traps.c
··· 581 581 return regs->ARM_r0; 582 582 583 583 case NR(set_tls): 584 - thread->tp_value = regs->ARM_r0; 584 + thread->tp_value[0] = regs->ARM_r0; 585 585 if (tls_emu) 586 586 return 0; 587 587 if (has_tls_reg) { ··· 699 699 int reg = (instr >> 12) & 15; 700 700 if (reg == 15) 701 701 return 1; 702 - regs->uregs[reg] = current_thread_info()->tp_value; 702 + regs->uregs[reg] = current_thread_info()->tp_value[0]; 703 703 regs->ARM_pc += 4; 704 704 return 0; 705 705 }
+4
arch/arm/kvm/interrupts_head.S
··· 497 497 add r5, vcpu, r4 498 498 strd r2, r3, [r5] 499 499 500 + @ Ensure host CNTVCT == CNTPCT 501 + mov r2, #0 502 + mcrr p15, 4, r2, r2, c14 @ CNTVOFF 503 + 500 504 1: 501 505 #endif 502 506 @ Allow physical timer/counter access for the host
+1 -1
arch/arm/mach-ebsa110/core.c
··· 116 116 iotable_init(ebsa110_io_desc, ARRAY_SIZE(ebsa110_io_desc)); 117 117 } 118 118 119 - static void __iomem *ebsa110_ioremap_caller(unsigned long cookie, size_t size, 119 + static void __iomem *ebsa110_ioremap_caller(phys_addr_t cookie, size_t size, 120 120 unsigned int flags, void *caller) 121 121 { 122 122 return (void __iomem *)cookie;
+1 -1
arch/arm/mach-exynos/Kconfig
··· 93 93 default y 94 94 depends on ARCH_EXYNOS5 95 95 select ARCH_HAS_OPP 96 - select ARM_ARCH_TIMER 96 + select HAVE_ARM_ARCH_TIMER 97 97 select AUTO_ZRELADDR 98 98 select MIGHT_HAVE_PCI 99 99 select PCI_DOMAINS if PCI
+1 -1
arch/arm/mach-imx/mm-imx3.c
··· 65 65 : "=r" (reg)); 66 66 } 67 67 68 - static void __iomem *imx3_ioremap_caller(unsigned long phys_addr, size_t size, 68 + static void __iomem *imx3_ioremap_caller(phys_addr_t phys_addr, size_t size, 69 69 unsigned int mtype, void *caller) 70 70 { 71 71 if (mtype == MT_DEVICE) {
+1 -1
arch/arm/mach-iop13xx/io.c
··· 23 23 24 24 #include "pci.h" 25 25 26 - static void __iomem *__iop13xx_ioremap_caller(unsigned long cookie, 26 + static void __iomem *__iop13xx_ioremap_caller(phys_addr_t cookie, 27 27 size_t size, unsigned int mtype, void *caller) 28 28 { 29 29 void __iomem * retval;
+1 -1
arch/arm/mach-ixp4xx/common.c
··· 559 559 * fallback to the default. 560 560 */ 561 561 562 - static void __iomem *ixp4xx_ioremap_caller(unsigned long addr, size_t size, 562 + static void __iomem *ixp4xx_ioremap_caller(phys_addr_t addr, size_t size, 563 563 unsigned int mtype, void *caller) 564 564 { 565 565 if (!is_pci_memory(addr))
+1 -1
arch/arm/mach-msm/common.h
··· 23 23 extern void msm_map_msm8960_io(void); 24 24 extern void msm_map_qsd8x50_io(void); 25 25 26 - extern void __iomem *__msm_ioremap_caller(unsigned long phys_addr, size_t size, 26 + extern void __iomem *__msm_ioremap_caller(phys_addr_t phys_addr, size_t size, 27 27 unsigned int mtype, void *caller); 28 28 29 29 extern struct smp_operations msm_smp_ops;
+1 -1
arch/arm/mach-msm/io.c
··· 168 168 } 169 169 #endif /* CONFIG_ARCH_MSM7X30 */ 170 170 171 - void __iomem *__msm_ioremap_caller(unsigned long phys_addr, size_t size, 171 + void __iomem *__msm_ioremap_caller(phys_addr_t phys_addr, size_t size, 172 172 unsigned int mtype, void *caller) 173 173 { 174 174 if (mtype == MT_DEVICE) {
+1
arch/arm/mach-omap2/Kconfig
··· 4 4 config ARCH_OMAP2PLUS 5 5 bool "TI OMAP2/3/4/5 SoCs with device tree support" if (ARCH_MULTI_V6 || ARCH_MULTI_V7) 6 6 select ARCH_HAS_CPUFREQ 7 + select ARCH_HAS_BANDGAP 7 8 select ARCH_HAS_HOLES_MEMORYMODEL 8 9 select ARCH_OMAP 9 10 select ARCH_REQUIRE_GPIOLIB
+2 -2
arch/arm/mach-shmobile/Kconfig
··· 23 23 select ARCH_WANT_OPTIONAL_GPIOLIB 24 24 select ARM_GIC 25 25 select CPU_V7 26 - select ARM_ARCH_TIMER 26 + select HAVE_ARM_ARCH_TIMER 27 27 select SH_CLK_CPG 28 28 select RENESAS_IRQC 29 29 ··· 59 59 select ARCH_WANT_OPTIONAL_GPIOLIB 60 60 select ARM_GIC 61 61 select CPU_V7 62 - select ARM_ARCH_TIMER 62 + select HAVE_ARM_ARCH_TIMER 63 63 select SH_CLK_CPG 64 64 select RENESAS_IRQC 65 65
+1 -1
arch/arm/mach-tegra/Kconfig
··· 60 60 61 61 config ARCH_TEGRA_114_SOC 62 62 bool "Enable support for Tegra114 family" 63 - select ARM_ARCH_TIMER 63 + select HAVE_ARM_ARCH_TIMER 64 64 select ARM_GIC 65 65 select ARM_L1_CACHE_SHIFT_6 66 66 select CPU_FREQ_TABLE if CPU_FREQ
+1 -1
arch/arm/mach-virt/Kconfig
··· 2 2 bool "Dummy Virtual Machine" if ARCH_MULTI_V7 3 3 select ARCH_WANT_OPTIONAL_GPIOLIB 4 4 select ARM_GIC 5 - select ARM_ARCH_TIMER 5 + select HAVE_ARM_ARCH_TIMER 6 6 select ARM_PSCI 7 7 select HAVE_SMP 8 8 select CPU_V7
+2 -1
arch/arm/mm/Kconfig
··· 392 392 select CPU_CACHE_V7 393 393 select CPU_CACHE_VIPT 394 394 select CPU_COPY_V6 if MMU 395 - select CPU_CP15_MMU 395 + select CPU_CP15_MMU if MMU 396 + select CPU_CP15_MPU if !MMU 396 397 select CPU_HAS_ASID if MMU 397 398 select CPU_PABRT_V7 398 399 select CPU_TLB_V7 if MMU
+1
arch/arm/mm/Makefile
··· 16 16 17 17 obj-$(CONFIG_ALIGNMENT_TRAP) += alignment.o 18 18 obj-$(CONFIG_HIGHMEM) += highmem.o 19 + obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o 19 20 20 21 obj-$(CONFIG_CPU_ABRT_NOMMU) += abort-nommu.o 21 22 obj-$(CONFIG_CPU_ABRT_EV4) += abort-ev4.o
+158
arch/arm/mm/cache-l2x0.c
··· 523 523 } 524 524 } 525 525 526 + /* 527 + * For certain Broadcom SoCs, depending on the address range, different offsets 528 + * need to be added to the address before passing it to L2 for 529 + * invalidation/clean/flush 530 + * 531 + * Section Address Range Offset EMI 532 + * 1 0x00000000 - 0x3FFFFFFF 0x80000000 VC 533 + * 2 0x40000000 - 0xBFFFFFFF 0x40000000 SYS 534 + * 3 0xC0000000 - 0xFFFFFFFF 0x80000000 VC 535 + * 536 + * When the start and end addresses have crossed two different sections, we 537 + * need to break the L2 operation into two, each within its own section. 538 + * For example, if we need to invalidate addresses starts at 0xBFFF0000 and 539 + * ends at 0xC0001000, we need do invalidate 1) 0xBFFF0000 - 0xBFFFFFFF and 2) 540 + * 0xC0000000 - 0xC0001000 541 + * 542 + * Note 1: 543 + * By breaking a single L2 operation into two, we may potentially suffer some 544 + * performance hit, but keep in mind the cross section case is very rare 545 + * 546 + * Note 2: 547 + * We do not need to handle the case when the start address is in 548 + * Section 1 and the end address is in Section 3, since it is not a valid use 549 + * case 550 + * 551 + * Note 3: 552 + * Section 1 in practical terms can no longer be used on rev A2. Because of 553 + * that the code does not need to handle section 1 at all. 554 + * 555 + */ 556 + #define BCM_SYS_EMI_START_ADDR 0x40000000UL 557 + #define BCM_VC_EMI_SEC3_START_ADDR 0xC0000000UL 558 + 559 + #define BCM_SYS_EMI_OFFSET 0x40000000UL 560 + #define BCM_VC_EMI_OFFSET 0x80000000UL 561 + 562 + static inline int bcm_addr_is_sys_emi(unsigned long addr) 563 + { 564 + return (addr >= BCM_SYS_EMI_START_ADDR) && 565 + (addr < BCM_VC_EMI_SEC3_START_ADDR); 566 + } 567 + 568 + static inline unsigned long bcm_l2_phys_addr(unsigned long addr) 569 + { 570 + if (bcm_addr_is_sys_emi(addr)) 571 + return addr + BCM_SYS_EMI_OFFSET; 572 + else 573 + return addr + BCM_VC_EMI_OFFSET; 574 + } 575 + 576 + static void bcm_inv_range(unsigned long start, unsigned long end) 577 + { 578 + unsigned long new_start, new_end; 579 + 580 + BUG_ON(start < BCM_SYS_EMI_START_ADDR); 581 + 582 + if (unlikely(end <= start)) 583 + return; 584 + 585 + new_start = bcm_l2_phys_addr(start); 586 + new_end = bcm_l2_phys_addr(end); 587 + 588 + /* normal case, no cross section between start and end */ 589 + if (likely(bcm_addr_is_sys_emi(end) || !bcm_addr_is_sys_emi(start))) { 590 + l2x0_inv_range(new_start, new_end); 591 + return; 592 + } 593 + 594 + /* They cross sections, so it can only be a cross from section 595 + * 2 to section 3 596 + */ 597 + l2x0_inv_range(new_start, 598 + bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR-1)); 599 + l2x0_inv_range(bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR), 600 + new_end); 601 + } 602 + 603 + static void bcm_clean_range(unsigned long start, unsigned long end) 604 + { 605 + unsigned long new_start, new_end; 606 + 607 + BUG_ON(start < BCM_SYS_EMI_START_ADDR); 608 + 609 + if (unlikely(end <= start)) 610 + return; 611 + 612 + if ((end - start) >= l2x0_size) { 613 + l2x0_clean_all(); 614 + return; 615 + } 616 + 617 + new_start = bcm_l2_phys_addr(start); 618 + new_end = bcm_l2_phys_addr(end); 619 + 620 + /* normal case, no cross section between start and end */ 621 + if (likely(bcm_addr_is_sys_emi(end) || !bcm_addr_is_sys_emi(start))) { 622 + l2x0_clean_range(new_start, new_end); 623 + return; 624 + } 625 + 626 + /* They cross sections, so it can only be a cross from section 627 + * 2 to section 3 628 + */ 629 + l2x0_clean_range(new_start, 630 + bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR-1)); 631 + l2x0_clean_range(bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR), 632 + new_end); 633 + } 634 + 635 + static void bcm_flush_range(unsigned long start, unsigned long end) 636 + { 637 + unsigned long new_start, new_end; 638 + 639 + BUG_ON(start < BCM_SYS_EMI_START_ADDR); 640 + 641 + if (unlikely(end <= start)) 642 + return; 643 + 644 + if ((end - start) >= l2x0_size) { 645 + l2x0_flush_all(); 646 + return; 647 + } 648 + 649 + new_start = bcm_l2_phys_addr(start); 650 + new_end = bcm_l2_phys_addr(end); 651 + 652 + /* normal case, no cross section between start and end */ 653 + if (likely(bcm_addr_is_sys_emi(end) || !bcm_addr_is_sys_emi(start))) { 654 + l2x0_flush_range(new_start, new_end); 655 + return; 656 + } 657 + 658 + /* They cross sections, so it can only be a cross from section 659 + * 2 to section 3 660 + */ 661 + l2x0_flush_range(new_start, 662 + bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR-1)); 663 + l2x0_flush_range(bcm_l2_phys_addr(BCM_VC_EMI_SEC3_START_ADDR), 664 + new_end); 665 + } 666 + 526 667 static void __init l2x0_of_setup(const struct device_node *np, 527 668 u32 *aux_val, u32 *aux_mask) 528 669 { ··· 906 765 }, 907 766 }; 908 767 768 + static const struct l2x0_of_data bcm_l2x0_data = { 769 + .setup = pl310_of_setup, 770 + .save = pl310_save, 771 + .outer_cache = { 772 + .resume = pl310_resume, 773 + .inv_range = bcm_inv_range, 774 + .clean_range = bcm_clean_range, 775 + .flush_range = bcm_flush_range, 776 + .sync = l2x0_cache_sync, 777 + .flush_all = l2x0_flush_all, 778 + .inv_all = l2x0_inv_all, 779 + .disable = l2x0_disable, 780 + }, 781 + }; 782 + 909 783 static const struct of_device_id l2x0_ids[] __initconst = { 910 784 { .compatible = "arm,pl310-cache", .data = (void *)&pl310_data }, 911 785 { .compatible = "arm,l220-cache", .data = (void *)&l2x0_data }, ··· 929 773 .data = (void *)&aurora_no_outer_data}, 930 774 { .compatible = "marvell,aurora-outer-cache", 931 775 .data = (void *)&aurora_with_outer_data}, 776 + { .compatible = "bcm,bcm11351-a2-pl310-cache", 777 + .data = (void *)&bcm_l2x0_data}, 932 778 {} 933 779 }; 934 780
+47 -17
arch/arm/mm/context.c
··· 20 20 #include <asm/smp_plat.h> 21 21 #include <asm/thread_notify.h> 22 22 #include <asm/tlbflush.h> 23 + #include <asm/proc-fns.h> 23 24 24 25 /* 25 26 * On ARMv6, we have the following structure in the Context ID: ··· 40 39 * non 64-bit operations. 41 40 */ 42 41 #define ASID_FIRST_VERSION (1ULL << ASID_BITS) 43 - #define NUM_USER_ASIDS (ASID_FIRST_VERSION - 1) 44 - 45 - #define ASID_TO_IDX(asid) ((asid & ~ASID_MASK) - 1) 46 - #define IDX_TO_ASID(idx) ((idx + 1) & ~ASID_MASK) 42 + #define NUM_USER_ASIDS ASID_FIRST_VERSION 47 43 48 44 static DEFINE_RAW_SPINLOCK(cpu_asid_lock); 49 45 static atomic64_t asid_generation = ATOMIC64_INIT(ASID_FIRST_VERSION); 50 46 static DECLARE_BITMAP(asid_map, NUM_USER_ASIDS); 51 47 52 - DEFINE_PER_CPU(atomic64_t, active_asids); 48 + static DEFINE_PER_CPU(atomic64_t, active_asids); 53 49 static DEFINE_PER_CPU(u64, reserved_asids); 54 50 static cpumask_t tlb_flush_pending; 51 + 52 + #ifdef CONFIG_ARM_ERRATA_798181 53 + void a15_erratum_get_cpumask(int this_cpu, struct mm_struct *mm, 54 + cpumask_t *mask) 55 + { 56 + int cpu; 57 + unsigned long flags; 58 + u64 context_id, asid; 59 + 60 + raw_spin_lock_irqsave(&cpu_asid_lock, flags); 61 + context_id = mm->context.id.counter; 62 + for_each_online_cpu(cpu) { 63 + if (cpu == this_cpu) 64 + continue; 65 + /* 66 + * We only need to send an IPI if the other CPUs are 67 + * running the same ASID as the one being invalidated. 68 + */ 69 + asid = per_cpu(active_asids, cpu).counter; 70 + if (asid == 0) 71 + asid = per_cpu(reserved_asids, cpu); 72 + if (context_id == asid) 73 + cpumask_set_cpu(cpu, mask); 74 + } 75 + raw_spin_unlock_irqrestore(&cpu_asid_lock, flags); 76 + } 77 + #endif 55 78 56 79 #ifdef CONFIG_ARM_LPAE 57 80 static void cpu_set_reserved_ttbr0(void) 58 81 { 59 - unsigned long ttbl = __pa(swapper_pg_dir); 60 - unsigned long ttbh = 0; 61 - 62 82 /* 63 83 * Set TTBR0 to swapper_pg_dir which contains only global entries. The 64 84 * ASID is set to 0. 65 85 */ 66 - asm volatile( 67 - " mcrr p15, 0, %0, %1, c2 @ set TTBR0\n" 68 - : 69 - : "r" (ttbl), "r" (ttbh)); 86 + cpu_set_ttbr(0, __pa(swapper_pg_dir)); 70 87 isb(); 71 88 } 72 89 #else ··· 147 128 asid = 0; 148 129 } else { 149 130 asid = atomic64_xchg(&per_cpu(active_asids, i), 0); 150 - __set_bit(ASID_TO_IDX(asid), asid_map); 131 + /* 132 + * If this CPU has already been through a 133 + * rollover, but hasn't run another task in 134 + * the meantime, we must preserve its reserved 135 + * ASID, as this is the only trace we have of 136 + * the process it is still running. 137 + */ 138 + if (asid == 0) 139 + asid = per_cpu(reserved_asids, i); 140 + __set_bit(asid & ~ASID_MASK, asid_map); 151 141 } 152 142 per_cpu(reserved_asids, i) = asid; 153 143 } ··· 195 167 /* 196 168 * Allocate a free ASID. If we can't find one, take a 197 169 * note of the currently active ASIDs and mark the TLBs 198 - * as requiring flushes. 170 + * as requiring flushes. We always count from ASID #1, 171 + * as we reserve ASID #0 to switch via TTBR0 and indicate 172 + * rollover events. 199 173 */ 200 - asid = find_first_zero_bit(asid_map, NUM_USER_ASIDS); 174 + asid = find_next_zero_bit(asid_map, NUM_USER_ASIDS, 1); 201 175 if (asid == NUM_USER_ASIDS) { 202 176 generation = atomic64_add_return(ASID_FIRST_VERSION, 203 177 &asid_generation); 204 178 flush_context(cpu); 205 - asid = find_first_zero_bit(asid_map, NUM_USER_ASIDS); 179 + asid = find_next_zero_bit(asid_map, NUM_USER_ASIDS, 1); 206 180 } 207 181 __set_bit(asid, asid_map); 208 - asid = generation | IDX_TO_ASID(asid); 182 + asid |= generation; 209 183 cpumask_clear(mm_cpumask(mm)); 210 184 } 211 185
+18 -4
arch/arm/mm/dma-mapping.c
··· 250 250 251 251 #ifdef CONFIG_MMU 252 252 #ifdef CONFIG_HUGETLB_PAGE 253 - #error ARM Coherent DMA allocator does not (yet) support huge TLB 253 + #warning ARM Coherent DMA allocator does not (yet) support huge TLB 254 254 #endif 255 255 256 256 static void *__alloc_from_contiguous(struct device *dev, size_t size, ··· 880 880 dma_cache_maint_page(page, off, size, dir, dmac_unmap_area); 881 881 882 882 /* 883 - * Mark the D-cache clean for this page to avoid extra flushing. 883 + * Mark the D-cache clean for these pages to avoid extra flushing. 884 884 */ 885 - if (dir != DMA_TO_DEVICE && off == 0 && size >= PAGE_SIZE) 886 - set_bit(PG_dcache_clean, &page->flags); 885 + if (dir != DMA_TO_DEVICE && size >= PAGE_SIZE) { 886 + unsigned long pfn; 887 + size_t left = size; 888 + 889 + pfn = page_to_pfn(page) + off / PAGE_SIZE; 890 + off %= PAGE_SIZE; 891 + if (off) { 892 + pfn++; 893 + left -= PAGE_SIZE - off; 894 + } 895 + while (left >= PAGE_SIZE) { 896 + page = pfn_to_page(pfn++); 897 + set_bit(PG_dcache_clean, &page->flags); 898 + left -= PAGE_SIZE; 899 + } 900 + } 887 901 } 888 902 889 903 /**
+2
arch/arm/mm/fault.c
··· 491 491 * Some section permission faults need to be handled gracefully. 492 492 * They can happen due to a __{get,put}_user during an oops. 493 493 */ 494 + #ifndef CONFIG_ARM_LPAE 494 495 static int 495 496 do_sect_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) 496 497 { 497 498 do_bad_area(addr, fsr, regs); 498 499 return 0; 499 500 } 501 + #endif /* CONFIG_ARM_LPAE */ 500 502 501 503 /* 502 504 * This abort handler always returns "fault".
+16 -11
arch/arm/mm/flush.c
··· 17 17 #include <asm/highmem.h> 18 18 #include <asm/smp_plat.h> 19 19 #include <asm/tlbflush.h> 20 + #include <linux/hugetlb.h> 20 21 21 22 #include "mm.h" 22 23 ··· 169 168 * coherent with the kernels mapping. 170 169 */ 171 170 if (!PageHighMem(page)) { 172 - __cpuc_flush_dcache_area(page_address(page), PAGE_SIZE); 171 + size_t page_size = PAGE_SIZE << compound_order(page); 172 + __cpuc_flush_dcache_area(page_address(page), page_size); 173 173 } else { 174 - void *addr; 175 - 174 + unsigned long i; 176 175 if (cache_is_vipt_nonaliasing()) { 177 - addr = kmap_atomic(page); 178 - __cpuc_flush_dcache_area(addr, PAGE_SIZE); 179 - kunmap_atomic(addr); 180 - } else { 181 - addr = kmap_high_get(page); 182 - if (addr) { 176 + for (i = 0; i < (1 << compound_order(page)); i++) { 177 + void *addr = kmap_atomic(page); 183 178 __cpuc_flush_dcache_area(addr, PAGE_SIZE); 184 - kunmap_high(page); 179 + kunmap_atomic(addr); 180 + } 181 + } else { 182 + for (i = 0; i < (1 << compound_order(page)); i++) { 183 + void *addr = kmap_high_get(page); 184 + if (addr) { 185 + __cpuc_flush_dcache_area(addr, PAGE_SIZE); 186 + kunmap_high(page); 187 + } 185 188 } 186 189 } 187 190 } ··· 292 287 mapping = page_mapping(page); 293 288 294 289 if (!cache_ops_need_broadcast() && 295 - mapping && !mapping_mapped(mapping)) 290 + mapping && !page_mapped(page)) 296 291 clear_bit(PG_dcache_clean, &page->flags); 297 292 else { 298 293 __flush_dcache_page(mapping, page);
+2 -2
arch/arm/mm/fsr-3level.c
··· 9 9 { do_page_fault, SIGSEGV, SEGV_MAPERR, "level 3 translation fault" }, 10 10 { do_bad, SIGBUS, 0, "reserved access flag fault" }, 11 11 { do_bad, SIGSEGV, SEGV_ACCERR, "level 1 access flag fault" }, 12 - { do_bad, SIGSEGV, SEGV_ACCERR, "level 2 access flag fault" }, 12 + { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 2 access flag fault" }, 13 13 { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 3 access flag fault" }, 14 14 { do_bad, SIGBUS, 0, "reserved permission fault" }, 15 15 { do_bad, SIGSEGV, SEGV_ACCERR, "level 1 permission fault" }, 16 - { do_sect_fault, SIGSEGV, SEGV_ACCERR, "level 2 permission fault" }, 16 + { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 2 permission fault" }, 17 17 { do_page_fault, SIGSEGV, SEGV_ACCERR, "level 3 permission fault" }, 18 18 { do_bad, SIGBUS, 0, "synchronous external abort" }, 19 19 { do_bad, SIGBUS, 0, "asynchronous external abort" },
+101
arch/arm/mm/hugetlbpage.c
··· 1 + /* 2 + * arch/arm/mm/hugetlbpage.c 3 + * 4 + * Copyright (C) 2012 ARM Ltd. 5 + * 6 + * Based on arch/x86/include/asm/hugetlb.h and Bill Carson's patches 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + * 17 + * You should have received a copy of the GNU General Public License 18 + * along with this program; if not, write to the Free Software 19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 + */ 21 + 22 + #include <linux/init.h> 23 + #include <linux/fs.h> 24 + #include <linux/mm.h> 25 + #include <linux/hugetlb.h> 26 + #include <linux/pagemap.h> 27 + #include <linux/err.h> 28 + #include <linux/sysctl.h> 29 + #include <asm/mman.h> 30 + #include <asm/tlb.h> 31 + #include <asm/tlbflush.h> 32 + #include <asm/pgalloc.h> 33 + 34 + /* 35 + * On ARM, huge pages are backed by pmd's rather than pte's, so we do a lot 36 + * of type casting from pmd_t * to pte_t *. 37 + */ 38 + 39 + pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) 40 + { 41 + pgd_t *pgd; 42 + pud_t *pud; 43 + pmd_t *pmd = NULL; 44 + 45 + pgd = pgd_offset(mm, addr); 46 + if (pgd_present(*pgd)) { 47 + pud = pud_offset(pgd, addr); 48 + if (pud_present(*pud)) 49 + pmd = pmd_offset(pud, addr); 50 + } 51 + 52 + return (pte_t *)pmd; 53 + } 54 + 55 + struct page *follow_huge_addr(struct mm_struct *mm, unsigned long address, 56 + int write) 57 + { 58 + return ERR_PTR(-EINVAL); 59 + } 60 + 61 + int pud_huge(pud_t pud) 62 + { 63 + return 0; 64 + } 65 + 66 + int huge_pmd_unshare(struct mm_struct *mm, unsigned long *addr, pte_t *ptep) 67 + { 68 + return 0; 69 + } 70 + 71 + pte_t *huge_pte_alloc(struct mm_struct *mm, 72 + unsigned long addr, unsigned long sz) 73 + { 74 + pgd_t *pgd; 75 + pud_t *pud; 76 + pte_t *pte = NULL; 77 + 78 + pgd = pgd_offset(mm, addr); 79 + pud = pud_alloc(mm, pgd, addr); 80 + if (pud) 81 + pte = (pte_t *)pmd_alloc(mm, pud, addr); 82 + 83 + return pte; 84 + } 85 + 86 + struct page * 87 + follow_huge_pmd(struct mm_struct *mm, unsigned long address, 88 + pmd_t *pmd, int write) 89 + { 90 + struct page *page; 91 + 92 + page = pte_page(*(pte_t *)pmd); 93 + if (page) 94 + page += ((address & ~PMD_MASK) >> PAGE_SHIFT); 95 + return page; 96 + } 97 + 98 + int pmd_huge(pmd_t pmd) 99 + { 100 + return pmd_val(pmd) && !(pmd_val(pmd) & PMD_TABLE_BIT); 101 + }
+10 -9
arch/arm/mm/init.c
··· 36 36 37 37 #include "mm.h" 38 38 39 - static unsigned long phys_initrd_start __initdata = 0; 39 + static phys_addr_t phys_initrd_start __initdata = 0; 40 40 static unsigned long phys_initrd_size __initdata = 0; 41 41 42 42 static int __init early_initrd(char *p) 43 43 { 44 - unsigned long start, size; 44 + phys_addr_t start; 45 + unsigned long size; 45 46 char *endp; 46 47 47 48 start = memparse(p, &endp); ··· 351 350 #ifdef CONFIG_BLK_DEV_INITRD 352 351 if (phys_initrd_size && 353 352 !memblock_is_region_memory(phys_initrd_start, phys_initrd_size)) { 354 - pr_err("INITRD: 0x%08lx+0x%08lx is not a memory region - disabling initrd\n", 355 - phys_initrd_start, phys_initrd_size); 353 + pr_err("INITRD: 0x%08llx+0x%08lx is not a memory region - disabling initrd\n", 354 + (u64)phys_initrd_start, phys_initrd_size); 356 355 phys_initrd_start = phys_initrd_size = 0; 357 356 } 358 357 if (phys_initrd_size && 359 358 memblock_is_region_reserved(phys_initrd_start, phys_initrd_size)) { 360 - pr_err("INITRD: 0x%08lx+0x%08lx overlaps in-use memory region - disabling initrd\n", 361 - phys_initrd_start, phys_initrd_size); 359 + pr_err("INITRD: 0x%08llx+0x%08lx overlaps in-use memory region - disabling initrd\n", 360 + (u64)phys_initrd_start, phys_initrd_size); 362 361 phys_initrd_start = phys_initrd_size = 0; 363 362 } 364 363 if (phys_initrd_size) { ··· 443 442 free_memmap(unsigned long start_pfn, unsigned long end_pfn) 444 443 { 445 444 struct page *start_pg, *end_pg; 446 - unsigned long pg, pgend; 445 + phys_addr_t pg, pgend; 447 446 448 447 /* 449 448 * Convert start_pfn/end_pfn to a struct page pointer. ··· 455 454 * Convert to physical addresses, and 456 455 * round start upwards and end downwards. 457 456 */ 458 - pg = (unsigned long)PAGE_ALIGN(__pa(start_pg)); 459 - pgend = (unsigned long)__pa(end_pg) & PAGE_MASK; 457 + pg = PAGE_ALIGN(__pa(start_pg)); 458 + pgend = __pa(end_pg) & PAGE_MASK; 460 459 461 460 /* 462 461 * If there are free pages between these,
+5 -5
arch/arm/mm/ioremap.c
··· 331 331 return (void __iomem *) (offset + addr); 332 332 } 333 333 334 - void __iomem *__arm_ioremap_caller(unsigned long phys_addr, size_t size, 334 + void __iomem *__arm_ioremap_caller(phys_addr_t phys_addr, size_t size, 335 335 unsigned int mtype, void *caller) 336 336 { 337 - unsigned long last_addr; 337 + phys_addr_t last_addr; 338 338 unsigned long offset = phys_addr & ~PAGE_MASK; 339 339 unsigned long pfn = __phys_to_pfn(phys_addr); 340 340 ··· 367 367 } 368 368 EXPORT_SYMBOL(__arm_ioremap_pfn); 369 369 370 - void __iomem * (*arch_ioremap_caller)(unsigned long, size_t, 370 + void __iomem * (*arch_ioremap_caller)(phys_addr_t, size_t, 371 371 unsigned int, void *) = 372 372 __arm_ioremap_caller; 373 373 374 374 void __iomem * 375 - __arm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype) 375 + __arm_ioremap(phys_addr_t phys_addr, size_t size, unsigned int mtype) 376 376 { 377 377 return arch_ioremap_caller(phys_addr, size, mtype, 378 378 __builtin_return_address(0)); ··· 387 387 * CONFIG_GENERIC_ALLOCATOR for allocating external memory. 388 388 */ 389 389 void __iomem * 390 - __arm_ioremap_exec(unsigned long phys_addr, size_t size, bool cached) 390 + __arm_ioremap_exec(phys_addr_t phys_addr, size_t size, bool cached) 391 391 { 392 392 unsigned int mtype; 393 393
+17 -32
arch/arm/mm/mmu.c
··· 675 675 } 676 676 677 677 static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr, 678 - unsigned long end, unsigned long phys, const struct mem_type *type) 678 + unsigned long end, phys_addr_t phys, 679 + const struct mem_type *type) 679 680 { 680 681 pud_t *pud = pud_offset(pgd, addr); 681 682 unsigned long next; ··· 990 989 void __init sanity_check_meminfo(void) 991 990 { 992 991 int i, j, highmem = 0; 992 + phys_addr_t vmalloc_limit = __pa(vmalloc_min - 1) + 1; 993 993 994 994 for (i = 0, j = 0; i < meminfo.nr_banks; i++) { 995 995 struct membank *bank = &meminfo.bank[j]; 996 + phys_addr_t size_limit; 997 + 996 998 *bank = meminfo.bank[i]; 999 + size_limit = bank->size; 997 1000 998 - if (bank->start > ULONG_MAX) 1001 + if (bank->start >= vmalloc_limit) 999 1002 highmem = 1; 1000 - 1001 - #ifdef CONFIG_HIGHMEM 1002 - if (__va(bank->start) >= vmalloc_min || 1003 - __va(bank->start) < (void *)PAGE_OFFSET) 1004 - highmem = 1; 1003 + else 1004 + size_limit = vmalloc_limit - bank->start; 1005 1005 1006 1006 bank->highmem = highmem; 1007 1007 1008 + #ifdef CONFIG_HIGHMEM 1008 1009 /* 1009 1010 * Split those memory banks which are partially overlapping 1010 1011 * the vmalloc area greatly simplifying things later. 1011 1012 */ 1012 - if (!highmem && __va(bank->start) < vmalloc_min && 1013 - bank->size > vmalloc_min - __va(bank->start)) { 1013 + if (!highmem && bank->size > size_limit) { 1014 1014 if (meminfo.nr_banks >= NR_BANKS) { 1015 1015 printk(KERN_CRIT "NR_BANKS too low, " 1016 1016 "ignoring high memory\n"); ··· 1020 1018 (meminfo.nr_banks - i) * sizeof(*bank)); 1021 1019 meminfo.nr_banks++; 1022 1020 i++; 1023 - bank[1].size -= vmalloc_min - __va(bank->start); 1024 - bank[1].start = __pa(vmalloc_min - 1) + 1; 1021 + bank[1].size -= size_limit; 1022 + bank[1].start = vmalloc_limit; 1025 1023 bank[1].highmem = highmem = 1; 1026 1024 j++; 1027 1025 } 1028 - bank->size = vmalloc_min - __va(bank->start); 1026 + bank->size = size_limit; 1029 1027 } 1030 1028 #else 1031 - bank->highmem = highmem; 1032 - 1033 1029 /* 1034 1030 * Highmem banks not allowed with !CONFIG_HIGHMEM. 1035 1031 */ ··· 1040 1040 } 1041 1041 1042 1042 /* 1043 - * Check whether this memory bank would entirely overlap 1044 - * the vmalloc area. 1045 - */ 1046 - if (__va(bank->start) >= vmalloc_min || 1047 - __va(bank->start) < (void *)PAGE_OFFSET) { 1048 - printk(KERN_NOTICE "Ignoring RAM at %.8llx-%.8llx " 1049 - "(vmalloc region overlap).\n", 1050 - (unsigned long long)bank->start, 1051 - (unsigned long long)bank->start + bank->size - 1); 1052 - continue; 1053 - } 1054 - 1055 - /* 1056 1043 * Check whether this memory bank would partially overlap 1057 1044 * the vmalloc area. 1058 1045 */ 1059 - if (__va(bank->start + bank->size - 1) >= vmalloc_min || 1060 - __va(bank->start + bank->size - 1) <= __va(bank->start)) { 1061 - unsigned long newsize = vmalloc_min - __va(bank->start); 1046 + if (bank->size > size_limit) { 1062 1047 printk(KERN_NOTICE "Truncating RAM at %.8llx-%.8llx " 1063 1048 "to -%.8llx (vmalloc region overlap).\n", 1064 1049 (unsigned long long)bank->start, 1065 1050 (unsigned long long)bank->start + bank->size - 1, 1066 - (unsigned long long)bank->start + newsize - 1); 1067 - bank->size = newsize; 1051 + (unsigned long long)bank->start + size_limit - 1); 1052 + bank->size = size_limit; 1068 1053 } 1069 1054 #endif 1070 1055 if (!bank->highmem && bank->start + bank->size > arm_lowmem_limit)
+259 -4
arch/arm/mm/nommu.c
··· 8 8 #include <linux/pagemap.h> 9 9 #include <linux/io.h> 10 10 #include <linux/memblock.h> 11 + #include <linux/kernel.h> 11 12 12 13 #include <asm/cacheflush.h> 13 14 #include <asm/sections.h> ··· 16 15 #include <asm/setup.h> 17 16 #include <asm/traps.h> 18 17 #include <asm/mach/arch.h> 18 + #include <asm/cputype.h> 19 + #include <asm/mpu.h> 19 20 20 21 #include "mm.h" 22 + 23 + #ifdef CONFIG_ARM_MPU 24 + struct mpu_rgn_info mpu_rgn_info; 25 + 26 + /* Region number */ 27 + static void rgnr_write(u32 v) 28 + { 29 + asm("mcr p15, 0, %0, c6, c2, 0" : : "r" (v)); 30 + } 31 + 32 + /* Data-side / unified region attributes */ 33 + 34 + /* Region access control register */ 35 + static void dracr_write(u32 v) 36 + { 37 + asm("mcr p15, 0, %0, c6, c1, 4" : : "r" (v)); 38 + } 39 + 40 + /* Region size register */ 41 + static void drsr_write(u32 v) 42 + { 43 + asm("mcr p15, 0, %0, c6, c1, 2" : : "r" (v)); 44 + } 45 + 46 + /* Region base address register */ 47 + static void drbar_write(u32 v) 48 + { 49 + asm("mcr p15, 0, %0, c6, c1, 0" : : "r" (v)); 50 + } 51 + 52 + static u32 drbar_read(void) 53 + { 54 + u32 v; 55 + asm("mrc p15, 0, %0, c6, c1, 0" : "=r" (v)); 56 + return v; 57 + } 58 + /* Optional instruction-side region attributes */ 59 + 60 + /* I-side Region access control register */ 61 + static void iracr_write(u32 v) 62 + { 63 + asm("mcr p15, 0, %0, c6, c1, 5" : : "r" (v)); 64 + } 65 + 66 + /* I-side Region size register */ 67 + static void irsr_write(u32 v) 68 + { 69 + asm("mcr p15, 0, %0, c6, c1, 3" : : "r" (v)); 70 + } 71 + 72 + /* I-side Region base address register */ 73 + static void irbar_write(u32 v) 74 + { 75 + asm("mcr p15, 0, %0, c6, c1, 1" : : "r" (v)); 76 + } 77 + 78 + static unsigned long irbar_read(void) 79 + { 80 + unsigned long v; 81 + asm("mrc p15, 0, %0, c6, c1, 1" : "=r" (v)); 82 + return v; 83 + } 84 + 85 + /* MPU initialisation functions */ 86 + void __init sanity_check_meminfo_mpu(void) 87 + { 88 + int i; 89 + struct membank *bank = meminfo.bank; 90 + phys_addr_t phys_offset = PHYS_OFFSET; 91 + phys_addr_t aligned_region_size, specified_mem_size, rounded_mem_size; 92 + 93 + /* Initially only use memory continuous from PHYS_OFFSET */ 94 + if (bank_phys_start(&bank[0]) != phys_offset) 95 + panic("First memory bank must be contiguous from PHYS_OFFSET"); 96 + 97 + /* Banks have already been sorted by start address */ 98 + for (i = 1; i < meminfo.nr_banks; i++) { 99 + if (bank[i].start <= bank_phys_end(&bank[0]) && 100 + bank_phys_end(&bank[i]) > bank_phys_end(&bank[0])) { 101 + bank[0].size = bank_phys_end(&bank[i]) - bank[0].start; 102 + } else { 103 + pr_notice("Ignoring RAM after 0x%.8lx. " 104 + "First non-contiguous (ignored) bank start: 0x%.8lx\n", 105 + (unsigned long)bank_phys_end(&bank[0]), 106 + (unsigned long)bank_phys_start(&bank[i])); 107 + break; 108 + } 109 + } 110 + /* All contiguous banks are now merged in to the first bank */ 111 + meminfo.nr_banks = 1; 112 + specified_mem_size = bank[0].size; 113 + 114 + /* 115 + * MPU has curious alignment requirements: Size must be power of 2, and 116 + * region start must be aligned to the region size 117 + */ 118 + if (phys_offset != 0) 119 + pr_info("PHYS_OFFSET != 0 => MPU Region size constrained by alignment requirements\n"); 120 + 121 + /* 122 + * Maximum aligned region might overflow phys_addr_t if phys_offset is 123 + * 0. Hence we keep everything below 4G until we take the smaller of 124 + * the aligned_region_size and rounded_mem_size, one of which is 125 + * guaranteed to be smaller than the maximum physical address. 126 + */ 127 + aligned_region_size = (phys_offset - 1) ^ (phys_offset); 128 + /* Find the max power-of-two sized region that fits inside our bank */ 129 + rounded_mem_size = (1 << __fls(bank[0].size)) - 1; 130 + 131 + /* The actual region size is the smaller of the two */ 132 + aligned_region_size = aligned_region_size < rounded_mem_size 133 + ? aligned_region_size + 1 134 + : rounded_mem_size + 1; 135 + 136 + if (aligned_region_size != specified_mem_size) 137 + pr_warn("Truncating memory from 0x%.8lx to 0x%.8lx (MPU region constraints)", 138 + (unsigned long)specified_mem_size, 139 + (unsigned long)aligned_region_size); 140 + 141 + meminfo.bank[0].size = aligned_region_size; 142 + pr_debug("MPU Region from 0x%.8lx size 0x%.8lx (end 0x%.8lx))\n", 143 + (unsigned long)phys_offset, 144 + (unsigned long)aligned_region_size, 145 + (unsigned long)bank_phys_end(&bank[0])); 146 + 147 + } 148 + 149 + static int mpu_present(void) 150 + { 151 + return ((read_cpuid_ext(CPUID_EXT_MMFR0) & MMFR0_PMSA) == MMFR0_PMSAv7); 152 + } 153 + 154 + static int mpu_max_regions(void) 155 + { 156 + /* 157 + * We don't support a different number of I/D side regions so if we 158 + * have separate instruction and data memory maps then return 159 + * whichever side has a smaller number of supported regions. 160 + */ 161 + u32 dregions, iregions, mpuir; 162 + mpuir = read_cpuid(CPUID_MPUIR); 163 + 164 + dregions = iregions = (mpuir & MPUIR_DREGION_SZMASK) >> MPUIR_DREGION; 165 + 166 + /* Check for separate d-side and i-side memory maps */ 167 + if (mpuir & MPUIR_nU) 168 + iregions = (mpuir & MPUIR_IREGION_SZMASK) >> MPUIR_IREGION; 169 + 170 + /* Use the smallest of the two maxima */ 171 + return min(dregions, iregions); 172 + } 173 + 174 + static int mpu_iside_independent(void) 175 + { 176 + /* MPUIR.nU specifies whether there is *not* a unified memory map */ 177 + return read_cpuid(CPUID_MPUIR) & MPUIR_nU; 178 + } 179 + 180 + static int mpu_min_region_order(void) 181 + { 182 + u32 drbar_result, irbar_result; 183 + /* We've kept a region free for this probing */ 184 + rgnr_write(MPU_PROBE_REGION); 185 + isb(); 186 + /* 187 + * As per ARM ARM, write 0xFFFFFFFC to DRBAR to find the minimum 188 + * region order 189 + */ 190 + drbar_write(0xFFFFFFFC); 191 + drbar_result = irbar_result = drbar_read(); 192 + drbar_write(0x0); 193 + /* If the MPU is non-unified, we use the larger of the two minima*/ 194 + if (mpu_iside_independent()) { 195 + irbar_write(0xFFFFFFFC); 196 + irbar_result = irbar_read(); 197 + irbar_write(0x0); 198 + } 199 + isb(); /* Ensure that MPU region operations have completed */ 200 + /* Return whichever result is larger */ 201 + return __ffs(max(drbar_result, irbar_result)); 202 + } 203 + 204 + static int mpu_setup_region(unsigned int number, phys_addr_t start, 205 + unsigned int size_order, unsigned int properties) 206 + { 207 + u32 size_data; 208 + 209 + /* We kept a region free for probing resolution of MPU regions*/ 210 + if (number > mpu_max_regions() || number == MPU_PROBE_REGION) 211 + return -ENOENT; 212 + 213 + if (size_order > 32) 214 + return -ENOMEM; 215 + 216 + if (size_order < mpu_min_region_order()) 217 + return -ENOMEM; 218 + 219 + /* Writing N to bits 5:1 (RSR_SZ) specifies region size 2^N+1 */ 220 + size_data = ((size_order - 1) << MPU_RSR_SZ) | 1 << MPU_RSR_EN; 221 + 222 + dsb(); /* Ensure all previous data accesses occur with old mappings */ 223 + rgnr_write(number); 224 + isb(); 225 + drbar_write(start); 226 + dracr_write(properties); 227 + isb(); /* Propagate properties before enabling region */ 228 + drsr_write(size_data); 229 + 230 + /* Check for independent I-side registers */ 231 + if (mpu_iside_independent()) { 232 + irbar_write(start); 233 + iracr_write(properties); 234 + isb(); 235 + irsr_write(size_data); 236 + } 237 + isb(); 238 + 239 + /* Store region info (we treat i/d side the same, so only store d) */ 240 + mpu_rgn_info.rgns[number].dracr = properties; 241 + mpu_rgn_info.rgns[number].drbar = start; 242 + mpu_rgn_info.rgns[number].drsr = size_data; 243 + return 0; 244 + } 245 + 246 + /* 247 + * Set up default MPU regions, doing nothing if there is no MPU 248 + */ 249 + void __init mpu_setup(void) 250 + { 251 + int region_err; 252 + if (!mpu_present()) 253 + return; 254 + 255 + region_err = mpu_setup_region(MPU_RAM_REGION, PHYS_OFFSET, 256 + ilog2(meminfo.bank[0].size), 257 + MPU_AP_PL1RW_PL0RW | MPU_RGN_NORMAL); 258 + if (region_err) { 259 + panic("MPU region initialization failure! %d", region_err); 260 + } else { 261 + pr_info("Using ARMv7 PMSA Compliant MPU. " 262 + "Region independence: %s, Max regions: %d\n", 263 + mpu_iside_independent() ? "Yes" : "No", 264 + mpu_max_regions()); 265 + } 266 + } 267 + #else 268 + static void sanity_check_meminfo_mpu(void) {} 269 + static void __init mpu_setup(void) {} 270 + #endif /* CONFIG_ARM_MPU */ 21 271 22 272 void __init arm_mm_memblock_reserve(void) 23 273 { ··· 289 37 290 38 void __init sanity_check_meminfo(void) 291 39 { 292 - phys_addr_t end = bank_phys_end(&meminfo.bank[meminfo.nr_banks - 1]); 40 + phys_addr_t end; 41 + sanity_check_meminfo_mpu(); 42 + end = bank_phys_end(&meminfo.bank[meminfo.nr_banks - 1]); 293 43 high_memory = __va(end - 1) + 1; 294 44 } 295 45 ··· 302 48 void __init paging_init(struct machine_desc *mdesc) 303 49 { 304 50 early_trap_init((void *)CONFIG_VECTORS_BASE); 51 + mpu_setup(); 305 52 bootmem_init(); 306 53 } 307 54 ··· 349 94 return __arm_ioremap_pfn(pfn, offset, size, mtype); 350 95 } 351 96 352 - void __iomem *__arm_ioremap(unsigned long phys_addr, size_t size, 97 + void __iomem *__arm_ioremap(phys_addr_t phys_addr, size_t size, 353 98 unsigned int mtype) 354 99 { 355 100 return (void __iomem *)phys_addr; 356 101 } 357 102 EXPORT_SYMBOL(__arm_ioremap); 358 103 359 - void __iomem * (*arch_ioremap_caller)(unsigned long, size_t, unsigned int, void *); 104 + void __iomem * (*arch_ioremap_caller)(phys_addr_t, size_t, unsigned int, void *); 360 105 361 - void __iomem *__arm_ioremap_caller(unsigned long phys_addr, size_t size, 106 + void __iomem *__arm_ioremap_caller(phys_addr_t phys_addr, size_t size, 362 107 unsigned int mtype, void *caller) 363 108 { 364 109 return __arm_ioremap(phys_addr, size, mtype);
+5 -1
arch/arm/mm/proc-v6.S
··· 140 140 ENTRY(cpu_v6_do_suspend) 141 141 stmfd sp!, {r4 - r9, lr} 142 142 mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID 143 + #ifdef CONFIG_MMU 143 144 mrc p15, 0, r5, c3, c0, 0 @ Domain ID 144 145 mrc p15, 0, r6, c2, c0, 1 @ Translation table base 1 146 + #endif 145 147 mrc p15, 0, r7, c1, c0, 1 @ auxiliary control register 146 148 mrc p15, 0, r8, c1, c0, 2 @ co-processor access control 147 149 mrc p15, 0, r9, c1, c0, 0 @ control register ··· 160 158 mcr p15, 0, ip, c13, c0, 1 @ set reserved context ID 161 159 ldmia r0, {r4 - r9} 162 160 mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID 161 + #ifdef CONFIG_MMU 163 162 mcr p15, 0, r5, c3, c0, 0 @ Domain ID 164 163 ALT_SMP(orr r1, r1, #TTB_FLAGS_SMP) 165 164 ALT_UP(orr r1, r1, #TTB_FLAGS_UP) 166 165 mcr p15, 0, r1, c2, c0, 0 @ Translation table base 0 167 166 mcr p15, 0, r6, c2, c0, 1 @ Translation table base 1 167 + mcr p15, 0, ip, c2, c0, 2 @ TTB control register 168 + #endif 168 169 mcr p15, 0, r7, c1, c0, 1 @ auxiliary control register 169 170 mcr p15, 0, r8, c1, c0, 2 @ co-processor access control 170 - mcr p15, 0, ip, c2, c0, 2 @ TTB control register 171 171 mcr p15, 0, ip, c7, c5, 4 @ ISB 172 172 mov r0, r9 @ control register 173 173 b cpu_resume_mmu
+28 -25
arch/arm/mm/proc-v7-3level.S
··· 39 39 #define TTB_FLAGS_SMP (TTB_IRGN_WBWA|TTB_S|TTB_RGN_OC_WBWA) 40 40 #define PMD_FLAGS_SMP (PMD_SECT_WBWA|PMD_SECT_S) 41 41 42 + #ifndef __ARMEB__ 43 + # define rpgdl r0 44 + # define rpgdh r1 45 + #else 46 + # define rpgdl r1 47 + # define rpgdh r0 48 + #endif 49 + 42 50 /* 43 51 * cpu_v7_switch_mm(pgd_phys, tsk) 44 52 * ··· 55 47 */ 56 48 ENTRY(cpu_v7_switch_mm) 57 49 #ifdef CONFIG_MMU 58 - mmid r1, r1 @ get mm->context.id 59 - asid r3, r1 60 - mov r3, r3, lsl #(48 - 32) @ ASID 61 - mcrr p15, 0, r0, r3, c2 @ set TTB 0 50 + mmid r2, r2 51 + asid r2, r2 52 + orr rpgdh, rpgdh, r2, lsl #(48 - 32) @ upper 32-bits of pgd 53 + mcrr p15, 0, rpgdl, rpgdh, c2 @ set TTB 0 62 54 isb 63 55 #endif 64 56 mov pc, lr ··· 114 106 */ 115 107 .macro v7_ttb_setup, zero, ttbr0, ttbr1, tmp 116 108 ldr \tmp, =swapper_pg_dir @ swapper_pg_dir virtual address 117 - cmp \ttbr1, \tmp @ PHYS_OFFSET > PAGE_OFFSET? (branch below) 109 + mov \tmp, \tmp, lsr #ARCH_PGD_SHIFT 110 + cmp \ttbr1, \tmp @ PHYS_OFFSET > PAGE_OFFSET? 118 111 mrc p15, 0, \tmp, c2, c0, 2 @ TTB control register 119 112 orr \tmp, \tmp, #TTB_EAE 120 113 ALT_SMP(orr \tmp, \tmp, #TTB_FLAGS_SMP) ··· 123 114 ALT_SMP(orr \tmp, \tmp, #TTB_FLAGS_SMP << 16) 124 115 ALT_UP(orr \tmp, \tmp, #TTB_FLAGS_UP << 16) 125 116 /* 126 - * TTBR0/TTBR1 split (PAGE_OFFSET): 127 - * 0x40000000: T0SZ = 2, T1SZ = 0 (not used) 128 - * 0x80000000: T0SZ = 0, T1SZ = 1 129 - * 0xc0000000: T0SZ = 0, T1SZ = 2 130 - * 131 - * Only use this feature if PHYS_OFFSET <= PAGE_OFFSET, otherwise 132 - * booting secondary CPUs would end up using TTBR1 for the identity 133 - * mapping set up in TTBR0. 117 + * Only use split TTBRs if PHYS_OFFSET <= PAGE_OFFSET (cmp above), 118 + * otherwise booting secondary CPUs would end up using TTBR1 for the 119 + * identity mapping set up in TTBR0. 134 120 */ 135 - bhi 9001f @ PHYS_OFFSET > PAGE_OFFSET? 136 - orr \tmp, \tmp, #(((PAGE_OFFSET >> 30) - 1) << 16) @ TTBCR.T1SZ 137 - #if defined CONFIG_VMSPLIT_2G 138 - /* PAGE_OFFSET == 0x80000000, T1SZ == 1 */ 139 - add \ttbr1, \ttbr1, #1 << 4 @ skip two L1 entries 140 - #elif defined CONFIG_VMSPLIT_3G 141 - /* PAGE_OFFSET == 0xc0000000, T1SZ == 2 */ 142 - add \ttbr1, \ttbr1, #4096 * (1 + 3) @ only L2 used, skip pgd+3*pmd 143 - #endif 144 - /* CONFIG_VMSPLIT_1G does not need TTBR1 adjustment */ 145 - 9001: mcr p15, 0, \tmp, c2, c0, 2 @ TTB control register 146 - mcrr p15, 1, \ttbr1, \zero, c2 @ load TTBR1 121 + orrls \tmp, \tmp, #TTBR1_SIZE @ TTBCR.T1SZ 122 + mcr p15, 0, \tmp, c2, c0, 2 @ TTBCR 123 + mov \tmp, \ttbr1, lsr #(32 - ARCH_PGD_SHIFT) @ upper bits 124 + mov \ttbr1, \ttbr1, lsl #ARCH_PGD_SHIFT @ lower bits 125 + addls \ttbr1, \ttbr1, #TTBR1_OFFSET 126 + mcrr p15, 1, \ttbr1, \zero, c2 @ load TTBR1 127 + mov \tmp, \ttbr0, lsr #(32 - ARCH_PGD_SHIFT) @ upper bits 128 + mov \ttbr0, \ttbr0, lsl #ARCH_PGD_SHIFT @ lower bits 129 + mcrr p15, 0, \ttbr0, \zero, c2 @ load TTBR0 130 + mcrr p15, 1, \ttbr1, \zero, c2 @ load TTBR1 131 + mcrr p15, 0, \ttbr0, \zero, c2 @ load TTBR0 147 132 .endm 148 133 149 134 __CPUINIT
+21 -6
arch/arm/mm/proc-v7.S
··· 98 98 mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID 99 99 mrc p15, 0, r5, c13, c0, 3 @ User r/o thread ID 100 100 stmia r0!, {r4 - r5} 101 + #ifdef CONFIG_MMU 101 102 mrc p15, 0, r6, c3, c0, 0 @ Domain ID 102 103 mrc p15, 0, r7, c2, c0, 1 @ TTB 1 103 104 mrc p15, 0, r11, c2, c0, 2 @ TTB control register 105 + #endif 104 106 mrc p15, 0, r8, c1, c0, 0 @ Control register 105 107 mrc p15, 0, r9, c1, c0, 1 @ Auxiliary control register 106 108 mrc p15, 0, r10, c1, c0, 2 @ Co-processor access control ··· 112 110 113 111 ENTRY(cpu_v7_do_resume) 114 112 mov ip, #0 115 - mcr p15, 0, ip, c8, c7, 0 @ invalidate TLBs 116 113 mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache 117 114 mcr p15, 0, ip, c13, c0, 1 @ set reserved context ID 118 115 ldmia r0!, {r4 - r5} 119 116 mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID 120 117 mcr p15, 0, r5, c13, c0, 3 @ User r/o thread ID 121 118 ldmia r0, {r6 - r11} 119 + #ifdef CONFIG_MMU 120 + mcr p15, 0, ip, c8, c7, 0 @ invalidate TLBs 122 121 mcr p15, 0, r6, c3, c0, 0 @ Domain ID 123 122 #ifndef CONFIG_ARM_LPAE 124 123 ALT_SMP(orr r1, r1, #TTB_FLAGS_SMP) ··· 128 125 mcr p15, 0, r1, c2, c0, 0 @ TTB 0 129 126 mcr p15, 0, r7, c2, c0, 1 @ TTB 1 130 127 mcr p15, 0, r11, c2, c0, 2 @ TTB control register 131 - mrc p15, 0, r4, c1, c0, 1 @ Read Auxiliary control register 132 - teq r4, r9 @ Is it already set? 133 - mcrne p15, 0, r9, c1, c0, 1 @ No, so write it 134 - mcr p15, 0, r10, c1, c0, 2 @ Co-processor access control 135 128 ldr r4, =PRRR @ PRRR 136 129 ldr r5, =NMRR @ NMRR 137 130 mcr p15, 0, r4, c10, c2, 0 @ write PRRR 138 131 mcr p15, 0, r5, c10, c2, 1 @ write NMRR 132 + #endif /* CONFIG_MMU */ 133 + mrc p15, 0, r4, c1, c0, 1 @ Read Auxiliary control register 134 + teq r4, r9 @ Is it already set? 135 + mcrne p15, 0, r9, c1, c0, 1 @ No, so write it 136 + mcr p15, 0, r10, c1, c0, 2 @ Co-processor access control 139 137 isb 140 138 dsb 141 139 mov r0, r8 @ control register ··· 182 178 */ 183 179 __v7_ca5mp_setup: 184 180 __v7_ca9mp_setup: 185 - mov r10, #(1 << 0) @ TLB ops broadcasting 181 + __v7_cr7mp_setup: 182 + mov r10, #(1 << 0) @ Cache/TLB ops broadcasting 186 183 b 1f 187 184 __v7_ca7mp_setup: 188 185 __v7_ca15mp_setup: ··· 446 441 __v7_proc __v7_pj4b_setup, proc_fns = pj4b_processor_functions 447 442 .size __v7_pj4b_proc_info, . - __v7_pj4b_proc_info 448 443 #endif 444 + 445 + /* 446 + * ARM Ltd. Cortex R7 processor. 447 + */ 448 + .type __v7_cr7mp_proc_info, #object 449 + __v7_cr7mp_proc_info: 450 + .long 0x410fc170 451 + .long 0xff0ffff0 452 + __v7_proc __v7_cr7mp_setup 453 + .size __v7_cr7mp_proc_info, . - __v7_cr7mp_proc_info 449 454 450 455 /* 451 456 * ARM Ltd. Cortex A7 processor.
-2
arch/arm/plat-versatile/headsmp.S
··· 11 11 #include <linux/linkage.h> 12 12 #include <linux/init.h> 13 13 14 - __INIT 15 - 16 14 /* 17 15 * Realview/Versatile Express specific entry point for secondary CPUs. 18 16 * This provides a "holding pen" into which all secondary cores are held
-10
arch/arm64/include/asm/arch_timer.h
··· 110 110 asm volatile("msr cntkctl_el1, %0" : : "r" (cntkctl)); 111 111 } 112 112 113 - static inline u64 arch_counter_get_cntpct(void) 114 - { 115 - u64 cval; 116 - 117 - isb(); 118 - asm volatile("mrs %0, cntpct_el0" : "=r" (cval)); 119 - 120 - return cval; 121 - } 122 - 123 113 static inline u64 arch_counter_get_cntvct(void) 124 114 { 125 115 u64 cval;
+5 -18
drivers/clocksource/arm_arch_timer.c
··· 186 186 return arch_timer_rate; 187 187 } 188 188 189 - /* 190 - * Some external users of arch_timer_read_counter (e.g. sched_clock) may try to 191 - * call it before it has been initialised. Rather than incur a performance 192 - * penalty checking for initialisation, provide a default implementation that 193 - * won't lead to time appearing to jump backwards. 194 - */ 195 - static u64 arch_timer_read_zero(void) 189 + u64 arch_timer_read_counter(void) 196 190 { 197 - return 0; 191 + return arch_counter_get_cntvct(); 198 192 } 199 - 200 - u64 (*arch_timer_read_counter)(void) = arch_timer_read_zero; 201 193 202 194 static cycle_t arch_counter_read(struct clocksource *cs) 203 195 { 204 - return arch_timer_read_counter(); 196 + return arch_counter_get_cntvct(); 205 197 } 206 198 207 199 static cycle_t arch_counter_read_cc(const struct cyclecounter *cc) 208 200 { 209 - return arch_timer_read_counter(); 201 + return arch_counter_get_cntvct(); 210 202 } 211 203 212 204 static struct clocksource clocksource_counter = { ··· 279 287 cyclecounter.mult = clocksource_counter.mult; 280 288 cyclecounter.shift = clocksource_counter.shift; 281 289 timecounter_init(&timecounter, &cyclecounter, 282 - arch_counter_get_cntpct()); 290 + arch_counter_get_cntvct()); 283 291 284 292 if (arch_timer_use_virtual) { 285 293 ppi = arch_timer_ppi[VIRT_PPI]; ··· 367 375 return; 368 376 } 369 377 } 370 - 371 - if (arch_timer_use_virtual) 372 - arch_timer_read_counter = arch_counter_get_cntvct; 373 - else 374 - arch_timer_read_counter = arch_counter_get_cntpct; 375 378 376 379 arch_timer_register(); 377 380 arch_timer_arch_init();
+126 -39
drivers/mmc/host/mmci.c
··· 61 61 * @pwrreg_powerup: power up value for MMCIPOWER register 62 62 * @signal_direction: input/out direction of bus signals can be indicated 63 63 * @pwrreg_clkgate: MMCIPOWER register must be used to gate the clock 64 + * @busy_detect: true if busy detection on dat0 is supported 64 65 */ 65 66 struct variant_data { 66 67 unsigned int clkreg; ··· 75 74 u32 pwrreg_powerup; 76 75 bool signal_direction; 77 76 bool pwrreg_clkgate; 77 + bool busy_detect; 78 78 }; 79 79 80 80 static struct variant_data variant_arm = { ··· 134 132 .pwrreg_powerup = MCI_PWR_ON, 135 133 .signal_direction = true, 136 134 .pwrreg_clkgate = true, 135 + .busy_detect = true, 137 136 }; 138 137 139 138 static struct variant_data variant_ux500v2 = { ··· 149 146 .pwrreg_powerup = MCI_PWR_ON, 150 147 .signal_direction = true, 151 148 .pwrreg_clkgate = true, 149 + .busy_detect = true, 152 150 }; 151 + 152 + static int mmci_card_busy(struct mmc_host *mmc) 153 + { 154 + struct mmci_host *host = mmc_priv(mmc); 155 + unsigned long flags; 156 + int busy = 0; 157 + 158 + pm_runtime_get_sync(mmc_dev(mmc)); 159 + 160 + spin_lock_irqsave(&host->lock, flags); 161 + if (readl(host->base + MMCISTATUS) & MCI_ST_CARDBUSY) 162 + busy = 1; 163 + spin_unlock_irqrestore(&host->lock, flags); 164 + 165 + pm_runtime_mark_last_busy(mmc_dev(mmc)); 166 + pm_runtime_put_autosuspend(mmc_dev(mmc)); 167 + 168 + return busy; 169 + } 153 170 154 171 /* 155 172 * Validate mmc prerequisites ··· 214 191 /* 215 192 * This must be called with host->lock held 216 193 */ 194 + static void mmci_write_datactrlreg(struct mmci_host *host, u32 datactrl) 195 + { 196 + /* Keep ST Micro busy mode if enabled */ 197 + datactrl |= host->datactrl_reg & MCI_ST_DPSM_BUSYMODE; 198 + 199 + if (host->datactrl_reg != datactrl) { 200 + host->datactrl_reg = datactrl; 201 + writel(datactrl, host->base + MMCIDATACTRL); 202 + } 203 + } 204 + 205 + /* 206 + * This must be called with host->lock held 207 + */ 217 208 static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired) 218 209 { 219 210 struct variant_data *variant = host->variant; 220 211 u32 clk = variant->clkreg; 212 + 213 + /* Make sure cclk reflects the current calculated clock */ 214 + host->cclk = 0; 221 215 222 216 if (desired) { 223 217 if (desired >= host->mclk) { ··· 269 229 /* This hasn't proven to be worthwhile */ 270 230 /* clk |= MCI_CLK_PWRSAVE; */ 271 231 } 232 + 233 + /* Set actual clock for debug */ 234 + host->mmc->actual_clock = host->cclk; 272 235 273 236 if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_4) 274 237 clk |= MCI_4BIT_BUS; ··· 318 275 319 276 static void mmci_stop_data(struct mmci_host *host) 320 277 { 321 - writel(0, host->base + MMCIDATACTRL); 278 + mmci_write_datactrlreg(host, 0); 322 279 mmci_set_mask1(host, 0); 323 280 host->data = NULL; 324 281 } ··· 347 304 const char *rxname, *txname; 348 305 dma_cap_mask_t mask; 349 306 350 - if (!plat || !plat->dma_filter) { 351 - dev_info(mmc_dev(host->mmc), "no DMA platform data\n"); 352 - return; 353 - } 307 + host->dma_rx_channel = dma_request_slave_channel(mmc_dev(host->mmc), "rx"); 308 + host->dma_tx_channel = dma_request_slave_channel(mmc_dev(host->mmc), "tx"); 354 309 355 310 /* initialize pre request cookie */ 356 311 host->next_data.cookie = 1; ··· 357 316 dma_cap_zero(mask); 358 317 dma_cap_set(DMA_SLAVE, mask); 359 318 319 + if (plat && plat->dma_filter) { 320 + if (!host->dma_rx_channel && plat->dma_rx_param) { 321 + host->dma_rx_channel = dma_request_channel(mask, 322 + plat->dma_filter, 323 + plat->dma_rx_param); 324 + /* E.g if no DMA hardware is present */ 325 + if (!host->dma_rx_channel) 326 + dev_err(mmc_dev(host->mmc), "no RX DMA channel\n"); 327 + } 328 + 329 + if (!host->dma_tx_channel && plat->dma_tx_param) { 330 + host->dma_tx_channel = dma_request_channel(mask, 331 + plat->dma_filter, 332 + plat->dma_tx_param); 333 + if (!host->dma_tx_channel) 334 + dev_warn(mmc_dev(host->mmc), "no TX DMA channel\n"); 335 + } 336 + } 337 + 360 338 /* 361 339 * If only an RX channel is specified, the driver will 362 340 * attempt to use it bidirectionally, however if it is 363 341 * is specified but cannot be located, DMA will be disabled. 364 342 */ 365 - if (plat->dma_rx_param) { 366 - host->dma_rx_channel = dma_request_channel(mask, 367 - plat->dma_filter, 368 - plat->dma_rx_param); 369 - /* E.g if no DMA hardware is present */ 370 - if (!host->dma_rx_channel) 371 - dev_err(mmc_dev(host->mmc), "no RX DMA channel\n"); 372 - } 373 - 374 - if (plat->dma_tx_param) { 375 - host->dma_tx_channel = dma_request_channel(mask, 376 - plat->dma_filter, 377 - plat->dma_tx_param); 378 - if (!host->dma_tx_channel) 379 - dev_warn(mmc_dev(host->mmc), "no TX DMA channel\n"); 380 - } else { 343 + if (host->dma_rx_channel && !host->dma_tx_channel) 381 344 host->dma_tx_channel = host->dma_rx_channel; 382 - } 383 345 384 346 if (host->dma_rx_channel) 385 347 rxname = dma_chan_name(host->dma_rx_channel); ··· 596 552 datactrl |= MCI_DPSM_DMAENABLE; 597 553 598 554 /* Trigger the DMA transfer */ 599 - writel(datactrl, host->base + MMCIDATACTRL); 555 + mmci_write_datactrlreg(host, datactrl); 600 556 601 557 /* 602 558 * Let the MMCI say when the data is ended and it's time ··· 794 750 irqmask = MCI_TXFIFOHALFEMPTYMASK; 795 751 } 796 752 797 - writel(datactrl, base + MMCIDATACTRL); 753 + mmci_write_datactrlreg(host, datactrl); 798 754 writel(readl(base + MMCIMASK0) & ~MCI_DATAENDMASK, base + MMCIMASK0); 799 755 mmci_set_mask1(host, irqmask); 800 756 } ··· 886 842 /* The error clause is handled above, success! */ 887 843 data->bytes_xfered = data->blksz * data->blocks; 888 844 889 - if (!data->stop) { 845 + if (!data->stop || host->mrq->sbc) { 890 846 mmci_request_end(host, data->mrq); 891 847 } else { 892 848 mmci_start_command(host, data->stop, 0); ··· 899 855 unsigned int status) 900 856 { 901 857 void __iomem *base = host->base; 858 + bool sbc = (cmd == host->mrq->sbc); 902 859 903 860 host->cmd = NULL; 904 861 ··· 914 869 cmd->resp[3] = readl(base + MMCIRESPONSE3); 915 870 } 916 871 917 - if (!cmd->data || cmd->error) { 872 + if ((!sbc && !cmd->data) || cmd->error) { 918 873 if (host->data) { 919 874 /* Terminate the DMA transfer */ 920 875 if (dma_inprogress(host)) { ··· 923 878 } 924 879 mmci_stop_data(host); 925 880 } 926 - mmci_request_end(host, cmd->mrq); 881 + mmci_request_end(host, host->mrq); 882 + } else if (sbc) { 883 + mmci_start_command(host, host->mrq->cmd, 0); 927 884 } else if (!(cmd->data->flags & MMC_DATA_READ)) { 928 885 mmci_start_data(host, cmd->data); 929 886 } ··· 1166 1119 if (mrq->data && mrq->data->flags & MMC_DATA_READ) 1167 1120 mmci_start_data(host, mrq->data); 1168 1121 1169 - mmci_start_command(host, mrq->cmd, 0); 1122 + if (mrq->sbc) 1123 + mmci_start_command(host, mrq->sbc, 0); 1124 + else 1125 + mmci_start_command(host, mrq->cmd, 0); 1170 1126 1171 1127 spin_unlock_irqrestore(&host->lock, flags); 1172 1128 } ··· 1193 1143 if (!IS_ERR(mmc->supply.vmmc)) 1194 1144 mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0); 1195 1145 1196 - if (!IS_ERR(mmc->supply.vqmmc) && 1197 - regulator_is_enabled(mmc->supply.vqmmc)) 1146 + if (!IS_ERR(mmc->supply.vqmmc) && host->vqmmc_enabled) { 1198 1147 regulator_disable(mmc->supply.vqmmc); 1148 + host->vqmmc_enabled = false; 1149 + } 1199 1150 1200 1151 break; 1201 1152 case MMC_POWER_UP: ··· 1212 1161 1213 1162 break; 1214 1163 case MMC_POWER_ON: 1215 - if (!IS_ERR(mmc->supply.vqmmc) && 1216 - !regulator_is_enabled(mmc->supply.vqmmc)) { 1164 + if (!IS_ERR(mmc->supply.vqmmc) && !host->vqmmc_enabled) { 1217 1165 ret = regulator_enable(mmc->supply.vqmmc); 1218 1166 if (ret < 0) 1219 1167 dev_err(mmc_dev(mmc), 1220 1168 "failed to enable vqmmc regulator\n"); 1169 + else 1170 + host->vqmmc_enabled = true; 1221 1171 } 1222 1172 1223 1173 pwr |= MCI_PWR_ON; ··· 1303 1251 return status; 1304 1252 } 1305 1253 1254 + static int mmci_sig_volt_switch(struct mmc_host *mmc, struct mmc_ios *ios) 1255 + { 1256 + int ret = 0; 1257 + 1258 + if (!IS_ERR(mmc->supply.vqmmc)) { 1259 + 1260 + pm_runtime_get_sync(mmc_dev(mmc)); 1261 + 1262 + switch (ios->signal_voltage) { 1263 + case MMC_SIGNAL_VOLTAGE_330: 1264 + ret = regulator_set_voltage(mmc->supply.vqmmc, 1265 + 2700000, 3600000); 1266 + break; 1267 + case MMC_SIGNAL_VOLTAGE_180: 1268 + ret = regulator_set_voltage(mmc->supply.vqmmc, 1269 + 1700000, 1950000); 1270 + break; 1271 + case MMC_SIGNAL_VOLTAGE_120: 1272 + ret = regulator_set_voltage(mmc->supply.vqmmc, 1273 + 1100000, 1300000); 1274 + break; 1275 + } 1276 + 1277 + if (ret) 1278 + dev_warn(mmc_dev(mmc), "Voltage switch failed\n"); 1279 + 1280 + pm_runtime_mark_last_busy(mmc_dev(mmc)); 1281 + pm_runtime_put_autosuspend(mmc_dev(mmc)); 1282 + } 1283 + 1284 + return ret; 1285 + } 1286 + 1306 1287 static irqreturn_t mmci_cd_irq(int irq, void *dev_id) 1307 1288 { 1308 1289 struct mmci_host *host = dev_id; ··· 1345 1260 return IRQ_HANDLED; 1346 1261 } 1347 1262 1348 - static const struct mmc_host_ops mmci_ops = { 1263 + static struct mmc_host_ops mmci_ops = { 1349 1264 .request = mmci_request, 1350 1265 .pre_req = mmci_pre_request, 1351 1266 .post_req = mmci_post_request, 1352 1267 .set_ios = mmci_set_ios, 1353 1268 .get_ro = mmci_get_ro, 1354 1269 .get_cd = mmci_get_cd, 1270 + .start_signal_voltage_switch = mmci_sig_volt_switch, 1355 1271 }; 1356 1272 1357 1273 #ifdef CONFIG_OF ··· 1448 1362 dev_dbg(mmc_dev(mmc), "designer ID = 0x%02x\n", host->hw_designer); 1449 1363 dev_dbg(mmc_dev(mmc), "revision = 0x%01x\n", host->hw_revision); 1450 1364 1451 - host->clk = clk_get(&dev->dev, NULL); 1365 + host->clk = devm_clk_get(&dev->dev, NULL); 1452 1366 if (IS_ERR(host->clk)) { 1453 1367 ret = PTR_ERR(host->clk); 1454 - host->clk = NULL; 1455 1368 goto host_free; 1456 1369 } 1457 1370 1458 1371 ret = clk_prepare_enable(host->clk); 1459 1372 if (ret) 1460 - goto clk_free; 1373 + goto host_free; 1461 1374 1462 1375 host->plat = plat; 1463 1376 host->variant = variant; ··· 1479 1394 if (!host->base) { 1480 1395 ret = -ENOMEM; 1481 1396 goto clk_disable; 1397 + } 1398 + 1399 + if (variant->busy_detect) { 1400 + mmci_ops.card_busy = mmci_card_busy; 1401 + mmci_write_datactrlreg(host, MCI_ST_DPSM_BUSYMODE); 1482 1402 } 1483 1403 1484 1404 mmc->ops = &mmci_ops; ··· 1666 1576 iounmap(host->base); 1667 1577 clk_disable: 1668 1578 clk_disable_unprepare(host->clk); 1669 - clk_free: 1670 - clk_put(host->clk); 1671 1579 host_free: 1672 1580 mmc_free_host(mmc); 1673 1581 rel_regions: ··· 1711 1623 1712 1624 iounmap(host->base); 1713 1625 clk_disable_unprepare(host->clk); 1714 - clk_put(host->clk); 1715 1626 1716 1627 mmc_free_host(mmc); 1717 1628
+4
drivers/mmc/host/mmci.h
··· 94 94 /* Extended status bits for the ST Micro variants */ 95 95 #define MCI_ST_SDIOIT (1 << 22) 96 96 #define MCI_ST_CEATAEND (1 << 23) 97 + #define MCI_ST_CARDBUSY (1 << 24) 97 98 98 99 #define MMCICLEAR 0x038 99 100 #define MCI_CMDCRCFAILCLR (1 << 0) ··· 111 110 /* Extended status bits for the ST Micro variants */ 112 111 #define MCI_ST_SDIOITC (1 << 22) 113 112 #define MCI_ST_CEATAENDC (1 << 23) 113 + #define MCI_ST_BUSYENDC (1 << 24) 114 114 115 115 #define MMCIMASK0 0x03c 116 116 #define MCI_CMDCRCFAILMASK (1 << 0) ··· 185 183 unsigned int cclk; 186 184 u32 pwr_reg; 187 185 u32 clk_reg; 186 + u32 datactrl_reg; 187 + bool vqmmc_enabled; 188 188 struct mmci_platform_data *plat; 189 189 struct variant_data *variant; 190 190
+1 -1
include/clocksource/arm_arch_timer.h
··· 32 32 #ifdef CONFIG_ARM_ARCH_TIMER 33 33 34 34 extern u32 arch_timer_get_rate(void); 35 - extern u64 (*arch_timer_read_counter)(void); 35 + extern u64 arch_timer_read_counter(void); 36 36 extern struct timecounter *arch_timer_get_timecounter(void); 37 37 38 38 #else