1/* 2 * Basic support for controlling the 8259 Programmable Interrupt Controllers. 3 * 4 * Initially written by Michael Brown (mcb30). 5 */ 6 7#ifndef PIC8259_H 8#define PIC8259_H 9 10/* For segoff_t */ 11#include <segoff.h> 12 13#define IRQ_PIC_CUTOFF (8) 14 15/* 8259 register locations */ 16#define PIC1_ICW1 (0x20) 17#define PIC1_OCW2 (0x20) 18#define PIC1_OCW3 (0x20) 19#define PIC1_ICR (0x20) 20#define PIC1_IRR (0x20) 21#define PIC1_ISR (0x20) 22#define PIC1_ICW2 (0x21) 23#define PIC1_ICW3 (0x21) 24#define PIC1_ICW4 (0x21) 25#define PIC1_IMR (0x21) 26#define PIC2_ICW1 (0xa0) 27#define PIC2_OCW2 (0xa0) 28#define PIC2_OCW3 (0xa0) 29#define PIC2_ICR (0xa0) 30#define PIC2_IRR (0xa0) 31#define PIC2_ISR (0xa0) 32#define PIC2_ICW2 (0xa1) 33#define PIC2_ICW3 (0xa1) 34#define PIC2_ICW4 (0xa1) 35#define PIC2_IMR (0xa1) 36 37/* Register command values */ 38#define OCW3_ID (0x08) 39#define OCW3_READ_IRR (0x03) 40#define OCW3_READ_ISR (0x02) 41#define ICR_EOI_NON_SPECIFIC (0x20) 42#define ICR_EOI_NOP (0x40) 43#define ICR_EOI_SPECIFIC (0x60) 44#define ICR_EOI_SET_PRIORITY (0xc0) 45 46/* Macros to enable/disable IRQs */ 47#define IMR_REG(x) ( (x) < IRQ_PIC_CUTOFF ? PIC1_IMR : PIC2_IMR ) 48#define IMR_BIT(x) ( 1 << ( (x) % IRQ_PIC_CUTOFF ) ) 49#define irq_enabled(x) ( ( inb ( IMR_REG(x) ) & IMR_BIT(x) ) == 0 ) 50#define enable_irq(x) outb ( inb( IMR_REG(x) ) & ~IMR_BIT(x), IMR_REG(x) ) 51#define disable_irq(x) outb ( inb( IMR_REG(x) ) | IMR_BIT(x), IMR_REG(x) ) 52 53/* Macros for acknowledging IRQs */ 54#define ICR_REG(x) ( (x) < IRQ_PIC_CUTOFF ? PIC1_ICR : PIC2_ICR ) 55#define ICR_VALUE(x) ( (x) % IRQ_PIC_CUTOFF ) 56#define CHAINED_IRQ 2 57 58/* Utility macros to convert IRQ numbers to INT numbers and INT vectors */ 59#define IRQ_INT(x) ( (x)<IRQ_PIC_CUTOFF ? (x)+0x08 : (x)-IRQ_PIC_CUTOFF+0x70 ) 60#define INT_VECTOR(x) ( (segoff_t*) phys_to_virt( 4 * (x) ) ) 61#define IRQ_VECTOR(x) ( INT_VECTOR ( IRQ_INT(x) ) ) 62 63/* Other constants */ 64typedef uint8_t irq_t; 65#define IRQ_MAX (15) 66#define IRQ_NONE (0xff) 67 68/* Labels in assembly code (asm.S) 69 */ 70extern void _undi_irq_handler_start; 71extern void _undi_irq_handler ( void ); 72extern volatile uint16_t _undi_irq_trigger_count; 73extern volatile uint16_t _undi_irq_fail_count; 74extern volatile uint16_t _undi_irq_not_ours_count; 75extern segoff_t _undi_irq_chain_to; 76extern uint8_t _undi_irq_chain; 77extern uint8_t _pxenv_undi_irq; 78extern segoff_t _pxenv_undi_entrypointsp; 79 80/* Function prototypes 81 */ 82int install_irq_handler ( irq_t irq, segoff_t *handler, 83 uint8_t *previously_enabled, 84 segoff_t *previous_handler ); 85int remove_irq_handler ( irq_t irq, segoff_t *handler, 86 uint8_t *previously_enabled, 87 segoff_t *previous_handler ); 88int install_undi_irq_handler ( irq_t irq, segoff_t ); 89int remove_undi_irq_handler ( irq_t irq ); 90int undi_irq_triggered ( irq_t irq ); 91void send_specific_eoi ( irq_t irq ); 92#ifdef DEBUG_IRQ 93void dump_irq_status ( void ); 94#else 95#define dump_irq_status() 96#endif 97 98#endif /* PIC8259_H */ 99