i8259.cc revision 5631
15390SN/A/*
25390SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan
35390SN/A * All rights reserved.
45390SN/A *
55390SN/A * Redistribution and use in source and binary forms, with or without
65390SN/A * modification, are permitted provided that the following conditions are
75390SN/A * met: redistributions of source code must retain the above copyright
85390SN/A * notice, this list of conditions and the following disclaimer;
95390SN/A * redistributions in binary form must reproduce the above copyright
105390SN/A * notice, this list of conditions and the following disclaimer in the
115390SN/A * documentation and/or other materials provided with the distribution;
125390SN/A * neither the name of the copyright holders nor the names of its
135390SN/A * contributors may be used to endorse or promote products derived from
145390SN/A * this software without specific prior written permission.
155390SN/A *
165390SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
175390SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
185390SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
195390SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
205390SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
215390SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
225390SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
235390SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
245390SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
255390SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
265390SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
275390SN/A *
285390SN/A * Authors: Gabe Black
295390SN/A */
305390SN/A
315631Sgblack@eecs.umich.edu#include "base/bitfield.hh"
325630Sgblack@eecs.umich.edu#include "dev/x86/i8259.hh"
335390SN/A
345390SN/ATick
355390SN/AX86ISA::I8259::read(PacketPtr pkt)
365390SN/A{
375631Sgblack@eecs.umich.edu    assert(pkt->getSize() == 1);
385631Sgblack@eecs.umich.edu    switch(pkt->getAddr() - pioAddr)
395631Sgblack@eecs.umich.edu    {
405631Sgblack@eecs.umich.edu      case 0x0:
415631Sgblack@eecs.umich.edu        if (readIRR) {
425631Sgblack@eecs.umich.edu            DPRINTF(I8259, "Reading IRR as %#x.\n", IRR);
435631Sgblack@eecs.umich.edu            pkt->set(IRR);
445631Sgblack@eecs.umich.edu        } else {
455631Sgblack@eecs.umich.edu            DPRINTF(I8259, "Reading ISR as %#x.\n", ISR);
465631Sgblack@eecs.umich.edu            pkt->set(ISR);
475631Sgblack@eecs.umich.edu        }
485631Sgblack@eecs.umich.edu        break;
495631Sgblack@eecs.umich.edu      case 0x1:
505631Sgblack@eecs.umich.edu        DPRINTF(I8259, "Reading IMR as %#x.\n", IMR);
515631Sgblack@eecs.umich.edu        pkt->set(IMR);
525631Sgblack@eecs.umich.edu        break;
535631Sgblack@eecs.umich.edu    }
545630Sgblack@eecs.umich.edu    return latency;
555390SN/A}
565390SN/A
575390SN/ATick
585390SN/AX86ISA::I8259::write(PacketPtr pkt)
595390SN/A{
605631Sgblack@eecs.umich.edu    assert(pkt->getSize() == 1);
615631Sgblack@eecs.umich.edu    uint8_t val = pkt->get<uint8_t>();
625631Sgblack@eecs.umich.edu    switch (pkt->getAddr() - pioAddr) {
635631Sgblack@eecs.umich.edu      case 0x0:
645631Sgblack@eecs.umich.edu        if (bits(val, 4)) {
655631Sgblack@eecs.umich.edu            DPRINTF(I8259, "Received initialization command word 1.\n");
665631Sgblack@eecs.umich.edu            IMR = 0;
675631Sgblack@eecs.umich.edu            edgeTriggered = bits(val, 3);
685631Sgblack@eecs.umich.edu            DPRINTF(I8259, "%s triggered mode.\n",
695631Sgblack@eecs.umich.edu                    edgeTriggered ? "Edge" : "Level");
705631Sgblack@eecs.umich.edu            cascadeMode = !bits(val, 1);
715631Sgblack@eecs.umich.edu            DPRINTF(I8259, "%s mode.\n",
725631Sgblack@eecs.umich.edu                    cascadeMode ? "Cascade" : "Single");
735631Sgblack@eecs.umich.edu            expectICW4 = bits(val, 0);
745631Sgblack@eecs.umich.edu            initControlWord = 1;
755631Sgblack@eecs.umich.edu            DPRINTF(I8259, "Expecting %d more bytes.\n", expectICW4 ? 3 : 2);
765631Sgblack@eecs.umich.edu        } else if (bits(val, 4, 3) == 0) {
775631Sgblack@eecs.umich.edu            DPRINTF(I8259, "Received operation command word 2.\n");
785631Sgblack@eecs.umich.edu            switch (bits(val, 7, 5)) {
795631Sgblack@eecs.umich.edu              case 0x0:
805631Sgblack@eecs.umich.edu                DPRINTF(I8259,
815631Sgblack@eecs.umich.edu                        "Subcommand: Rotate in auto-EOI mode (clear).\n");
825631Sgblack@eecs.umich.edu                break;
835631Sgblack@eecs.umich.edu              case 0x1:
845631Sgblack@eecs.umich.edu                DPRINTF(I8259, "Subcommand: Nonspecific EOI.\n");
855631Sgblack@eecs.umich.edu                break;
865631Sgblack@eecs.umich.edu              case 0x2:
875631Sgblack@eecs.umich.edu                DPRINTF(I8259, "Subcommand: No operation.\n");
885631Sgblack@eecs.umich.edu                break;
895631Sgblack@eecs.umich.edu              case 0x3:
905631Sgblack@eecs.umich.edu                DPRINTF(I8259, "Subcommand: Specific EIO.");
915631Sgblack@eecs.umich.edu                DPRINTF(I8259, "Reset In-Service bit %d.\n", bits(val, 2, 0));
925631Sgblack@eecs.umich.edu                break;
935631Sgblack@eecs.umich.edu              case 0x4:
945631Sgblack@eecs.umich.edu                DPRINTF(I8259, "Subcommand: Rotate in auto-EOI mode (set).\n");
955631Sgblack@eecs.umich.edu                break;
965631Sgblack@eecs.umich.edu              case 0x5:
975631Sgblack@eecs.umich.edu                DPRINTF(I8259, "Subcommand: Rotate on nonspecific EOI.\n");
985631Sgblack@eecs.umich.edu                break;
995631Sgblack@eecs.umich.edu              case 0x6:
1005631Sgblack@eecs.umich.edu                DPRINTF(I8259, "Subcommand: Set priority command.\n");
1015631Sgblack@eecs.umich.edu                DPRINTF(I8259, "Lowest: IRQ%d   Highest IRQ%d.\n",
1025631Sgblack@eecs.umich.edu                        bits(val, 2, 0), (bits(val, 2, 0) + 1) % 8);
1035631Sgblack@eecs.umich.edu                break;
1045631Sgblack@eecs.umich.edu              case 0x7:
1055631Sgblack@eecs.umich.edu                DPRINTF(I8259, "Subcommand: Rotate on specific EOI.\n");
1065631Sgblack@eecs.umich.edu                DPRINTF(I8259, "Lowest: IRQ%d   Highest IRQ%d.\n",
1075631Sgblack@eecs.umich.edu                        bits(val, 2, 0), (bits(val, 2, 0) + 1) % 8);
1085631Sgblack@eecs.umich.edu                break;
1095631Sgblack@eecs.umich.edu            }
1105631Sgblack@eecs.umich.edu        } else if (bits(val, 4, 3) == 1) {
1115631Sgblack@eecs.umich.edu            DPRINTF(I8259, "Received operation command word 3.\n");
1125631Sgblack@eecs.umich.edu            if (bits(val, 7)) {
1135631Sgblack@eecs.umich.edu                DPRINTF(I8259, "%s special mask mode.\n",
1145631Sgblack@eecs.umich.edu                        bits(val, 6) ? "Set" : "Clear");
1155631Sgblack@eecs.umich.edu            }
1165631Sgblack@eecs.umich.edu            if (bits(val, 1)) {
1175631Sgblack@eecs.umich.edu                readIRR = bits(val, 0);
1185631Sgblack@eecs.umich.edu                DPRINTF(I8259, "Read %s.\n", readIRR ? "IRR" : "ISR");
1195631Sgblack@eecs.umich.edu            }
1205631Sgblack@eecs.umich.edu        }
1215631Sgblack@eecs.umich.edu        break;
1225631Sgblack@eecs.umich.edu      case 0x1:
1235631Sgblack@eecs.umich.edu        switch (initControlWord) {
1245631Sgblack@eecs.umich.edu          case 0x0:
1255631Sgblack@eecs.umich.edu            DPRINTF(I8259, "Received operation command word 1.\n");
1265631Sgblack@eecs.umich.edu            DPRINTF(I8259, "Wrote IMR value %#x.\n", val);
1275631Sgblack@eecs.umich.edu            IMR = val;
1285631Sgblack@eecs.umich.edu            break;
1295631Sgblack@eecs.umich.edu          case 0x1:
1305631Sgblack@eecs.umich.edu            DPRINTF(I8259, "Received initialization command word 2.\n");
1315631Sgblack@eecs.umich.edu            DPRINTF(I8259, "Responsible for vectors %#x-%#x.\n",
1325631Sgblack@eecs.umich.edu                    val & ~mask(3), val | mask(3));
1335631Sgblack@eecs.umich.edu            if (cascadeMode) {
1345631Sgblack@eecs.umich.edu                initControlWord++;
1355631Sgblack@eecs.umich.edu            } else {
1365631Sgblack@eecs.umich.edu                initControlWord = 0;
1375631Sgblack@eecs.umich.edu            }
1385631Sgblack@eecs.umich.edu            break;
1395631Sgblack@eecs.umich.edu          case 0x2:
1405631Sgblack@eecs.umich.edu            DPRINTF(I8259, "Received initialization command word 3.\n");
1415631Sgblack@eecs.umich.edu            if (master) {
1425631Sgblack@eecs.umich.edu                DPRINTF(I8259, "Slaves attached to IRQs:%s%s%s%s%s%s%s%s\n",
1435631Sgblack@eecs.umich.edu                        bits(val, 0) ? " 0" : "",
1445631Sgblack@eecs.umich.edu                        bits(val, 1) ? " 1" : "",
1455631Sgblack@eecs.umich.edu                        bits(val, 2) ? " 2" : "",
1465631Sgblack@eecs.umich.edu                        bits(val, 3) ? " 3" : "",
1475631Sgblack@eecs.umich.edu                        bits(val, 4) ? " 4" : "",
1485631Sgblack@eecs.umich.edu                        bits(val, 5) ? " 5" : "",
1495631Sgblack@eecs.umich.edu                        bits(val, 6) ? " 6" : "",
1505631Sgblack@eecs.umich.edu                        bits(val, 7) ? " 7" : "");
1515631Sgblack@eecs.umich.edu            } else {
1525631Sgblack@eecs.umich.edu                DPRINTF(I8259, "Slave ID is %d.\n", val & mask(3));
1535631Sgblack@eecs.umich.edu            }
1545631Sgblack@eecs.umich.edu            if (expectICW4)
1555631Sgblack@eecs.umich.edu                initControlWord++;
1565631Sgblack@eecs.umich.edu            else
1575631Sgblack@eecs.umich.edu                initControlWord = 0;
1585631Sgblack@eecs.umich.edu            break;
1595631Sgblack@eecs.umich.edu          case 0x3:
1605631Sgblack@eecs.umich.edu            DPRINTF(I8259, "Received initialization command word 4.\n");
1615631Sgblack@eecs.umich.edu            if (bits(val, 4)) {
1625631Sgblack@eecs.umich.edu                DPRINTF(I8259, "Special fully nested mode.\n");
1635631Sgblack@eecs.umich.edu            } else {
1645631Sgblack@eecs.umich.edu                DPRINTF(I8259, "Not special fully nested mode.\n");
1655631Sgblack@eecs.umich.edu            }
1665631Sgblack@eecs.umich.edu            if (bits(val, 3) == 0) {
1675631Sgblack@eecs.umich.edu                DPRINTF(I8259, "Nonbuffered.\n");
1685631Sgblack@eecs.umich.edu            } else if (bits(val, 2) == 0) {
1695631Sgblack@eecs.umich.edu                DPRINTF(I8259, "Buffered.\n");
1705631Sgblack@eecs.umich.edu            } else {
1715631Sgblack@eecs.umich.edu                DPRINTF(I8259, "Unrecognized buffer mode.\n");
1725631Sgblack@eecs.umich.edu            }
1735631Sgblack@eecs.umich.edu            DPRINTF(I8259, "%s End Of Interrupt.\n",
1745631Sgblack@eecs.umich.edu                    bits(val, 1) ? "Automatic" : "Normal");
1755631Sgblack@eecs.umich.edu            DPRINTF(I8259, "%s mode.\n", bits(val, 0) ? "80x86" : "MCX-80/85");
1765631Sgblack@eecs.umich.edu            initControlWord = 0;
1775631Sgblack@eecs.umich.edu            break;
1785631Sgblack@eecs.umich.edu        }
1795631Sgblack@eecs.umich.edu        break;
1805631Sgblack@eecs.umich.edu    }
1815630Sgblack@eecs.umich.edu    return latency;
1825390SN/A}
1835630Sgblack@eecs.umich.edu
1845630Sgblack@eecs.umich.eduX86ISA::I8259 *
1855630Sgblack@eecs.umich.eduI8259Params::create()
1865630Sgblack@eecs.umich.edu{
1875630Sgblack@eecs.umich.edu    return new X86ISA::I8259(this);
1885630Sgblack@eecs.umich.edu}
189