Has anyone found a way to get cpu_number() on aarch64 ?

Since it is Private exported, can't use it directly.

Replies

uint32_t
getcpuid(void)
{
#if defined(__aarch64__)
    uint64_t mpidr_el1;
    asm volatile("mrs %0, mpidr_el1" : "=r" (mpidr_el1));
    return (uint8_t)(mpidr_el1 & 0xff);
#else
    return ((uint32_t)cpu_number());
#endif
}

Is a start, on my 8core M2, it returns values 0x00 to 0x03 from Aff0 bits. Generally the 4 fast cores.

If you idle for a bit, you can probably look at the Aff1 (cluster) values, returning values like 0x0102 - which probably means the slower cores.

But for the sake of reducing contention by spreading out locks over cores, this is a good start.

To be complete, this is what we went with:

#if defined(__aarch64__)
    uint64_t mpidr_el1;

    asm volatile("mrs %0, mpidr_el1" : "=r" (mpidr_el1));
    /*                                                                          
     * To save us looking up number of eCores and pCores, we                    
     * just wrap eCores backwards from max_ncpu.                                
     * 0: [P0 P1 P2 ... Px Ex .. E2 E1 E0] : max_ncpu                           
     *                                                                          
     * XNU: Aff2: "1" - PCORE, "0" - ECORE                                      
     */
#define PCORE_BIT (1ULL << 16)
    if (mpidr_el1 & PCORE_BIT)
        return ((uint32_t)mpidr_el1 & 0xff);
    else
        return ((max_ncpus -1) - (uint32_t)(mpidr_el1 & 0xff));

#else
    return ((uint32_t)cpu_number());
#endif
}