source: asp_ewarm/asp-1.7.0/extension/dcre/kernel/interrupt.c@ 61

Last change on this file since 61 was 61, checked in by ertl-honda, 11 years ago

ASP for EWARM のコミット.

File size: 10.6 KB
Line 
1/*
2 * TOPPERS/ASP Kernel
3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Advanced Standard Profile Kernel
5 *
6 * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7 * Toyohashi Univ. of Technology, JAPAN
8 * Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
9 * Graduate School of Information Science, Nagoya Univ., JAPAN
10 *
11 * ã‹L’˜ìŒ ŽÒ‚́CˆÈ‰º‚Ì(1)`(4)‚ÌðŒ‚ð–ž‚½‚·ê‡‚ÉŒÀ‚èC–{ƒ\ƒtƒgƒEƒF
12 * ƒAi–{ƒ\ƒtƒgƒEƒFƒA‚ð‰ü•Ï‚µ‚½‚à‚Ì‚ðŠÜ‚ށDˆÈ‰º“¯‚¶j‚ðŽg—pE•¡»E‰ü
13 * •ÏEÄ”z•ziˆÈ‰ºC—˜—p‚ƌĂԁj‚·‚邱‚Ƃ𖳏ž‚Å‹–‘ø‚·‚éD
14 * (1) –{ƒ\ƒtƒgƒEƒFƒA‚ðƒ\[ƒXƒR[ƒh‚ÌŒ`‚Å—˜—p‚·‚éê‡‚ɂ́Cã‹L‚Ì’˜ì
15 * Œ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L‚Ì–³•ÛØ‹K’肪C‚»‚Ì‚Ü‚Ü‚ÌŒ`‚Ń\[
16 * ƒXƒR[ƒh’†‚ÉŠÜ‚Ü‚ê‚Ä‚¢‚邱‚ƁD
17 * (2) –{ƒ\ƒtƒgƒEƒFƒA‚ðCƒ‰ƒCƒuƒ‰ƒŠŒ`Ž®‚ȂǁC‘¼‚̃\ƒtƒgƒEƒFƒAŠJ”­‚ÉŽg
18 * —p‚Å‚«‚éŒ`‚ōĔz•z‚·‚éê‡‚ɂ́CÄ”z•z‚É”º‚¤ƒhƒLƒ…
19ƒƒ“ƒgi—˜—p
20 * ŽÒƒ}ƒjƒ…
21ƒAƒ‹‚Ȃǁj‚ɁCã‹L‚Ì’˜ìŒ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L
22 * ‚Ì–³•ÛØ‹K’è‚ðŒfÚ‚·‚邱‚ƁD
23 * (3) –{ƒ\ƒtƒgƒEƒFƒA‚ðC‹@Ší‚É‘g‚ݍž‚ނȂǁC‘¼‚̃\ƒtƒgƒEƒFƒAŠJ”­‚ÉŽg
24 * —p‚Å‚«‚È‚¢Œ`‚ōĔz•z‚·‚éê‡‚ɂ́CŽŸ‚Ì‚¢‚¸‚ê‚©‚ÌðŒ‚ð–ž‚½‚·‚±
25 * ‚ƁD
26 * (a) Ä”z•z‚É”º‚¤ƒhƒLƒ…
27ƒƒ“ƒgi—˜—pŽÒƒ}ƒjƒ…
28ƒAƒ‹‚Ȃǁj‚ɁCã‹L‚Ì’˜
29 * ìŒ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L‚Ì–³•ÛØ‹K’è‚ðŒfÚ‚·‚邱‚ƁD
30 * (b) Ä”z•z‚ÌŒ`‘Ô‚ðC•Ê‚É’è‚ß‚é•û–@‚É‚æ‚Á‚āCTOPPERSƒvƒƒWƒFƒNƒg‚É
31 * •ñ‚·‚邱‚ƁD
32 * (4) –{ƒ\ƒtƒgƒEƒFƒA‚Ì—˜—p‚É‚æ‚è’¼Ú“I‚Ü‚½‚͊ԐړI‚ɐ¶‚¶‚é‚¢‚©‚Ȃ鑹
33 * ŠQ‚©‚ç‚àCã‹L’˜ìŒ ŽÒ‚¨‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚ð–Ɛӂ·‚邱‚ƁD
34 * ‚Ü‚½C–{ƒ\ƒtƒgƒEƒFƒA‚̃†[ƒU‚Ü‚½‚̓Gƒ“ƒhƒ†[ƒU‚©‚ç‚Ì‚¢‚©‚Ȃ闝
35 * —R‚ÉŠî‚­¿‹‚©‚ç‚àCã‹L’˜ìŒ ŽÒ‚¨‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚ð
36 * –Ɛӂ·‚邱‚ƁD
37 *
38 * –{ƒ\ƒtƒgƒEƒFƒA‚́C–³•ÛØ‚Å’ñ‹Ÿ‚³‚ê‚Ä‚¢‚é‚à‚Ì‚Å‚ ‚éDã‹L’˜ìŒ ŽÒ‚¨
39 * ‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚́C–{ƒ\ƒtƒgƒEƒFƒA‚ÉŠÖ‚µ‚āC“Á’è‚ÌŽg—p–Ú“I
40 * ‚ɑ΂·‚é“K‡«‚àŠÜ‚߂āC‚¢‚©‚È‚é•ÛØ‚às‚í‚È‚¢D‚Ü‚½C–{ƒ\ƒtƒgƒEƒF
41 * ƒA‚Ì—˜—p‚É‚æ‚è’¼Ú“I‚Ü‚½‚͊ԐړI‚ɐ¶‚¶‚½‚¢‚©‚Ȃ鑹ŠQ‚ÉŠÖ‚µ‚Ä‚àC‚»
42 * ‚̐ӔC‚𕉂í‚È‚¢D
43 *
44 * @(#) $Id: interrupt.c 2018 2010-12-31 13:43:05Z ertl-hiro $
45 */
46
47/*
48 * Š„ž‚ÝŠÇ—‹@”\
49 */
50
51#include "kernel_impl.h"
52#include "check.h"
53#include "task.h"
54#include "interrupt.h"
55
56/*
57 * ƒgƒŒ[ƒXƒƒOƒ}ƒNƒ‚̃fƒtƒHƒ‹ƒg’è‹`
58 */
59#ifndef LOG_ISR_ENTER
60#define LOG_ISR_ENTER(intno)
61#endif /* LOG_ISR_ENTER */
62
63#ifndef LOG_ISR_LEAVE
64#define LOG_ISR_LEAVE(intno)
65#endif /* LOG_ISR_LEAVE */
66
67#ifndef LOG_ACRE_ISR_ENTER
68#define LOG_ACRE_ISR_ENTER(pk_cisr)
69#endif /* LOG_ACRE_ISR_ENTER */
70
71#ifndef LOG_ACRE_ISR_LEAVE
72#define LOG_ACRE_ISR_LEAVE(ercd)
73#endif /* LOG_ACRE_ISR_LEAVE */
74
75#ifndef LOG_DEL_ISR_ENTER
76#define LOG_DEL_ISR_ENTER(isrid)
77#endif /* LOG_DEL_ISR_ENTER */
78
79#ifndef LOG_DEL_ISR_LEAVE
80#define LOG_DEL_ISR_LEAVE(ercd)
81#endif /* LOG_DEL_ISR_LEAVE */
82
83#ifndef LOG_DIS_INT_ENTER
84#define LOG_DIS_INT_ENTER(intno)
85#endif /* LOG_DIS_INT_ENTER */
86
87#ifndef LOG_DIS_INT_LEAVE
88#define LOG_DIS_INT_LEAVE(ercd)
89#endif /* LOG_DIS_INT_LEAVE */
90
91#ifndef LOG_ENA_INT_ENTER
92#define LOG_ENA_INT_ENTER(intno)
93#endif /* LOG_ENA_INT_ENTER */
94
95#ifndef LOG_ENA_INT_LEAVE
96#define LOG_ENA_INT_LEAVE(ercd)
97#endif /* LOG_ENA_INT_LEAVE */
98
99#ifndef LOG_CHG_IPM_ENTER
100#define LOG_CHG_IPM_ENTER(intpri)
101#endif /* LOG_CHG_IPM_ENTER */
102
103#ifndef LOG_CHG_IPM_LEAVE
104#define LOG_CHG_IPM_LEAVE(ercd)
105#endif /* LOG_CHG_IPM_LEAVE */
106
107#ifndef LOG_GET_IPM_ENTER
108#define LOG_GET_IPM_ENTER(p_intpri)
109#endif /* LOG_GET_IPM_ENTER */
110
111#ifndef LOG_GET_IPM_LEAVE
112#define LOG_GET_IPM_LEAVE(ercd, intpri)
113#endif /* LOG_GET_IPM_LEAVE */
114
115/*
116 * Š„ž‚݃T[ƒrƒXƒ‹[ƒ`ƒ“‚̐”
117 */
118#define tnum_isr ((uint_t)(tmax_isrid - TMIN_SEMID + 1) + tnum_sisr)
119
120/*
121 * Š„ž‚݃T[ƒrƒXƒ‹[ƒ`ƒ“ID‚©‚犄ž‚݃T[ƒrƒXƒ‹[ƒ`ƒ“ŠÇ—ƒuƒƒbƒN‚ðŽæ
122 * ‚èo‚·‚½‚߂̃}ƒNƒ
123 */
124#define INDEX_ISR(isrid) ((uint_t)((isrid) - TMIN_ISRID) + tnum_sisr)
125#define get_isrcb(isrid) (&(isrcb_table[INDEX_ISR(isrid)]))
126
127/*
128 * Š„ž‚݃T[ƒrƒXƒ‹[ƒ`ƒ“ƒLƒ…
129[‚Ö‚Ì“o˜^
130 */
131Inline void
132enqueue_isr(QUEUE *p_isr_queue, ISRCB *p_isrcb)
133{
134 QUEUE *p_entry;
135 PRI isrpri = p_isrcb->p_isrinib->isrpri;
136
137 for (p_entry = p_isr_queue->p_next; p_entry != p_isr_queue;
138 p_entry = p_entry->p_next) {
139 if (isrpri < ((ISRCB *) p_entry)->p_isrinib->isrpri) {
140 break;
141 }
142 }
143 queue_insert_prev(p_entry, &(p_isrcb->isr_queue));
144}
145
146#ifdef TOPPERS_isrini
147
148/*
149 * Žg—p‚µ‚Ä‚¢‚È‚¢Š„ž‚݃T[ƒrƒXƒ‹[ƒ`ƒ“ŠÇ—ƒuƒƒbƒN‚̃ŠƒXƒg
150 */
151QUEUE free_isrcb;
152
153/*
154 * Š„ž‚݃T[ƒrƒXƒ‹[ƒ`ƒ“‹@”\‚̏‰Šú‰»
155 */
156void
157initialize_isr(void)
158{
159 uint_t i, j;
160 ISRCB *p_isrcb;
161 ISRINIB *p_isrinib;
162
163 for (i = 0; i < tnum_isr_queue; i++) {
164 queue_initialize(&(isr_queue_table[i]));
165 }
166 for (p_isrcb = isrcb_table, i = 0; i < tnum_sisr; p_isrcb++, i++) {
167 p_isrcb->p_isrinib = &(sisrinib_table[i]);
168 enqueue_isr(p_isrcb->p_isrinib->p_isr_queue, p_isrcb);
169 }
170 queue_initialize(&free_isrcb);
171 for (j = 0; i < tnum_isr; p_isrcb++, i++, j++) {
172 p_isrinib = &(aisrinib_table[j]);
173 p_isrinib->isratr = TA_NOEXS;
174 p_isrcb->p_isrinib = ((const ISRINIB *) p_isrinib);
175 queue_insert_prev(&free_isrcb, &(p_isrcb->isr_queue));
176 }
177}
178
179#endif /* TOPPERS_isrini */
180
181/*
182 * Š„ž‚݃T[ƒrƒXƒ‹[ƒ`ƒ“‚̌ďo‚µ
183 */
184#ifdef TOPPERS_isrcal
185
186void
187call_isr(QUEUE *p_isr_queue)
188{
189 QUEUE *p_queue;
190 ISRINIB *p_isrinib;
191 PRI saved_ipm;
192
193 saved_ipm = i_get_ipm();
194 for (p_queue = p_isr_queue->p_next; p_queue != p_isr_queue;
195 p_queue = p_queue->p_next) {
196 p_isrinib = (ISRINIB *)(((ISRCB *) p_queue)->p_isrinib);
197 LOG_ISR_ENTER(p_isrinib->intno);
198 (*(p_isrinib->isr))(p_isrinib->exinf);
199 LOG_ISR_LEAVE(p_isrinib->intno);
200
201 if (p_queue->p_next != p_isr_queue) {
202 /* ISR‚̌ďo‚µ‘O‚̏ó‘Ô‚É–ß‚· */
203 if (i_sense_lock()) {
204 i_unlock_cpu();
205 }
206 i_set_ipm(saved_ipm);
207 }
208 }
209}
210
211#endif /* TOPPERS_isrcal */
212
213/*
214 * Š„ž‚݃T[ƒrƒXƒ‹[ƒ`ƒ“ŒÄo‚µƒLƒ…
215[‚ÌŒŸõ
216 */
217Inline QUEUE *
218search_isr_queue(INTNO intno)
219{
220 int_t left, right, i;
221
222 if (tnum_isr_queue == 0) {
223 return(NULL);
224 }
225
226 left = 0;
227 right = tnum_isr_queue - 1;
228 while (left < right) {
229 i = (left + right + 1) / 2;
230 if (intno < isr_queue_list[i].intno) {
231 right = i - 1;
232 }
233 else {
234 left = i;
235 }
236 }
237 if (isr_queue_list[left].intno == intno) {
238 return(isr_queue_list[left].p_isr_queue);
239 }
240 else {
241 return(NULL);
242 }
243}
244
245/*
246 * Š„ž‚݃T[ƒrƒXƒ‹[ƒ`ƒ“‚̐¶¬
247 */
248#ifdef TOPPERS_acre_isr
249
250ER_UINT
251acre_isr(const T_CISR *pk_cisr)
252{
253 ISRCB *p_isrcb;
254 ISRINIB *p_isrinib;
255 QUEUE *p_isr_queue;
256 ER ercd;
257
258 LOG_ACRE_ISR_ENTER(pk_cisr);
259 CHECK_TSKCTX_UNL();
260 CHECK_RSATR(pk_cisr->isratr, TARGET_ISRATR);
261 CHECK_INTNO_CREISR(pk_cisr->intno);
262 CHECK_ALIGN_FUNC(pk_cisr->isr);
263 CHECK_NONNULL_FUNC(pk_cisr->isr);
264 CHECK_ISRPRI(pk_cisr->isrpri);
265
266 p_isr_queue = search_isr_queue(pk_cisr->intno);
267 CHECK_PAR(p_isr_queue != NULL);
268
269 t_lock_cpu();
270 if (queue_empty(&free_isrcb)) {
271 ercd = E_NOID;
272 }
273 else {
274 p_isrcb = ((ISRCB *) queue_delete_next(&free_isrcb));
275 p_isrinib = (ISRINIB *)(p_isrcb->p_isrinib);
276 p_isrinib->isratr = pk_cisr->isratr;
277 p_isrinib->exinf = pk_cisr->exinf;
278 p_isrinib->intno = pk_cisr->intno;
279 p_isrinib->p_isr_queue = p_isr_queue;
280 p_isrinib->isr = pk_cisr->isr;
281 p_isrinib->isrpri = pk_cisr->isrpri;
282 enqueue_isr(p_isr_queue, p_isrcb);
283 ercd = ISRID(p_isrcb);
284 }
285 t_unlock_cpu();
286
287 error_exit:
288 LOG_ACRE_ISR_LEAVE(ercd);
289 return(ercd);
290}
291
292#endif /* TOPPERS_acre_isr */
293
294/*
295 * Š„ž‚݃T[ƒrƒXƒ‹[ƒ`ƒ“‚̍폜
296 */
297#ifdef TOPPERS_del_isr
298
299ER
300del_isr(ID isrid)
301{
302 ISRCB *p_isrcb;
303 ISRINIB *p_isrinib;
304 ER ercd;
305
306 LOG_DEL_ISR_ENTER(isrid);
307 CHECK_TSKCTX_UNL();
308 CHECK_ISRID(isrid);
309 p_isrcb = get_isrcb(isrid);
310
311 t_lock_cpu();
312 if (p_isrcb->p_isrinib->isratr == TA_NOEXS) {
313 ercd = E_NOEXS;
314 }
315 else {
316 queue_delete(&(p_isrcb->isr_queue));
317 p_isrinib = (ISRINIB *)(p_isrcb->p_isrinib);
318 p_isrinib->isratr = TA_NOEXS;
319 queue_insert_prev(&free_isrcb, &(p_isrcb->isr_queue));
320 }
321 t_unlock_cpu();
322
323 error_exit:
324 LOG_DEL_ISR_LEAVE(ercd);
325 return(ercd);
326}
327
328#endif /* TOPPERS_del_isr */
329
330/*
331 * Š„ž‚ÝŠÇ—‹@”\‚̏‰Šú‰»
332 */
333#ifdef TOPPERS_intini
334#ifndef OMIT_INITIALIZE_INTERRUPT
335
336void
337initialize_interrupt(void)
338{
339 uint_t i;
340 const INHINIB *p_inhinib;
341 const INTINIB *p_intinib;
342
343 for (p_inhinib = inhinib_table, i = 0; i < tnum_inhno; p_inhinib++, i++) {
344 x_define_inh(p_inhinib->inhno, p_inhinib->int_entry);
345 }
346 for (p_intinib = intinib_table, i = 0; i < tnum_intno; p_intinib++, i++) {
347 x_config_int(p_intinib->intno, p_intinib->intatr, p_intinib->intpri);
348 }
349}
350
351#endif /* OMIT_INITIALIZE_INTERRUPT */
352#endif /* TOPPERS_intini */
353
354/*
355 * Š„ž‚Ý‚Ì‹ÖŽ~
356 */
357#ifdef TOPPERS_dis_int
358#ifdef TOPPERS_SUPPORT_DIS_INT
359
360ER
361dis_int(INTNO intno)
362{
363 bool_t locked;
364 ER ercd;
365
366 LOG_DIS_INT_ENTER(intno);
367 CHECK_TSKCTX();
368 CHECK_INTNO_DISINT(intno);
369
370 locked = t_sense_lock();
371 if (!locked) {
372 t_lock_cpu();
373 }
374 if (t_disable_int(intno)) {
375 ercd = E_OK;
376 }
377 else {
378 ercd = E_OBJ;
379 }
380 if (!locked) {
381 t_unlock_cpu();
382 }
383
384 error_exit:
385 LOG_DIS_INT_LEAVE(ercd);
386 return(ercd);
387}
388
389#endif /* TOPPERS_SUPPORT_DIS_INT */
390#endif /* TOPPERS_dis_int */
391
392/*
393 * Š„ž‚Ý‚Ì‹–‰Â
394 */
395#ifdef TOPPERS_ena_int
396#ifdef TOPPERS_SUPPORT_ENA_INT
397
398ER
399ena_int(INTNO intno)
400{
401 bool_t locked;
402 ER ercd;
403
404 LOG_ENA_INT_ENTER(intno);
405 CHECK_TSKCTX();
406 CHECK_INTNO_DISINT(intno);
407
408 locked = t_sense_lock();
409 if (!locked) {
410 t_lock_cpu();
411 }
412 if (t_enable_int(intno)) {
413 ercd = E_OK;
414 }
415 else {
416 ercd = E_OBJ;
417 }
418 if (!locked) {
419 t_unlock_cpu();
420 }
421
422 error_exit:
423 LOG_ENA_INT_LEAVE(ercd);
424 return(ercd);
425}
426
427#endif /* TOPPERS_SUPPORT_ENA_INT */
428#endif /* TOPPERS_ena_int */
429
430/*
431 * Š„ž‚Ý—Dæ“xƒ}ƒXƒN‚̕ύX
432 */
433#ifdef TOPPERS_chg_ipm
434
435ER
436chg_ipm(PRI intpri)
437{
438 ER ercd;
439
440 LOG_CHG_IPM_ENTER(intpri);
441 CHECK_TSKCTX_UNL();
442 CHECK_INTPRI_CHGIPM(intpri);
443
444 t_lock_cpu();
445 t_set_ipm(intpri);
446 if (intpri == TIPM_ENAALL) {
447 ipmflg = true;
448 if (!disdsp) {
449 dspflg = true;
450 if (p_runtsk != p_schedtsk) {
451 dispatch();
452 }
453 }
454 if (p_runtsk->enatex && p_runtsk->texptn != 0U) {
455 call_texrtn();
456 }
457 }
458 else {
459 ipmflg = false;
460 dspflg = false;
461 }
462 ercd = E_OK;
463 t_unlock_cpu();
464
465 error_exit:
466 LOG_CHG_IPM_LEAVE(ercd);
467 return(ercd);
468}
469
470#endif /* TOPPERS_chg_ipm */
471
472/*
473 * Š„ž‚Ý—Dæ“xƒ}ƒXƒN‚ÌŽQÆ
474 */
475#ifdef TOPPERS_get_ipm
476
477ER
478get_ipm(PRI *p_intpri)
479{
480 ER ercd;
481
482 LOG_GET_IPM_ENTER(p_intpri);
483 CHECK_TSKCTX_UNL();
484
485 t_lock_cpu();
486 *p_intpri = t_get_ipm();
487 ercd = E_OK;
488 t_unlock_cpu();
489
490 error_exit:
491 LOG_GET_IPM_LEAVE(ercd, *p_intpri);
492 return(ercd);
493}
494
495#endif /* TOPPERS_get_ipm */
Note: See TracBrowser for help on using the repository browser.