1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
//! Identity of the core executing this code.
//!
//! Separate from `multicore`, which is about *starting* cores 1-3 and is
//! compiled only behind that feature, because asking which core is
//! running is useful without it: [`crate::generic_timer`] indexes a
//! per-core register with it on a single-core build, and an application
//! that has brought up secondary cores needs it in code shared by all of
//! them -- an interrupt handler, or a panic handler naming the core it
//! died on. Neither should have to enable a feature about spawning to ask.
/// The calling core's id (0-3), from `MPIDR`'s Aff0 field.
///
/// A `usize` rather than a `u8` because every use is an index or an offset
/// multiplier: the ARM-local peripherals give each core its own copy of
/// several registers, addressed as `base + stride * core_id()`.
///
/// The value is fixed for the lifetime of the code reading it — a core
/// cannot migrate — but that is only true of the *core*, not of a task or
/// future, which an executor may well poll somewhere else. Code that wants
/// to pin work to a core has to keep it out of anything relocatable, not
/// merely read this once.
/// Always 0: the BCM2835's ARM1176JZF-S is a uniprocessor part, so there
/// is one core and this is its id.
///
/// A constant rather than a register read, and not only because the
/// answer is knowable. `MPIDR` is an ARMv7 register; whether an ARMv6
/// core provides anything at `c0, c0, 5` is implementation-defined, and
/// reading a CP15 register a core does not implement is UNPREDICTABLE —
/// on this one, plausibly an undefined-instruction trap in code whose
/// whole job is to answer a question with one possible answer.
/// See the AArch32 sibling above.
/// The `MIDR` Main ID register: which core this code is running on,
/// straight from the core itself.
///
/// The interesting field is the part number, bits\[15:4\]: `0xb76` is the
/// ARM1176JZF-S (BCM2835 — Pi 1, Pi Zero), `0xc07` the Cortex-A7
/// (BCM2836 — Pi 2), `0xc08` the Cortex-A53 (BCM2837 — Pi 3) and `0xd08`
/// the Cortex-A72 (BCM2711 — Pi 4). Bits\[31:24\] are the implementer
/// (`0x41`, ARM), and the rest are the variant and revision of that
/// particular part.
///
/// Worth printing as the first line out of a new board's console: it
/// says both that the console works and that the chip underneath is the
/// one the binary was built for, which are the two things in doubt at
/// that point.
///
/// `MIDR` is 32 bits on both execution states; the AArch64 register
/// `MIDR_EL1` is 64 bits wide with the top half reserved zero, and this
/// returns the meaningful low half.
/// See the AArch32 sibling above.