4 uint64_t get_tpidr(void) {
6 __asm__
volatile("mrs %0, tpidr_el0" : "=r"(tpidr
));
10 uint64_t get_tpidr2(void) {
12 // S3_3_C13_C0_5 means tpidr2, and will work with older tools.
13 __asm__
volatile("mrs %0, S3_3_C13_C0_5" : "=r"(tpidr2
));
17 void set_tpidr(uint64_t value
) {
18 __asm__
volatile("msr tpidr_el0, %0" ::"r"(value
));
21 void set_tpidr2(uint64_t value
) {
22 __asm__
volatile("msr S3_3_C13_C0_5, %0" ::"r"(value
));
25 bool use_tpidr2
= false;
26 const uint64_t tpidr_pattern
= 0x1122334455667788;
27 const uint64_t tpidr2_pattern
= 0x8877665544332211;
30 set_tpidr(~tpidr_pattern
);
32 set_tpidr2(~tpidr2_pattern
);
35 int main(int argc
, char *argv
[]) {
36 use_tpidr2
= argc
> 1;
38 uint64_t original_tpidr
= get_tpidr();
39 // Accessing this on a core without it produces SIGILL. Only do this if
41 uint64_t original_tpidr2
= 0;
43 original_tpidr2
= get_tpidr2();
45 set_tpidr(tpidr_pattern
);
48 set_tpidr2(tpidr2_pattern
);
50 // Set break point at this line.
51 // lldb will now set its own pattern(s) for us to find.
53 uint64_t new_tpidr
= get_tpidr();
54 volatile bool tpidr_was_set
= new_tpidr
== 0x1111222233334444;
56 uint64_t new_tpidr2
= 0;
57 volatile bool tpidr2_was_set
= false;
59 new_tpidr2
= get_tpidr2();
60 tpidr2_was_set
= new_tpidr2
== 0x4444333322221111;
63 set_tpidr(original_tpidr
);
65 set_tpidr2(original_tpidr2
);
67 return 0; // Set break point 2 at this line.