summaryrefslogtreecommitdiffstats
path: root/arch/arm/cpu/mmu.c
Commit message (Collapse)AuthorAgeFilesLines
* arm/cpu: Replace license and copyright boilerplate by SPDX identfiersUwe Kleine-König2020-07-141-13/+2
| | | | | | | | | | | | | This adapts all files that were identifed by licensecheck (https://salsa.debian.org/build-common-team/licensecheck.git) as licensed under the GPL. While touching these files also do some minor comment reformatting to get some uniform layout. Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* treewide: remove references to CREDITSUwe Kleine-König2020-04-271-3/+0
| | | | | | | | The CREDITS file was removed from barebox in 2015 by commit 6570288f2d97 ("Remove the CREDITS file"). Remove references to it from several files. Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* device: Introduce dma_offsetSascha Hauer2019-12-201-0/+4
| | | | | | | | | | For devices that do not have a 1:1 mapping between DMA and CPU we need a dma_offset. This adds dma_offset to struct device_d and starts honoring it in ARM dma_(un)map_single(). Also we add some comments to functions that would normally need a device argument to make the DMA <-> CPU translations device specific. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: mmu: use client domain permissions to support ARMv7 eXecute NeverAhmad Fatoum2019-10-141-1/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | The ARM Architecture Reference Manual notes[1]: > When using the Short-descriptor translation table format, the XN > attribute is not checked for domains marked as Manager. > Therefore, the system must not include read-sensitive memory in > domains marked as Manager, because the XN bit does not prevent > speculative fetches from a Manager domain. To avoid speculative access to read-sensitive memory-mapped peripherals on ARMv7, let's use client domain permissions for all memory, so the XN bit (and also R/W bits) can function. This aligns us with what Linux is doing on ARMv7. This fixes cache corruption instances that had been observed on the i.MX6UL(L) when the instruction prefetcher speculates into memory following the end of a 512M SDRAM[2]. While this is not necessary to avoid speculative accesses on < ARMv7, we could probably have everything there in client domain as well, but due to lack of test coverage, we'll restrict the change to ARMv7. [1]: B3.7.2 - Execute-never restrictions on instruction fetching [2]: "Cache Corruption on MX6UL(L)": https://community.nxp.com/thread/511925 Fixes: 0198567c4 ("ARM: mmu: mark uncached regions as eXecute never on v7") Signed-off-by: Ahmad Fatoum <ahmad@a3f.at> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: mmu: set R/W bits in ARMv7 translation tableAhmad Fatoum2019-10-141-5/+6
| | | | | | | | | | | | | With barebox using the manager permissions for domain 0 that's used for all page table entries and directories, we never had the need so far to explicitly set R/W bits. We did so anyway for sections in the early MMU code, but later on in the normal MMU setup, we didn't do so consistently. In preparation for switching to DOMAIN_CLIENT for ARMv7, configure R/W everywhere in normal MMU code as well. Signed-off-by: Ahmad Fatoum <ahmad@a3f.at> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: mmu: remove no longer accurate commentAhmad Fatoum2019-10-141-5/+0
| | | | | | | | | | | This comment refers to the state of things prior to e3e54c644 ("ARM: mmu: Implement on-demand PTE allocation"). Since then, we no longer generate 2nd level page tables directly below. Remove it to avoid confusion. Cc: Lucas Stach <l.stach@pengutronix.de> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: mmu: mark uncached regions as eXecute never on v7Ahmad Fatoum2019-04-291-5/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | The ARM Cortex-A Series Programmer's Guide notes[1]: > When set, the Execute Never (XN) bit in the translation table entry > prevents speculative instruction fetches taking place from desired > memory locations and will cause a prefetch abort to occur if execution > from the memory location is attempted. > > Typically device memory regions are marked as execute never to prevent > accidental execution from such locations, and to prevent undesirable > side-effects which might be caused by speculative instruction fetches. Heed the advice and mark uncached memory with the XN bit, when the CPU is >=v7. It's possible that there are SoCs that have a section shared between device memory and the on-chip RAM hosting the PBL. In such a section, every page except for the OCRAM's should be mapped XN, but as we know of no SoC with such an OCRAM layout, we ignore this possibility for now and let mmu_early_enable map sections only. [1]: 9.6.3 "Execute Never", Version 4.0 Suggested-by: Lucas Stach <l.stach@pengutronix.de> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: mmu: remove doubly defined macroAhmad Fatoum2019-04-291-1/+0
| | | | | | | | PMD_SECT_DEF_CACHED is defined along with PMD_SECT_DEF_UNCACHED in mmu.h, which is included two lines prior. Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: mmu: Make sure DMA coherent memory is zeroed outAndrey Smirnov2019-01-211-1/+1
| | | | | | | | | | | In order to avoid passing random/junky values to DMA/HW as well as to allow simplifying memory initialization in individual drivers, change dma_alloc_coherent() to guarantee that memory it returns is properly zeroed out. Reviewed-by: Sam Ravnborg <sam@ravnborg.org> Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: mmu: Share code for arm_mmu_not_initialized_error()Andrey Smirnov2019-01-211-11/+0
| | | | | | Reviewed-by: Sam Ravnborg <sam@ravnborg.org> Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: mmu: Share sanity checking code in mmu_init()Andrey Smirnov2019-01-211-14/+2
| | | | | | | | | Share sanity checking code in mmu_init() as well as code to detect if MMU is on or not on both ARM and ARM64. Reviewed-by: Sam Ravnborg <sam@ravnborg.org> Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: mmu: Share code for dma_sync_single_for_cpu()Andrey Smirnov2019-01-211-7/+0
| | | | | | | | | Both ARM and ARM64 have identical code for dma_sync_single_for_cpu(). Move it to mmu-common.c so it can be shared. Reviewed-by: Sam Ravnborg <sam@ravnborg.org> Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: mmu: Share code for dma_alloc_coherent()Andrey Smirnov2019-01-211-22/+1
| | | | | | | | | | Both ARM and ARM64 implement almost identical algorithms in dma_alloc_coherent(). Move the code to mmu-common.c, so it can be shared. Reviewed-by: Sam Ravnborg <sam@ravnborg.org> Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: mmu: Share code for dma_free_coherent()Andrey Smirnov2019-01-211-8/+0
| | | | | | | | | | Now that AArch64 version is calling arch_remap_range() it is identical to ARM version in mmu.c. Move the definition to mmu-common.c to avoid duplication. Reviewed-by: Sam Ravnborg <sam@ravnborg.org> Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: mmu: Share code for dma_(un)map_single()Andrey Smirnov2019-01-211-16/+0
| | | | | | | | | | Both ARM and ARM64 define DMA mapping/unmapping functions that are exactly the same. Introduce mmu-common.c and move the code there so it can be shared. Reviewed-by: Sam Ravnborg <sam@ravnborg.org> Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: mmu: Simplify the use of dma_inv_range()Andrey Smirnov2019-01-211-3/+6
| | | | | | | | | | | Simplify the use of dma_inv_range() by changing its signature to accept pointer to start of the data and data size. This change allows us to avoid a whole bunch of repetitive arithmetic currently done by all of the callers. Reviewed-by: Sam Ravnborg <sam@ravnborg.org> Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: mmu: Drop custom virt_to_phys/phys_to_virtAndrey Smirnov2019-01-211-10/+0
| | | | | | | | | | Neither ARM nor ARM64 define any address mapping functions that differ from default provided for no-MMU configuration. Drop all the extra code and just rely on functions provided in asm/io.h Reviewed-by: Sam Ravnborg <sam@ravnborg.org> Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: mmu: include dma.hSascha Hauer2018-10-191-0/+1
| | | | | | | dma.h provides the prototypes for the different dma_alloc_* functions, so we should include it to make sure the prototypes are consistent. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: mmu: rename dma_allocSascha Hauer2018-10-181-3/+3
| | | | | | | a function named dma_alloc is already declared in include/dma.h, so when we want to include that file we must rename the function. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: MMU: fix wrong dma_flush_range in arm_create_pte()Sascha Hauer2018-08-151-1/+1
| | | | | | | | | | | Since 7ba0f2d299 arm_create_pte() flushes the page table entries itself and it's no longer done in arch_remap_range(). Unfortunately it does not flush the modified 1st level page table entry, but instead the base of the page table. Fix it up. Fixes: 7ba0f2d299 ARM: mmu: fix cache flushing when replacing a section with a PTE Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: mmu: fix cache flushing when replacing a section with a PTELucas Stach2018-07-271-45/+32
| | | | | | | | | | | | | | When replacing a section with a PTE, we must make sure that the newly initialized PTE entries are flushed from the cache before changing the entry in the TTB. Otherwise a L1 TLB miss causes the hardware pagetable walker to walk into a PTE with undefined content, causing exactly that behaviour. Move all the necessary cache flushing to arm_create_pte(), to avoid any caller getting this wrong in the future. Fixes: e3e54c644180 (ARM: mmu: Implement on-demand PTE allocation) Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
* ARM: MMU: fix arch_remap_range() across section boundariesSascha Hauer2018-07-121-1/+1
| | | | | | | | | | | Fixes: e3e54c6441 ARM: mmu: Implement on-demand PTE allocation PGD_FLAGS_WC_V7 lacks the PMD_TYPE_SECT and PMD_SECT_BUFFERABLE flags. Without them a dma_alloc_writecombine() creates an invalid section when it crosses a section boundary. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> Reviewed-by: Lucas Stach <l.stach@pengutronix.de>
* ARM: mmu: psci: Make use of get_ttbr()Andrey Smirnov2018-06-181-3/+1
| | | | | | | | Introduce a simple inline function to get TTBR and use it in mmu.c and sm.c Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: mmu: only create flat mapping when early MMU hasn't done it alreadySascha Hauer2018-05-281-6/+6
| | | | Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: mmu: Introduce ARM_TTB_SIZEAndrey Smirnov2018-05-221-1/+1
| | | | | | | | | | | | | | | | | | Commit 1c33aacf8a247ab45814b43ac0ca903677afffae ("ARM: use memalign to allocate page table"), reasonalby changed TTB allocation size from SZ_32K to SZ_16K (TTB's real size), but it also changed alignment from SZ_16K to SZ_64K for unclear reasons. Reading various TTBR related ARM documentation it seems that worst case alignment for it is 16KiB (bits [0, 13 - N] must be zero) which also matches early TTB allocation code. Since both early and regular MMU code has to share this paramter, introduce ARM_TTB_SIZE and use it in both cases for both size and alignment. Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: mmu: Implement on-demand PTE allocationAndrey Smirnov2018-05-221-99/+110
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Allocating PTEs for every 4K page corresponding to SDRAM upfront costs us quite a bit of memory: 1KB per 1MB or RAM. This is far from being a deal-breaker for majority of use-cases, but for builds where amount of free memory is in hundres of KBs* it becomes a real hurdle for being able to use MMU (which also means no L1 cache). Given how we really only need PTEs for a very few regions of memory dedicated from DMA buffers (Ethernet, USB, etc), changing MMU code to do on-demand section splitting can allow us to save significant amount of memory without any functionality loss. Below is a very trivial comparison of memory usages on start before and after this patch is applied. Before: barebox@ZII VF610 Development Board, Rev B:/ meminfo used: 1271584 free: 265553032 After: barebox@ZII VF610 Development Board, Rev B:/ meminfo used: 795276 free: 266024448 Tested on: - VF610 Tower Board, - VF610 ZII Development Board (Rev. C) - i.MX51 Babbage Board - i.MX7 SabreSD Board - i.MX6 ZII RDU2 Board - AT91SAM9X5-EK Board * One example of such use-case is memory testing while running purely out of SRAM Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: mmu: Simplify the use of dma_flush_range()Andrey Smirnov2018-05-221-8/+8
| | | | | | | | | | | Simplify the use of dma_flush_range() by changing its signature to accept pointer to start of the data and data size. This change allows us to avoid a whole bunch of repetitive arithmetic currently done by all of the callers. Reviewed-by: Lucas Stach <l.stach@pengutronix.de> Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: mmu: Use dma_inv_range() in dma_sync_single_for_cpu()Andrey Smirnov2018-05-221-5/+2
| | | | | | | | | The code in the if () statement is identical to already existing dma_inv_rand(). Use it instead. Reviewed-by: Lucas Stach <l.stach@pengutronix.de> Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: mmu: Use find_pte() to find PTE in create_vector_table()Andrey Smirnov2018-05-221-5/+4
| | | | | | | | | There's already a function that implement necessary arithemtic to find offset within page table for a given address, so make use of it instead of re-implementing it again. Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: mmu: Make sure that address is 1M aligned in arm_create_pte()Andrey Smirnov2018-05-221-2/+3
| | | | | | | | | | | | | | If address passed arm_create_pte() is not 1M (PGDIR_SIZE) aligned, page table that is created will end up having unexpected mapping offset, breaking "1:1 mapping" assumption and leading to bugs that are not immediately obvious in their nature. To prevent this and because all of the callers already do said alignement in-place, move the alignment code to be a part of arm_create_pte(). Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: mmu: Pass PTE flags a parameter to arm_create_pte()Andrey Smirnov2018-05-181-4/+5
| | | | | | | | | | In order to make it possible to use this functions in contexts where creating a new PTE of uncached pages in not appropriate, pass PTE flags a parameter to arm_create_pte() and fix all of the current users as necessary. Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: mmu: Share code between dma_alloc_*() functionsAndrey Smirnov2018-05-181-14/+8
| | | | | | | | | | Code of dma_alloc_coherent() and dma_alloc_writecombine() is almost identical with exception of the flags passed to undelying call to __remap_range(). Move commong code into a shared subroutine and convert both functions to use it. Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: mmu: Use xmemalign in mmu_init()Andrey Smirnov2018-05-181-1/+1
| | | | | | | | We don't handle OOM case in that code, so using xmemalign seems like a better option. Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: mmu: Use xmemalign in arm_create_pte()Andrey Smirnov2018-05-181-2/+2
| | | | | | | | We don't handle the OOM case in that code, so using xmemalign seems like a better option. Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: mmu: Use PAGE_SIZE instead of magic right shift by 12Andrey Smirnov2018-05-181-1/+1
| | | | | Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: mmu: Define and use PTRS_PER_PTEAndrey Smirnov2018-05-181-3/+5
| | | | | Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: mmu: Use PAGE_SIZE when specifying size of one pageAndrey Smirnov2018-05-181-2/+2
| | | | | Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: mmu: Replace various SZ_1M with PGDIR_SIZEAndrey Smirnov2018-05-181-4/+4
| | | | | Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: mmu: Trivial simplification in arm_mmu_remap_sdram()Andrey Smirnov2018-05-181-1/+1
| | | | | Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: mmu: Replace hardcoded shifts with pgd_index() from LinuxAndrey Smirnov2018-05-181-6/+6
| | | | | Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: mmu: Drop needless shifting in map_io_sections()Andrey Smirnov2018-05-181-3/+2
| | | | | | | | | Instead of shifting phys right by 20 and then again left by the same amount, just convert the code to expect it to be in unit of bytes all the time. Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: mmu: Share code for initial flat mapping creationAndrey Smirnov2018-05-181-5/+1
| | | | | | | | Code creating inital 4GiB flat mapping is identical between mmu.c and mmu-early.c, so move it to mmu.h and share. Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: mmu: Specify size in bytes in create_sections()Andrey Smirnov2018-05-181-2/+2
| | | | | | | | | | | | | | | | | | | Seeing create_sections(ttb, 0, PAGE_SIZE, ...); as the code the creates initial flat 4 GiB mapping is a bit less intuitive then create_sections(ttb, 0, SZ_4G - 1, ...); so, for the sake of clarification, convert create_sections() to accept address of the last byte in the region instead of size in MiB. Note the alternative of converting size to units of bytes was not chosen to avoid converting 3-rd function argument into a 64-bit number. Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: mmu: Share code for create_sections()Andrey Smirnov2018-05-181-19/+8
| | | | | | | | | | Regular MMU code never creates anything but 1:1 mapping, and barring that plus the call to __mmu_cache_flush(), early MMU code version of the function is pretty much identical. To avoid code duplication, move it to mmu.h and convert both regular and early MMU code to use it. Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: mmu: Introduce set_domain()Andrey Smirnov2018-05-181-5/+1
| | | | | | | | Port set_domain() form Linux kernel and share it between regular and early MMU code to avoid duplication. Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: mmu: Introduce set_ttbr()Andrey Smirnov2018-05-181-2/+1
| | | | | Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: mmu: Make use of IS_ALIGNED in arm_mmu_remap_sdram()Andrey Smirnov2018-05-181-1/+1
| | | | | Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: mmu: Remove unused ARM_VECTORS_SIZEAndrey Smirnov2018-05-181-6/+0
| | | | | Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* ARM: implement dma mapping functionsSascha Hauer2018-03-291-0/+16
| | | | | | | Implement basic dma mapping functions. For now just assume every address is valid for dma mapping. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
* dma: Use dma_addr_t as type for DMA addressesSascha Hauer2018-03-291-2/+2
| | | | | | | DMA addresses are not necessarily the same as unsigned long. Fix the type for the dma_sync_single_* operations. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>