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