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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [kernel/] [v2_0/] [src/] [intr/] [intr.cxx] - Blame information for rev 174

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
//==========================================================================
2
//
3
//      intr/intr.cxx
4
//
5
//      Interrupt class implementations
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):    nickg
44
// Contributors: nickg
45
// Date:         1999-02-17
46
// Purpose:      Interrupt class implementation
47
// Description:  This file contains the definitions of the interrupt
48
//               class.
49
//
50
//####DESCRIPTIONEND####
51
//
52
//==========================================================================
53
 
54
#include <pkgconf/kernel.h>
55
 
56
#include <cyg/kernel/ktypes.h>             // base kernel types
57
#include <cyg/infra/cyg_trac.h>           // tracing macros
58
#include <cyg/infra/cyg_ass.h>            // assertion macros
59
#include <cyg/kernel/instrmnt.h>           // instrumentation
60
 
61
#include <cyg/kernel/intr.hxx>             // our header
62
 
63
#include <cyg/kernel/sched.hxx>            // scheduler
64
 
65
#include <cyg/kernel/sched.inl>
66
 
67
// -------------------------------------------------------------------------
68
// Statics
69
 
70
volatile cyg_int32 Cyg_Interrupt::disable_counter[CYGNUM_KERNEL_CPU_MAX];
71
 
72
Cyg_SpinLock Cyg_Interrupt::interrupt_disable_spinlock CYG_INIT_PRIORITY( INTERRUPTS );
73
 
74
CYG_INTERRUPT_STATE Cyg_Interrupt::interrupt_disable_state[CYGNUM_KERNEL_CPU_MAX];
75
 
76
// -------------------------------------------------------------------------
77
 
78
Cyg_Interrupt::Cyg_Interrupt(
79
    cyg_vector      vec,                // Vector to attach to
80
    cyg_priority    pri,                // Queue priority
81
    CYG_ADDRWORD    d,                  // Data pointer
82
    cyg_ISR         *ir,                // Interrupt Service Routine
83
    cyg_DSR         *dr                 // Deferred Service Routine
84
    )
85
{
86
    CYG_REPORT_FUNCTION();
87
    CYG_REPORT_FUNCARG5("vector=%d, priority=%d, data=%08x, isr=%08x, "
88
                        "dsr=%08x", vec, pri, d, ir, dr);
89
 
90
    vector      = vec;
91
    priority    = pri;
92
    isr         = ir;
93
    dsr         = dr;
94
    data        = d;
95
 
96
#ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_LIST
97
 
98
    dsr_count   = 0;
99
    next_dsr    = NULL;
100
 
101
#endif
102
 
103
#ifdef CYGIMP_KERNEL_INTERRUPTS_CHAIN
104
 
105
    next        = NULL;
106
 
107
#endif
108
 
109
    CYG_REPORT_RETURN();
110
 
111
};
112
 
113
// -------------------------------------------------------------------------
114
 
115
Cyg_Interrupt::~Cyg_Interrupt()
116
{
117
    CYG_REPORT_FUNCTION();
118
    detach();
119
    CYG_REPORT_RETURN();
120
};
121
 
122
// -------------------------------------------------------------------------
123
// DSR handling statics:
124
 
125
#ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_TABLE
126
 
127
Cyg_Interrupt *
128
Cyg_Interrupt::dsr_table[CYGNUM_KERNEL_CPU_MAX][CYGNUM_KERNEL_INTERRUPTS_DSRS_TABLE_SIZE];
129
 
130
cyg_ucount32 Cyg_Interrupt::dsr_table_head[CYGNUM_KERNEL_CPU_MAX];
131
 
132
volatile cyg_ucount32 Cyg_Interrupt::dsr_table_tail[CYGNUM_KERNEL_CPU_MAX];
133
 
134
#endif
135
 
136
#ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_LIST
137
 
138
Cyg_Interrupt* volatile Cyg_Interrupt::dsr_list[CYGNUM_KERNEL_CPU_MAX];
139
 
140
#endif
141
 
142
// -------------------------------------------------------------------------
143
// Call any pending DSRs
144
 
145
void
146
Cyg_Interrupt::call_pending_DSRs_inner(void)
147
{
148
//    CYG_REPORT_FUNCTION();
149
 
150
    HAL_SMP_CPU_TYPE cpu = CYG_KERNEL_CPU_THIS();
151
 
152
#ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_TABLE    
153
 
154
    while( dsr_table_head[cpu] != dsr_table_tail[cpu] )
155
    {
156
        Cyg_Interrupt *intr = dsr_table[cpu][dsr_table_head[cpu]];
157
 
158
        dsr_table_head[cpu]++;
159
        if( dsr_table_head[cpu] >= CYGNUM_KERNEL_INTERRUPTS_DSRS_TABLE_SIZE )
160
            dsr_table_head[cpu] = 0;
161
 
162
        CYG_INSTRUMENT_INTR(CALL_DSR, intr->vector, 0);
163
 
164
        CYG_ASSERT( intr->dsr != NULL , "No DSR defined");
165
 
166
        intr->dsr( intr->vector, 1, (CYG_ADDRWORD)intr->data );
167
    }
168
 
169
#endif
170
 
171
#ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_LIST
172
 
173
    while( dsr_list[cpu] != NULL )
174
    {
175
        Cyg_Interrupt* intr;
176
        cyg_uint32 old_intr;
177
        cyg_count32 count;
178
 
179
        HAL_DISABLE_INTERRUPTS(old_intr);
180
 
181
        intr = dsr_list[cpu];
182
        dsr_list[cpu] = intr->next_dsr;
183
        count = intr->dsr_count;
184
        intr->dsr_count = 0;
185
 
186
        HAL_RESTORE_INTERRUPTS(old_intr);
187
 
188
        CYG_ASSERT( intr->dsr != NULL , "No DSR defined");
189
 
190
        intr->dsr( intr->vector, count, (CYG_ADDRWORD)intr->data );
191
 
192
    }
193
 
194
#endif
195
 
196
};
197
 
198
externC void
199
cyg_interrupt_call_pending_DSRs(void)
200
{
201
    Cyg_Interrupt::call_pending_DSRs_inner();
202
}
203
 
204
//
205
// Use HAL supported function to run through the DSRs, but executing using
206
// the separate interrupt stack if available.  This function calls back
207
// into this module via 'cyg_interrupt_call_pending_DSRs' above, to keep
208
// the whole process as general as possible.
209
 
210
void
211
Cyg_Interrupt::call_pending_DSRs(void)
212
{
213
    CYG_ASSERT( Cyg_Scheduler::get_sched_lock() == 1,
214
                "DSRs being called with sched_lock not equal to 1");
215
    HAL_INTERRUPT_STACK_CALL_PENDING_DSRS();
216
}
217
 
218
 
219
// -------------------------------------------------------------------------
220
 
221
void
222
Cyg_Interrupt::post_dsr(void)
223
{
224
//    CYG_REPORT_FUNCTION();
225
    HAL_SMP_CPU_TYPE cpu = CYG_KERNEL_CPU_THIS();
226
 
227
    CYG_INSTRUMENT_INTR(POST_DSR, vector, 0);
228
 
229
    cyg_uint32 old_intr;
230
 
231
    // We need to disable interrupts during this part to
232
    // guard against nested interrupts.
233
 
234
    HAL_DISABLE_INTERRUPTS(old_intr);
235
 
236
#ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_TABLE
237
 
238
    dsr_table[cpu][dsr_table_tail[cpu]++] = this;
239
    if( dsr_table_tail[cpu] >= CYGNUM_KERNEL_INTERRUPTS_DSRS_TABLE_SIZE )
240
        dsr_table_tail[cpu] = 0;
241
 
242
#endif
243
 
244
#ifdef CYGIMP_KERNEL_INTERRUPTS_DSRS_LIST
245
 
246
    // Only add the interrupt to the dsr list if this is
247
    // the first DSR call.
248
    // At present DSRs are pushed onto the list and will be
249
    // called in reverse order. We do not define the order
250
    // in which DSRs are called, so this is acceptable.
251
 
252
    if( dsr_count++ == 0 )
253
    {
254
        next_dsr = dsr_list[cpu];
255
        dsr_list[cpu] = this;
256
    }
257
 
258
#endif
259
 
260
    HAL_RESTORE_INTERRUPTS(old_intr);
261
};
262
 
263
// -------------------------------------------------------------------------
264
// A C callable interface to Cyg_Interrupt::post_dsr() that can be used from
265
// the HAL.
266
 
267
externC void
268
cyg_interrupt_post_dsr( CYG_ADDRWORD intr_obj )
269
{
270
    Cyg_Interrupt* intr = (Cyg_Interrupt*) intr_obj;
271
    intr->post_dsr ();
272
}
273
 
274
// -------------------------------------------------------------------------
275
 
276
// FIXME: should have better name - Jifl
277
externC void
278
interrupt_end(
279
    cyg_uint32          isr_ret,
280
    Cyg_Interrupt       *intr,
281
    HAL_SavedRegisters  *regs
282
    )
283
{
284
//    CYG_REPORT_FUNCTION();
285
 
286
#ifdef CYGPKG_KERNEL_SMP_SUPPORT
287
    Cyg_Scheduler::lock();
288
#endif
289
 
290
    // Sometimes we have a NULL intr object pointer.
291
    cyg_vector vector = (intr!=NULL)?intr->vector:0;
292
 
293
    CYG_INSTRUMENT_INTR(END, vector, isr_ret);
294
 
295
    CYG_UNUSED_PARAM( cyg_vector, vector ); // prevent compiler warning
296
 
297
#ifndef CYGIMP_KERNEL_INTERRUPTS_CHAIN
298
 
299
    // Only do this if we are in a non-chained configuration.
300
    // If we are chained, then chain_isr below will do the DSR
301
    // posting.
302
 
303
    if( isr_ret & Cyg_Interrupt::CALL_DSR && intr != NULL ) intr->post_dsr();
304
 
305
#endif    
306
 
307
#ifdef CYGDBG_KERNEL_DEBUG_GDB_THREAD_SUPPORT
308
 
309
    // If we have GDB support enabled, and there is the possibility
310
    // that this thread will be context switched as a result of this
311
    // interrupt, then save the pointer to the saved thread context in
312
    // the thread object so that GDB can get a meaningful context to
313
    // look at.
314
 
315
    Cyg_Scheduler::get_current_thread()->set_saved_context(regs);
316
 
317
#endif    
318
 
319
    // Now unlock the scheduler, which may also call DSRs
320
    // and cause a thread switch to happen.
321
 
322
    Cyg_Scheduler::unlock();
323
 
324
#ifdef CYGDBG_KERNEL_DEBUG_GDB_THREAD_SUPPORT
325
 
326
    Cyg_Scheduler::get_current_thread()->set_saved_context(0);
327
 
328
#endif    
329
 
330
    CYG_INSTRUMENT_INTR(RESTORE, vector, 0);
331
}
332
 
333
// -------------------------------------------------------------------------
334
// Interrupt chaining statics.
335
 
336
#ifdef CYGIMP_KERNEL_INTERRUPTS_CHAIN
337
 
338
Cyg_Interrupt *Cyg_Interrupt::chain_list[CYGNUM_HAL_ISR_TABLE_SIZE];
339
 
340
#endif
341
 
342
// -------------------------------------------------------------------------
343
// Chaining ISR inserted in HAL vector
344
 
345
#ifdef CYGIMP_KERNEL_INTERRUPTS_CHAIN
346
 
347
cyg_uint32
348
Cyg_Interrupt::chain_isr(cyg_vector vector, CYG_ADDRWORD data)
349
{
350
    Cyg_Interrupt *p = *(Cyg_Interrupt **)data;
351
    register cyg_uint32 isr_ret = 0;
352
    register cyg_uint32 isr_chain_ret = 0;
353
 
354
    CYG_INSTRUMENT_INTR(CHAIN_ISR, vector, 0);
355
 
356
    while( p != NULL )
357
    {
358
        if( p->vector == vector )
359
        {
360
            isr_ret = p->isr(vector, p->data);
361
 
362
            isr_chain_ret |= isr_ret;
363
 
364
            if( isr_ret & Cyg_Interrupt::CALL_DSR ) p->post_dsr();
365
 
366
            if( isr_ret & Cyg_Interrupt::HANDLED ) break;
367
        }
368
 
369
        p = p->next;
370
    }
371
 
372
#ifdef HAL_DEFAULT_ISR
373
    if( (isr_chain_ret & (Cyg_Interrupt::HANDLED|Cyg_Interrupt::CALL_DSR)) == 0 )
374
    {
375
        // If we finished the loop for some reason other than that an
376
        // ISR has handled the interrupt, call any default ISR to either
377
        // report the spurious interrupt, or do some other HAL level processing
378
        // such as GDB interrupt detection etc.
379
 
380
        HAL_DEFAULT_ISR( vector, 0 );
381
    }
382
#endif    
383
 
384
    return isr_ret & ~Cyg_Interrupt::CALL_DSR;
385
}
386
 
387
#endif
388
 
389
// -------------------------------------------------------------------------
390
// Attach an ISR to an interrupt vector.
391
 
392
void
393
Cyg_Interrupt::attach(void)
394
{
395
    CYG_REPORT_FUNCTION();
396
 
397
    CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
398
    CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
399
 
400
    CYG_INSTRUMENT_INTR(ATTACH, vector, 0);
401
 
402
    HAL_INTERRUPT_SET_LEVEL( vector, priority );
403
 
404
#ifdef CYGIMP_KERNEL_INTERRUPTS_CHAIN
405
 
406
    CYG_ASSERT( next == NULL , "Cyg_Interrupt already on a list");
407
 
408
    cyg_uint32 index;
409
 
410
    HAL_TRANSLATE_VECTOR( vector, index );
411
 
412
    if( chain_list[index] == NULL )
413
    {
414
        int in_use;
415
        // First Interrupt on this chain, just assign it and register
416
        // the chain_isr with the HAL.
417
 
418
        chain_list[index] = this;
419
 
420
        HAL_INTERRUPT_IN_USE( vector, in_use );
421
        CYG_ASSERT( 0 == in_use, "Interrupt vector not free.");
422
        HAL_INTERRUPT_ATTACH( vector, chain_isr, &chain_list[index], NULL );
423
    }
424
    else
425
    {
426
        // There are already interrupts chained, add this one into the
427
        // chain in priority order.
428
 
429
        Cyg_Interrupt **p = &chain_list[index];
430
 
431
        while( *p != NULL )
432
        {
433
            Cyg_Interrupt *n = *p;
434
 
435
            if( n->priority < priority ) break;
436
 
437
            p = &n->next;
438
        }
439
        next = *p;
440
        *p = this;
441
    }
442
 
443
#else
444
 
445
    {
446
        int in_use;
447
 
448
 
449
        HAL_INTERRUPT_IN_USE( vector, in_use );
450
        CYG_ASSERT( 0 == in_use, "Interrupt vector not free.");
451
 
452
        HAL_INTERRUPT_ATTACH( vector, isr, data, this );
453
    }
454
 
455
#endif    
456
    CYG_REPORT_RETURN();
457
}
458
 
459
// -------------------------------------------------------------------------
460
// Detach the ISR from the vector
461
 
462
void
463
Cyg_Interrupt::detach(void)
464
{
465
    CYG_REPORT_FUNCTION();
466
 
467
    CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
468
    CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
469
 
470
    CYG_INSTRUMENT_INTR(DETACH, vector, 0);
471
 
472
#ifdef CYGIMP_KERNEL_INTERRUPTS_CHAIN
473
 
474
    // Remove the interrupt object from the vector chain.
475
 
476
    cyg_uint32 index;
477
 
478
    HAL_TRANSLATE_VECTOR( vector, index );
479
 
480
    Cyg_Interrupt **p = &chain_list[index];
481
 
482
    while( *p != NULL )
483
    {
484
        Cyg_Interrupt *n = *p;
485
 
486
        if( n == this )
487
        {
488
            *p = next;
489
            break;
490
        }
491
 
492
        p = &n->next;
493
    }
494
 
495
    // If this was the last one, detach the vector.
496
 
497
    if( chain_list[index] == NULL )
498
        HAL_INTERRUPT_DETACH( vector, chain_isr );
499
 
500
#else
501
 
502
    HAL_INTERRUPT_DETACH( vector, isr );
503
 
504
#endif
505
 
506
    CYG_REPORT_RETURN();
507
 
508
}
509
 
510
// -------------------------------------------------------------------------
511
// Get the current service routine
512
 
513
void
514
Cyg_Interrupt::get_vsr(cyg_vector vector, cyg_VSR **vsr)
515
{
516
    CYG_REPORT_FUNCTION();
517
    CYG_REPORT_FUNCARG2("vector = %d, mem to put VSR in is at %08x", vector,
518
                        vsr);
519
 
520
    CYG_ASSERT( vector >= CYGNUM_HAL_VSR_MIN, "Invalid vector");
521
    CYG_ASSERT( vector <= CYGNUM_HAL_VSR_MAX, "Invalid vector");
522
 
523
    HAL_VSR_GET( vector, vsr );
524
 
525
    CYG_REPORT_RETURN();
526
}
527
 
528
// -------------------------------------------------------------------------
529
// Install a vector service routine
530
 
531
void
532
Cyg_Interrupt::set_vsr(cyg_vector vector, cyg_VSR *vsr, cyg_VSR **old)
533
{
534
    CYG_REPORT_FUNCTION();
535
 
536
    CYG_REPORT_FUNCARG3( "vector = %d, new vsr is at %08x, mem to put "
537
                         "old VSR in is at %08x", vector, vsr, old);
538
 
539
    CYG_INSTRUMENT_INTR(SET_VSR, vector, vsr);
540
 
541
    CYG_ASSERT( vector >= CYGNUM_HAL_VSR_MIN, "Invalid vector");
542
    CYG_ASSERT( vector <= CYGNUM_HAL_VSR_MAX, "Invalid vector");
543
 
544
    CYG_INTERRUPT_STATE old_ints;
545
 
546
    HAL_DISABLE_INTERRUPTS(old_ints);
547
 
548
    HAL_VSR_SET( vector, vsr, old );
549
 
550
    HAL_RESTORE_INTERRUPTS(old_ints);
551
 
552
    CYG_REPORT_RETURN();
553
}
554
 
555
// -------------------------------------------------------------------------
556
// Disable interrupts at the CPU
557
 
558
 
559
void
560
Cyg_Interrupt::disable_interrupts(void)
561
{
562
    CYG_REPORT_FUNCTION();
563
 
564
    CYG_INSTRUMENT_INTR(DISABLE, disable_counter[CYG_KERNEL_CPU_THIS()]+1, 0);
565
 
566
    HAL_SMP_CPU_TYPE cpu_this = CYG_KERNEL_CPU_THIS();
567
 
568
    // If the disable_counter is zero, disable interrupts and claim the spinlock.
569
 
570
    if( 0 == disable_counter[cpu_this] )
571
    {
572
        // Claim the spinlock and disable interrupts. We save the original interrupt
573
        // enable state to restore later.
574
        interrupt_disable_spinlock.spin_intsave(&interrupt_disable_state[cpu_this]);
575
    }
576
 
577
    // Now increment our disable counter.
578
 
579
    disable_counter[cpu_this]++;
580
 
581
    CYG_REPORT_RETURN();
582
}
583
 
584
 
585
// -------------------------------------------------------------------------
586
// Re-enable CPU interrupts
587
 
588
void
589
Cyg_Interrupt::enable_interrupts(void)
590
{
591
    CYG_REPORT_FUNCTION();
592
 
593
    CYG_INSTRUMENT_INTR(ENABLE, disable_counter[CYG_KERNEL_CPU_THIS()], 0);
594
 
595
    HAL_SMP_CPU_TYPE cpu_this = CYG_KERNEL_CPU_THIS();
596
 
597
    CYG_ASSERT( disable_counter[cpu_this] > 0 , "Disable counter not greater than zero");
598
 
599
    // If the disable counter goes to zero, then release the spinlock and restore
600
    // the previous interrupt state.
601
 
602
    if( --disable_counter[cpu_this] == 0 )
603
    {
604
        interrupt_disable_spinlock.clear_intsave(interrupt_disable_state[cpu_this]);
605
    }
606
 
607
    CYG_REPORT_RETURN();
608
}
609
 
610
// -------------------------------------------------------------------------
611
// Mask a specific interrupt in a PIC
612
 
613
void
614
Cyg_Interrupt::mask_interrupt(cyg_vector vector)
615
{
616
    CYG_REPORT_FUNCTION();
617
    CYG_REPORT_FUNCARG1("vector=%d", vector);
618
 
619
    CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
620
    CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
621
 
622
    CYG_INSTRUMENT_INTR(MASK, vector, 0);
623
 
624
    CYG_INTERRUPT_STATE old_ints;
625
 
626
    HAL_DISABLE_INTERRUPTS(old_ints);
627
    HAL_INTERRUPT_MASK( vector );
628
    HAL_RESTORE_INTERRUPTS(old_ints);
629
 
630
    CYG_REPORT_RETURN();
631
}
632
 
633
// -------------------------------------------------------------------------
634
// Mask a specific interrupt in a PIC (but not interrupt safe)
635
 
636
void
637
Cyg_Interrupt::mask_interrupt_intunsafe(cyg_vector vector)
638
{
639
    CYG_REPORT_FUNCTION();
640
    CYG_REPORT_FUNCARG1("vector=%d", vector);
641
 
642
 
643
    CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
644
    CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
645
 
646
    CYG_INSTRUMENT_INTR(MASK, vector, 0);
647
 
648
    HAL_INTERRUPT_MASK( vector );
649
 
650
    CYG_REPORT_RETURN();
651
}
652
 
653
// -------------------------------------------------------------------------
654
// Clear PIC mask
655
 
656
void
657
Cyg_Interrupt::unmask_interrupt(cyg_vector vector)
658
{
659
    CYG_REPORT_FUNCTION();
660
 
661
    CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
662
    CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
663
 
664
    CYG_INSTRUMENT_INTR(UNMASK, vector, 0);
665
 
666
    CYG_INTERRUPT_STATE old_ints;
667
 
668
    HAL_DISABLE_INTERRUPTS(old_ints);
669
    HAL_INTERRUPT_UNMASK( vector );
670
    HAL_RESTORE_INTERRUPTS(old_ints);
671
 
672
    CYG_REPORT_RETURN();
673
}
674
 
675
 
676
// -------------------------------------------------------------------------
677
// Clear PIC mask (but not interrupt safe)
678
 
679
void
680
Cyg_Interrupt::unmask_interrupt_intunsafe(cyg_vector vector)
681
{
682
    CYG_REPORT_FUNCTION();
683
 
684
    CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
685
    CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
686
 
687
    CYG_INSTRUMENT_INTR(UNMASK, vector, 0);
688
 
689
    HAL_INTERRUPT_UNMASK( vector );
690
 
691
    CYG_REPORT_RETURN();
692
}
693
 
694
 
695
// -------------------------------------------------------------------------
696
// Acknowledge interrupt at PIC
697
 
698
void
699
Cyg_Interrupt::acknowledge_interrupt(cyg_vector vector)
700
{
701
//    CYG_REPORT_FUNCTION();
702
 
703
    CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
704
    CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
705
 
706
    CYG_INSTRUMENT_INTR(ACK, vector, 0);
707
 
708
    HAL_INTERRUPT_ACKNOWLEDGE( vector );
709
}
710
 
711
// -------------------------------------------------------------------------
712
// Change interrupt detection at PIC
713
 
714
void
715
Cyg_Interrupt::configure_interrupt(
716
    cyg_vector vector,              // vector to control
717
    cyg_bool level,                 // level or edge triggered
718
    cyg_bool up                     // hi/lo level, rising/falling edge
719
    )
720
{
721
    CYG_REPORT_FUNCTION();
722
    CYG_REPORT_FUNCARG3("vector = %d, level = %d, up = %d", vector, level,
723
                        up);
724
 
725
    CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
726
    CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
727
 
728
    CYG_INSTRUMENT_INTR(CONFIGURE, vector, (level<<1)|up);
729
 
730
    HAL_INTERRUPT_CONFIGURE( vector, level, up );
731
 
732
    CYG_REPORT_RETURN();
733
}
734
 
735
// -------------------------------------------------------------------------
736
// SMP support for setting/getting interrupt CPU
737
 
738
#ifdef CYGPKG_KERNEL_SMP_SUPPORT
739
 
740
void
741
Cyg_Interrupt::set_cpu(
742
    cyg_vector vector,              // vector to control
743
    HAL_SMP_CPU_TYPE cpu            // CPU to set
744
    )
745
{
746
    CYG_REPORT_FUNCTION();
747
    CYG_REPORT_FUNCARG2("vector = %d, cpu = %d", vector, cpu );
748
 
749
    CYG_ASSERT( vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
750
    CYG_ASSERT( vector <= CYGNUM_HAL_ISR_MAX, "Invalid vector");
751
 
752
    CYG_INSTRUMENT_INTR(SET_CPU, vector, cpu);
753
 
754
    HAL_INTERRUPT_SET_CPU( vector, cpu );
755
 
756
    CYG_REPORT_RETURN();
757
}
758
 
759
HAL_SMP_CPU_TYPE
760
Cyg_Interrupt::get_cpu(
761
    cyg_vector vector              // vector to control
762
    )
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_SMP_CPU_TYPE cpu = 0;
771
 
772
    HAL_INTERRUPT_GET_CPU( vector, cpu );
773
 
774
    CYG_INSTRUMENT_INTR(GET_CPU, vector, cpu);
775
 
776
    CYG_REPORT_RETURN();
777
 
778
    return cpu;
779
}
780
 
781
#endif
782
 
783
// -------------------------------------------------------------------------
784
// EOF intr/intr.cxx

powered by: WebSVN 2.1.0

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