1. 29 6月, 2013 3 次提交
  2. 24 6月, 2013 12 次提交
  3. 20 6月, 2013 2 次提交
    • L
      ARM: kernel: implement stack pointer save array through MPIDR hashing · 7604537b
      Lorenzo Pieralisi 提交于
      Current implementation of cpu_{suspend}/cpu_{resume} relies on the MPIDR
      to index the array of pointers where the context is saved and restored.
      The current approach works as long as the MPIDR can be considered a
      linear index, so that the pointers array can simply be dereferenced by
      using the MPIDR[7:0] value.
      On ARM multi-cluster systems, where the MPIDR may not be a linear index,
      to properly dereference the stack pointer array, a mapping function should
      be applied to it so that it can be used for arrays look-ups.
      
      This patch adds code in the cpu_{suspend}/cpu_{resume} implementation
      that relies on shifting and ORing hashing method to map a MPIDR value to a
      set of buckets precomputed at boot to have a collision free mapping from
      MPIDR to context pointers.
      
      The hashing algorithm must be simple, fast, and implementable with few
      instructions since in the cpu_resume path the mapping is carried out with
      the MMU off and the I-cache off, hence code and data are fetched from DRAM
      with no-caching available. Simplicity is counterbalanced with a little
      increase of memory (allocated dynamically) for stack pointers buckets, that
      should be anyway fairly limited on most systems.
      
      Memory for context pointers is allocated in a early_initcall with
      size precomputed and stashed previously in kernel data structures.
      Memory for context pointers is allocated through kmalloc; this
      guarantees contiguous physical addresses for the allocated memory which
      is fundamental to the correct functioning of the resume mechanism that
      relies on the context pointer array to be a chunk of contiguous physical
      memory. Virtual to physical address conversion for the context pointer
      array base is carried out at boot to avoid fiddling with virt_to_phys
      conversions in the cpu_resume path which is quite fragile and should be
      optimized to execute as few instructions as possible.
      Virtual and physical context pointer base array addresses are stashed in a
      struct that is accessible from assembly using values generated through the
      asm-offsets.c mechanism.
      
      Cc: Will Deacon <will.deacon@arm.com>
      Cc: Catalin Marinas <catalin.marinas@arm.com>
      Cc: Russell King <linux@arm.linux.org.uk>
      Cc: Colin Cross <ccross@android.com>
      Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
      Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
      Cc: Amit Kucheria <amit.kucheria@linaro.org>
      Signed-off-by: NLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
      Reviewed-by: NDave Martin <Dave.Martin@arm.com>
      Reviewed-by: NNicolas Pitre <nico@linaro.org>
      Tested-by: NShawn Guo <shawn.guo@linaro.org>
      Tested-by: NKevin Hilman <khilman@linaro.org>
      Tested-by: NStephen Warren <swarren@wwwdotorg.org>
      7604537b
    • L
      ARM: kernel: build MPIDR hash function data structure · 8cf72172
      Lorenzo Pieralisi 提交于
      On ARM SMP systems, cores are identified by their MPIDR register.
      The MPIDR guidelines in the ARM ARM do not provide strict enforcement of
      MPIDR layout, only recommendations that, if followed, split the MPIDR
      on ARM 32 bit platforms in three affinity levels. In multi-cluster
      systems like big.LITTLE, if the affinity guidelines are followed, the
      MPIDR can not be considered an index anymore. This means that the
      association between logical CPU in the kernel and the HW CPU identifier
      becomes somewhat more complicated requiring methods like hashing to
      associate a given MPIDR to a CPU logical index, in order for the look-up
      to be carried out in an efficient and scalable way.
      
      This patch provides a function in the kernel that starting from the
      cpu_logical_map, implement collision-free hashing of MPIDR values by checking
      all significative bits of MPIDR affinity level bitfields. The hashing
      can then be carried out through bits shifting and ORing; the resulting
      hash algorithm is a collision-free though not minimal hash that can be
      executed with few assembly instructions. The mpidr is filtered through a
      mpidr mask that is built by checking all bits that toggle in the set of
      MPIDRs corresponding to possible CPUs. Bits that do not toggle do not carry
      information so they do not contribute to the resulting hash.
      
      Pseudo code:
      
      /* check all bits that toggle, so they are required */
      for (i = 1, mpidr_mask = 0; i < num_possible_cpus(); i++)
      	mpidr_mask |= (cpu_logical_map(i) ^ cpu_logical_map(0));
      
      /*
       * Build shifts to be applied to aff0, aff1, aff2 values to hash the mpidr
       * fls() returns the last bit set in a word, 0 if none
       * ffs() returns the first bit set in a word, 0 if none
       */
      fs0 = mpidr_mask[7:0] ? ffs(mpidr_mask[7:0]) - 1 : 0;
      fs1 = mpidr_mask[15:8] ? ffs(mpidr_mask[15:8]) - 1 : 0;
      fs2 = mpidr_mask[23:16] ? ffs(mpidr_mask[23:16]) - 1 : 0;
      ls0 = fls(mpidr_mask[7:0]);
      ls1 = fls(mpidr_mask[15:8]);
      ls2 = fls(mpidr_mask[23:16]);
      bits0 = ls0 - fs0;
      bits1 = ls1 - fs1;
      bits2 = ls2 - fs2;
      aff0_shift = fs0;
      aff1_shift = 8 + fs1 - bits0;
      aff2_shift = 16 + fs2 - (bits0 + bits1);
      u32 hash(u32 mpidr) {
      	u32 l0, l1, l2;
      	u32 mpidr_masked = mpidr & mpidr_mask;
      	l0 = mpidr_masked & 0xff;
      	l1 = mpidr_masked & 0xff00;
      	l2 = mpidr_masked & 0xff0000;
      	return (l0 >> aff0_shift | l1 >> aff1_shift | l2 >> aff2_shift);
      }
      
      The hashing algorithm relies on the inherent properties set in the ARM ARM
      recommendations for the MPIDR. Exotic configurations, where for instance the
      MPIDR values at a given affinity level have large holes, can end up requiring
      big hash tables since the compression of values that can be achieved through
      shifting is somewhat crippled when holes are present. Kernel warns if
      the number of buckets of the resulting hash table exceeds the number of
      possible CPUs by a factor of 4, which is a symptom of a very sparse HW
      MPIDR configuration.
      
      The hash algorithm is quite simple and can easily be implemented in assembly
      code, to be used in code paths where the kernel virtual address space is
      not set-up (ie cpu_resume) and instruction and data fetches are strongly
      ordered so code must be compact and must carry out few data accesses.
      
      Cc: Will Deacon <will.deacon@arm.com>
      Cc: Catalin Marinas <catalin.marinas@arm.com>
      Cc: Russell King <linux@arm.linux.org.uk>
      Cc: Colin Cross <ccross@android.com>
      Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
      Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
      Cc: Amit Kucheria <amit.kucheria@linaro.org>
      Signed-off-by: NLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
      Reviewed-by: NDave Martin <Dave.Martin@arm.com>
      Reviewed-by: NNicolas Pitre <nico@linaro.org>
      Tested-by: NShawn Guo <shawn.guo@linaro.org>
      Tested-by: NKevin Hilman <khilman@linaro.org>
      Tested-by: NStephen Warren <swarren@wwwdotorg.org>
      8cf72172
  4. 18 6月, 2013 2 次提交
  5. 17 6月, 2013 13 次提交
  6. 11 6月, 2013 2 次提交
    • T
      ARM: SAMSUNG: pm: Adjust for pinctrl- and DT-enabled platforms · cd3fc1b9
      Tomasz Figa 提交于
      This patch makes legacy code on suspend/resume path being executed
      conditionally, on non-DT platforms only, to fix suspend/resume of
      DT-enabled systems, for which the code is inappropriate.
      Signed-off-by: NTomasz Figa <t.figa@samsung.com>
      Signed-off-by: NKyungmin Park <kyungmin.park@samsung.com>
      [olof: add #include <linux/of.h>]
      Signed-off-by: NOlof Johansson <olof@lixom.net>
      cd3fc1b9
    • H
      ARM: prima2: fix incorrect panic usage · 7e5955db
      Haojian Zhuang 提交于
      In prima2, some functions of checking DT is registered in initcall
      level. If it doesn't match the compatible name of sirf, kernel
      will panic. It blocks the usage of multiplatform on other verndor.
      
      The error message is in below.
      
      Knic - not syncing: unable to find compatible pwrc node in dtb
      CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.10.0-rc3-00006-gd7f26ea-dirty #86
      [<c0013adc>] (unwind_backtrace+0x0/0xf8) from [<c0011430>] (show_stack+0x10/0x1)
      [<c0011430>] (show_stack+0x10/0x14) from [<c026f724>] (panic+0x90/0x1e8)
      [<c026f724>] (panic+0x90/0x1e8) from [<c03267fc>] (sirfsoc_of_pwrc_init+0x24/0x)
      [<c03267fc>] (sirfsoc_of_pwrc_init+0x24/0x58) from [<c0320864>] (do_one_initcal)
      [<c0320864>] (do_one_initcall+0x90/0x150) from [<c0320a20>] (kernel_init_freeab)
      [<c0320a20>] (kernel_init_freeable+0xfc/0x1c4) from [<c026b9e8>] (kernel_init+0)
      [<c026b9e8>] (kernel_init+0x8/0xe4) from [<c000e158>] (ret_from_fork+0x14/0x3c)
      Signen-off-by: NHaojian Zhuang <haojian.zhuang@linaro.org>
      Signed-off-by: NOlof Johansson <olof@lixom.net>
      7e5955db
  7. 08 6月, 2013 6 次提交
    • D
      ARM: exynos: add debug_ll_io_init() call in exynos_init_io() · 9c1fcdcc
      Doug Anderson 提交于
      If the early MMU mapping of the UART happens to get booted out of the
      TLB between the start of paging_init() and when we finally re-add the
      UART at the very end of s3c_init_cpu(), we'll get a hang at bootup if
      we've got early_printk enabled.  Avoid this hang by calling
      debug_ll_io_init() early.
      
      Without this patch, you can reliably reproduce a hang when early
      printk is enabled by adding flush_tlb_all() at the start of
      exynos_init_io().  After this patch the hang goes away.
      Signed-off-by: NDoug Anderson <dianders@chromium.org>
      Acked-by: NKukjin Kim <kgene.kim@samsung.com>
      Signed-off-by: NOlof Johansson <olof@lixom.net>
      9c1fcdcc
    • T
      ARM: EXYNOS: uncompress - print debug messages if DEBUG_LL is defined · 437d8ac5
      Tushar Behera 提交于
      Printing low-level debug messages make an assumption that the specified
      UART port has been preconfigured by the bootloader. Incorrectly
      specified UART port results in system getting stalled while printing the
      message "Uncompressing Linux... done, booting the kernel"
      This UART port number is specified through S3C_LOWLEVEL_UART_PORT. Since
      the UART port might different for different board, it is not possible to
      specify it correctly for every board that use a common defconfig file.
      
      Calling this print subroutine only when DEBUG_LL fixes the problem. By
      disabling DEBUG_LL in default config file, we would be able to boot
      multiple boards with different default UART ports.
      
      With this current approach, we miss the print "Uncompressing Linux...
      done, booting the kernel." when DEBUG_LL is not defined.
      Signed-off-by: NTushar Behera <tushar.behera@linaro.org>
      Signed-off-by: NOlof Johansson <olof@lixom.net>
      437d8ac5
    • J
      ARM: mpu: add MPU initialisation for secondary cores · eb08375e
      Jonathan Austin 提交于
      The MPU initialisation on the primary core is performed in two stages, one
      minimal stage to ensure the CPU can boot and a second one after
      sanity_check_meminfo. As the memory configuration is known by the time we
      boot secondary cores only a single step is necessary, provided the values
      for DRSR are passed to secondaries.
      
      This patch implements this arrangement. The configuration generated for the
      MPU regions is made available to the secondary core, which can then use the
      asm MPU intialisation code to program a complete region configuration.
      
      This is necessary for SMP configurations without an MMU, as the MPU
      initialisation is the only way to ensure that memory is specified as
      'shared'.
      Signed-off-by: NJonathan Austin <jonathan.austin@arm.com>
      Reviewed-by: NWill Deacon <will.deacon@arm.com>
      CC: Nicolas Pitre <nico@linaro.org>
      eb08375e
    • J
      ARM: mpu: Complete initialisation of the MPU after reaching the C-world · 9a271567
      Jonathan Austin 提交于
      Much like with the MMU, MPU initialisation is performed in two stages; the
      first in the pre-C world and the 'real' initialisation during arch setup.
      
      This patch wires in previously added MPU initialisation functions so that
      the whole of memory is mapped with the appropriate region properties for
      'normal' RAM (the appropriate properties depend on whether the system is
      SMP).
      
      Stub initialisation functions are added for the case that there MPU support
      is not configured in to the kernel.
      Signed-off-by: NJonathan Austin <jonathan.austin@arm.com>
      Reviewed-by: NWill Deacon <will.deacon@arm.com>
      CC: Hyok S. Choi <hyok.choi@samsung.com>
      9a271567
    • J
      ARM: mpu: add MPU probe and initialisation functions in C · 5ad7dcbe
      Jonathan Austin 提交于
      This patch adds new functions for probing and initialising the ARMv7
      PMSA-compliant MPU.
      
      These use the pre-defined and reserved MPU_PROBE_REGION for establishing
      properties of the MPU, which is necessary because certain probe operations
      require modifying region properties and reading back the results.
      
      This patch also introduces a minimal sanity_check_meminfo_mpu function, that
      ensures that the memory set-up passed to the kernel can be used in conjunction
      with the MPU. The base address of a region must be aligned to the region size,
      otherwise behavior is unpredictable and region sizes can only be specified as a
      power-of-two. To simplify the satisfaction of these requirements this
      implementation currently enforces that all memory is contiguous from
      PHYS_OFFSET, merging banks that are contiguous but passed in separately.
      
      The functions are added in this patch but wired in to the boot process later
      in the series.
      Signed-off-by: NJonathan Austin <jonathan.austin@arm.com>
      Reviewed-by: NWill Deacon <will.deacon@arm.com>
      CC: Hyok S. Choi <hyok.choi@samsung.com>
      5ad7dcbe
    • J
      ARM: mpu: add early bring-up code for the ARMv7 PMSA-compliant MPU · 67c9845b
      Jonathan Austin 提交于
      This patch adds initial support for using the MPU, which is necessary for
      SMP operation on PMSAv7 processors because it is the only way to ensure
      memory is shared. This is an initial patch and full SMP support is added
      later in this series.
      
      The setup of the MPU is performed in a way analagous to that for the MMU:
      Very early initialisation before the C environment is brought up, followed
      by a sanity check and more complete initialisation in C.
      
      This patch provides the simplest possible memory region configuration:
      MPU_PROBE_REGION: Reserved for probing MPU details, not enabled
      MPU_BG_REGION: A 'background' region that specifies all memory strongly ordered
      MPU_RAM_REGION: A single shared, cacheable, normal region for the valid RAM.
      
      In this early initialisation code we simply map the whole of the address
      space with the BG_REGION and (at least) the kernel with the RAM_REGION. The
      MPU has region alignment constraints that require us to round past the end
      of the kernel.
      
      As region 2 has a higher priority than region 1, it overrides the strongly-
      ordered behaviour for RAM only.
      
      Subsequent patches will add more complete initialisation from the C-world
      and support for bringing up secondary CPUs.
      Signed-off-by: NJonathan Austin <jonathan.austin@arm.com>
      Reviewed-by: NWill Deacon <will.deacon@arm.com>
      CC: Hyok S. Choi <hyok.choi@samsung.com>
      67c9845b