source: branches/v4/softs/giet_tsar/isr.c @ 374

Last change on this file since 374 was 248, checked in by meunier, 12 years ago

Updates in the soft_filter application (bug corrections, formatting, and adaptation to the architecture generic_mmu)

File size: 6.4 KB
Line 
1/*************************************************************************************
2   File : isr.c
3   Authors : Alain Greiner
4   Date : april 2011
5
6   These routines must be "intalled" by the boot code in the
7   interrupt vector, depending on the system architecture.
8*************************************************************************************/
9
10#include "isr.h"
11#include "drivers.h"
12
13#define in_isr __attribute__((section (".isr")))
14
15struct plaf;
16
17extern struct plaf seg_dma_base;
18extern struct plaf seg_ioc_base;
19extern struct plaf seg_timer_base;
20extern struct plaf seg_tty_base;
21
22extern struct plaf NB_TIMERS;
23extern struct plaf NB_TASKS;
24
25//////////////////////////////////////////////////////////////////////////////////////
26//  _isr_dma
27//  Each processor controls its own private DMA.
28//  It acknowledge the IRQ using the dma base address depending on the proc_id
29//  as computed by the  _segment_increment() function, writes the transfer
30//  status in the _dma_status[pid] variable, and resets the _dma_busy[pid]
31//  synchrnisation variable to signal completion.
32//  Both variables are defined in the drivers.c file.
33/////////////////////////////////////////////////////////////////////////////////////
34in_isr void _isr_dma()
35{
36    int*                dma_address;
37    unsigned int        base            = (unsigned int)&seg_dma_base;
38    unsigned int        increment       = _segment_increment(DMA_SPAN*4);
39    size_t              pid             = _procid();
40   
41    dma_address = (int*)(base + increment);
42   
43    _dma_status[pid]            = dma_address[DMA_LEN]; // save status
44    _dma_busy[pid]              = 0;                    // release DMA
45    dma_address[DMA_RESET]      = 0;                    // reset IRQ
46}
47//////////////////////////////////////////////////////////////////////////////////////
48//  _isr_ioc
49//  There is only one IOC controler shared by all tasks.
50//  It acknowledge the IRQ using the ioc base address, save the status,
51//  and set the _ioc_done variable to signal completion.
52//  This variable is defined in the drivers.c file.
53//////////////////////////////////////////////////////////////////////////////////////
54in_isr void _isr_ioc()
55{
56    int* ioc_address = (int*)&seg_ioc_base;
57   
58    _ioc_status = ioc_address[BLOCK_DEVICE_STATUS];     // save status & reset IRQ
59    _ioc_done   = 1;                                    // signals completion
60}
61//////////////////////////////////////////////////////////////////////////////////////
62//  _isr_timer* (* = 0,1,2,3)
63//  A single processor can use up to 4 independant timers.
64//  These 4 ISRs handle up to 4 IRQs generated by 4 independant timers,
65//  connected to a single processor.
66//  It acknowledge the IRQ using the timer base address depending
67//  on both the proc_id and the timer_id (0,1,2,3).
68//  It displays a message on TTY[proc_id,task_id].
69//////////////////////////////////////////////////////////////////////////////////////
70in_isr void _isr_timer_indexed(size_t timer_id)
71{
72    int*                timer_address;
73    size_t              ntimers         = (size_t)&NB_TIMERS;
74    unsigned int        base            = (unsigned int)&seg_timer_base;
75    unsigned int        increment       = _segment_increment(ntimers*TIMER_SPAN*4);
76    int                 date            = (int)_proctime();
77    char                buf[10];
78
79    timer_address = (int*)(base + increment + timer_id*TIMER_SPAN*4);
80
81    timer_address[TIMER_RESETIRQ] = 0;                  // reset IRQ
82
83    _itoa_dec(date, buf);                               // print message
84    _tty_write("\n!!! interrupt timer0 received at cycle ", 40);
85    _tty_write(buf, 10); 
86    _tty_write("\n\n", 2);
87}
88in_isr void _isr_timer()
89{
90    _isr_timer_indexed(0);
91}
92in_isr void _isr_timer0()
93{
94    _isr_timer_indexed(0);
95}
96in_isr void _isr_timer1()
97{
98    _isr_timer_indexed(1);
99}
100in_isr void _isr_timer2()
101{
102    _isr_timer_indexed(2);
103}
104in_isr void _isr_timer3()
105{
106    _isr_timer_indexed(3);
107}
108//////////////////////////////////////////////////////////////////////////////////////
109//  _isr_tty_get_task* (* = 0,1,2,3)
110//  A single processor can run up to 4 tasks in pseudo-parallelismr,
111//  and each task has is own private terminal.
112//  These 4 ISRs handle up to 4 IRQs associate to 4 independant terminals
113//  connected to a single processor.
114//  It acknowledge the IRQ using the terminal basee address depending
115//  on both the proc_id  and the task_id (0,1,2,3).
116//  There is one communication buffer _tty_get_buf[tty_id] per terminal.
117//  protected by a set/reset variable _tty_get_full[tty_id].
118//  The _tty_get_full[tty_id] synchronisation variable is set
119//  by the ISR, and reset by the OS.
120//  Both variables are defined in the drivers.c file.
121//  To access these buffers, the terminal index is computed as
122//      tty_id = proc_id*ntasks + task_id
123//  A character is lost if the buffer is full when the ISR is executed.
124//////////////////////////////////////////////////////////////////////////////////////
125in_isr void _isr_tty_get_indexed(size_t task_id)
126{
127    char*               tty_address;
128    size_t              ntasks          = (size_t)&NB_TASKS;
129    size_t              tty_id          = _procid()*ntasks + task_id;
130    unsigned int        base            = (unsigned int)&seg_tty_base;
131    unsigned int        increment       = _segment_increment(ntasks*TTY_SPAN*4);
132
133    tty_address = (char*)(base + increment + task_id*TTY_SPAN*4);
134
135    _tty_get_buf[tty_id] = tty_address[TTY_READ*4];     // save character and reset IRQ
136    _tty_get_full[tty_id] = 1;                          // signals character available
137}
138in_isr void _isr_tty_get()
139{
140    _isr_tty_get_indexed(0);
141}
142in_isr void _isr_tty_get_task0()
143{
144    _isr_tty_get_indexed(0);
145}
146in_isr void _isr_tty_get_task1()
147{
148    _isr_tty_get_indexed(1);
149}
150in_isr void _isr_tty_get_task2()
151{
152    _isr_tty_get_indexed(2);
153}
154in_isr void _isr_tty_get_task3()
155{
156    _isr_tty_get_indexed(3);
157}
158//////////////////////////////////////////////////////////////////////////////////////
159//  _isr_switch
160//  This ISR is in charge of context switch.
161//  It handles up to 4 IRQs, corresponding to 4 different processors.
162//  If the processor uses several timers, the context switch is driven
163//  by the IRQ associated to timer0.
164//  It acknowledges the IRQ on TIMER[proc_id] and calls the _ctx_switch() function.
165//////////////////////////////////////////////////////////////////////////////////////
166in_isr void _isr_switch()
167{
168    int*                timer_address;
169    unsigned int        base            = (unsigned int)&seg_timer_base;
170    unsigned int        increment       = _segment_increment(TIMER_SPAN*4);
171
172    timer_address = (int*)(base + increment);
173
174    timer_address[TIMER_RESETIRQ] = 0;                  // reset IRQ
175    _ctx_switch();
176}
177
178/* Local Variables:
179   tab-width: 4;
180   c-basic-offset: 4;
181   c-file-offsets:((innamespace . 0)(inline-open . 0));
182   indent-tabs-mode: nil;
183   End: */
184
185/* vim: set filetype=c expandtab shiftwidth=4 tabstop=4 softtabstop=4: */
186
Note: See TracBrowser for help on using the repository browser.