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