source: SVN/cambria/redboot/packages/hal/common/current/src/drv_api.c @ 1

Last change on this file since 1 was 1, checked in by Tim Harvey, 2 years ago

restored latest version of files from server backup

Signed-off-by: Tim Harvey <tharvey@…>

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