How to write C program for 8259 controller -
i working on interrupts. have understand how use 8259 pic. can guide me how write program in c it. (i worked on 8051) suppose can used 8051.
this set of definitions common rest of section. outb(), inb() , io_wait() functions, see page.
#define pic1 0x20 /* io base address master pic */ #define pic2 0xa0 /* io base address slave pic */ #define pic1_command pic1 #define pic1_data (pic1+1) #define pic2_command pic2 #define pic2_data (pic2+1)
perhaps common command issued pic chips end of interrupt (eoi) command (code 0x20). issued pic chips @ end of irq-based interrupt routine. if irq came master pic, sufficient issue command master pic; if irq came slave pic, necessary issue command both pic chips.
#define pic_eoi 0x20 /* end-of-interrupt command code */ void pic_sendeoi(unsigned char irq) { if(irq >= 8) outb(pic2_command,pic_eoi); outb(pic1_command,pic_eoi); }
when enter protected mode (or before hand, if you're not using grub) first command need give 2 pics initialise command (code 0x11). command makes pic wait 3 "initialisation words" on data port. these bytes give pic:
- its vector offset. (icw2)
- tell how wired master/slaves. (icw3)
- gives additional information environment. (icw4)
#define icw1_icw4 0x01 /* icw4 (not) needed */ #define icw1_single 0x02 /* single (cascade) mode */ #define icw1_interval4 0x04 /* call address interval 4 (8) */ #define icw1_level 0x08 /* level triggered (edge) mode */ #define icw1_init 0x10 /* initialization - required! */ #define icw4_8086 0x01 /* 8086/88 (mcs-80/85) mode */ #define icw4_auto 0x02 /* auto (normal) eoi */ #define icw4_buf_slave 0x08 /* buffered mode/slave */ #define icw4_buf_master 0x0c /* buffered mode/master */ #define icw4_sfnm 0x10 /* special nested (not) */
void pic_remap(int offset1, int offset2) { unsigned char a1, a2; a1 = inb(pic1_data); // save masks a2 = inb(pic2_data); outb(pic1_command, icw1_init+icw1_icw4); // starts initialization sequence (in cascade mode) io_wait(); outb(pic2_command, icw1_init+icw1_icw4); io_wait(); outb(pic1_data, offset1); // icw2: master pic vector offset io_wait(); outb(pic2_data, offset2); // icw2: slave pic vector offset io_wait(); outb(pic1_data, 4); // icw3: tell master pic there slave pic @ irq2 (0000 0100) io_wait(); outb(pic2_data, 2); // icw3: tell slave pic cascade identity (0000 0010) io_wait(); outb(pic1_data, icw4_8086); io_wait(); outb(pic2_data, icw4_8086); io_wait(); outb(pic1_data, a1); // restore saved masks. outb(pic2_data, a2); }
for masking
void irq_set_mask(unsigned char irqline) { uint16_t port; uint8_t value; if(irqline < 8) { port = pic1_data; } else { port = pic2_data; irqline -= 8; } value = inb(port) | (1 << irqline); outb(port, value); } void irq_clear_mask(unsigned char irqline) { uint16_t port; uint8_t value; if(irqline < 8) { port = pic1_data; } else { port = pic2_data; irqline -= 8; } value = inb(port) & ~(1 << irqline); outb(port, value); }
Comments
Post a Comment