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>
This commit is contained in:
Laurent Dufour 2013-09-17 11:52:48 +02:00 committed by Benjamin Herrenschmidt
parent e48673360b
commit dbd0c5d529
1 changed files with 22 additions and 6 deletions

View File

@ -858,7 +858,8 @@ static void __init prom_send_capabilities(void)
{ {
ihandle root; ihandle root;
prom_arg_t ret; prom_arg_t ret;
__be32 *cores; u32 cores;
unsigned char *ptcores;
root = call_prom("open", 1, 1, ADDR("/")); root = call_prom("open", 1, 1, ADDR("/"));
if (root != 0) { if (root != 0) {
@ -868,15 +869,30 @@ static void __init prom_send_capabilities(void)
* (we assume this is the same for all cores) and use it to * (we assume this is the same for all cores) and use it to
* divide NR_CPUS. * divide NR_CPUS.
*/ */
cores = (__be32 *)&ibm_architecture_vec[IBM_ARCH_VEC_NRCORES_OFFSET];
if (be32_to_cpup(cores) != NR_CPUS) { /* The core value may start at an odd address. If such a word
* access is made at a cache line boundary, this leads to an
* exception which may not be handled at this time.
* Forcing a per byte access to avoid exception.
*/
ptcores = &ibm_architecture_vec[IBM_ARCH_VEC_NRCORES_OFFSET];
cores = 0;
cores |= ptcores[0] << 24;
cores |= ptcores[1] << 16;
cores |= ptcores[2] << 8;
cores |= ptcores[3];
if (cores != NR_CPUS) {
prom_printf("WARNING ! " prom_printf("WARNING ! "
"ibm_architecture_vec structure inconsistent: %lu!\n", "ibm_architecture_vec structure inconsistent: %lu!\n",
be32_to_cpup(cores)); cores);
} else { } else {
*cores = cpu_to_be32(DIV_ROUND_UP(NR_CPUS, prom_count_smt_threads())); cores = DIV_ROUND_UP(NR_CPUS, prom_count_smt_threads());
prom_printf("Max number of cores passed to firmware: %lu (NR_CPUS = %lu)\n", prom_printf("Max number of cores passed to firmware: %lu (NR_CPUS = %lu)\n",
be32_to_cpup(cores), NR_CPUS); cores, NR_CPUS);
ptcores[0] = (cores >> 24) & 0xff;
ptcores[1] = (cores >> 16) & 0xff;
ptcores[2] = (cores >> 8) & 0xff;
ptcores[3] = cores & 0xff;
} }
/* try calling the ibm,client-architecture-support method */ /* try calling the ibm,client-architecture-support method */