1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17#include <stdlib.h>
18#include <stdio.h>
19#include <stdint.h>
20
21#define ARM_COMMPAGE (0xffff0f00u)
22#define ARM_KUSER_VERSION (*(int32_t *)(ARM_COMMPAGE + 0xfc))
23typedef void * (get_tls_fn)(void);
24#define ARM_KUSER_GET_TLS (*(get_tls_fn *)(ARM_COMMPAGE + 0xe0))
25typedef int (cmpxchg_fn)(int oldval, int newval, volatile int *ptr);
26#define ARM_KUSER_CMPXCHG (*(cmpxchg_fn *)(ARM_COMMPAGE + 0xc0))
27typedef void (dmb_fn)(void);
28#define ARM_KUSER_DMB (*(dmb_fn *)(ARM_COMMPAGE + 0xa0))
29typedef int (cmpxchg64_fn)(const int64_t *oldval,
30 const int64_t *newval,
31 volatile int64_t *ptr);
32#define ARM_KUSER_CMPXCHG64 (*(cmpxchg64_fn *)(ARM_COMMPAGE + 0x60))
33
34#define fail_unless(x) \
35 do { \
36 if (!(x)) { \
37 fprintf(stderr, "FAILED at %s:%d\n", __FILE__, __LINE__); \
38 exit(EXIT_FAILURE); \
39 } \
40 } while (0)
41
42
43int main(int argc, char *argv[argc])
44{
45 void *kuser_tls;
46 int val = 1;
47 const int64_t oldval = 1, newval = 2;
48 int64_t val64 = 1;
49
50 fail_unless(ARM_KUSER_VERSION == 0x5);
51 kuser_tls = ARM_KUSER_GET_TLS();
52 printf("TLS = %p\n", kuser_tls);
53 fail_unless(kuser_tls != 0);
54 fail_unless(ARM_KUSER_CMPXCHG(1, 2, &val) == 0);
55 printf("val = %d\n", val);
56
57 ARM_KUSER_DMB();
58 fail_unless(ARM_KUSER_CMPXCHG64(&oldval, &newval, &val64) == 0);
59 printf("val64 = %lld\n", val64);
60 return 0;
61}
62