aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/prom_init.c
diff options
context:
space:
mode:
authorLaurent Dufour <ldufour@linux.vnet.ibm.com>2013-09-17 05:52:48 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2013-10-11 01:53:16 -0400
commitdbd0c5d5296f291a5c3affee4fbdde254632ffca (patch)
tree9b622a06c6dcd9150b24b27435ce5fe000b71749 /arch/powerpc/kernel/prom_init.c
parente48673360b8b113ca83dc3a45e02ad37fdf9f2d0 (diff)
powerpc: prom_init exception when updating core value
Since the CPU is generating an exception when accessing unaligned word, and as this exception is not yet handled when running prom_init, data should be copied from the architecture vector byte per byte. Signed-off-by: Laurent Dufour <ldufour@linux.vnet.ibm.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/kernel/prom_init.c')
-rw-r--r--arch/powerpc/kernel/prom_init.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index 5fe2842e8bab..cb64a6e1dc51 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -858,7 +858,8 @@ static void __init prom_send_capabilities(void)
858{ 858{
859 ihandle root; 859 ihandle root;
860 prom_arg_t ret; 860 prom_arg_t ret;
861 __be32 *cores; 861 u32 cores;
862 unsigned char *ptcores;
862 863
863 root = call_prom("open", 1, 1, ADDR("/")); 864 root = call_prom("open", 1, 1, ADDR("/"));
864 if (root != 0) { 865 if (root != 0) {
@@ -868,15 +869,30 @@ static void __init prom_send_capabilities(void)
868 * (we assume this is the same for all cores) and use it to 869 * (we assume this is the same for all cores) and use it to
869 * divide NR_CPUS. 870 * divide NR_CPUS.
870 */ 871 */
871 cores = (__be32 *)&ibm_architecture_vec[IBM_ARCH_VEC_NRCORES_OFFSET]; 872
872 if (be32_to_cpup(cores) != NR_CPUS) { 873 /* The core value may start at an odd address. If such a word
874 * access is made at a cache line boundary, this leads to an
875 * exception which may not be handled at this time.
876 * Forcing a per byte access to avoid exception.
877 */
878 ptcores = &ibm_architecture_vec[IBM_ARCH_VEC_NRCORES_OFFSET];
879 cores = 0;
880 cores |= ptcores[0] << 24;
881 cores |= ptcores[1] << 16;
882 cores |= ptcores[2] << 8;
883 cores |= ptcores[3];
884 if (cores != NR_CPUS) {
873 prom_printf("WARNING ! " 885 prom_printf("WARNING ! "
874 "ibm_architecture_vec structure inconsistent: %lu!\n", 886 "ibm_architecture_vec structure inconsistent: %lu!\n",
875 be32_to_cpup(cores)); 887 cores);
876 } else { 888 } else {
877 *cores = cpu_to_be32(DIV_ROUND_UP(NR_CPUS, prom_count_smt_threads())); 889 cores = DIV_ROUND_UP(NR_CPUS, prom_count_smt_threads());
878 prom_printf("Max number of cores passed to firmware: %lu (NR_CPUS = %lu)\n", 890 prom_printf("Max number of cores passed to firmware: %lu (NR_CPUS = %lu)\n",
879 be32_to_cpup(cores), NR_CPUS); 891 cores, NR_CPUS);
892 ptcores[0] = (cores >> 24) & 0xff;
893 ptcores[1] = (cores >> 16) & 0xff;
894 ptcores[2] = (cores >> 8) & 0xff;
895 ptcores[3] = cores & 0xff;
880 } 896 }
881 897
882 /* try calling the ibm,client-architecture-support method */ 898 /* try calling the ibm,client-architecture-support method */