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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [kernel/] [current/] [src/] [common/] [kapi.cxx] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
2
//
3
//      common/kapi.cxx
4
//
5
//      C API Implementation
6
//
7
//==========================================================================
8
// ####ECOSGPLCOPYRIGHTBEGIN####                                            
9
// -------------------------------------------                              
10
// This file is part of eCos, the Embedded Configurable Operating System.   
11
// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
12
//
13
// eCos is free software; you can redistribute it and/or modify it under    
14
// the terms of the GNU General Public License as published by the Free     
15
// Software Foundation; either version 2 or (at your option) any later      
16
// version.                                                                 
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT      
19
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
20
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
21
// for more details.                                                        
22
//
23
// You should have received a copy of the GNU General Public License        
24
// along with eCos; if not, write to the Free Software Foundation, Inc.,    
25
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
26
//
27
// As a special exception, if other files instantiate templates or use      
28
// macros or inline functions from this file, or you compile this file      
29
// and link it with other works to produce a work based on this file,       
30
// this file does not by itself cause the resulting work to be covered by   
31
// the GNU General Public License. However the source code for this file    
32
// must still be made available in accordance with section (3) of the GNU   
33
// General Public License v2.                                               
34
//
35
// This exception does not invalidate any other reasons why a work based    
36
// on this file might be covered by the GNU General Public License.         
37
// -------------------------------------------                              
38
// ####ECOSGPLCOPYRIGHTEND####                                              
39
//==========================================================================
40
//#####DESCRIPTIONBEGIN####
41
//
42
// Author(s):   nickg, dsm
43
// Contributors:        nickg
44
// Date:        1998-03-02
45
// Purpose:     C API Implementation
46
// Description: C++ implementation of the C API
47
//              
48
//
49
//####DESCRIPTIONEND####
50
//
51
//==========================================================================
52
 
53
#include <pkgconf/kernel.h>
54
 
55
#ifdef CYGFUN_KERNEL_API_C
56
 
57
#include <cyg/kernel/ktypes.h>         // base kernel types
58
#include <cyg/infra/cyg_trac.h>        // tracing macros
59
#include <cyg/infra/cyg_ass.h>         // assertion macros
60
#include <cyg/kernel/instrmnt.h>       // instrumentation
61
#include <cyg/kernel/diag.h>
62
 
63
#include <cyg/kernel/thread.hxx>
64
#include <cyg/kernel/thread.inl>       // thread inlines
65
#include <cyg/kernel/sched.hxx>
66
#include <cyg/kernel/intr.hxx>
67
#include <cyg/kernel/clock.hxx>
68
 
69
#include <cyg/kernel/sema.hxx>
70
#include <cyg/kernel/flag.hxx>
71
#include <cyg/kernel/mutex.hxx>
72
#include <cyg/kernel/mbox.hxx>
73
 
74
#include <cyg/kernel/sched.inl>        // scheduler inlines
75
#include <cyg/kernel/clock.inl>        // clock inlines
76
 
77
#include <cyg/kernel/kapi.h>           // C API
78
 
79
// -------------------------------------------------------------------------
80
// Magic new function
81
 
82
inline void *operator new(size_t size, void *ptr)
83
{
84
    CYG_CHECK_DATA_PTR( ptr, "Bad pointer" );
85
    return ptr;
86
}
87
 
88
// -------------------------------------------------------------------------
89
 
90
#ifdef CYGDBG_USE_ASSERTS
91
 
92
#define CYG_ASSERT_SIZES(cstruct, cxxstruct)                      \
93
CYG_MACRO_START                                                   \
94
    char *msg = "Size of C struct " #cstruct                      \
95
                       " != size of C++ struct " #cxxstruct ;     \
96
    CYG_ASSERT( sizeof(cstruct) == sizeof(cxxstruct) , msg );     \
97
CYG_MACRO_END
98
 
99
#else
100
 
101
#define CYG_ASSERT_SIZES(cstruct, cxxstruct)
102
 
103
#endif
104
 
105
/*---------------------------------------------------------------------------*/
106
/* Scheduler operations */
107
 
108
/* Starts scheduler with created threads.  Never returns. */
109
externC void cyg_scheduler_start(void) __THROW
110
{
111
    Cyg_Scheduler::start();
112
}
113
 
114
/* Lock the scheduler. */
115
externC void cyg_scheduler_lock(void) __THROW
116
{
117
    Cyg_Scheduler::lock();
118
    // get_sched_lock() is unsigned, see below "cyg_ucount32 lock"
119
    CYG_ASSERT( (0xff000000 & (Cyg_Scheduler::get_sched_lock())) == 0,
120
                "Scheduler overlocked" );
121
}
122
 
123
/* Lock the scheduler, but never more than level=1. */
124
externC void cyg_scheduler_safe_lock(void) __THROW
125
{
126
    Cyg_Scheduler::lock();
127
    cyg_ucount32 slock = Cyg_Scheduler::get_sched_lock();
128
    if (slock > 1)
129
        Cyg_Scheduler::unlock();
130
    // get_sched_lock() is unsigned, see below "cyg_ucount32 lock"
131
    CYG_ASSERT( (0xff000000 & (Cyg_Scheduler::get_sched_lock())) == 0,
132
                "Scheduler overlocked" );
133
}
134
 
135
/* Unlock the scheduler. */
136
externC void cyg_scheduler_unlock(void) __THROW
137
{
138
    cyg_ucount32 slock = Cyg_Scheduler::get_sched_lock();
139
    CYG_ASSERT( 0 < slock, "Scheduler not locked" );
140
    // And program defensively too:
141
    if ( 0 < slock )
142
        Cyg_Scheduler::unlock();
143
}
144
 
145
/* Read the scheduler lock value. */
146
externC cyg_ucount32 cyg_scheduler_read_lock(void) __THROW
147
{
148
    cyg_ucount32 slock = Cyg_Scheduler::get_sched_lock();
149
    return slock;
150
}
151
 
152
/*---------------------------------------------------------------------------*/
153
/* Thread operations */
154
 
155
externC void cyg_thread_create(
156
    cyg_addrword_t      sched_info,             /* scheduling info (eg pri)  */
157
    cyg_thread_entry_t  *entry,                 /* entry point function      */
158
    cyg_addrword_t      entry_data,             /* entry data                */
159
    char                *name,                  /* optional thread name      */
160
    void                *stack_base,            /* stack base, NULL = alloc  */
161
    cyg_ucount32        stack_size,             /* stack size, 0 = default   */
162
    cyg_handle_t        *handle,                /* returned thread handle    */
163
    cyg_thread          *thread                 /* put thread here           */
164
) __THROW
165
{
166
    CYG_ASSERT_SIZES( cyg_thread, Cyg_Thread );
167
 
168
    Cyg_Thread *t = new((void *)thread) Cyg_Thread (
169
        (CYG_ADDRWORD) sched_info,
170
        (cyg_thread_entry *)entry,
171
        (CYG_ADDRWORD) entry_data,
172
        name,
173
        (CYG_ADDRWORD) stack_base,
174
        stack_size
175
        );
176
    t=t;
177
 
178
    CYG_CHECK_DATA_PTR( handle, "Bad handle pointer" );
179
    *handle = (cyg_handle_t)thread;
180
}
181
 
182
externC void cyg_thread_exit() __THROW
183
{
184
    Cyg_Thread::exit();
185
}
186
 
187
externC cyg_bool_t cyg_thread_delete( cyg_handle_t thread ) __THROW
188
{
189
    Cyg_Thread *th = (Cyg_Thread *)thread;
190
    if( th->get_state() != Cyg_Thread::EXITED )
191
        th->kill(); // encourage it to terminate
192
    if( th->get_state() != Cyg_Thread::EXITED )
193
        return false; // it didn't run yet, leave it up to the app to fix
194
    th->~Cyg_Thread();
195
    return true;
196
}
197
 
198
externC void cyg_thread_suspend(cyg_handle_t thread) __THROW
199
{
200
    ((Cyg_Thread *)thread)->suspend();
201
}
202
 
203
externC void cyg_thread_resume(cyg_handle_t thread) __THROW
204
{
205
    Cyg_Thread *th = (Cyg_Thread *)thread;
206
 
207
    // If we are resuming an exited thread then
208
    // reinitialize it.
209
 
210
    if( th->get_state() == Cyg_Thread::EXITED )
211
        th->reinitialize();
212
 
213
    th->resume();
214
}
215
 
216
externC void cyg_thread_kill( cyg_handle_t thread) __THROW
217
{
218
    ((Cyg_Thread *)thread)->kill();
219
}
220
 
221
externC void cyg_thread_release( cyg_handle_t thread) __THROW
222
{
223
    ((Cyg_Thread *)thread)->release();
224
}
225
 
226
externC void cyg_thread_yield() __THROW
227
{
228
    Cyg_Thread::yield();
229
}
230
 
231
externC cyg_handle_t cyg_thread_self() __THROW
232
{
233
    return (cyg_handle_t)Cyg_Thread::self();
234
}
235
 
236
externC cyg_uint16 cyg_thread_get_id( cyg_handle_t thread) __THROW
237
{
238
    return ((Cyg_Thread *)thread)->get_unique_id();
239
}
240
 
241
// idle thread is not really a plain CygThread; danger.
242
externC cyg_handle_t cyg_thread_idle_thread() __THROW
243
{
244
    extern Cyg_Thread idle_thread;
245
    return (cyg_handle_t)&idle_thread;
246
}
247
 
248
/* Priority manipulation */
249
externC void cyg_thread_set_priority(
250
    cyg_handle_t thread, cyg_priority_t priority ) __THROW
251
{
252
#ifdef CYGIMP_THREAD_PRIORITY
253
    ((Cyg_Thread *)thread)->set_priority(priority);
254
#endif
255
}
256
 
257
 
258
/* Get the normal priority, ie without any applied mutex inheritance or
259
 * ceiling protocol. */
260
externC cyg_priority_t cyg_thread_get_priority(cyg_handle_t thread) __THROW
261
{
262
#ifdef CYGIMP_THREAD_PRIORITY
263
    return ((Cyg_Thread *)thread)->get_priority();
264
#else
265
    return 0;
266
#endif
267
}
268
 
269
 
270
/* Get the current priority, ie any applied mutex inheritance or
271
 * ceiling protocol. */
272
externC cyg_priority_t cyg_thread_get_current_priority(cyg_handle_t thread) __THROW
273
{
274
#ifdef CYGIMP_THREAD_PRIORITY
275
    return ((Cyg_Thread *)thread)->get_current_priority();
276
#else
277
    return 0;
278
#endif
279
}
280
 
281
/* Deadline scheduling control (optional) */
282
 
283
externC void cyg_thread_deadline_wait(
284
    cyg_tick_count_t    start_time,             /* abs earliest start time   */
285
    cyg_tick_count_t    run_time,               /* worst case execution time */
286
    cyg_tick_count_t    deadline                /* absolute deadline         */
287
) __THROW
288
{
289
    CYG_ASSERT(0,"Not implemented");
290
}
291
 
292
externC void cyg_thread_delay(cyg_tick_count_t delay) __THROW
293
{
294
    Cyg_Thread::self()->delay(delay);
295
}
296
 
297
/* Stack information */
298
externC cyg_addrword_t cyg_thread_get_stack_base(cyg_handle_t thread) __THROW
299
{
300
    return ((Cyg_Thread *)thread)->get_stack_base();
301
}
302
 
303
externC cyg_uint32 cyg_thread_get_stack_size(cyg_handle_t thread) __THROW
304
{
305
    return ((Cyg_Thread *)thread)->get_stack_size();
306
}
307
 
308
#ifdef CYGFUN_KERNEL_THREADS_STACK_MEASUREMENT
309
externC cyg_uint32 cyg_thread_measure_stack_usage(cyg_handle_t thread) __THROW
310
{
311
    return ((Cyg_Thread *)thread)->measure_stack_usage();
312
}
313
#endif
314
 
315
/*---------------------------------------------------------------------------*/
316
/* Thread enumeration and information                                        */
317
 
318
#ifdef CYGVAR_KERNEL_THREADS_LIST
319
 
320
cyg_bool_t cyg_thread_get_next( cyg_handle_t *current, cyg_uint16 *id ) __THROW
321
{
322
    cyg_bool_t result = true;
323
 
324
    // There is a minute but finite chance that the thread could have
325
    // exitted since the previous cyg_thread_get_next() call, and we can't
326
    // detect the ID mismatch further down. So be quite zealous with checking.
327
 
328
    CYG_CHECK_DATA_PTRC( current );
329
    CYG_CHECK_DATA_PTRC( id );
330
    if ( *current != 0 )
331
        CYG_CHECK_DATA_PTRC( *current );
332
 
333
    Cyg_Scheduler::lock();
334
 
335
    Cyg_Thread *thread = (Cyg_Thread *)*current;
336
    CYG_ASSERT_ZERO_OR_CLASSC( thread );
337
    if( *current == 0 )
338
    {
339
        thread = Cyg_Thread::get_list_head();
340
        *current = (cyg_handle_t)thread;
341
        *id = thread->get_unique_id();
342
    }
343
    else if( (thread->get_unique_id() == *id) &&
344
             (thread = thread->get_list_next()) != NULL )
345
    {
346
        CYG_CHECK_DATA_PTRC( thread );
347
        CYG_ASSERT_CLASSC( thread );
348
        *current = (cyg_handle_t)thread;
349
        *id = thread->get_unique_id();
350
    }
351
    else
352
    {
353
        *current = 0;
354
        *id = 0;
355
        result = false;
356
    }
357
 
358
    Cyg_Scheduler::unlock();
359
 
360
    return result;
361
}
362
 
363
cyg_handle_t cyg_thread_find( cyg_uint16 id ) __THROW
364
{
365
    Cyg_Scheduler::lock();
366
 
367
    Cyg_Thread *thread = Cyg_Thread::get_list_head();
368
 
369
    while( thread != NULL )
370
    {
371
        if( thread->get_unique_id() == id )
372
            break;
373
 
374
        thread = thread->get_list_next();
375
    }
376
 
377
    Cyg_Scheduler::unlock();
378
 
379
    return (cyg_handle_t)thread;
380
}
381
 
382
#endif
383
 
384
cyg_bool_t cyg_thread_get_info( cyg_handle_t threadh,
385
                                cyg_uint16 id,
386
                                cyg_thread_info *info ) __THROW
387
{
388
    cyg_bool_t result = true;
389
    Cyg_Thread *thread = (Cyg_Thread *)threadh;
390
    CYG_CHECK_DATA_PTRC( thread );
391
    if ( NULL != info )
392
        CYG_CHECK_DATA_PTRC( info );
393
 
394
    Cyg_Scheduler::lock();
395
 
396
    if( thread->get_unique_id() == id && info != NULL )
397
    {
398
        CYG_ASSERT_CLASSC( thread );
399
        info->handle = threadh;
400
        info->id = id;
401
        info->state = thread->get_state();
402
#ifdef CYGVAR_KERNEL_THREADS_NAME
403
        info->name = thread->get_name();
404
#else
405
        info->name = NULL;
406
#endif
407
        info->set_pri = thread->get_priority();
408
        info->cur_pri = thread->get_current_priority();
409
        info->stack_base = thread->get_stack_base();
410
        info->stack_size = thread->get_stack_size();
411
 
412
#ifdef CYGFUN_KERNEL_THREADS_STACK_MEASUREMENT
413
        info->stack_used = thread->measure_stack_usage();
414
#else
415
        info->stack_used = 0;
416
#endif
417
    }
418
    else result = false;
419
 
420
    Cyg_Scheduler::unlock();
421
 
422
    return result;
423
}
424
 
425
/*---------------------------------------------------------------------------*/
426
/* Per-thread data                                                           */
427
 
428
#ifdef CYGVAR_KERNEL_THREADS_DATA
429
 
430
externC cyg_ucount32 cyg_thread_new_data_index() __THROW
431
{
432
    Cyg_Thread::cyg_data_index index = Cyg_Thread::new_data_index();
433
    CYG_ASSERT(index >= 0, "failed to allocate data index" );
434
    return index;
435
}
436
 
437
externC void cyg_thread_free_data_index(cyg_ucount32 index) __THROW
438
{
439
    Cyg_Thread::free_data_index(index);
440
}
441
 
442
externC CYG_ADDRWORD cyg_thread_get_data(cyg_ucount32 index) __THROW
443
{
444
    return Cyg_Thread::get_data(index);
445
}
446
 
447
externC CYG_ADDRWORD *cyg_thread_get_data_ptr(cyg_ucount32 index) __THROW
448
{
449
    return Cyg_Thread::get_data_ptr(index);
450
}
451
 
452
externC void cyg_thread_set_data(cyg_ucount32 index, CYG_ADDRWORD
453
data) __THROW
454
{
455
    Cyg_Thread::self()->set_data(index, data);
456
}
457
#endif
458
 
459
/*---------------------------------------------------------------------------*/
460
/* Thread destructors                                                        */
461
 
462
#ifdef CYGPKG_KERNEL_THREADS_DESTRUCTORS
463
__externC cyg_bool_t
464
cyg_thread_add_destructor( cyg_thread_destructor_fn fn,
465
                           cyg_addrword_t data ) __THROW
466
{
467
        return Cyg_Thread::self()->add_destructor( fn, data );
468
}
469
 
470
__externC cyg_bool_t
471
cyg_thread_rem_destructor( cyg_thread_destructor_fn fn,
472
                           cyg_addrword_t data ) __THROW
473
{
474
        return Cyg_Thread::self()->rem_destructor( fn, data );
475
}
476
#endif
477
 
478
/*---------------------------------------------------------------------------*/
479
/* Exception handling.                                                       */
480
 
481
#ifdef CYGPKG_KERNEL_EXCEPTIONS    
482
externC void cyg_exception_set_handler(
483
    cyg_code_t                  exception_number,
484
    cyg_exception_handler_t     *new_handler,
485
    cyg_addrword_t              new_data,
486
    cyg_exception_handler_t     **old_handler,
487
    cyg_addrword_t              *old_data
488
) __THROW
489
{
490
    Cyg_Thread::register_exception(
491
        exception_number,
492
        (cyg_exception_handler *)new_handler,
493
        (CYG_ADDRWORD)new_data,
494
        (cyg_exception_handler **)old_handler,
495
        (CYG_ADDRWORD *)old_data
496
        );
497
}
498
 
499
/* Clear exception handler to default                                        */
500
externC void cyg_exception_clear_handler(
501
    cyg_code_t                  exception_number
502
) __THROW
503
{
504
    Cyg_Thread::deregister_exception( exception_number );
505
}
506
 
507
/* Invoke exception handler                                                  */
508
externC void cyg_exception_call_handler(
509
    cyg_handle_t                thread,
510
    cyg_code_t                  exception_number,
511
    cyg_addrword_t              error_code
512
) __THROW
513
{
514
    Cyg_Thread *t = (Cyg_Thread *)thread;
515
 
516
    t->deliver_exception( exception_number, error_code );
517
}
518
#endif    
519
 
520
/*---------------------------------------------------------------------------*/
521
/* Interrupt handling                                                        */
522
 
523
externC void cyg_interrupt_create(
524
    cyg_vector_t        vector,         /* Vector to attach to               */
525
    cyg_priority_t      priority,       /* Queue priority                    */
526
    cyg_addrword_t      data,           /* Data pointer                      */
527
    cyg_ISR_t           *isr,           /* Interrupt Service Routine         */
528
    cyg_DSR_t           *dsr,           /* Deferred Service Routine          */
529
    cyg_handle_t        *handle,        /* returned handle                   */
530
    cyg_interrupt       *intr           /* put interrupt here                */
531
) __THROW
532
{
533
    CYG_ASSERT_SIZES( cyg_interrupt, Cyg_Interrupt );
534
 
535
    Cyg_Interrupt *t = new((void *)intr) Cyg_Interrupt (
536
        (cyg_vector)vector,
537
        (cyg_priority)priority,
538
        (CYG_ADDRWORD)data,
539
        (cyg_ISR *)isr,
540
        (cyg_DSR *)dsr );
541
    t=t;
542
 
543
    CYG_CHECK_DATA_PTR( handle, "Bad handle pointer" );
544
    *handle = (cyg_handle_t)intr;
545
}
546
 
547
externC void cyg_interrupt_delete( cyg_handle_t interrupt) __THROW
548
{
549
    ((Cyg_Interrupt *)interrupt)->~Cyg_Interrupt();
550
}
551
 
552
void cyg_interrupt_attach( cyg_handle_t interrupt ) __THROW
553
{
554
    ((Cyg_Interrupt *)interrupt)->attach();
555
}
556
 
557
void cyg_interrupt_detach( cyg_handle_t interrupt ) __THROW
558
{
559
    ((Cyg_Interrupt *)interrupt)->detach();
560
}
561
 
562
/* VSR manipulation */
563
 
564
externC void cyg_interrupt_get_vsr(
565
    cyg_vector_t        vector,         /* vector to get                     */
566
    cyg_VSR_t           **vsr           /* vsr got                           */
567
) __THROW
568
{
569
    Cyg_Interrupt::get_vsr( (cyg_vector)vector, (cyg_VSR **)vsr);
570
}
571
 
572
externC void cyg_interrupt_set_vsr(
573
    cyg_vector_t        vector,         /* vector to set                     */
574
    cyg_VSR_t           *vsr            /* vsr to set                        */
575
) __THROW
576
{
577
    Cyg_Interrupt::set_vsr( (cyg_vector)vector, (cyg_VSR *)vsr);
578
}
579
 
580
/* CPU level interrupt mask                                                  */
581
externC void cyg_interrupt_disable() __THROW
582
{
583
    Cyg_Interrupt::disable_interrupts();
584
}
585
 
586
externC void cyg_interrupt_enable() __THROW
587
{
588
    Cyg_Interrupt::enable_interrupts();
589
}
590
 
591
/* Interrupt controller access                                               */
592
externC void cyg_interrupt_mask(cyg_vector_t vector) __THROW
593
{
594
    Cyg_Interrupt::mask_interrupt( (cyg_vector)vector);
595
}
596
 
597
externC void cyg_interrupt_mask_intunsafe(cyg_vector_t vector) __THROW
598
{
599
    Cyg_Interrupt::mask_interrupt_intunsafe( (cyg_vector)vector);
600
}
601
 
602
externC void cyg_interrupt_unmask(cyg_vector_t vector) __THROW
603
{
604
    Cyg_Interrupt::unmask_interrupt( (cyg_vector)vector);
605
}
606
 
607
externC void cyg_interrupt_unmask_intunsafe(cyg_vector_t vector) __THROW
608
{
609
    Cyg_Interrupt::unmask_interrupt_intunsafe( (cyg_vector)vector);
610
}
611
 
612
externC void cyg_interrupt_acknowledge(cyg_vector_t vector) __THROW
613
{
614
    Cyg_Interrupt::acknowledge_interrupt( (cyg_vector)vector);
615
}
616
 
617
 
618
externC void cyg_interrupt_configure(
619
    cyg_vector_t        vector,         /* vector to configure               */
620
    cyg_bool_t          level,          /* level or edge triggered           */
621
    cyg_bool_t          up              /* rising/faling edge, high/low level*/
622
) __THROW
623
{
624
    Cyg_Interrupt::configure_interrupt( (cyg_vector)vector, level, up );
625
}
626
 
627
externC void cyg_interrupt_set_cpu(
628
    cyg_vector_t        vector,         /* vector to control                 */
629
    cyg_cpu_t           cpu             /* CPU to set                        */
630
) __THROW
631
{
632
#ifdef CYGPKG_KERNEL_SMP_SUPPORT    
633
    Cyg_Interrupt::set_cpu( vector, cpu );
634
#endif    
635
}
636
 
637
externC cyg_cpu_t cyg_interrupt_get_cpu(
638
    cyg_vector_t        vector          /* vector to control                 */
639
) __THROW
640
{
641
#ifdef CYGPKG_KERNEL_SMP_SUPPORT        
642
    return Cyg_Interrupt::get_cpu( vector );
643
#else
644
    return CYG_KERNEL_CPU_THIS();
645
#endif    
646
 
647
}
648
 
649
/*---------------------------------------------------------------------------*/
650
/* Counters, Clocks and Alarms                                               */
651
 
652
externC void cyg_counter_create(
653
    cyg_handle_t        *handle,        /* returned counter handle           */
654
    cyg_counter         *counter        /* put counter here                  */
655
) __THROW
656
{
657
    CYG_ASSERT_SIZES( cyg_counter, Cyg_Counter );
658
 
659
    Cyg_Counter *t = new((void *)counter) Cyg_Counter ();
660
    t=t;
661
 
662
    CYG_CHECK_DATA_PTR( handle, "Bad handle pointer" );
663
    *handle = (cyg_handle_t)counter;
664
}
665
 
666
externC void cyg_counter_delete(cyg_handle_t counter) __THROW
667
{
668
    ((Cyg_Counter *)counter)->~Cyg_Counter();
669
}
670
 
671
/* Return current value of counter                                           */
672
externC cyg_tick_count_t cyg_counter_current_value(cyg_handle_t counter) __THROW
673
{
674
    return ((Cyg_Counter *)counter)->current_value();
675
}
676
 
677
/* Set new current value                                                     */
678
externC void cyg_counter_set_value(
679
    cyg_handle_t        counter,
680
    cyg_tick_count_t new_value
681
) __THROW
682
{
683
    ((Cyg_Counter *)counter)->set_value( new_value );
684
}
685
 
686
/* Advance counter by one tick                                               */
687
externC void cyg_counter_tick(cyg_handle_t counter) __THROW
688
{
689
    ((Cyg_Counter *)counter)->tick();
690
}
691
 
692
/* Advance counter by multiple ticks                                         */
693
externC void cyg_counter_multi_tick(cyg_handle_t counter, cyg_tick_count_t ticks) __THROW
694
{
695
    ((Cyg_Counter *)counter)->tick(ticks);
696
}
697
 
698
/* Create a clock object                */
699
externC void cyg_clock_create(
700
    cyg_resolution_t    resolution,     /* Initial resolution                */
701
    cyg_handle_t        *handle,        /* Returned clock handle             */
702
    cyg_clock           *clock          /* put clock here                    */
703
) __THROW
704
{
705
    CYG_ASSERT_SIZES( cyg_clock, Cyg_Clock );
706
 
707
    Cyg_Clock::cyg_resolution res;
708
 
709
    res.dividend = resolution.dividend;
710
    res.divisor  = resolution.divisor;
711
 
712
    Cyg_Clock *t = new((void *)clock) Cyg_Clock ( res );
713
    t=t;
714
 
715
    CYG_CHECK_DATA_PTR( handle, "Bad handle pointer" );
716
    *handle = (cyg_handle_t)clock;
717
}
718
 
719
externC void cyg_clock_delete(cyg_handle_t clock) __THROW
720
{
721
    ((Cyg_Clock *)clock)->~Cyg_Clock();
722
}
723
 
724
/* convert a clock handle to a counter handle so we can use the              */
725
/* counter API on it.                                                        */
726
externC void cyg_clock_to_counter(
727
    cyg_handle_t        clock,
728
    cyg_handle_t        *counter
729
) __THROW
730
{
731
    CYG_CHECK_DATA_PTR( counter, "Bad counter handle pointer" );
732
    *counter = (cyg_handle_t)(Cyg_Counter *)clock;
733
}
734
 
735
externC void cyg_clock_set_resolution(
736
    cyg_handle_t        clock,
737
    cyg_resolution_t    resolution      /* New resolution                    */
738
) __THROW
739
{
740
    Cyg_Clock::cyg_resolution res;
741
 
742
    res.dividend = resolution.dividend;
743
    res.divisor  = resolution.divisor;
744
 
745
    ((Cyg_Clock *)clock)->set_resolution( res );
746
}
747
 
748
externC cyg_resolution_t cyg_clock_get_resolution(cyg_handle_t clock) __THROW
749
{
750
    Cyg_Clock::cyg_resolution res =
751
        ((Cyg_Clock *)clock)->get_resolution();
752
 
753
    cyg_resolution_t resolution;
754
 
755
    resolution.dividend = res.dividend;
756
    resolution.divisor  = res.divisor;
757
 
758
    return resolution;
759
}
760
 
761
#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK
762
externC cyg_handle_t cyg_real_time_clock(void) __THROW
763
{
764
    return (cyg_handle_t)Cyg_Clock::real_time_clock;
765
}
766
 
767
externC cyg_tick_count_t cyg_current_time(void) __THROW
768
{
769
    return Cyg_Clock::real_time_clock->current_value();
770
}
771
#endif
772
 
773
externC void cyg_alarm_create(
774
    cyg_handle_t        counter,        /* Attached to this counter          */
775
    cyg_alarm_t         *alarmfn,       /* Call-back function                */
776
    cyg_addrword_t      data,           /* Call-back data                    */
777
    cyg_handle_t        *handle,        /* Returned alarm object             */
778
    cyg_alarm           *alarm          /* put alarm here                    */
779
) __THROW
780
{
781
    CYG_ASSERT_SIZES( cyg_alarm, Cyg_Alarm );
782
 
783
    Cyg_Alarm *t = new((void *)alarm) Cyg_Alarm (
784
        (Cyg_Counter *)counter,
785
        (cyg_alarm_fn *)alarmfn,
786
        (CYG_ADDRWORD)data
787
    );
788
    t=t;
789
 
790
    CYG_CHECK_DATA_PTR( handle, "Bad handle pointer" );
791
    *handle = (cyg_handle_t)alarm;
792
}
793
 
794
/* Disable alarm, detach from counter and invalidate handles                 */
795
externC void cyg_alarm_delete( cyg_handle_t alarm) __THROW
796
{
797
    ((Cyg_Alarm *)alarm)->~Cyg_Alarm();
798
}
799
 
800
externC void cyg_alarm_initialize(
801
    cyg_handle_t        alarm,
802
    cyg_tick_count_t    trigger,        /* Absolute trigger time             */
803
    cyg_tick_count_t    interval        /* Relative retrigger interval       */
804
) __THROW
805
{
806
    ((Cyg_Alarm *)alarm)->initialize(
807
        (cyg_tick_count)trigger,
808
        (cyg_tick_count)interval);
809
}
810
 
811
externC void cyg_alarm_get_times(
812
    cyg_handle_t        alarm,
813
    cyg_tick_count_t    *trigger,       /* Next trigger time                 */
814
    cyg_tick_count_t    *interval       /* Current interval                  */
815
) __THROW
816
{
817
    ((Cyg_Alarm *)alarm)->get_times(
818
        (cyg_tick_count*)trigger,
819
        (cyg_tick_count*)interval);
820
}
821
 
822
externC void cyg_alarm_enable( cyg_handle_t alarm ) __THROW
823
{
824
    ((Cyg_Alarm *)alarm)->enable();
825
}
826
 
827
externC void cyg_alarm_disable( cyg_handle_t alarm ) __THROW
828
{
829
    ((Cyg_Alarm *)alarm)->disable();
830
}
831
 
832
/*---------------------------------------------------------------------------*/
833
/* Mail boxes                                                                */
834
 
835
externC void cyg_mbox_create(
836
    cyg_handle_t        *handle,
837
    cyg_mbox            *mbox
838
) __THROW
839
{
840
    CYG_ASSERT_SIZES( cyg_mbox, Cyg_Mbox );
841
 
842
    Cyg_Mbox *t = new((void *)mbox) Cyg_Mbox();
843
    t=t;
844
 
845
    CYG_CHECK_DATA_PTR( handle, "Bad handle pointer" );
846
    *handle = (cyg_handle_t)mbox;
847
}
848
 
849
externC void cyg_mbox_delete(cyg_handle_t mbox) __THROW
850
{
851
    ((Cyg_Mbox *)mbox)->~Cyg_Mbox();
852
}
853
 
854
externC void *cyg_mbox_get(cyg_handle_t mbox) __THROW
855
{
856
    return ((Cyg_Mbox *)mbox)->get();
857
}
858
 
859
#ifdef CYGFUN_KERNEL_THREADS_TIMER
860
void *cyg_mbox_timed_get(
861
    cyg_handle_t mbox,
862
    cyg_tick_count_t abstime
863
    ) __THROW
864
{
865
    return ((Cyg_Mbox *)mbox)->get(abstime);
866
}
867
#endif
868
 
869
externC void *cyg_mbox_tryget(cyg_handle_t mbox) __THROW
870
{
871
    return ((Cyg_Mbox *)mbox)->tryget();
872
}
873
 
874
externC void *cyg_mbox_peek_item(cyg_handle_t mbox) __THROW
875
{
876
    return ((Cyg_Mbox *)mbox)->peek_item();
877
}
878
 
879
#ifdef CYGMFN_KERNEL_SYNCH_MBOXT_PUT_CAN_WAIT
880
externC cyg_bool_t cyg_mbox_put(cyg_handle_t mbox, void *item) __THROW
881
{
882
    return ((Cyg_Mbox *)mbox)->put(item);
883
}
884
 
885
#ifdef CYGFUN_KERNEL_THREADS_TIMER
886
externC cyg_bool_t cyg_mbox_timed_put(
887
    cyg_handle_t mbox,
888
    void *item,
889
    cyg_tick_count_t abstime
890
    ) __THROW
891
{
892
    return ((Cyg_Mbox *)mbox)->put(item, abstime);
893
}
894
#endif
895
#endif
896
 
897
externC cyg_bool_t cyg_mbox_tryput(cyg_handle_t mbox, void *item) __THROW
898
{
899
    return ((Cyg_Mbox *)mbox)->tryput(item);
900
}
901
 
902
externC cyg_count32 cyg_mbox_peek(cyg_handle_t mbox) __THROW
903
{
904
    return ((Cyg_Mbox *)mbox)->peek();
905
}
906
 
907
externC cyg_bool_t cyg_mbox_waiting_to_get(cyg_handle_t mbox) __THROW
908
{
909
    return ((Cyg_Mbox *)mbox)->waiting_to_get();
910
}
911
 
912
externC cyg_bool_t cyg_mbox_waiting_to_put(cyg_handle_t mbox) __THROW
913
{
914
    return ((Cyg_Mbox *)mbox)->waiting_to_put();
915
}
916
 
917
 
918
/*---------------------------------------------------------------------------*/
919
/* Semaphores                                                                */
920
 
921
externC void      cyg_semaphore_init(
922
    cyg_sem_t           *sem,            /* Semaphore to init                */
923
    cyg_count32         val              /* Initial semaphore value          */
924
) __THROW
925
{
926
    CYG_ASSERT_SIZES( cyg_sem_t, Cyg_Counting_Semaphore );
927
 
928
    Cyg_Counting_Semaphore *t = new((void *)sem) Cyg_Counting_Semaphore(val);
929
    t=t;
930
}
931
 
932
externC void cyg_semaphore_destroy( cyg_sem_t *sem ) __THROW
933
{
934
    ((Cyg_Counting_Semaphore *)sem)->~Cyg_Counting_Semaphore();
935
}
936
 
937
externC cyg_bool_t cyg_semaphore_wait( cyg_sem_t *sem ) __THROW
938
{
939
    return ((Cyg_Counting_Semaphore *)sem)->wait();
940
}
941
 
942
#ifdef CYGFUN_KERNEL_THREADS_TIMER
943
externC cyg_bool_t cyg_semaphore_timed_wait(
944
    cyg_sem_t          *sem,
945
    cyg_tick_count_t   abstime
946
    ) __THROW
947
{
948
    return ((Cyg_Counting_Semaphore *)sem)->wait(abstime);
949
}
950
#endif
951
 
952
 
953
externC int cyg_semaphore_trywait( cyg_sem_t *sem ) __THROW
954
{
955
    return ((Cyg_Counting_Semaphore *)sem)->trywait();
956
}
957
 
958
externC void cyg_semaphore_post( cyg_sem_t *sem ) __THROW
959
{
960
    ((Cyg_Counting_Semaphore *)sem)->post();
961
}
962
 
963
externC void cyg_semaphore_peek( cyg_sem_t *sem, cyg_count32 *val ) __THROW
964
{
965
    CYG_CHECK_DATA_PTR( val, "Bad val parameter" );
966
 
967
    *val = ((Cyg_Counting_Semaphore *)sem)->peek();
968
}
969
 
970
 
971
/*---------------------------------------------------------------------------*/
972
/* Flags                                                                     */
973
 
974
void cyg_flag_init(
975
    cyg_flag_t        *flag             /* Flag to init                      */
976
) __THROW
977
{
978
    CYG_ASSERT_SIZES( cyg_flag_t, Cyg_Flag );
979
    CYG_ASSERT(
980
        ( Cyg_Flag::AND == CYG_FLAG_WAITMODE_AND ) &&
981
        ( Cyg_Flag::OR  == CYG_FLAG_WAITMODE_OR  ) &&
982
        ( Cyg_Flag::CLR == CYG_FLAG_WAITMODE_CLR ),
983
        "CYG_FLAG_WAITMODE_xxx definition != C++ Cyg_Flag::xxx" );
984
 
985
    Cyg_Flag *t = new((void *)flag) Cyg_Flag();
986
    t=t;
987
}
988
 
989
void cyg_flag_destroy( cyg_flag_t *flag ) __THROW
990
{
991
    ((Cyg_Flag *)flag)->~Cyg_Flag();
992
}
993
 
994
void cyg_flag_setbits( cyg_flag_t *flag, cyg_flag_value_t value) __THROW
995
{
996
    ((Cyg_Flag *)flag)->setbits( value );
997
}
998
 
999
void cyg_flag_maskbits( cyg_flag_t *flag, cyg_flag_value_t value) __THROW
1000
{
1001
    ((Cyg_Flag *)flag)->maskbits( value );
1002
}
1003
 
1004
cyg_flag_value_t cyg_flag_wait( cyg_flag_t        *flag,
1005
                                cyg_flag_value_t   pattern,
1006
                                cyg_flag_mode_t    mode ) __THROW
1007
{
1008
    if ( 0 == pattern || 0 != (mode & ~3) )
1009
        return 0;
1010
    return ((Cyg_Flag *)flag)->wait( pattern, mode );
1011
 
1012
}
1013
 
1014
#ifdef CYGFUN_KERNEL_THREADS_TIMER
1015
cyg_flag_value_t cyg_flag_timed_wait( cyg_flag_t        *flag,
1016
                                      cyg_flag_value_t   pattern,
1017
                                      cyg_flag_mode_t    mode,
1018
                                      cyg_tick_count_t   abstime ) __THROW
1019
{
1020
    if ( 0 == pattern || 0 != (mode & ~3) )
1021
        return 0;
1022
    return ((Cyg_Flag *)flag)->wait( pattern, mode, abstime );
1023
 
1024
}
1025
#endif
1026
 
1027
cyg_flag_value_t cyg_flag_poll( cyg_flag_t         *flag,
1028
                                cyg_flag_value_t    pattern,
1029
                                cyg_flag_mode_t     mode ) __THROW
1030
{
1031
    if ( 0 == pattern || 0 != (mode & ~3) )
1032
        return 0;
1033
    return ((Cyg_Flag *)flag)->poll( pattern, mode );
1034
 
1035
}
1036
 
1037
cyg_flag_value_t cyg_flag_peek( cyg_flag_t *flag ) __THROW
1038
{
1039
    return ((Cyg_Flag *)flag)->peek();
1040
}
1041
 
1042
cyg_bool_t cyg_flag_waiting( cyg_flag_t *flag ) __THROW
1043
{
1044
    return ((Cyg_Flag *)flag)->waiting();
1045
}
1046
 
1047
/*---------------------------------------------------------------------------*/
1048
/* Mutex                                                                     */
1049
 
1050
externC void cyg_mutex_init(
1051
    cyg_mutex_t        *mutex          /* Mutex to init                      */
1052
) __THROW
1053
{
1054
    CYG_ASSERT_SIZES( cyg_mutex_t, Cyg_Mutex );
1055
 
1056
    Cyg_Mutex *m = new((void *)mutex) Cyg_Mutex;
1057
 
1058
    m=m;
1059
}
1060
 
1061
externC void cyg_mutex_destroy( cyg_mutex_t *mutex ) __THROW
1062
{
1063
    ((Cyg_Mutex *)mutex)->~Cyg_Mutex();
1064
}
1065
 
1066
externC cyg_bool_t cyg_mutex_lock( cyg_mutex_t *mutex ) __THROW
1067
{
1068
    return ((Cyg_Mutex *)mutex)->lock();
1069
}
1070
 
1071
externC cyg_bool_t cyg_mutex_trylock( cyg_mutex_t *mutex ) __THROW
1072
{
1073
    return ((Cyg_Mutex *)mutex)->trylock();
1074
}
1075
 
1076
externC void cyg_mutex_unlock( cyg_mutex_t *mutex ) __THROW
1077
{
1078
    ((Cyg_Mutex *)mutex)->unlock();
1079
}
1080
 
1081
externC void cyg_mutex_release( cyg_mutex_t *mutex ) __THROW
1082
{
1083
    ((Cyg_Mutex *)mutex)->release();
1084
}
1085
 
1086
#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_CEILING
1087
externC void cyg_mutex_set_ceiling(
1088
    cyg_mutex_t *mutex,
1089
    cyg_priority_t priority ) __THROW
1090
{
1091
    ((Cyg_Mutex *)mutex)->set_ceiling(priority);
1092
}
1093
#endif
1094
 
1095
#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DYNAMIC
1096
externC void cyg_mutex_set_protocol(
1097
    cyg_mutex_t *mutex,
1098
    enum cyg_mutex_protocol protocol ) __THROW
1099
{
1100
    ((Cyg_Mutex *)mutex)->set_protocol((Cyg_Mutex::cyg_protcol)protocol);
1101
}
1102
#endif
1103
 
1104
/*---------------------------------------------------------------------------*/
1105
/* Condition Variables                                                       */
1106
 
1107
externC void cyg_cond_init(
1108
    cyg_cond_t          *cond,          /* condition variable to init        */
1109
    cyg_mutex_t         *mutex          /* associated mutex                  */
1110
) __THROW
1111
{
1112
    CYG_ASSERT_SIZES( cyg_cond_t, Cyg_Condition_Variable );
1113
 
1114
    Cyg_Condition_Variable *t = new((void *)cond) Cyg_Condition_Variable(
1115
        *(Cyg_Mutex *)mutex);
1116
    t=t;
1117
}
1118
 
1119
externC void cyg_cond_destroy( cyg_cond_t *cond ) __THROW
1120
{
1121
    ((Cyg_Condition_Variable *)cond)->~Cyg_Condition_Variable();
1122
}
1123
 
1124
externC cyg_bool_t cyg_cond_wait( cyg_cond_t *cond ) __THROW
1125
{
1126
    return ((Cyg_Condition_Variable *)cond)->wait();
1127
}
1128
 
1129
externC void cyg_cond_signal( cyg_cond_t *cond ) __THROW
1130
{
1131
    ((Cyg_Condition_Variable *)cond)->signal();
1132
}
1133
 
1134
externC void cyg_cond_broadcast( cyg_cond_t *cond ) __THROW
1135
{
1136
    ((Cyg_Condition_Variable *)cond)->broadcast();
1137
}
1138
 
1139
#ifdef CYGMFN_KERNEL_SYNCH_CONDVAR_TIMED_WAIT
1140
externC cyg_bool_t cyg_cond_timed_wait(
1141
    cyg_cond_t        *cond,
1142
    cyg_tick_count_t  abstime
1143
    ) __THROW
1144
{
1145
    return ((Cyg_Condition_Variable *)cond)->wait(abstime);
1146
}
1147
 
1148
#endif
1149
 
1150
/*---------------------------------------------------------------------------*/
1151
/* Spinlocks                                                                 */
1152
 
1153
externC void cyg_spinlock_init(
1154
    cyg_spinlock_t      *lock,          /* spinlock to initialize            */
1155
    cyg_bool_t          locked          /* init locked or unlocked           */
1156
) __THROW
1157
{
1158
    CYG_ASSERT_SIZES( cyg_spinlock_t, Cyg_SpinLock );
1159
 
1160
    // Create the spinlock in cleared state
1161
    Cyg_SpinLock *t = new((void *)lock) Cyg_SpinLock();
1162
 
1163
    // If the lock is to start locked, then lock it now.
1164
    if( locked )
1165
        t->spin();
1166
}
1167
 
1168
externC void cyg_spinlock_destroy( cyg_spinlock_t *lock ) __THROW
1169
{
1170
    ((Cyg_SpinLock *)lock)->~Cyg_SpinLock();
1171
}
1172
 
1173
externC void cyg_spinlock_spin( cyg_spinlock_t *lock ) __THROW
1174
{
1175
    ((Cyg_SpinLock *)lock)->spin();
1176
}
1177
 
1178
externC void cyg_spinlock_clear( cyg_spinlock_t *lock ) __THROW
1179
{
1180
    ((Cyg_SpinLock *)lock)->clear();
1181
}
1182
 
1183
externC cyg_bool_t cyg_spinlock_try( cyg_spinlock_t *lock ) __THROW
1184
{
1185
    return ((Cyg_SpinLock *)lock)->trylock();
1186
}
1187
 
1188
externC cyg_bool_t cyg_spinlock_test( cyg_spinlock_t *lock ) __THROW
1189
{
1190
    return ((Cyg_SpinLock *)lock)->test();
1191
}
1192
 
1193
externC void cyg_spinlock_spin_intsave( cyg_spinlock_t *lock,
1194
                                cyg_addrword_t *istate ) __THROW
1195
{
1196
    ((Cyg_SpinLock *)lock)->spin_intsave((CYG_INTERRUPT_STATE *)istate);
1197
}
1198
 
1199
externC void cyg_spinlock_clear_intsave( cyg_spinlock_t *lock,
1200
                                 cyg_addrword_t istate ) __THROW
1201
{
1202
    ((Cyg_SpinLock *)lock)->clear_intsave((CYG_INTERRUPT_STATE)istate);
1203
}
1204
 
1205
 
1206
// -------------------------------------------------------------------------
1207
// Check structure sizes.
1208
// This class and constructor get run automatically in debug versions
1209
// of the kernel and check that the structures configured in the C
1210
// code are the same size as the C++ classes they should match.
1211
 
1212
#ifdef CYGPKG_INFRA_DEBUG
1213
 
1214
class Cyg_Check_Structure_Sizes
1215
{
1216
    int dummy;
1217
public:
1218
    Cyg_Check_Structure_Sizes( int x ) __THROW;
1219
 
1220
};
1221
 
1222
#define CYG_CHECK_SIZES(cstruct, cxxstruct)                               \
1223
if( sizeof(cstruct) != sizeof(cxxstruct) )                                \
1224
{                                                                         \
1225
    char *fmt = "Size of C struct " #cstruct                              \
1226
                " != size of C++ struct " #cxxstruct ;                    \
1227
    CYG_TRACE2(1, fmt, sizeof(cstruct) , sizeof(cxxstruct) );             \
1228
    fail = true;                                                          \
1229
    fmt = fmt;                                                            \
1230
}
1231
 
1232
Cyg_Check_Structure_Sizes::Cyg_Check_Structure_Sizes(int x) __THROW
1233
{
1234
    cyg_bool fail = false;
1235
 
1236
    dummy = x+1;
1237
 
1238
    CYG_CHECK_SIZES( cyg_thread, Cyg_Thread );
1239
    CYG_CHECK_SIZES( cyg_interrupt, Cyg_Interrupt );
1240
    CYG_CHECK_SIZES( cyg_counter, Cyg_Counter );
1241
    CYG_CHECK_SIZES( cyg_clock, Cyg_Clock );
1242
    CYG_CHECK_SIZES( cyg_alarm, Cyg_Alarm );
1243
    CYG_CHECK_SIZES( cyg_mbox, Cyg_Mbox );
1244
    CYG_CHECK_SIZES( cyg_sem_t, Cyg_Counting_Semaphore );
1245
    CYG_CHECK_SIZES( cyg_flag_t, Cyg_Flag );
1246
    CYG_CHECK_SIZES( cyg_mutex_t, Cyg_Mutex );
1247
    CYG_CHECK_SIZES( cyg_cond_t, Cyg_Condition_Variable );
1248
    CYG_CHECK_SIZES( cyg_spinlock_t, Cyg_SpinLock );
1249
 
1250
    CYG_ASSERT( !fail, "Size checks failed");
1251
}
1252
 
1253
static Cyg_Check_Structure_Sizes cyg_kapi_check_structure_sizes(1);
1254
 
1255
#endif
1256
 
1257
 
1258
// -------------------------------------------------------------------------
1259
 
1260
#endif
1261
// EOF common/kapi.cxx

powered by: WebSVN 2.1.0

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