17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * Basic support for controlling the 8259 Programmable Interrupt Controllers. 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * Initially written by Michael Brown (mcb30). 57c478bd9Sstevel@tonic-gate */ 67c478bd9Sstevel@tonic-gate 77c478bd9Sstevel@tonic-gate #ifndef PIC8259_H 87c478bd9Sstevel@tonic-gate #define PIC8259_H 97c478bd9Sstevel@tonic-gate 107c478bd9Sstevel@tonic-gate /* For segoff_t */ 117c478bd9Sstevel@tonic-gate #include <segoff.h> 127c478bd9Sstevel@tonic-gate 137c478bd9Sstevel@tonic-gate #define IRQ_PIC_CUTOFF (8) 147c478bd9Sstevel@tonic-gate 157c478bd9Sstevel@tonic-gate /* 8259 register locations */ 167c478bd9Sstevel@tonic-gate #define PIC1_ICW1 (0x20) 177c478bd9Sstevel@tonic-gate #define PIC1_OCW2 (0x20) 187c478bd9Sstevel@tonic-gate #define PIC1_OCW3 (0x20) 197c478bd9Sstevel@tonic-gate #define PIC1_ICR (0x20) 207c478bd9Sstevel@tonic-gate #define PIC1_IRR (0x20) 217c478bd9Sstevel@tonic-gate #define PIC1_ISR (0x20) 227c478bd9Sstevel@tonic-gate #define PIC1_ICW2 (0x21) 237c478bd9Sstevel@tonic-gate #define PIC1_ICW3 (0x21) 247c478bd9Sstevel@tonic-gate #define PIC1_ICW4 (0x21) 257c478bd9Sstevel@tonic-gate #define PIC1_IMR (0x21) 267c478bd9Sstevel@tonic-gate #define PIC2_ICW1 (0xa0) 277c478bd9Sstevel@tonic-gate #define PIC2_OCW2 (0xa0) 287c478bd9Sstevel@tonic-gate #define PIC2_OCW3 (0xa0) 297c478bd9Sstevel@tonic-gate #define PIC2_ICR (0xa0) 307c478bd9Sstevel@tonic-gate #define PIC2_IRR (0xa0) 317c478bd9Sstevel@tonic-gate #define PIC2_ISR (0xa0) 327c478bd9Sstevel@tonic-gate #define PIC2_ICW2 (0xa1) 337c478bd9Sstevel@tonic-gate #define PIC2_ICW3 (0xa1) 347c478bd9Sstevel@tonic-gate #define PIC2_ICW4 (0xa1) 357c478bd9Sstevel@tonic-gate #define PIC2_IMR (0xa1) 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gate /* Register command values */ 387c478bd9Sstevel@tonic-gate #define OCW3_ID (0x08) 397c478bd9Sstevel@tonic-gate #define OCW3_READ_IRR (0x03) 407c478bd9Sstevel@tonic-gate #define OCW3_READ_ISR (0x02) 417c478bd9Sstevel@tonic-gate #define ICR_EOI_NON_SPECIFIC (0x20) 427c478bd9Sstevel@tonic-gate #define ICR_EOI_NOP (0x40) 437c478bd9Sstevel@tonic-gate #define ICR_EOI_SPECIFIC (0x60) 447c478bd9Sstevel@tonic-gate #define ICR_EOI_SET_PRIORITY (0xc0) 457c478bd9Sstevel@tonic-gate 467c478bd9Sstevel@tonic-gate /* Macros to enable/disable IRQs */ 477c478bd9Sstevel@tonic-gate #define IMR_REG(x) ( (x) < IRQ_PIC_CUTOFF ? PIC1_IMR : PIC2_IMR ) 487c478bd9Sstevel@tonic-gate #define IMR_BIT(x) ( 1 << ( (x) % IRQ_PIC_CUTOFF ) ) 497c478bd9Sstevel@tonic-gate #define irq_enabled(x) ( ( inb ( IMR_REG(x) ) & IMR_BIT(x) ) == 0 ) 507c478bd9Sstevel@tonic-gate #define enable_irq(x) outb ( inb( IMR_REG(x) ) & ~IMR_BIT(x), IMR_REG(x) ) 517c478bd9Sstevel@tonic-gate #define disable_irq(x) outb ( inb( IMR_REG(x) ) | IMR_BIT(x), IMR_REG(x) ) 527c478bd9Sstevel@tonic-gate 537c478bd9Sstevel@tonic-gate /* Macros for acknowledging IRQs */ 547c478bd9Sstevel@tonic-gate #define ICR_REG(x) ( (x) < IRQ_PIC_CUTOFF ? PIC1_ICR : PIC2_ICR ) 557c478bd9Sstevel@tonic-gate #define ICR_VALUE(x) ( (x) % IRQ_PIC_CUTOFF ) 567c478bd9Sstevel@tonic-gate #define CHAINED_IRQ 2 577c478bd9Sstevel@tonic-gate 587c478bd9Sstevel@tonic-gate /* Utility macros to convert IRQ numbers to INT numbers and INT vectors */ 597c478bd9Sstevel@tonic-gate #define IRQ_INT(x) ( (x)<IRQ_PIC_CUTOFF ? (x)+0x08 : (x)-IRQ_PIC_CUTOFF+0x70 ) 607c478bd9Sstevel@tonic-gate #define INT_VECTOR(x) ( (segoff_t*) phys_to_virt( 4 * (x) ) ) 617c478bd9Sstevel@tonic-gate #define IRQ_VECTOR(x) ( INT_VECTOR ( IRQ_INT(x) ) ) 627c478bd9Sstevel@tonic-gate 637c478bd9Sstevel@tonic-gate /* Other constants */ 647c478bd9Sstevel@tonic-gate typedef uint8_t irq_t; 657c478bd9Sstevel@tonic-gate #define IRQ_MAX (15) 667c478bd9Sstevel@tonic-gate #define IRQ_NONE (0xff) 677c478bd9Sstevel@tonic-gate 687c478bd9Sstevel@tonic-gate /* Labels in assembly code (asm.S) 697c478bd9Sstevel@tonic-gate */ 707c478bd9Sstevel@tonic-gate extern void _undi_irq_handler_start; 717c478bd9Sstevel@tonic-gate extern void _undi_irq_handler ( void ); 727c478bd9Sstevel@tonic-gate extern volatile uint16_t _undi_irq_trigger_count; 737c478bd9Sstevel@tonic-gate extern volatile uint16_t _undi_irq_fail_count; 747c478bd9Sstevel@tonic-gate extern volatile uint16_t _undi_irq_not_ours_count; 757c478bd9Sstevel@tonic-gate extern segoff_t _undi_irq_chain_to; 767c478bd9Sstevel@tonic-gate extern uint8_t _undi_irq_chain; 777c478bd9Sstevel@tonic-gate extern uint8_t _pxenv_undi_irq; 787c478bd9Sstevel@tonic-gate extern segoff_t _pxenv_undi_entrypointsp; 797c478bd9Sstevel@tonic-gate 807c478bd9Sstevel@tonic-gate /* Function prototypes 817c478bd9Sstevel@tonic-gate */ 827c478bd9Sstevel@tonic-gate int install_irq_handler ( irq_t irq, segoff_t *handler, 837c478bd9Sstevel@tonic-gate uint8_t *previously_enabled, 847c478bd9Sstevel@tonic-gate segoff_t *previous_handler ); 857c478bd9Sstevel@tonic-gate int remove_irq_handler ( irq_t irq, segoff_t *handler, 867c478bd9Sstevel@tonic-gate uint8_t *previously_enabled, 877c478bd9Sstevel@tonic-gate segoff_t *previous_handler ); 887c478bd9Sstevel@tonic-gate int install_undi_irq_handler ( irq_t irq, segoff_t ); 897c478bd9Sstevel@tonic-gate int remove_undi_irq_handler ( irq_t irq ); 907c478bd9Sstevel@tonic-gate int undi_irq_triggered ( irq_t irq ); 917c478bd9Sstevel@tonic-gate void send_specific_eoi ( irq_t irq ); 927c478bd9Sstevel@tonic-gate #ifdef DEBUG_IRQ 937c478bd9Sstevel@tonic-gate void dump_irq_status ( void ); 947c478bd9Sstevel@tonic-gate #else 957c478bd9Sstevel@tonic-gate #define dump_irq_status() 967c478bd9Sstevel@tonic-gate #endif 977c478bd9Sstevel@tonic-gate 987c478bd9Sstevel@tonic-gate #endif /* PIC8259_H */ 99