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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [hal/] [common/] [v2_0/] [src/] [drv_api.c] - Blame information for rev 27

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
//==========================================================================
2
//
3
//      drv_api.c
4
//
5
//      Driver API for non-kernel configurations
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 Red Hat, 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 version.
16
//
17
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
19
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20
// for more details.
21
//
22
// You should have received a copy of the GNU General Public License along
23
// with eCos; if not, write to the Free Software Foundation, Inc.,
24
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25
//
26
// As a special exception, if other files instantiate templates or use macros
27
// or inline functions from this file, or you compile this file and link it
28
// with other works to produce a work based on this file, this file does not
29
// by itself cause the resulting work to be covered by the GNU General Public
30
// License. However the source code for this file must still be made available
31
// in accordance with section (3) of the GNU General Public License.
32
//
33
// This exception does not invalidate any other reasons why a work based on
34
// this file might be covered by the GNU General Public License.
35
//
36
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37
// at http://sources.redhat.com/ecos/ecos-license/
38
// -------------------------------------------
39
//####ECOSGPLCOPYRIGHTEND####
40
//==========================================================================
41
//#####DESCRIPTIONBEGIN####
42
//
43
// Author(s):   Nick Garnett
44
// Date:        1999-02-24
45
// Purpose:     Driver API for non-kernel configurations
46
// Description: These functions are used to support drivers when the kernel
47
//              is not present.
48
//              
49
//              
50
//
51
//####DESCRIPTIONEND####
52
//
53
//==========================================================================
54
 
55
#include <pkgconf/system.h>
56
 
57
#ifndef CYGPKG_KERNEL
58
 
59
#include <cyg/infra/cyg_type.h>
60
#include <cyg/infra/cyg_trac.h>
61
#include <cyg/infra/cyg_ass.h>
62
 
63
#include <pkgconf/hal.h>
64
#include <cyg/hal/drv_api.h>
65
 
66
#include <cyg/hal/hal_arch.h>
67
#include <cyg/hal/hal_intr.h>
68
 
69
//--------------------------------------------------------------------------
70
// Statics
71
 
72
static volatile cyg_int32 isr_disable_counter = 1;  // ISR disable counter
73
 
74
static CYG_INTERRUPT_STATE isr_disable_state;
75
 
76
volatile cyg_int32 dsr_disable_counter  // DSR disable counter
77
                      CYGBLD_ATTRIB_ASM_ALIAS( cyg_scheduler_sched_lock );
78
 
79
static cyg_interrupt* volatile dsr_list;        // List of pending DSRs
80
 
81
#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN
82
 
83
cyg_interrupt *chain_list[CYGNUM_HAL_ISR_COUNT];
84
 
85
#endif
86
 
87
//--------------------------------------------------------------------------
88
// DSR handling functions.
89
// post_dsr() places a DSR on the list of DSRs to be called.
90
// call_dsrs() calls the DSRs.
91
 
92
static void post_dsr( cyg_interrupt *intr )
93
{
94
    CYG_INTERRUPT_STATE old_intr;
95
 
96
    CYG_REPORT_FUNCTION();
97
 
98
    HAL_DISABLE_INTERRUPTS(old_intr);
99
 
100
    if( intr->dsr_count++ == 0 )
101
    {
102
        intr->next_dsr = dsr_list;
103
        dsr_list = intr;
104
    }
105
 
106
    HAL_RESTORE_INTERRUPTS(old_intr);
107
 
108
    CYG_REPORT_RETURN();
109
}
110
 
111
static void call_dsrs(void)
112
{
113
    CYG_REPORT_FUNCTION();
114
 
115
    while( dsr_list != NULL )
116
    {
117
        cyg_interrupt *intr;
118
        cyg_int32 count;
119
        CYG_INTERRUPT_STATE old_intr;
120
 
121
        HAL_DISABLE_INTERRUPTS(old_intr);
122
 
123
        intr = dsr_list;
124
        dsr_list = intr->next_dsr;
125
        count = intr->dsr_count;
126
        intr->dsr_count = 0;
127
 
128
        HAL_RESTORE_INTERRUPTS(old_intr);
129
 
130
        intr->dsr( intr->vector, count, (CYG_ADDRWORD)intr->data );
131
    }
132
 
133
    CYG_REPORT_RETURN();
134
 
135
}
136
 
137
//--------------------------------------------------------------------------
138
// This is referenced from the HAL, although it does not actually get called.
139
 
140
externC void
141
cyg_interrupt_call_pending_DSRs(void)
142
{
143
    call_dsrs();
144
}
145
 
146
 
147
//--------------------------------------------------------------------------
148
// Interrupt end function called from HAL VSR to tidy up. This is where
149
// DSRs will be called if necessary.
150
 
151
externC void
152
interrupt_end(
153
    cyg_uint32          isr_ret,
154
    cyg_interrupt       *intr,
155
    HAL_SavedRegisters  *regs
156
    )
157
{
158
    CYG_REPORT_FUNCTION();
159
 
160
#ifndef CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN
161
 
162
    // Only do this if we are in a non-chained configuration.
163
    // If we are chained, then chain_isr will do the DSR
164
    // posting.
165
 
166
    if( isr_ret & CYG_ISR_CALL_DSR && intr != NULL ) post_dsr(intr);
167
 
168
#endif
169
 
170
    if( dsr_disable_counter == 0 ) call_dsrs();
171
 
172
    CYG_REPORT_RETURN();
173
}
174
 
175
//--------------------------------------------------------------------------
176
// ISR for handling chained interrupts.
177
 
178
#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN
179
 
180
cyg_uint32 chain_isr(cyg_vector_t vector, CYG_ADDRWORD data)
181
{
182
    cyg_interrupt *p = *(cyg_interrupt **)data;
183
    register cyg_uint32 isr_ret = 0;
184
    register cyg_uint32 isr_chain_ret = 0;
185
 
186
    CYG_REPORT_FUNCTION();
187
 
188
    while( p != NULL )
189
    {
190
        if( p->vector == vector )
191
        {
192
            isr_ret = p->isr(vector, p->data);
193
 
194
            isr_chain_ret |= isr_ret;
195
 
196
            if( isr_ret & CYG_ISR_CALL_DSR ) post_dsr(p);
197
 
198
            if( isr_ret & CYG_ISR_HANDLED ) break;
199
        }
200
 
201
        p = p->next;
202
    }
203
 
204
#ifdef HAL_DEFAULT_ISR
205
    if( (isr_chain_ret & (CYG_ISR_CALL_DSR|CYG_ISR_HANDLED)) == 0 )
206
    {
207
        // If we finished the loop for some reason other than that an
208
        // ISR has handled the interrupt, call any default ISR to either
209
        // report the spurious interrupt, or do some other HAL level processing
210
        // such as GDB interrupt detection etc.
211
 
212
        HAL_DEFAULT_ISR( vector, 0 );
213
    }
214
#endif    
215
 
216
    CYG_REPORT_RETURN();
217
 
218
    return isr_ret & CYG_ISR_CALL_DSR;
219
}
220
 
221
#endif
222
 
223
//--------------------------------------------------------------------------
224
// ISR lock. This disables interrupts and keeps a count of the number
225
// times it has been called.
226
 
227
externC void cyg_drv_isr_lock()
228
{
229
    CYG_REPORT_FUNCTION();
230
 
231
    if( isr_disable_counter == 0 )
232
        HAL_DISABLE_INTERRUPTS(isr_disable_state);
233
 
234
    CYG_ASSERT( isr_disable_counter >= 0 , "Disable counter negative");
235
 
236
    isr_disable_counter++;
237
 
238
    CYG_REPORT_RETURN();
239
}
240
 
241
//--------------------------------------------------------------------------
242
// Unlock ISRs. This decrements the count and re-enables interrupts if it
243
// goes zero.
244
 
245
externC void cyg_drv_isr_unlock()
246
{
247
    CYG_REPORT_FUNCTION();
248
 
249
    CYG_ASSERT( isr_disable_counter > 0 , "Disable counter not greater than zero");
250
 
251
    isr_disable_counter--;
252
 
253
    if ( isr_disable_counter == 0 )
254
    {
255
        HAL_RESTORE_INTERRUPTS(isr_disable_state);
256
    }
257
 
258
    CYG_REPORT_RETURN();
259
}
260
 
261
//--------------------------------------------------------------------------
262
// Lock DSR lock. Simply increment the counter.
263
 
264
externC void cyg_drv_dsr_lock()
265
{
266
    CYG_REPORT_FUNCTION();
267
 
268
    dsr_disable_counter++;
269
 
270
    CYG_REPORT_RETURN();
271
}
272
 
273
//--------------------------------------------------------------------------
274
// Unlock DSR lock. If the counter is about to go zero, call any pending
275
// DSRs and then zero the counter.
276
 
277
externC void cyg_drv_dsr_unlock()
278
{
279
    CYG_REPORT_FUNCTION();
280
 
281
    do
282
    {
283
        if( dsr_disable_counter == 1 )
284
        {
285
            call_dsrs();
286
        }
287
 
288
        HAL_REORDER_BARRIER();
289
 
290
        dsr_disable_counter = 0;
291
 
292
        HAL_REORDER_BARRIER();
293
 
294
        // Check that no DSRs have been posted between calling
295
        // call_dsrs() and zeroing dsr_disable_counter. If so,
296
        // loop back and call them.
297
 
298
        if( dsr_list != NULL )
299
        {
300
            dsr_disable_counter = 1;
301
            continue;
302
        }
303
 
304
        CYG_REPORT_RETURN();
305
 
306
        return;
307
 
308
    } while(1);
309
 
310
    CYG_FAIL( "Should not be executed" );
311
}
312
 
313
//--------------------------------------------------------------------------
314
// Initialize a mutex.
315
 
316
externC void cyg_drv_mutex_init( cyg_drv_mutex_t *mutex )
317
{
318
    CYG_REPORT_FUNCTION();
319
 
320
    mutex->lock = 0;
321
 
322
    CYG_REPORT_RETURN();
323
}
324
 
325
//--------------------------------------------------------------------------
326
// Destroy a mutex.
327
 
328
externC void cyg_drv_mutex_destroy( cyg_drv_mutex_t *mutex )
329
{
330
    CYG_REPORT_FUNCTION();
331
 
332
    mutex->lock = -1;
333
 
334
    CYG_REPORT_RETURN();
335
}
336
 
337
//--------------------------------------------------------------------------
338
// Lock a mutex. We check that we are not trying to lock a locked or
339
// destroyed mutex and if not, set it locked.
340
 
341
externC cyg_bool_t cyg_drv_mutex_lock( cyg_drv_mutex_t *mutex )
342
{
343
    CYG_REPORT_FUNCTION();
344
 
345
    CYG_ASSERT( mutex->lock == 0 , "Trying to lock locked mutex");
346
 
347
    mutex->lock = 1;
348
 
349
    CYG_REPORT_RETURN();
350
 
351
    return true;
352
}
353
 
354
//--------------------------------------------------------------------------
355
// Attempt to claim a mutex, and return if it cannot be.
356
 
357
externC cyg_bool_t cyg_drv_mutex_trylock( cyg_drv_mutex_t *mutex )
358
{
359
    cyg_bool_t result = true;
360
 
361
    CYG_REPORT_FUNCTION();
362
 
363
    if( mutex->lock == 1 ) result = false;
364
 
365
    mutex->lock = 1;
366
 
367
    CYG_REPORT_RETURN();
368
 
369
    return result;
370
}
371
 
372
//--------------------------------------------------------------------------
373
// Unlock a mutex. We check that the mutex is actually locked before doing
374
// this.
375
 
376
externC void cyg_drv_mutex_unlock( cyg_drv_mutex_t *mutex )
377
{
378
    CYG_REPORT_FUNCTION();
379
 
380
    CYG_ASSERT( mutex->lock == 1 , "Trying to unlock unlocked mutex");
381
 
382
    mutex->lock = 0;
383
 
384
    CYG_REPORT_RETURN();
385
}
386
 
387
//--------------------------------------------------------------------------
388
// Release all threads waiting for the mutex.
389
// This is really for threads, so we do nothing here.
390
 
391
externC void cyg_drv_mutex_release( cyg_drv_mutex_t *mutex )
392
{
393
    CYG_REPORT_FUNCTION();
394
 
395
 
396
 
397
    CYG_REPORT_RETURN();
398
}
399
 
400
 
401
//--------------------------------------------------------------------------
402
// Initialized a condition variable.
403
 
404
externC void cyg_drv_cond_init( cyg_drv_cond_t  *cond, cyg_drv_mutex_t *mutex )
405
{
406
    CYG_REPORT_FUNCTION();
407
 
408
    cond->wait = 0;
409
    cond->mutex = mutex;
410
 
411
    CYG_REPORT_RETURN();
412
}
413
 
414
 
415
//--------------------------------------------------------------------------
416
// Destroy a condition variable.
417
 
418
externC void cyg_drv_cond_destroy( cyg_drv_cond_t  *cond )
419
{
420
    CYG_REPORT_FUNCTION();
421
 
422
    cond->wait = -1;
423
    cond->mutex = NULL;
424
 
425
    CYG_REPORT_RETURN();
426
}
427
 
428
// -------------------------------------------------------------------------
429
// Wait for a condition variable to be signalled. We simply busy wait
430
// polling the condition variable's wait member until a DSR sets it to
431
// 0.  Note that the semantics of condition variables means that the
432
// wakeup only happens if there is a thread actually waiting on the CV
433
// when the signal is sent.
434
 
435
externC cyg_bool cyg_drv_cond_wait( cyg_drv_cond_t *cond )
436
{
437
    CYG_REPORT_FUNCTION();
438
 
439
    CYG_ASSERT( cond->mutex != NULL, "Uninitialized condition variable");
440
    CYG_ASSERT( cond->mutex->lock, "Mutex not locked");
441
 
442
    cyg_drv_dsr_lock();
443
 
444
    cond->wait = 1;
445
 
446
    while( cond->wait == 1 )
447
    {
448
        // While looping we call call_dsrs() to service any DSRs that
449
        // get posted. One of these will make the call to cond_signal
450
        // to break us out of this loop. If we do not have the DSR
451
        // lock claimed, then a race condition could occur and keep us
452
        // stuck here forever.
453
 
454
        call_dsrs();
455
    }
456
 
457
    cyg_drv_dsr_unlock();
458
 
459
    CYG_REPORT_RETURN();
460
 
461
    return true;
462
}
463
 
464
//--------------------------------------------------------------------------
465
// Signal a condition variable. This sets the wait member to zero, which
466
// has no effect when there is no waiter, but will wake up any waiting
467
// thread.
468
 
469
externC void cyg_drv_cond_signal( cyg_drv_cond_t *cond )
470
{
471
    CYG_REPORT_FUNCTION();
472
 
473
    cond->wait = 0;
474
 
475
    CYG_REPORT_RETURN();
476
}
477
 
478
 
479
//--------------------------------------------------------------------------
480
// Broadcast to condition variable. This is exactly the same a signal since
481
// there can only be one waiter.
482
 
483
externC void cyg_drv_cond_broadcast( cyg_drv_cond_t *cond )
484
{
485
    CYG_REPORT_FUNCTION();
486
 
487
    cond->wait = 0;
488
 
489
    CYG_REPORT_RETURN();
490
}
491
 
492
//--------------------------------------------------------------------------
493
// Spinlock support.
494
// Since we can only support a single CPU in this version of the API, we only
495
// set and clear the lock variable to keep track of what's happening.
496
 
497
void cyg_drv_spinlock_init(
498
    cyg_drv_spinlock_t  *lock,          /* spinlock to initialize            */
499
    cyg_bool_t          locked          /* init locked or unlocked           */
500
)
501
{
502
    CYG_REPORT_FUNCTION();
503
 
504
    lock->lock = locked;
505
 
506
    CYG_REPORT_RETURN();
507
}
508
 
509
void cyg_drv_spinlock_destroy( cyg_drv_spinlock_t *lock )
510
{
511
    CYG_REPORT_FUNCTION();
512
 
513
    lock->lock = -1;
514
 
515
    CYG_REPORT_RETURN();
516
}
517
 
518
void cyg_drv_spinlock_spin( cyg_drv_spinlock_t *lock )
519
{
520
    CYG_REPORT_FUNCTION();
521
 
522
    CYG_ASSERT( lock->lock == 0 , "Trying to lock locked spinlock");
523
 
524
    lock->lock = 1;
525
 
526
    CYG_REPORT_RETURN();
527
}
528
 
529
void cyg_drv_spinlock_clear( cyg_drv_spinlock_t *lock )
530
{
531
    CYG_REPORT_FUNCTION();
532
 
533
    CYG_ASSERT( lock->lock == 1 , "Trying to clear cleared spinlock");
534
 
535
    lock->lock = 0;
536
 
537
    CYG_REPORT_RETURN();
538
}
539
 
540
cyg_bool_t cyg_drv_spinlock_try( cyg_drv_spinlock_t *lock )
541
{
542
    cyg_bool_t result = true;
543
 
544
    CYG_REPORT_FUNCTION();
545
 
546
    if( lock->lock == 1 ) result = false;
547
 
548
    lock->lock = 1;
549
 
550
    CYG_REPORT_RETURN();
551
 
552
    return result;
553
}
554
 
555
cyg_bool_t cyg_drv_spinlock_test( cyg_drv_spinlock_t *lock )
556
{
557
    cyg_bool_t result = true;
558
 
559
    CYG_REPORT_FUNCTION();
560
 
561
    if( lock->lock == 1 ) result = false;
562
 
563
    CYG_REPORT_RETURN();
564
 
565
    return result;
566
}
567
 
568
void cyg_drv_spinlock_spin_intsave( cyg_drv_spinlock_t *lock,
569
                                    cyg_addrword_t *istate )
570
{
571
    CYG_REPORT_FUNCTION();
572
 
573
    HAL_DISABLE_INTERRUPTS( *istate );
574
 
575
    lock->lock = 1;
576
 
577
    CYG_REPORT_RETURN();
578
}
579
 
580
 
581
void cyg_drv_spinlock_clear_intsave( cyg_drv_spinlock_t *lock,
582
                                     cyg_addrword_t istate )
583
{
584
    CYG_REPORT_FUNCTION();
585
 
586
    lock->lock = 0;
587
 
588
    HAL_RESTORE_INTERRUPTS( istate );
589
 
590
    CYG_REPORT_RETURN();
591
}
592
 
593
//--------------------------------------------------------------------------
594
// Create an interrupt object.
595
 
596
externC void cyg_drv_interrupt_create(
597
                     cyg_vector_t        vector,
598
                     cyg_priority_t      priority,
599
                     cyg_addrword_t      data,
600
                     cyg_ISR_t           *isr,
601
                     cyg_DSR_t           *dsr,
602
                     cyg_handle_t        *handle,
603
                     cyg_interrupt       *intr
604
                     )
605
{
606
    CYG_REPORT_FUNCTION();
607
 
608
    intr->vector        = vector;
609
    intr->priority      = priority;
610
    intr->isr           = isr;
611
    intr->dsr           = dsr;
612
    intr->data          = data;
613
    intr->next_dsr      = NULL;
614
    intr->dsr_count     = 0;
615
 
616
#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN
617
 
618
    intr->next          = NULL;
619
 
620
#endif    
621
 
622
    *handle = (cyg_handle_t)intr;
623
 
624
    CYG_REPORT_RETURN();
625
}
626
 
627
//--------------------------------------------------------------------------
628
// Delete an interrupt object. This merely ensures that it is detached from
629
// the vector.
630
 
631
externC void cyg_drv_interrupt_delete( cyg_handle_t interrupt )
632
{
633
    CYG_REPORT_FUNCTION();
634
 
635
    cyg_drv_interrupt_detach( interrupt );
636
 
637
    CYG_REPORT_RETURN();
638
}
639
 
640
//--------------------------------------------------------------------------
641
// 
642
 
643
externC void cyg_drv_interrupt_attach( cyg_handle_t interrupt )
644
{
645
    cyg_interrupt *intr = (cyg_interrupt *)interrupt;
646
 
647
    CYG_REPORT_FUNCTION();
648
 
649
    CYG_ASSERT( intr->vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
650
    CYG_ASSERT( intr->vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
651
 
652
    HAL_INTERRUPT_SET_LEVEL( intr->vector, intr->priority );
653
 
654
#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN
655
 
656
    CYG_ASSERT( intr->next == NULL , "cyg_interrupt already on a list");
657
 
658
    {
659
        cyg_uint32 index;
660
 
661
        HAL_TRANSLATE_VECTOR( intr->vector, index );
662
 
663
        if( chain_list[index] == NULL )
664
        {
665
            // First Interrupt on this chain, just assign it and
666
            // register the chain_isr with the HAL.
667
 
668
            chain_list[index] = intr;
669
 
670
            HAL_INTERRUPT_ATTACH( intr->vector, chain_isr,
671
                                  &chain_list[index], NULL );
672
        }
673
        else
674
        {
675
            // There are already interrupts chained, add this one into
676
            // the chain in priority order.
677
 
678
            cyg_interrupt **p = &chain_list[index];
679
 
680
            while( *p != NULL )
681
            {
682
                cyg_interrupt *n = *p;
683
 
684
                if( n->priority < intr->priority ) break;
685
 
686
                p = &n->next;
687
            }
688
            intr->next = *p;
689
            *p = intr;
690
        }
691
    }
692
 
693
#else
694
 
695
    HAL_INTERRUPT_ATTACH( intr->vector, intr->isr, intr->data, intr );
696
 
697
#endif    
698
 
699
    CYG_REPORT_RETURN();
700
}
701
 
702
 
703
//--------------------------------------------------------------------------
704
// Detach an interrupt from its vector.
705
 
706
externC void cyg_drv_interrupt_detach( cyg_handle_t interrupt )
707
{
708
    cyg_interrupt *intr = (cyg_interrupt *)interrupt;
709
 
710
    CYG_REPORT_FUNCTION();
711
 
712
    CYG_ASSERT( intr->vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
713
    CYG_ASSERT( intr->vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
714
 
715
#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN
716
 
717
    // Remove the interrupt object from the vector chain.
718
 
719
    {
720
        cyg_uint32 index;
721
        cyg_interrupt **p;
722
 
723
        HAL_TRANSLATE_VECTOR( intr->vector, index );
724
 
725
        p = &chain_list[index];
726
 
727
        while( *p != NULL )
728
        {
729
            cyg_interrupt *n = *p;
730
 
731
            if( n == intr )
732
            {
733
                *p = intr->next;
734
                break;
735
            }
736
 
737
            p = &n->next;
738
        }
739
 
740
        // If this was the last one, detach the vector.
741
 
742
        if( chain_list[index] == NULL )
743
            HAL_INTERRUPT_DETACH( intr->vector, chain_isr );
744
    }
745
 
746
#else
747
 
748
    HAL_INTERRUPT_DETACH( intr->vector, intr->isr );
749
 
750
#endif
751
 
752
    CYG_REPORT_RETURN();
753
}
754
 
755
 
756
//--------------------------------------------------------------------------
757
// Mask delivery of an interrupt at the interrupt controller.
758
// (Interrupt safe)
759
 
760
externC void cyg_drv_interrupt_mask( cyg_vector_t vector )
761
{
762
    CYG_INTERRUPT_STATE old_ints;
763
 
764
    CYG_REPORT_FUNCTION();
765
    CYG_REPORT_FUNCARG1("vector=%d", vector);
766
 
767
    CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
768
    CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
769
 
770
    HAL_DISABLE_INTERRUPTS(old_ints);
771
    HAL_INTERRUPT_MASK( vector );
772
    HAL_RESTORE_INTERRUPTS(old_ints);
773
 
774
    CYG_REPORT_RETURN();
775
}
776
 
777
//--------------------------------------------------------------------------
778
// Mask delivery of an interrupt at the interrupt controller.
779
// (Not interrupt safe)
780
 
781
externC void cyg_drv_interrupt_mask_intunsafe( cyg_vector_t vector )
782
{
783
    CYG_REPORT_FUNCTION();
784
    CYG_REPORT_FUNCARG1("vector=%d", vector);
785
 
786
    CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
787
    CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
788
 
789
    HAL_INTERRUPT_MASK( vector );
790
 
791
    CYG_REPORT_RETURN();
792
}
793
 
794
//--------------------------------------------------------------------------
795
// Unmask delivery of an interrupt at the interrupt controller.
796
// (Interrupt safe)
797
 
798
externC void cyg_drv_interrupt_unmask( cyg_vector_t vector )
799
{
800
    CYG_INTERRUPT_STATE old_ints;
801
 
802
    CYG_REPORT_FUNCTION();
803
    CYG_REPORT_FUNCARG1("vector=%d", vector);
804
 
805
    CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
806
    CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
807
 
808
    HAL_DISABLE_INTERRUPTS(old_ints);
809
    HAL_INTERRUPT_UNMASK( vector );
810
    HAL_RESTORE_INTERRUPTS(old_ints);
811
 
812
    CYG_REPORT_RETURN();
813
}
814
 
815
//--------------------------------------------------------------------------
816
// Unmask delivery of an interrupt at the interrupt controller.
817
// (Not interrupt safe)
818
 
819
externC void cyg_drv_interrupt_unmask_intunsafe( cyg_vector_t vector )
820
{
821
    CYG_REPORT_FUNCTION();
822
    CYG_REPORT_FUNCARG1("vector=%d", vector);
823
 
824
    CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
825
    CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
826
 
827
    HAL_INTERRUPT_UNMASK( vector );
828
 
829
    CYG_REPORT_RETURN();
830
}
831
 
832
//--------------------------------------------------------------------------
833
// Acknowledge an interrupt at the controller to allow another interrupt
834
// to be delivered.
835
 
836
externC void cyg_drv_interrupt_acknowledge( cyg_vector_t vector )
837
{
838
//    CYG_REPORT_FUNCTION();
839
 
840
    CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
841
    CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
842
 
843
    HAL_INTERRUPT_ACKNOWLEDGE( vector );
844
 
845
//    CYG_REPORT_RETURN();    
846
}
847
 
848
//--------------------------------------------------------------------------
849
// Configure interrupt detection parameters.
850
 
851
externC void cyg_drv_interrupt_configure(
852
                     cyg_vector_t        vector,
853
                     cyg_bool_t          level,
854
                     cyg_bool_t          up
855
                     )
856
{
857
    CYG_REPORT_FUNCTION();
858
    CYG_REPORT_FUNCARG3("vector = %d, level = %d, up = %d", vector, level,
859
                        up);
860
 
861
    CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
862
    CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
863
 
864
    HAL_INTERRUPT_CONFIGURE( vector, level, up );
865
 
866
    CYG_REPORT_RETURN();
867
}
868
 
869
//--------------------------------------------------------------------------
870
// Configure interrupt priority level.
871
 
872
externC void cyg_drv_interrupt_level( cyg_vector_t vector, cyg_priority_t level )
873
{
874
    CYG_REPORT_FUNCTION();
875
    CYG_REPORT_FUNCARG2("vector = %d, level = %d", vector, level);
876
 
877
    CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
878
    CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
879
 
880
    HAL_INTERRUPT_SET_LEVEL( vector, level );
881
 
882
    CYG_REPORT_RETURN();
883
}
884
 
885
// -------------------------------------------------------------------------
886
// CPU interrupt routing
887
 
888
externC void cyg_drv_interrupt_set_cpu( cyg_vector_t vector, cyg_cpu_t cpu )
889
{
890
    CYG_REPORT_FUNCTION();
891
    CYG_REPORT_FUNCARG2("vector = %d, cpu = %d", vector, cpu);
892
 
893
    CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
894
    CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
895
 
896
#ifdef CYGPKG_HAL_SMP_SUPPORT    
897
    HAL_INTERRUPT_SET_CPU( vector, cpu );
898
#endif
899
 
900
    CYG_REPORT_RETURN();
901
}
902
 
903
externC cyg_cpu_t cyg_drv_interrupt_get_cpu( cyg_vector_t vector )
904
{
905
    cyg_cpu_t cpu = 0;
906
 
907
    CYG_REPORT_FUNCTION();
908
    CYG_REPORT_FUNCARG1("vector = %d", vector);
909
 
910
    CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
911
    CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
912
 
913
#ifdef CYGPKG_HAL_SMP_SUPPORT    
914
    HAL_INTERRUPT_GET_CPU( vector, cpu );
915
#endif
916
 
917
    CYG_REPORT_RETURN();
918
 
919
    return cpu;
920
}
921
 
922
// -------------------------------------------------------------------------
923
// Exception delivery function called from the HAL as a result of a
924
// hardware exception being raised.
925
 
926
externC void cyg_hal_deliver_exception( CYG_WORD code, CYG_ADDRWORD data )
927
{
928
    CYG_FAIL(" !!! Exception !!! ");
929
}
930
 
931
 
932
#endif
933
 
934
//--------------------------------------------------------------------------
935
// EOF drv_api.c

powered by: WebSVN 2.1.0

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