OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [lib/] [libcpu/] [hppa1.1/] [semaphore/] [semaphore.c] - Blame information for rev 173

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 30 unneback
/*
2
 *  Description:
3
 *      HPPA fast spinlock semaphores based on LDCWX instruction.
4
 *      These semaphores are not known to RTEMS.
5
 *
6
 *  TODO:
7
 *      Put node number in high 16 bits of flag??
8
 *      XXX: Need h_s_deallocate
9
 *
10
 *  COPYRIGHT (c) 1994 by Division Incorporated
11
 *
12
 *  The license and distribution terms for this file may be
13
 *  found in the file LICENSE in this distribution or at
14
 *  http://www.OARcorp.com/rtems/license.html.
15
 *
16
 *  $Id: semaphore.c,v 1.2 2001-09-27 12:01:21 chris Exp $
17
 */
18
 
19
#include <rtems.h>
20
 
21
#include <hppa1.1/semaphore.h>
22
 
23
/*
24
 * Report fatal semaphore error
25
 */
26
 
27
#define SEM_FATAL_ERROR(sp)  rtems_fatal_error_occurred((rtems_unsigned32) sp)
28
 
29
#define SEM_CHECK(sp)   do { \
30
                              if (((sp) == 0) || (int) (sp) & 0xf) \
31
                              { \
32
                                  SEM_FATAL_ERROR(sp); \
33
                              } \
34
                         } while (0)
35
 
36
/*
37
 * Init a semaphore to be free
38
 */
39
 
40
#define SEM_FREE_INIT(sp) \
41
    do { \
42
        (sp)->lock = 1; \
43
        (sp)->flags = 0; \
44
        (sp)->owner_tcb  = 0; \
45
    } while (0)
46
 
47
/*
48
 * Grab a semaphore recording its owner.
49
 */
50
 
51
#define SEM_MARK_GRABBED(sp) \
52
    do { \
53
        (sp)->owner_tcb  = _Thread_Executing; \
54
    } while (0)
55
 
56
/*
57
 * Mark the semaphore busy
58
 */
59
 
60
#define SEM_MARK_BUSY(sp)    ((sp)->flags |= HPPA_SEM_IN_USE)
61
 
62
/*
63
 * Is a semaphore available?
64
 */
65
 
66
#define SEM_IS_AVAILABLE(sp)  ((sp)->owner_tcb == 0)
67
 
68
/*
69
 * The pool control semaphore is the first in the pool
70
 */
71
 
72
#define SEM_CONTROL  (&hppa_semaphore_pool[0])
73
#define SEM_FIRST    (&hppa_semaphore_pool[1])
74
 
75
#define SEM_PRIVATE(cookie)  rtems_interrupt_disable(cookie)
76
 
77
#define SEM_PUBLIC(cookie)   rtems_interrupt_enable(cookie)
78
 
79
 
80
/*
81
 * Control variables for the pool
82
 */
83
 
84
hppa_semaphore_t *hppa_semaphore_pool;        /* ptr to first */
85
int               hppa_semaphores;
86
int               hppa_semaphores_available;
87
 
88
void
89
hppa_semaphore_pool_initialize(void *pool_base,
90
                               int   pool_size)
91
{
92
    hppa_semaphore_t *sp;
93
    int align_factor;
94
    rtems_unsigned32 isr_level;
95
 
96
    /*
97
     * round pool_base up to be a multiple of SEM_ALIGN
98
     */
99
 
100
    align_factor = SEM_ALIGN - (((int) pool_base) & (SEM_ALIGN-1));
101
    if (align_factor != SEM_ALIGN)
102
    {
103
        pool_base += align_factor;
104
        pool_size -= align_factor;
105
    }
106
 
107
    /*
108
     * How many can the pool hold?
109
     * Assumes the semaphores are SEM_ALIGN bytes each
110
     */
111
 
112
    if (sizeof(hppa_semaphore_t) != SEM_ALIGN)
113
        rtems_fatal_error_occurred(RTEMS_INVALID_SIZE);
114
 
115
    pool_size &= ~(SEM_ALIGN - 1);
116
 
117
    SEM_PRIVATE(isr_level);
118
 
119
    hppa_semaphore_pool = pool_base;
120
    hppa_semaphores = pool_size / SEM_ALIGN;
121
 
122
    /*
123
     * If we are node0, then init all in the pool
124
     */
125
 
126
#if 0
127
    if (cpu_number == 0)
128
#else
129
    if (_Configuration_Table->User_multiprocessing_table->node == 1)
130
#endif
131
    {
132
        /*
133
         * Tell other cpus we are not done, jic
134
         */
135
        SEM_CONTROL->user = rtems_build_name('!', 'D', 'N', 'E');
136
 
137
        for (sp=SEM_FIRST; sp < &hppa_semaphore_pool[hppa_semaphores]; sp++)
138
            SEM_FREE_INIT(sp);
139
        SEM_FREE_INIT(SEM_CONTROL);
140
    }
141
 
142
    /*
143
     * Tell other cpus we are done, or wait for it to be done if on another cpu
144
     */
145
 
146
#if 0
147
    if (cpu_number == 0)
148
#else
149
    if (_Configuration_Table->User_multiprocessing_table->node == 1)
150
#endif
151
        SEM_CONTROL->user = rtems_build_name('D', 'O', 'N', 'E');
152
    else
153
        while (SEM_CONTROL->user != rtems_build_name('D', 'O', 'N', 'E'))
154
            ;
155
 
156
    hppa_semaphores_available = hppa_semaphores;
157
 
158
    SEM_PUBLIC(isr_level);
159
}
160
 
161
/*
162
 *  Function:   hppa_semaphore_acquire
163
 *  Created:    94/11/29
164
 *  RespEngr:   tony bennett
165
 *
166
 *  Description:
167
 *      Acquire a semaphore.   Will spin on the semaphore unless
168
 *      'flag' says not to.
169
 *
170
 *  Parameters:
171
 *
172
 *
173
 *  Returns:
174
 *      0        -- if did not acquire
175
 *      non-zero -- if acquired semaphore
176
 *                      (actually this is the spin count)
177
 *
178
 *  Notes:
179
 *      There is no requirement that the semaphore be within the pool
180
 *
181
 *  Deficiencies/ToDo:
182
 *
183
 */
184
 
185
 
186
rtems_unsigned32
187
hppa_semaphore_acquire(hppa_semaphore_t *sp,
188
                       int               flag)
189
{
190
    rtems_unsigned32 lock_value;
191
    rtems_unsigned32 spin_count = 1;
192
 
193
    SEM_CHECK(sp);
194
 
195
    for (;;)
196
    {
197
        HPPA_ASM_LDCWS(0, 0, sp, lock_value);
198
 
199
        if (lock_value)         /* we now own the lock */
200
        {
201
            SEM_MARK_GRABBED(sp);
202
            return spin_count ? spin_count : ~0;        /* jic */
203
        }
204
 
205
        if (flag & HPPA_SEM_NO_SPIN)
206
            return 0;
207
 
208
        spin_count++;
209
    }
210
}
211
 
212
void
213
hppa_semaphore_release(hppa_semaphore_t *sp)
214
{
215
    SEM_CHECK(sp);
216
 
217
    if (sp->owner_tcb != _Thread_Executing)
218
        SEM_FATAL_ERROR("owner mismatch");
219
 
220
    sp->lock = 1;
221
}
222
 
223
 
224
/*
225
 *  Function:   hppa_semaphore_allocate
226
 *  Created:    94/11/29
227
 *  RespEngr:   tony bennett
228
 *
229
 *  Description:
230
 *      Get a pointer to a semaphore.
231
 *
232
 *  Parameters:
233
 *      which -- if 0, then allocate a free semaphore from the pool
234
 *               if non-zero, then return pointer to that one, even
235
 *                  if it is already busy.
236
 *
237
 *  Returns:
238
 *      successful -- pointer to semaphore
239
 *                    NULL otherwise
240
 *
241
 *  Notes:
242
 *
243
 *
244
 *  Deficiencies/ToDo:
245
 *
246
 *
247
 */
248
 
249
hppa_semaphore_t *
250
hppa_semaphore_allocate(rtems_unsigned32 which,
251
                        int              flag)
252
{
253
    hppa_semaphore_t *sp = 0;
254
 
255
    /*
256
     * grab the control semaphore
257
     */
258
 
259
    if (hppa_semaphore_acquire(SEM_CONTROL, 0) == 0)
260
        SEM_FATAL_ERROR("could not grab control semaphore");
261
 
262
    /*
263
     * Find a free one and init it
264
     */
265
 
266
    if (which)
267
    {
268
        if (which >= hppa_semaphores)
269
            SEM_FATAL_ERROR("requested non-existent semaphore");
270
        sp = &hppa_semaphore_pool[which];
271
 
272
        /*
273
         * if it is "free", then mark it claimed now.
274
         * If it is not free then we are done.
275
         */
276
 
277
        if (SEM_IS_AVAILABLE(sp))
278
            goto allmine;
279
    }
280
    else for (sp = SEM_FIRST;
281
              sp < &hppa_semaphore_pool[hppa_semaphores];
282
              sp++)
283
    {
284
        if (SEM_IS_AVAILABLE(sp))
285
        {
286
allmine:    SEM_FREE_INIT(sp);
287
            SEM_MARK_BUSY(sp);
288
            if ( ! (flag & HPPA_SEM_INITIALLY_FREE))
289
                SEM_MARK_GRABBED(sp);
290
            break;
291
        }
292
    }
293
 
294
    /*
295
     * Free up the control semaphore
296
     */
297
 
298
    hppa_semaphore_release(SEM_CONTROL);
299
 
300
    return sp;
301
}
302
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.