i8259.cc revision 5656:f548d22a2f71
110431SOmar.Naji@arm.com/*
210431SOmar.Naji@arm.com * Copyright (c) 2004-2005 The Regents of The University of Michigan
310431SOmar.Naji@arm.com * All rights reserved.
410431SOmar.Naji@arm.com *
510431SOmar.Naji@arm.com * Redistribution and use in source and binary forms, with or without
610431SOmar.Naji@arm.com * modification, are permitted provided that the following conditions are
710431SOmar.Naji@arm.com * met: redistributions of source code must retain the above copyright
810431SOmar.Naji@arm.com * notice, this list of conditions and the following disclaimer;
910431SOmar.Naji@arm.com * redistributions in binary form must reproduce the above copyright
1010431SOmar.Naji@arm.com * notice, this list of conditions and the following disclaimer in the
1110431SOmar.Naji@arm.com * documentation and/or other materials provided with the distribution;
1210431SOmar.Naji@arm.com * neither the name of the copyright holders nor the names of its
1310431SOmar.Naji@arm.com * contributors may be used to endorse or promote products derived from
1410431SOmar.Naji@arm.com * this software without specific prior written permission.
1510431SOmar.Naji@arm.com *
1610431SOmar.Naji@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1710431SOmar.Naji@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1810431SOmar.Naji@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1910431SOmar.Naji@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2010431SOmar.Naji@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2110431SOmar.Naji@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2210431SOmar.Naji@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2310431SOmar.Naji@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2410431SOmar.Naji@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2510431SOmar.Naji@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2610431SOmar.Naji@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2710431SOmar.Naji@arm.com *
2810431SOmar.Naji@arm.com * Authors: Gabe Black
2910431SOmar.Naji@arm.com */
3010431SOmar.Naji@arm.com
3110431SOmar.Naji@arm.com#include "base/bitfield.hh"
3210431SOmar.Naji@arm.com#include "dev/x86/i8259.hh"
3310431SOmar.Naji@arm.com
3410431SOmar.Naji@arm.comTick
3510431SOmar.Naji@arm.comX86ISA::I8259::read(PacketPtr pkt)
3610431SOmar.Naji@arm.com{
3710431SOmar.Naji@arm.com    assert(pkt->getSize() == 1);
3810431SOmar.Naji@arm.com    switch(pkt->getAddr() - pioAddr)
3910431SOmar.Naji@arm.com    {
4010431SOmar.Naji@arm.com      case 0x0:
4110431SOmar.Naji@arm.com        if (readIRR) {
4210431SOmar.Naji@arm.com            DPRINTF(I8259, "Reading IRR as %#x.\n", IRR);
4310431SOmar.Naji@arm.com            pkt->set(IRR);
4410431SOmar.Naji@arm.com        } else {
4510431SOmar.Naji@arm.com            DPRINTF(I8259, "Reading ISR as %#x.\n", ISR);
4610431SOmar.Naji@arm.com            pkt->set(ISR);
4710431SOmar.Naji@arm.com        }
4810431SOmar.Naji@arm.com        break;
4910431SOmar.Naji@arm.com      case 0x1:
5010431SOmar.Naji@arm.com        DPRINTF(I8259, "Reading IMR as %#x.\n", IMR);
5110431SOmar.Naji@arm.com        pkt->set(IMR);
5210431SOmar.Naji@arm.com        break;
5310431SOmar.Naji@arm.com    }
5410431SOmar.Naji@arm.com    return latency;
5510431SOmar.Naji@arm.com}
5610431SOmar.Naji@arm.com
5710431SOmar.Naji@arm.comTick
5810431SOmar.Naji@arm.comX86ISA::I8259::write(PacketPtr pkt)
5910431SOmar.Naji@arm.com{
6010431SOmar.Naji@arm.com    assert(pkt->getSize() == 1);
6110431SOmar.Naji@arm.com    uint8_t val = pkt->get<uint8_t>();
6210431SOmar.Naji@arm.com    switch (pkt->getAddr() - pioAddr) {
6310431SOmar.Naji@arm.com      case 0x0:
6410431SOmar.Naji@arm.com        if (bits(val, 4)) {
6510431SOmar.Naji@arm.com            DPRINTF(I8259, "Received initialization command word 1.\n");
6610431SOmar.Naji@arm.com            IMR = 0;
6710431SOmar.Naji@arm.com            edgeTriggered = bits(val, 3);
6810431SOmar.Naji@arm.com            DPRINTF(I8259, "%s triggered mode.\n",
6910431SOmar.Naji@arm.com                    edgeTriggered ? "Edge" : "Level");
7010431SOmar.Naji@arm.com            cascadeMode = !bits(val, 1);
7110431SOmar.Naji@arm.com            DPRINTF(I8259, "%s mode.\n",
7210431SOmar.Naji@arm.com                    cascadeMode ? "Cascade" : "Single");
7310431SOmar.Naji@arm.com            expectICW4 = bits(val, 0);
7410431SOmar.Naji@arm.com            initControlWord = 1;
7510431SOmar.Naji@arm.com            DPRINTF(I8259, "Expecting %d more bytes.\n", expectICW4 ? 3 : 2);
7610431SOmar.Naji@arm.com        } else if (bits(val, 4, 3) == 0) {
7710431SOmar.Naji@arm.com            DPRINTF(I8259, "Received operation command word 2.\n");
7810431SOmar.Naji@arm.com            switch (bits(val, 7, 5)) {
7910431SOmar.Naji@arm.com              case 0x0:
8010431SOmar.Naji@arm.com                DPRINTF(I8259,
8110431SOmar.Naji@arm.com                        "Subcommand: Rotate in auto-EOI mode (clear).\n");
8210431SOmar.Naji@arm.com                break;
8310431SOmar.Naji@arm.com              case 0x1:
8410431SOmar.Naji@arm.com                DPRINTF(I8259, "Subcommand: Nonspecific EOI.\n");
8510431SOmar.Naji@arm.com                break;
8610431SOmar.Naji@arm.com              case 0x2:
8710431SOmar.Naji@arm.com                DPRINTF(I8259, "Subcommand: No operation.\n");
8810431SOmar.Naji@arm.com                break;
8910431SOmar.Naji@arm.com              case 0x3:
9010431SOmar.Naji@arm.com                DPRINTF(I8259, "Subcommand: Specific EIO.");
9110431SOmar.Naji@arm.com                DPRINTF(I8259, "Reset In-Service bit %d.\n", bits(val, 2, 0));
9210431SOmar.Naji@arm.com                break;
9310431SOmar.Naji@arm.com              case 0x4:
9410431SOmar.Naji@arm.com                DPRINTF(I8259, "Subcommand: Rotate in auto-EOI mode (set).\n");
9510431SOmar.Naji@arm.com                break;
9610431SOmar.Naji@arm.com              case 0x5:
9710431SOmar.Naji@arm.com                DPRINTF(I8259, "Subcommand: Rotate on nonspecific EOI.\n");
9810431SOmar.Naji@arm.com                break;
9910431SOmar.Naji@arm.com              case 0x6:
10010431SOmar.Naji@arm.com                DPRINTF(I8259, "Subcommand: Set priority command.\n");
10110431SOmar.Naji@arm.com                DPRINTF(I8259, "Lowest: IRQ%d   Highest IRQ%d.\n",
10210431SOmar.Naji@arm.com                        bits(val, 2, 0), (bits(val, 2, 0) + 1) % 8);
10310431SOmar.Naji@arm.com                break;
104              case 0x7:
105                DPRINTF(I8259, "Subcommand: Rotate on specific EOI.\n");
106                DPRINTF(I8259, "Lowest: IRQ%d   Highest IRQ%d.\n",
107                        bits(val, 2, 0), (bits(val, 2, 0) + 1) % 8);
108                break;
109            }
110        } else if (bits(val, 4, 3) == 1) {
111            DPRINTF(I8259, "Received operation command word 3.\n");
112            if (bits(val, 7)) {
113                DPRINTF(I8259, "%s special mask mode.\n",
114                        bits(val, 6) ? "Set" : "Clear");
115            }
116            if (bits(val, 1)) {
117                readIRR = bits(val, 0);
118                DPRINTF(I8259, "Read %s.\n", readIRR ? "IRR" : "ISR");
119            }
120        }
121        break;
122      case 0x1:
123        switch (initControlWord) {
124          case 0x0:
125            DPRINTF(I8259, "Received operation command word 1.\n");
126            DPRINTF(I8259, "Wrote IMR value %#x.\n", val);
127            IMR = val;
128            break;
129          case 0x1:
130            DPRINTF(I8259, "Received initialization command word 2.\n");
131            vectorOffset = val & ~mask(3);
132            DPRINTF(I8259, "Responsible for vectors %#x-%#x.\n",
133                    vectorOffset, vectorOffset | mask(3));
134            if (cascadeMode) {
135                initControlWord++;
136            } else {
137                cascadeBits = 0;
138                initControlWord = 0;
139            }
140            break;
141          case 0x2:
142            DPRINTF(I8259, "Received initialization command word 3.\n");
143            if (mode == Enums::I8259Master) {
144                DPRINTF(I8259, "Slaves attached to IRQs:%s%s%s%s%s%s%s%s\n",
145                        bits(val, 0) ? " 0" : "",
146                        bits(val, 1) ? " 1" : "",
147                        bits(val, 2) ? " 2" : "",
148                        bits(val, 3) ? " 3" : "",
149                        bits(val, 4) ? " 4" : "",
150                        bits(val, 5) ? " 5" : "",
151                        bits(val, 6) ? " 6" : "",
152                        bits(val, 7) ? " 7" : "");
153                cascadeBits = val;
154            } else {
155                DPRINTF(I8259, "Slave ID is %d.\n", val & mask(3));
156                cascadeBits = val & mask(3);
157            }
158            if (expectICW4)
159                initControlWord++;
160            else
161                initControlWord = 0;
162            break;
163          case 0x3:
164            DPRINTF(I8259, "Received initialization command word 4.\n");
165            if (bits(val, 4)) {
166                DPRINTF(I8259, "Special fully nested mode.\n");
167            } else {
168                DPRINTF(I8259, "Not special fully nested mode.\n");
169            }
170            if (bits(val, 3) == 0) {
171                DPRINTF(I8259, "Nonbuffered.\n");
172            } else if (bits(val, 2) == 0) {
173                DPRINTF(I8259, "Buffered.\n");
174            } else {
175                DPRINTF(I8259, "Unrecognized buffer mode.\n");
176            }
177            DPRINTF(I8259, "%s End Of Interrupt.\n",
178                    bits(val, 1) ? "Automatic" : "Normal");
179            DPRINTF(I8259, "%s mode.\n", bits(val, 0) ? "80x86" : "MCX-80/85");
180            initControlWord = 0;
181            break;
182        }
183        break;
184    }
185    return latency;
186}
187
188void
189X86ISA::I8259::signalInterrupt(int line)
190{
191    DPRINTF(I8259, "Interrupt raised on line %d.\n", line);
192    if (line > 7)
193        fatal("Line number %d doesn't exist. The max is 7.\n");
194    if (bits(IMR, line)) {
195        DPRINTF(I8259, "Interrupt %d was masked.\n", line);
196    } else {
197        if (output) {
198            DPRINTF(I8259, "Propogating interrupt.\n");
199            output->signalInterrupt();
200        } else {
201            warn("Received interrupt but didn't have "
202                    "anyone to tell about it.\n");
203        }
204    }
205}
206
207X86ISA::I8259 *
208I8259Params::create()
209{
210    return new X86ISA::I8259(this);
211}
212