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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [hal/] [common/] [current/] [src/] [drv_api.c] - Blame information for rev 786

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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