Advertisement
iocoder

8259A PIC Device Driver

Dec 20th, 2012
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.19 KB | None | 0 0
  1. /*
  2.       +----------------------------------------------------------+
  3.       | +------------------------------------------------------+ |
  4.       | |  Quafios Kernel 1.0.1.                   | |
  5.       | |  -> Intel 8259A PIC Device Driver.           | |
  6.       | +------------------------------------------------------+ |
  7.       +----------------------------------------------------------+
  8. */
  9.  
  10. // This file is part of Quafios 1.0.1 source code.
  11. // Copyright (C) 2012  Mostafa Abd El-Aziz Mohamed.
  12.  
  13. // This program is free software: you can redistribute it and/or modify
  14. // it under the terms of the GNU General Public License as published by
  15. // the Free Software Foundation, either version 3 of the License, or
  16. // (at your option) any later version.
  17.  
  18. // This program is distributed in the hope that it will be useful,
  19. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21. // GNU General Public License for more details.
  22.  
  23. // You should have received a copy of the GNU General Public License
  24. // along with Quafios.  If not, see <http://www.gnu.org/licenses/>.
  25.  
  26. // Visit http://www.quafios.com/ for contact information.
  27.  
  28. #define PIC8259A_CMD        0 /* Command Port */
  29. #define PIC8259A_DATA       1 /* Data Port */
  30.  
  31. struct {
  32.     unsigned char used;    // 0: free entry, 1: used
  33.     io_addr       iobase;  // IO Addresses Base.
  34.     unsigned int  baseirq; // IRQ Base.
  35.     unsigned int  cascade; // defined in pic.h
  36.     unsigned int  casirq;  // Cascade IRQ.
  37. } pic8259A_inst[100] = {0};
  38.  
  39. int pic8259A_eoi(unsigned int inst, void*data) {
  40.     // send EOI (End of interrupt) command:
  41.     // Operation Control Word 2 {interrupt command register} [Command Port]:
  42.     // bits 0-2: IRQ level to act upon.
  43.     // bits 3-4: must be zero for OCW2.
  44.     // bits 5-7: EOI Code:  001: non-specific EOI command.
  45.     //          011: specific EOI command.
  46.     //          100: rotate in automatic EOI mode.
  47.     //          101: rotate on non-specific EOI command.
  48.     //          111: rotate on specific EOI command.
  49.     //          010: NOP.
  50.     //          110: set priority command (using bits 0-2).
  51.     unsigned char OCW2 = 0x20;
  52.     iowrite(1, OCW2, pic8259A_inst[inst].iobase, PIC8259A_CMD);
  53.     return 0;
  54. }
  55.  
  56. int pic8259A_mkinst(dev_mkinst_data *data) {
  57.  
  58.     // PIC 8259A needs one (and only one) iobase parameter:
  59.     if (data->iobase->count != 1)
  60.         return EBUSY;
  61.  
  62.     // search for free instance:
  63.     unsigned int inst;
  64.     for (inst = 0; inst < 100 && pic8259A_inst[inst].used; inst++);
  65.     if ((*(data->new_inst) = inst) == 100)
  66.         return ENOMEM;
  67.  
  68.     // Store data:
  69.     pic8259A_inst[inst].used    = 1;
  70.     pic8259A_inst[inst].iobase  = data->iobase->arr[0];
  71.     pic8259A_inst[inst].baseirq = ((pic_init_t *) data->specific)->baseirq;
  72.     pic8259A_inst[inst].cascade = ((pic_init_t *) data->specific)->cascade;
  73.     pic8259A_inst[inst].casirq  = ((pic_init_t *) data->specific)->casirq;
  74.  
  75.     // initialize 8259A chip:
  76.  
  77.     // Initialization Command Word 1 [Command Port]:
  78.     // bit0: 0: no ICW4 needed, 1: ICW4 needed
  79.     // bit1: 0: cascading, 1: single.
  80.     // bit2: 0: 8-byte int vectors, 1: 4-byte int vectors.
  81.     // bit3: 0: edge-triggered, 1: level-triggered.
  82.     // bit4: must be 1 (shows that this is ICW1).
  83.     // bit5-7: should be zeros.
  84.     unsigned char ICW1 = 0x10 | (pic8259A_inst[inst].cascade > 0 ? 2 : 0);
  85.     iowrite(1, ICW1, pic8259A_inst[inst].iobase, PIC8259A_CMD);
  86.  
  87.     // Initialization Command Word 2 [Data Port]:
  88.     // bit0-2: zeros for 80x86 systems.
  89.     // bit3-7: bits3-7 of the vector.
  90.     unsigned char ICW2 = IRQ_TO_VECTOR(pic8259A_inst[inst].baseirq);
  91.     iowrite(1, ICW2, pic8259A_inst[inst].iobase, PIC8259A_DATA);
  92.  
  93.     // Initialization Command Word 3 [Data Port]:
  94.     // for master device:
  95.     // bit n: 0: no slave at IRQ bin n, 1: a slave device is attached.
  96.     // for slave:
  97.     // bits0-2: Master IRQ to which this slave chip is attached.
  98.     // bits3-7: should be zeros.
  99.     if (pic8259A_inst[inst].cascade) {
  100.         unsigned char ICW3 = 0;
  101.         if (pic8259A_inst[inst].cascade == CASCADE_MASTER)
  102.             ICW3 = 1 << pic8259A_inst[inst].casirq;
  103.         else
  104.             ICW3 = pic8259A_inst[inst].casirq;
  105.         iowrite(1, ICW3, pic8259A_inst[inst].iobase, PIC8259A_DATA);
  106.     }
  107.  
  108.     // Initialization Command Word 4 [Data Port]:
  109.     // bit0: 0: MCS 80/85 mode, 1: 80x86 mode
  110.     // bit1: 0: Normal EOI, 1: Auto EOI.
  111.     // bit2-3: 00, 01: not buffered, 10: buffered mode (slave), 11: master.
  112.     // bit4: 0: Sequential, 1: Special Fully Nested Mode.
  113.     // bit5-7: should be zero.
  114.     unsigned char ICW4 = 0x01;
  115.     iowrite(1, ICW4, pic8259A_inst[inst].iobase, PIC8259A_DATA);
  116.  
  117.     // Operation Control Word 1 {interrupt mask register} [Data Port]:
  118.     // bit n: 0: service IRQ n, 1: mask off.
  119.     unsigned char OCW1 = 0;
  120.     iowrite(1, OCW1, pic8259A_inst[inst].iobase, PIC8259A_DATA);
  121.  
  122.     // Initialize IRQs:
  123.     unsigned int devid = interface_to_devid((void *) &pic8259A_interface);
  124.     for (int i = pic8259A_inst[inst].baseirq; i < 8; i++) {
  125.         irq[i].pic_devid = devid;
  126.         irq[i].pic_inst  = inst;
  127.         irq[i].usable = 1;
  128.     }
  129.  
  130.     // Enable IRQ system:
  131.     if (((pic_init_t *) data->specific)->irqenable)
  132.         enable_irq_system();
  133.  
  134.     // return:
  135.     return 0;
  136. }
  137.  
  138. unsigned int pic8259A_interface(unsigned int cmd, unsigned int inst, void*data) {
  139.     switch (cmd) {
  140.         case DEV_MKINST:
  141.             return pic8259A_mkinst(data);
  142.  
  143.         case DEV_PIC_EOI:
  144.             return pic8259A_eoi(inst, data);
  145.  
  146.         default:
  147.             return EBUSY;
  148.     }
  149. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement