source: mainline/uspace/lib/c/arch/arm32/src/atomic.c@ f114d40

ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since f114d40 was eb630cf, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 3 years ago

Fix handling of ABS32 relocation on arm32

A bad symbol reference in entryjmp.S was creating
an ABS32 relocation causing issues for dynamic
linker, leading to the ABS32 relocation being
generally ignored. However, that was not the
correct solution, as doing so breaks stacktrace
code (which emits global function pointers in
static data, creating ABS32 relocs).

The symbol reference in entryjmp.S was fixed by
converting the function to inline assembly, let
GCC deal with variable addresses.

  • Property mode set to 100644
File size: 5.0 KB
Line 
1/*
2 * Copyright (c) 2007 Michal Kebrt
3 * Copyright (c) 2018 CZ.NIC, z.s.p.o.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/*
31 * Older ARMs don't have atomic instructions, so we need to define a bunch
32 * of symbols for GCC to use.
33 */
34
35#include <stdbool.h>
36#include "ras_page.h"
37
38volatile unsigned *ras_page;
39
40bool __atomic_compare_exchange_4(volatile unsigned *mem, unsigned *expected, unsigned desired, bool weak, int success, int failure)
41{
42 (void) success;
43 (void) failure;
44 (void) weak;
45
46 unsigned ov = *expected;
47 unsigned ret;
48
49 /*
50 * The following instructions between labels 1 and 2 constitute a
51 * Restartable Atomic Sequence. Should the sequence be non-atomic,
52 * the kernel will restart it.
53 */
54 asm volatile (
55 "1:\n"
56 " adr %[ret], 1b\n"
57 " str %[ret], %[rp0]\n"
58 " adr %[ret], 2f\n"
59 " str %[ret], %[rp1]\n"
60
61 " ldr %[ret], %[addr]\n"
62 " cmp %[ret], %[ov]\n"
63 " streq %[nv], %[addr]\n"
64 "2:\n"
65 : [ret] "=&r" (ret),
66 [rp0] "=m" (ras_page[0]),
67 [rp1] "=m" (ras_page[1]),
68 [addr] "+m" (*mem)
69 : [ov] "r" (ov),
70 [nv] "r" (desired)
71 : "memory"
72 );
73
74 ras_page[0] = 0;
75 ras_page[1] = 0xffffffff;
76
77 if (ret == ov)
78 return true;
79
80 *expected = ret;
81 return false;
82}
83
84unsigned short __atomic_fetch_add_2(volatile unsigned short *mem, unsigned short val, int model)
85{
86 (void) model;
87
88 unsigned short ret;
89
90 /*
91 * The following instructions between labels 1 and 2 constitute a
92 * Restartable Atomic Seqeunce. Should the sequence be non-atomic,
93 * the kernel will restart it.
94 */
95 asm volatile (
96 "1:\n"
97 " adr %[ret], 1b\n"
98 " str %[ret], %[rp0]\n"
99 " adr %[ret], 2f\n"
100 " str %[ret], %[rp1]\n"
101 " ldrh %[ret], %[addr]\n"
102 " add %[ret], %[ret], %[imm]\n"
103 " strh %[ret], %[addr]\n"
104 "2:\n"
105 : [ret] "=&r" (ret),
106 [rp0] "=m" (ras_page[0]),
107 [rp1] "=m" (ras_page[1]),
108 [addr] "+m" (*mem)
109 : [imm] "r" (val)
110 );
111
112 ras_page[0] = 0;
113 ras_page[1] = 0xffffffff;
114
115 return ret - val;
116}
117
118unsigned __atomic_fetch_add_4(volatile unsigned *mem, unsigned val, int model)
119{
120 (void) model;
121
122 unsigned ret;
123
124 /*
125 * The following instructions between labels 1 and 2 constitute a
126 * Restartable Atomic Seqeunce. Should the sequence be non-atomic,
127 * the kernel will restart it.
128 */
129 asm volatile (
130 "1:\n"
131 " adr %[ret], 1b\n"
132 " str %[ret], %[rp0]\n"
133 " adr %[ret], 2f\n"
134 " str %[ret], %[rp1]\n"
135 " ldr %[ret], %[addr]\n"
136 " add %[ret], %[ret], %[imm]\n"
137 " str %[ret], %[addr]\n"
138 "2:\n"
139 : [ret] "=&r" (ret),
140 [rp0] "=m" (ras_page[0]),
141 [rp1] "=m" (ras_page[1]),
142 [addr] "+m" (*mem)
143 : [imm] "r" (val)
144 );
145
146 ras_page[0] = 0;
147 ras_page[1] = 0xffffffff;
148
149 return ret - val;
150}
151
152unsigned __atomic_fetch_sub_4(volatile unsigned *mem, unsigned val, int model)
153{
154 return __atomic_fetch_add_4(mem, -val, model);
155}
156
157void __sync_synchronize(void)
158{
159 // FIXME: Full memory barrier. We might need a syscall for this.
160}
161
162unsigned __sync_add_and_fetch_4(volatile void *vptr, unsigned val)
163{
164 return __atomic_fetch_add_4(vptr, val, __ATOMIC_SEQ_CST) + val;
165}
166
167unsigned __sync_sub_and_fetch_4(volatile void *vptr, unsigned val)
168{
169 return __atomic_fetch_sub_4(vptr, val, __ATOMIC_SEQ_CST) - val;
170}
171
172bool __sync_bool_compare_and_swap_4(volatile void *ptr, unsigned old_val, unsigned new_val)
173{
174 return __atomic_compare_exchange_4(ptr, &old_val, new_val, false,
175 __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
176}
177
178unsigned __sync_val_compare_and_swap_4(volatile void *ptr, unsigned old_val, unsigned new_val)
179{
180 __atomic_compare_exchange_4(ptr, &old_val, new_val, false,
181 __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
182 return old_val;
183}
Note: See TracBrowser for help on using the repository browser.