mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 05:37:54 +00:00
base-hw: Implement CPU core identification for Cortex-A55.
According to ARM Cortex-A55 Core Technical Reference Manual r1p0 the lowest 8 bits (Aff0) of MPIDR register represent thread IDs within a multi-threaded core. The actual core identification bits are in Aff1. This layout can be identified by checking the MT bit of MPIDR register. Basically, if MT=1 core id is in Aff1, if MT=0 core id is in Aff0. Without this change Genode will identify all CPU cores on A55 as primary (0) core. Its worth to mention that Cortex-A55 by itself is not a multi-threaded CPU. Aff0 values are always expected to be 0 for pure A55 cores. A55 cores can however be paired with cores that are multi-threaded. To support such big.LITTLE CPUs in Genode we'd probably need to add a different mechanism for mapping MPIDR values to logical, contignous core IDs which Genode expects. Ref: https://developer.arm.com/documentation/100442/0100/register-descriptions/aarch64-system-registers/mpidr-el1--multiprocessor-affinity-register--el1?lang=en
This commit is contained in:
parent
c265218ba8
commit
bade0a85e7
@ -138,11 +138,8 @@ static inline void prepare_hypervisor(Cpu::Ttbr::access_t const ttbr,
|
||||
|
||||
unsigned Bootstrap::Platform::enable_mmu()
|
||||
{
|
||||
static volatile bool primary_cpu = true;
|
||||
bool primary = primary_cpu;
|
||||
if (primary) primary_cpu = false;
|
||||
|
||||
unsigned cpu_id = (Cpu::Mpidr::read() & 0xff);
|
||||
unsigned const cpu_id { Cpu::current_core_id() };
|
||||
bool const primary { cpu_id == 0 };
|
||||
|
||||
Cpu::Ttbr::access_t ttbr =
|
||||
Cpu::Ttbr::Baddr::masked((Genode::addr_t)core_pd->table_base);
|
||||
|
@ -16,6 +16,10 @@
|
||||
*/
|
||||
.macro _cpu_number
|
||||
mrs x0, mpidr_el1
|
||||
and x8, x0, #(1<<24) /* MT bit */
|
||||
cbz x8, 1f
|
||||
lsr x0, x0, #8
|
||||
1:
|
||||
and x0, x0, #0b11111111
|
||||
.endm
|
||||
|
||||
|
@ -106,7 +106,7 @@ struct Genode::Cpu : Hw::Arm_64_cpu
|
||||
/**
|
||||
* Return kernel name of the executing CPU
|
||||
*/
|
||||
static unsigned executing_id() { return Cpu::Mpidr::read() & 0xff; }
|
||||
static unsigned executing_id() { return Cpu::current_core_id(); }
|
||||
|
||||
static size_t cache_line_size();
|
||||
static void clear_memory_region(addr_t const addr,
|
||||
|
@ -141,7 +141,12 @@ struct Hw::Arm_64_cpu
|
||||
SYSTEM_REGISTER(64, Mair_el1, mair_el1);
|
||||
SYSTEM_REGISTER(64, Mair_el2, mair_el2);
|
||||
|
||||
SYSTEM_REGISTER(64, Mpidr, mpidr_el1);
|
||||
SYSTEM_REGISTER(64, Mpidr, mpidr_el1,
|
||||
struct Aff0 : Bitfield<0, 8> {};
|
||||
struct Aff1 : Bitfield<8, 8> {};
|
||||
struct Aff2 : Bitfield<16, 8> {};
|
||||
struct MT : Bitfield<24, 1> {};
|
||||
);
|
||||
|
||||
SYSTEM_REGISTER(32, Pmcr_el0, pmcr_el0);
|
||||
SYSTEM_REGISTER(32, Pmcntenset_el0, pmcntenset_el0);
|
||||
@ -256,6 +261,14 @@ struct Hw::Arm_64_cpu
|
||||
using Cntpct = Cntpct_el0;
|
||||
using Cntp_tval = Cntp_tval_el0;
|
||||
|
||||
static inline unsigned current_core_id()
|
||||
{
|
||||
Mpidr::access_t mpidr = Mpidr::read();
|
||||
if (Mpidr::MT::get(mpidr))
|
||||
return (unsigned)Mpidr::Aff1::get(mpidr);
|
||||
return (unsigned)Mpidr::Aff0::get(mpidr);
|
||||
}
|
||||
|
||||
static inline void wait_for_xchg(volatile int * addr,
|
||||
int new_value,
|
||||
int expected_value)
|
||||
|
Loading…
Reference in New Issue
Block a user