Updated: October 26, 2022

Information about each CPU in the system

The cpuinfo area contains information about each CPU in the system, such as the CPU type, speed, capabilities, performance, and cache sizes.

The number of cpuinfo_entry instances is equal to the value in the num_cpu member of the syspage_entry structure.

Each cpuinfo_entry structure is automatically filled in by the startup library function init_cpuinfo(). The members include:

A number that represents the type of CPU. The meaning of this number depends on the CPU architecture. For example, for the x86 processor family, this number is the processor chip number (e.g., 586).
The MHz rating of the processor.
The CPU capabilities; see flags below.
A number identifying each core; used for SMP.
Not used.
An index into the strings member in the system page structure. The character string at the specified index contains an ASCII, NULL-terminated machine name.
An index into the cacheattr array, which is described below. This index points to the first definition in a list for the instruction cache.
An index into the cacheattr array, which is described below. This index points to the first definition in a list for the data cache.


The flags member contains a bitmapped indication of the CPU's capabilities. The prefix for a flag name (i.e., macro constant) indicates the CPU family it applies to (e.g., ARM_ indicates that this constant is for use on the ARM family of processors). If there is no prefix, the constant is generic; it is relevant to any CPU supported by QNX Neutrino RTOS.

Generic flags are defined in <sys/syspage.h>, while architecture-specific flags are defined in <arch/syspage.h>. You'll need the values to interpret the output of the pidin syspage command.

The bits include the following:
This bit: Means that the CPU has or supports:
CPU_FLAG_FPU A Floating Point Unit (FPU)
CPU_FLAG_MMU A Memory Management Unit (MMU), and the MMU is enabled (i.e., the CPU is currently in virtual addressing mode)
ARM_CPU_FLAG_CC_INCR_BIT_32 A 32-bit clock cycle counter (CLOCKCYCLES_INCR_BIT is 32)
ARM_CPU_FLAG_IDIV H/W division: the UDIV and SDIV instructions are supported
ARM_CPU_FLAG_LPAE Large Physical Address Extension support is enabled
ARM_CPU_FLAG_NEON NEON technology, a 128-bit SIMD architecture extension to the ARM Cortex-A series processor
ARM_CPU_FLAG_SMP Multiple processors
ARM_CPU_FLAG_V7 ARMv7 architecture
ARM_CPU_FLAG_V7_MP ARMv7 multiprocessor extensions
ARM_CPU_FLAG_VFP_D32 VFP has 32 double registers
ARM_CPU_FLAG_WMMX2 An iWMMX2 coprocessor
AARCH64_CPU_ACTLR Auxiliary Control Register
AARCH64_CPU_FLAG_CC_INCR_32 A 32-bit clock cycle counter (CLOCKCYCLES_INCR_BIT is 32)
AARCH64_CPU_FLAG_KRYO_TLB The system needs to use the workaround for the Qualcomm Technologies Falkor/Kryo erratum 1003 or the Qualcomm Falkor errata 1009 for Kryo. If your target needs to use this workaround, you must manually set this flag using the -F option for startup-*.
AARCH64_CPU_FLAG_LSE The system supports the Large System Extension; see LL/SC vs LSE atomic operations,” below
AARCH64_CPU_FLAG_SMP Multiple processors
AARCH64_CPU_FLAG_SIMD NEON technology, a 128-bit SIMD architecture extension to the ARM Cortex-A series processor
AARCH64_CPU_FLAG_VHE ARM v8.1 and more recent. Support virtualization host extensions (VHE).
AARCH64_CPU_PAUTH CPU supports Pointer Authentication (ARM v8.3 and more recent). This flag is set using the -U option for startup-*. When -U is specified, the kernel checks each CPU to determine if it supports Pointer Authentication and then sets AARCH64_CPU_PAUTH for CPUs that support it.
AARCH64_CPU_SSBS If this flag is set for CPU 0, the kernel checks each CPU to determine whether it supports FEAT_SSBS (Speculative Store Bypass Safe (SSBS)).

To determine whether a CPU supports SSBS, the kernel queries the CPU's ID_AA64PFR1_EL1 feature register (not its cpuinfo entry). If the CPU supports SSBS, its PSTATE.SSBS bit is set.

A CPU's PSTATE.SSBS bit is not cleared if AARCH64_CPU_SSBS is not set for cpuinfo for CPU 0.


Advanced Vector Extensions


BSWAP instruction


CMOVxx instructions


CPUID instruction


FXSAVE/FXRSTOR instructions


Invariant (constant) Time Stamp Counter


INVLPG instruction


MMX instructions


MTRR (Memory Type Range Register) registers


No-eXecute PTE bit


Extended addressing


Page Attribute Tables


Process-Context Identifiers


TLB global mappings


Needs TLB flush when splitting a large page


Page size extensions


RDTSC instruction


SYSENTER and SYSEXIT instructions


SIMD instructions


Streaming SIMD Extensions 2


XSAVE and XRSTOR instructions


WP bit in the CR0 register

LL/SC vs LSE atomic operations

The ARMv8-A architecture (see https://developer.arm.com/documentation/ddi0487/latest/) provides two groups of opcodes for atomic operations:

On the 64-bit ARM variant of procnto, if all CPUs support LSE atomics, the set of QNX-specific atomic functions default to using LSE, otherwise we revert to LLSC. The following QNX Neutrino functions are affected:

Note that pthread_spin_lock() and pthread_spin_trylock() use these atomic functions; pthread_barrier_wait() and pthread_mutex_destroy() also use them, but to a lesser extent.

If all the CPUs in your system support ARMv8.1-A LSE atomics, you can profile these functions using both LLSC and LSE to determine which version gives better performance. On systems that default to LSE, you can revert to using LLSC by clearing the AARCH64_CPU_FLAG_LSE flag in the system page by either temporarily modifying the startup, or if the startup supports the -F option, clearing the CPU flag by passing -F~0x8000 to startup.

Note that the set of C11-specific atomic functions (such as atomic_fetch_add() in stdatomic.h) use LSE instructions only if you specify -march==armv8-a+lse or -march=armv8.N (where N is 1 or higher) on the compiler command line. The default is to build for the lowest common denominator ARMv8 instruction set, which doesn't include the LSE instructions.