Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- +----------------------------------------------------------+
- | +------------------------------------------------------+ |
- | | Quafios Kernel 1.0.1. | |
- | | -> Intel 8259A PIC Device Driver. | |
- | +------------------------------------------------------+ |
- +----------------------------------------------------------+
- */
- // This file is part of Quafios 1.0.1 source code.
- // Copyright (C) 2012 Mostafa Abd El-Aziz Mohamed.
- // This program is free software: you can redistribute it and/or modify
- // it under the terms of the GNU General Public License as published by
- // the Free Software Foundation, either version 3 of the License, or
- // (at your option) any later version.
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- // You should have received a copy of the GNU General Public License
- // along with Quafios. If not, see <http://www.gnu.org/licenses/>.
- // Visit http://www.quafios.com/ for contact information.
- #define PIC8259A_CMD 0 /* Command Port */
- #define PIC8259A_DATA 1 /* Data Port */
- struct {
- unsigned char used; // 0: free entry, 1: used
- io_addr iobase; // IO Addresses Base.
- unsigned int baseirq; // IRQ Base.
- unsigned int cascade; // defined in pic.h
- unsigned int casirq; // Cascade IRQ.
- } pic8259A_inst[100] = {0};
- int pic8259A_eoi(unsigned int inst, void*data) {
- // send EOI (End of interrupt) command:
- // Operation Control Word 2 {interrupt command register} [Command Port]:
- // bits 0-2: IRQ level to act upon.
- // bits 3-4: must be zero for OCW2.
- // bits 5-7: EOI Code: 001: non-specific EOI command.
- // 011: specific EOI command.
- // 100: rotate in automatic EOI mode.
- // 101: rotate on non-specific EOI command.
- // 111: rotate on specific EOI command.
- // 010: NOP.
- // 110: set priority command (using bits 0-2).
- unsigned char OCW2 = 0x20;
- iowrite(1, OCW2, pic8259A_inst[inst].iobase, PIC8259A_CMD);
- return 0;
- }
- int pic8259A_mkinst(dev_mkinst_data *data) {
- // PIC 8259A needs one (and only one) iobase parameter:
- if (data->iobase->count != 1)
- return EBUSY;
- // search for free instance:
- unsigned int inst;
- for (inst = 0; inst < 100 && pic8259A_inst[inst].used; inst++);
- if ((*(data->new_inst) = inst) == 100)
- return ENOMEM;
- // Store data:
- pic8259A_inst[inst].used = 1;
- pic8259A_inst[inst].iobase = data->iobase->arr[0];
- pic8259A_inst[inst].baseirq = ((pic_init_t *) data->specific)->baseirq;
- pic8259A_inst[inst].cascade = ((pic_init_t *) data->specific)->cascade;
- pic8259A_inst[inst].casirq = ((pic_init_t *) data->specific)->casirq;
- // initialize 8259A chip:
- // Initialization Command Word 1 [Command Port]:
- // bit0: 0: no ICW4 needed, 1: ICW4 needed
- // bit1: 0: cascading, 1: single.
- // bit2: 0: 8-byte int vectors, 1: 4-byte int vectors.
- // bit3: 0: edge-triggered, 1: level-triggered.
- // bit4: must be 1 (shows that this is ICW1).
- // bit5-7: should be zeros.
- unsigned char ICW1 = 0x10 | (pic8259A_inst[inst].cascade > 0 ? 2 : 0);
- iowrite(1, ICW1, pic8259A_inst[inst].iobase, PIC8259A_CMD);
- // Initialization Command Word 2 [Data Port]:
- // bit0-2: zeros for 80x86 systems.
- // bit3-7: bits3-7 of the vector.
- unsigned char ICW2 = IRQ_TO_VECTOR(pic8259A_inst[inst].baseirq);
- iowrite(1, ICW2, pic8259A_inst[inst].iobase, PIC8259A_DATA);
- // Initialization Command Word 3 [Data Port]:
- // for master device:
- // bit n: 0: no slave at IRQ bin n, 1: a slave device is attached.
- // for slave:
- // bits0-2: Master IRQ to which this slave chip is attached.
- // bits3-7: should be zeros.
- if (pic8259A_inst[inst].cascade) {
- unsigned char ICW3 = 0;
- if (pic8259A_inst[inst].cascade == CASCADE_MASTER)
- ICW3 = 1 << pic8259A_inst[inst].casirq;
- else
- ICW3 = pic8259A_inst[inst].casirq;
- iowrite(1, ICW3, pic8259A_inst[inst].iobase, PIC8259A_DATA);
- }
- // Initialization Command Word 4 [Data Port]:
- // bit0: 0: MCS 80/85 mode, 1: 80x86 mode
- // bit1: 0: Normal EOI, 1: Auto EOI.
- // bit2-3: 00, 01: not buffered, 10: buffered mode (slave), 11: master.
- // bit4: 0: Sequential, 1: Special Fully Nested Mode.
- // bit5-7: should be zero.
- unsigned char ICW4 = 0x01;
- iowrite(1, ICW4, pic8259A_inst[inst].iobase, PIC8259A_DATA);
- // Operation Control Word 1 {interrupt mask register} [Data Port]:
- // bit n: 0: service IRQ n, 1: mask off.
- unsigned char OCW1 = 0;
- iowrite(1, OCW1, pic8259A_inst[inst].iobase, PIC8259A_DATA);
- // Initialize IRQs:
- unsigned int devid = interface_to_devid((void *) &pic8259A_interface);
- for (int i = pic8259A_inst[inst].baseirq; i < 8; i++) {
- irq[i].pic_devid = devid;
- irq[i].pic_inst = inst;
- irq[i].usable = 1;
- }
- // Enable IRQ system:
- if (((pic_init_t *) data->specific)->irqenable)
- enable_irq_system();
- // return:
- return 0;
- }
- unsigned int pic8259A_interface(unsigned int cmd, unsigned int inst, void*data) {
- switch (cmd) {
- case DEV_MKINST:
- return pic8259A_mkinst(data);
- case DEV_PIC_EOI:
- return pic8259A_eoi(inst, data);
- default:
- return EBUSY;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement