Changeset a62222fb in rtems
- Timestamp:
- 02/19/09 20:22:25 (15 years ago)
- Branches:
- 4.10, 4.11, 5, master
- Children:
- a064ef5
- Parents:
- 9bb39026
- Location:
- c/src/lib/libbsp/i386
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
c/src/lib/libbsp/i386/ChangeLog
r9bb39026 ra62222fb 1 2009-02-19 Joel Sherrill <joel.sherrill@oarcorp.com> 2 3 * shared/irq/irq.c, shared/irq/irq.h, shared/irq/irq_asm.S: Add shared 4 interrupt support to i386. 5 1 6 2009-02-11 Joel Sherrill <joel.sherrill@oarcorp.com> 2 7 -
c/src/lib/libbsp/i386/shared/irq/irq.c
r9bb39026 ra62222fb 3 3 * This file contains the implementation of the function described in irq.h 4 4 * 5 * Copy Right (C) 1998 valette@crf.canon.fr5 * Copyright (C) 1998 valette@crf.canon.fr 6 6 * 7 7 * The license and distribution terms for this file may be … … 196 196 197 197 /* 198 * ------------------------ RTEMS Single Irq Handler Mngt Routines ---------------- 198 * ------------------- RTEMS Shared Irq Handler Mngt Routines ------------ 199 */ 200 int BSP_install_rtems_shared_irq_handler (const rtems_irq_connect_data* irq) 201 { 202 rtems_interrupt_level level; 203 rtems_irq_connect_data* vchain; 204 205 if (!isValidInterrupt(irq->name)) { 206 printk("Invalid interrupt vector %d\n",irq->name); 207 return 0; 208 } 209 210 rtems_interrupt_disable(level); 211 212 if ( (int)rtems_hdl_tbl[irq->name].next_handler == -1 ) { 213 rtems_interrupt_enable(level); 214 printk( 215 "IRQ vector %d already connected to an unshared handler\n", 216 irq->name 217 ); 218 return 0; 219 } 220 221 vchain = (rtems_irq_connect_data*)malloc(sizeof(rtems_irq_connect_data)); 222 223 /* save off topmost handler */ 224 vchain[0]= rtems_hdl_tbl[irq->name]; 225 226 /* 227 * store the data provided by user 228 */ 229 rtems_hdl_tbl[irq->name] = *irq; 230 231 /* link chain to new topmost handler */ 232 rtems_hdl_tbl[irq->name].next_handler = (void *)vchain; 233 234 /* 235 * enable_irq_at_pic is supposed to ignore 236 * requests to disable interrupts outside 237 * of the range handled by the PIC 238 */ 239 BSP_irq_enable_at_i8259s (irq->name); 240 241 /* 242 * Enable interrupt on device 243 */ 244 if (irq->on) 245 irq->on(irq); 246 247 rtems_interrupt_enable(level); 248 249 return 1; 250 } 251 252 253 /* 254 * --------------- RTEMS Single Irq Handler Mngt Routines --------------- 199 255 */ 200 256 … … 223 279 */ 224 280 rtems_hdl_tbl[irq->name] = *irq; 281 rtems_hdl_tbl[irq->name].next_handler = (void *)-1; 282 225 283 /* 226 284 * Enable interrupt at PIC level … … 230 288 * Enable interrupt on device 231 289 */ 232 290 if (irq->on) 233 291 irq->on(irq); 234 292 … … 253 311 int BSP_remove_rtems_irq_handler (const rtems_irq_connect_data* irq) 254 312 { 255 rtems_interrupt_level level; 256 257 if (!isValidInterrupt(irq->name)) { 313 rtems_interrupt_level level; 314 rtems_irq_connect_data *pchain= NULL, *vchain = NULL; 315 316 if (!isValidInterrupt(irq->name)) { 317 return 0; 318 } 319 320 /* 321 * Check if default handler is actually connected. If not issue an error. 322 * You must first get the current handler via i386_get_current_idt_entry 323 * and then disconnect it using i386_delete_idt_entry. 324 * RATIONALE : to always have the same transition by forcing the user 325 * to get the previous handler before accepting to disconnect. 326 */ 327 rtems_interrupt_disable(level); 328 if (rtems_hdl_tbl[irq->name].hdl != irq->hdl) { 329 rtems_interrupt_enable(level); 330 return 0; 331 } 332 333 if ( (int)rtems_hdl_tbl[irq->name].next_handler != -1 ) { 334 int found = 0; 335 336 for( (pchain= NULL, vchain = &rtems_hdl_tbl[irq->name]); 337 (vchain->hdl != default_rtems_entry.hdl); 338 (pchain= vchain, 339 vchain = (rtems_irq_connect_data*)vchain->next_handler) ) { 340 if ( vchain->hdl == irq->hdl ) { 341 found = -1; 342 break; 343 } 344 } 345 346 if ( !found ) { 347 rtems_interrupt_enable(level); 258 348 return 0; 259 349 } 260 /* 261 * Check if default handler is actually connected. If not issue an error. 262 * You must first get the current handler via i386_get_current_idt_entry 263 * and then disconnect it using i386_delete_idt_entry. 264 * RATIONALE : to always have the same transition by forcing the user 265 * to get the previous handler before accepting to disconnect. 266 */ 267 rtems_interrupt_disable(level); 350 } else { 268 351 if (rtems_hdl_tbl[irq->name].hdl != irq->hdl) { 269 352 rtems_interrupt_enable(level); 270 353 return 0; 271 354 } 272 273 /* 274 * disable interrupt at PIC level 275 */ 276 BSP_irq_disable_at_i8259s (irq->name); 277 278 /* 279 * Disable interrupt on device 280 */ 281 if (irq->off) 282 irq->off(irq); 283 284 /* 285 * restore the default irq value 286 */ 287 rtems_hdl_tbl[irq->name] = default_rtems_entry; 288 289 rtems_interrupt_enable(level); 290 291 return 1; 355 } 356 357 /* 358 * disable interrupt at PIC level 359 */ 360 BSP_irq_disable_at_i8259s (irq->name); 361 362 /* 363 * Disable interrupt on device 364 */ 365 if (irq->off) 366 irq->off(irq); 367 368 /* 369 * restore the default irq value 370 */ 371 if( !vchain ) { 372 /* single handler vector... */ 373 rtems_hdl_tbl[irq->name] = default_rtems_entry; 374 } else { 375 if ( pchain ) { 376 /* non-first handler being removed */ 377 pchain->next_handler = vchain->next_handler; 378 } else { 379 /* first handler isn't malloc'ed, so just overwrite it. Since 380 * the contents of vchain are being struct copied, vchain itself 381 * goes away 382 */ 383 vchain = vchain->next_handler; 384 rtems_hdl_tbl[irq->name]= *vchain; 385 } 386 free(vchain); 387 } 388 389 390 rtems_interrupt_enable(level); 391 392 return 1; 292 393 } 293 394 … … 299 400 { 300 401 int i; 402 rtems_irq_connect_data* vchain; 301 403 rtems_interrupt_level level; 302 404 … … 315 417 316 418 for (i=0; i < internal_config->irqNb; i++) { 317 if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) { 419 BSP_irq_disable_at_i8259s (i); 420 for( vchain = &rtems_hdl_tbl[i]; 421 ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl); 422 vchain = (rtems_irq_connect_data*)vchain->next_handler ) { 318 423 BSP_irq_enable_at_i8259s (i); 319 if (rtems_hdl_tbl[i].on)320 rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]);424 if (vchain->on) 425 vchain->on(vchain); 321 426 } 322 else { 323 if (rtems_hdl_tbl[i].off) 324 rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]); 325 BSP_irq_disable_at_i8259s (i); 326 } 327 } 427 } 428 328 429 /* 329 430 * must enable slave pic anyway … … 364 465 } 365 466 467 static inline void 468 bsp_irq_dispatch_list( 469 rtems_irq_connect_data *tbl, 470 unsigned irq, 471 rtems_irq_hdl sentinel 472 ) 473 { 474 rtems_irq_connect_data* vchain; 475 for( vchain = &tbl[irq]; 476 ((int)vchain != -1 && vchain->hdl != sentinel); 477 vchain = (rtems_irq_connect_data*)vchain->next_handler ) { 478 vchain->hdl(vchain->handle); 479 } 480 } 481 482 483 void C_dispatch_isr(int irq) 484 { 485 bsp_irq_dispatch_list(rtems_hdl_tbl, irq, default_rtems_entry.hdl); 486 } -
c/src/lib/libbsp/i386/shared/irq/irq.h
r9bb39026 ra62222fb 32 32 #include <bsp/irq_asm.h> 33 33 #include <rtems.h> 34 #define BSP_SHARED_HANDLER_SUPPORT 1 34 35 #include <rtems/irq.h> 35 36 -
c/src/lib/libbsp/i386/shared/irq/irq_asm.S
r9bb39026 ra62222fb 108 108 109 109 pushl ecx /* push vector number */ 110 lea (ecx,ecx,2), eax 111 mov SYM (rtems_hdl_tbl), edx 112 shl $0x3,eax 113 pushl 0x8(edx,eax,1) /* push hdl argument */ 114 call *0x4(edx,eax,1) /* call hdl */ 110 call C_dispatch_isr 115 111 addl $4, esp 116 112
Note: See TracChangeset
for help on using the changeset viewer.