diff options
Diffstat (limited to 'src/arch/arm64')
-rw-r--r-- | src/arch/arm64/cpu_ramstage.c | 2 | ||||
-rw-r--r-- | src/arch/arm64/include/arch/mpidr.h | 64 | ||||
-rw-r--r-- | src/arch/arm64/include/armv8/arch/cpu.h | 3 |
3 files changed, 69 insertions, 0 deletions
diff --git a/src/arch/arm64/cpu_ramstage.c b/src/arch/arm64/cpu_ramstage.c index 0f26206683..f28667861b 100644 --- a/src/arch/arm64/cpu_ramstage.c +++ b/src/arch/arm64/cpu_ramstage.c @@ -105,6 +105,8 @@ static void init_this_cpu(void *arg) cpu_set_device_operations(dev); + printk(BIOS_DEBUG, "CPU%x: MPIDR: %llx\n", ci->id, ci->mpidr); + el3_init(); /* Initialize the GIC. */ diff --git a/src/arch/arm64/include/arch/mpidr.h b/src/arch/arm64/include/arch/mpidr.h new file mode 100644 index 0000000000..0735a6a1b0 --- /dev/null +++ b/src/arch/arm64/include/arch/mpidr.h @@ -0,0 +1,64 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2014 Google Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA + */ + +#ifndef __ARCH_MPIDR_H__ +#define __ARCH_MPIDR_H__ + +#include <stdint.h> +#include <arch/lib_helpers.h> + +enum { + MPIDR_RES1_SHIFT = 31, + MPIDR_U_SHIFT = 30, + MPIDR_MT_SHIFT = 24, + + MPIDR_AFFINITY_0_SHIFT = 0, + MPIDR_AFFINITY_1_SHIFT = 8, + MPIDR_AFFINITY_2_SHIFT = 16, + MPIDR_AFFINITY_3_SHIFT = 32, + MPIDR_AFFINITY_MASK = 0xff, +}; + +static inline uint64_t mpidr_mask(uint8_t aff3, uint8_t aff2, + uint8_t aff1, uint8_t aff0) +{ + uint64_t mpidr = 0; + + mpidr |= (uint64_t)aff3 << MPIDR_AFFINITY_3_SHIFT; + mpidr |= (uint64_t)aff2 << MPIDR_AFFINITY_2_SHIFT; + mpidr |= (uint64_t)aff1 << MPIDR_AFFINITY_1_SHIFT; + mpidr |= (uint64_t)aff0 << MPIDR_AFFINITY_0_SHIFT; + + return mpidr; +} + +static inline uint64_t read_mpidr(void) +{ + return raw_read_mpidr_el1(); +} + +static inline uint64_t read_affinity_mpidr(void) +{ + uint64_t affinity_mask; + affinity_mask = mpidr_mask(MPIDR_AFFINITY_MASK, MPIDR_AFFINITY_MASK, + MPIDR_AFFINITY_MASK, MPIDR_AFFINITY_MASK); + return read_mpidr() & affinity_mask; +} + +#endif /* __ARCH_MPIDR_H__ */ diff --git a/src/arch/arm64/include/armv8/arch/cpu.h b/src/arch/arm64/include/armv8/arch/cpu.h index fc31903f52..d4ff907495 100644 --- a/src/arch/arm64/include/armv8/arch/cpu.h +++ b/src/arch/arm64/include/armv8/arch/cpu.h @@ -24,6 +24,7 @@ #if !defined(__PRE_RAM__) #include <arch/barrier.h> +#include <arch/mpidr.h> #include <device/device.h> enum { @@ -62,6 +63,7 @@ struct cpu_info { unsigned int online; /* Current assumption is that id matches smp_processor_id(). */ unsigned int id; + uint64_t mpidr; }; /* Obtain cpu_info for current executing CPU. */ @@ -93,6 +95,7 @@ static inline int cpu_online(struct cpu_info *ci) static inline void cpu_mark_online(struct cpu_info *ci) { + ci->mpidr = read_affinity_mpidr(); store_release(&ci->online, 1); } |