iob.cc revision 9090
16019Shines@cs.fsu.edu/*
26019Shines@cs.fsu.edu * Copyright (c) 2006 The Regents of The University of Michigan
37152Sgblack@eecs.umich.edu * All rights reserved.
47152Sgblack@eecs.umich.edu *
57152Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
67152Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
77152Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
87152Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
97152Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
107152Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
117152Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
127152Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
137152Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
147152Sgblack@eecs.umich.edu * this software without specific prior written permission.
156019Shines@cs.fsu.edu *
166019Shines@cs.fsu.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
176019Shines@cs.fsu.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
186019Shines@cs.fsu.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
196019Shines@cs.fsu.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
206019Shines@cs.fsu.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
216019Shines@cs.fsu.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
226019Shines@cs.fsu.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
236019Shines@cs.fsu.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
246019Shines@cs.fsu.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
256019Shines@cs.fsu.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
266019Shines@cs.fsu.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
276019Shines@cs.fsu.edu *
286019Shines@cs.fsu.edu * Authors: Ali Saidi
296019Shines@cs.fsu.edu */
306019Shines@cs.fsu.edu
316019Shines@cs.fsu.edu/** @file
326019Shines@cs.fsu.edu * This device implemetns the niagara I/O bridge chip. It manages incomming
336019Shines@cs.fsu.edu * interrupts and posts them to the CPU when needed. It holds mask registers and
346019Shines@cs.fsu.edu * various status registers for CPUs to check what interrupts are pending as
356019Shines@cs.fsu.edu * well as facilities to send IPIs to other cpus.
366019Shines@cs.fsu.edu */
376019Shines@cs.fsu.edu
386019Shines@cs.fsu.edu#include <cstring>
396019Shines@cs.fsu.edu
406019Shines@cs.fsu.edu#include "arch/sparc/faults.hh"
416019Shines@cs.fsu.edu#include "arch/sparc/isa_traits.hh"
426019Shines@cs.fsu.edu#include "base/bitfield.hh"
436019Shines@cs.fsu.edu#include "base/trace.hh"
446019Shines@cs.fsu.edu#include "cpu/intr_control.hh"
456019Shines@cs.fsu.edu#include "cpu/thread_context.hh"
466019Shines@cs.fsu.edu#include "debug/Iob.hh"
476019Shines@cs.fsu.edu#include "dev/sparc/iob.hh"
487152Sgblack@eecs.umich.edu#include "dev/platform.hh"
497152Sgblack@eecs.umich.edu#include "mem/packet_access.hh"
507152Sgblack@eecs.umich.edu#include "mem/port.hh"
517152Sgblack@eecs.umich.edu#include "sim/faults.hh"
527152Sgblack@eecs.umich.edu#include "sim/system.hh"
537152Sgblack@eecs.umich.edu
547152Sgblack@eecs.umich.eduIob::Iob(const Params *p)
557152Sgblack@eecs.umich.edu    : PioDevice(p), ic(p->platform->intrctrl)
567152Sgblack@eecs.umich.edu{
577152Sgblack@eecs.umich.edu    iobManAddr = ULL(0x9800000000);
587152Sgblack@eecs.umich.edu    iobManSize = ULL(0x0100000000);
597152Sgblack@eecs.umich.edu    iobJBusAddr = ULL(0x9F00000000);
607152Sgblack@eecs.umich.edu    iobJBusSize = ULL(0x0100000000);
617152Sgblack@eecs.umich.edu    assert (params()->system->threadContexts.size() <= MaxNiagaraProcs);
627152Sgblack@eecs.umich.edu
637152Sgblack@eecs.umich.edu    pioDelay = p->pio_latency;
647152Sgblack@eecs.umich.edu
657152Sgblack@eecs.umich.edu    for (int x = 0; x < NumDeviceIds; ++x) {
667152Sgblack@eecs.umich.edu        intMan[x].cpu = 0;
677152Sgblack@eecs.umich.edu        intMan[x].vector = 0;
687152Sgblack@eecs.umich.edu        intCtl[x].mask = true;
697152Sgblack@eecs.umich.edu        intCtl[x].pend = false;
707152Sgblack@eecs.umich.edu    }
717152Sgblack@eecs.umich.edu
727152Sgblack@eecs.umich.edu}
737152Sgblack@eecs.umich.edu
747152Sgblack@eecs.umich.eduTick
757152Sgblack@eecs.umich.eduIob::read(PacketPtr pkt)
767152Sgblack@eecs.umich.edu{
777152Sgblack@eecs.umich.edu
787152Sgblack@eecs.umich.edu    if (pkt->getAddr() >= iobManAddr && pkt->getAddr() < iobManAddr + iobManSize)
797152Sgblack@eecs.umich.edu        readIob(pkt);
807152Sgblack@eecs.umich.edu    else if (pkt->getAddr() >= iobJBusAddr && pkt->getAddr() < iobJBusAddr+iobJBusSize)
817152Sgblack@eecs.umich.edu        readJBus(pkt);
827152Sgblack@eecs.umich.edu    else
837152Sgblack@eecs.umich.edu        panic("Invalid address reached Iob\n");
847152Sgblack@eecs.umich.edu
857152Sgblack@eecs.umich.edu    pkt->makeAtomicResponse();
867152Sgblack@eecs.umich.edu    return pioDelay;
877154Sgblack@eecs.umich.edu}
887154Sgblack@eecs.umich.edu
897154Sgblack@eecs.umich.eduvoid
907154Sgblack@eecs.umich.eduIob::readIob(PacketPtr pkt)
917154Sgblack@eecs.umich.edu{
927154Sgblack@eecs.umich.edu        Addr accessAddr = pkt->getAddr() - iobManAddr;
937154Sgblack@eecs.umich.edu
947200Sgblack@eecs.umich.edu        if (accessAddr >= IntManAddr && accessAddr < IntManAddr + IntManSize) {
957154Sgblack@eecs.umich.edu            int index = (accessAddr - IntManAddr) >> 3;
967154Sgblack@eecs.umich.edu            uint64_t data = intMan[index].cpu << 8 | intMan[index].vector << 0;
977154Sgblack@eecs.umich.edu            pkt->set(data);
987154Sgblack@eecs.umich.edu            return;
997154Sgblack@eecs.umich.edu        }
1007154Sgblack@eecs.umich.edu
1017154Sgblack@eecs.umich.edu        if (accessAddr >= IntCtlAddr && accessAddr < IntCtlAddr + IntCtlSize) {
1027154Sgblack@eecs.umich.edu            int index = (accessAddr - IntCtlAddr) >> 3;
1037154Sgblack@eecs.umich.edu            uint64_t data = intCtl[index].mask  ? 1 << 2 : 0 |
1047154Sgblack@eecs.umich.edu                intCtl[index].pend  ? 1 << 0 : 0;
1057154Sgblack@eecs.umich.edu            pkt->set(data);
1067154Sgblack@eecs.umich.edu            return;
1077154Sgblack@eecs.umich.edu        }
1087155Sgblack@eecs.umich.edu
1097154Sgblack@eecs.umich.edu        if (accessAddr == JIntVecAddr) {
1107155Sgblack@eecs.umich.edu            pkt->set(jIntVec);
1117155Sgblack@eecs.umich.edu            return;
1127155Sgblack@eecs.umich.edu        }
1137155Sgblack@eecs.umich.edu
1147155Sgblack@eecs.umich.edu        panic("Read to unknown IOB offset 0x%x\n", accessAddr);
1157155Sgblack@eecs.umich.edu}
1167155Sgblack@eecs.umich.edu
1177155Sgblack@eecs.umich.eduvoid
1187155Sgblack@eecs.umich.eduIob::readJBus(PacketPtr pkt)
1197155Sgblack@eecs.umich.edu{
1207155Sgblack@eecs.umich.edu        Addr accessAddr = pkt->getAddr() - iobJBusAddr;
1217155Sgblack@eecs.umich.edu        int cpuid = pkt->req->contextId();
1227155Sgblack@eecs.umich.edu        int index;
1237155Sgblack@eecs.umich.edu        uint64_t data;
1247155Sgblack@eecs.umich.edu
1257155Sgblack@eecs.umich.edu
1267155Sgblack@eecs.umich.edu
1277155Sgblack@eecs.umich.edu
1287155Sgblack@eecs.umich.edu        if (accessAddr >= JIntData0Addr && accessAddr < JIntData1Addr) {
1297155Sgblack@eecs.umich.edu            index = (accessAddr - JIntData0Addr) >> 3;
1307155Sgblack@eecs.umich.edu            pkt->set(jBusData0[index]);
1317155Sgblack@eecs.umich.edu            return;
1327155Sgblack@eecs.umich.edu        }
1337155Sgblack@eecs.umich.edu
1347155Sgblack@eecs.umich.edu        if (accessAddr >= JIntData1Addr && accessAddr < JIntDataA0Addr) {
1357155Sgblack@eecs.umich.edu            index = (accessAddr - JIntData1Addr) >> 3;
1367204Sgblack@eecs.umich.edu            pkt->set(jBusData1[index]);
1377204Sgblack@eecs.umich.edu            return;
1387204Sgblack@eecs.umich.edu        }
1397204Sgblack@eecs.umich.edu
1407204Sgblack@eecs.umich.edu        if (accessAddr == JIntDataA0Addr) {
1417155Sgblack@eecs.umich.edu            pkt->set(jBusData0[cpuid]);
1427155Sgblack@eecs.umich.edu            return;
1437204Sgblack@eecs.umich.edu        }
1447204Sgblack@eecs.umich.edu
1457204Sgblack@eecs.umich.edu        if (accessAddr == JIntDataA1Addr) {
1467204Sgblack@eecs.umich.edu            pkt->set(jBusData1[cpuid]);
1477204Sgblack@eecs.umich.edu            return;
1487204Sgblack@eecs.umich.edu        }
1497155Sgblack@eecs.umich.edu
1507155Sgblack@eecs.umich.edu        if (accessAddr >= JIntBusyAddr && accessAddr < JIntBusyAddr + JIntBusySize) {
1517155Sgblack@eecs.umich.edu            index = (accessAddr - JIntBusyAddr) >> 3;
1527155Sgblack@eecs.umich.edu            data = jIntBusy[index].busy ? 1 << 5 : 0 |
1537155Sgblack@eecs.umich.edu                   jIntBusy[index].source;
1547155Sgblack@eecs.umich.edu            pkt->set(data);
1557155Sgblack@eecs.umich.edu            return;
1567155Sgblack@eecs.umich.edu        }
1577155Sgblack@eecs.umich.edu        if (accessAddr == JIntABusyAddr) {
1587155Sgblack@eecs.umich.edu            data = jIntBusy[cpuid].busy ? 1 << 5 : 0 |
1597155Sgblack@eecs.umich.edu                   jIntBusy[cpuid].source;
1607155Sgblack@eecs.umich.edu            pkt->set(data);
1617155Sgblack@eecs.umich.edu            return;
1627155Sgblack@eecs.umich.edu        };
1637155Sgblack@eecs.umich.edu
1647155Sgblack@eecs.umich.edu        panic("Read to unknown JBus offset 0x%x\n", accessAddr);
1657155Sgblack@eecs.umich.edu}
1667155Sgblack@eecs.umich.edu
1677155Sgblack@eecs.umich.eduTick
1687155Sgblack@eecs.umich.eduIob::write(PacketPtr pkt)
1697155Sgblack@eecs.umich.edu{
1707155Sgblack@eecs.umich.edu    if (pkt->getAddr() >= iobManAddr && pkt->getAddr() < iobManAddr + iobManSize)
1717155Sgblack@eecs.umich.edu        writeIob(pkt);
1727155Sgblack@eecs.umich.edu    else if (pkt->getAddr() >= iobJBusAddr && pkt->getAddr() < iobJBusAddr+iobJBusSize)
1737155Sgblack@eecs.umich.edu        writeJBus(pkt);
1747155Sgblack@eecs.umich.edu    else
1757155Sgblack@eecs.umich.edu        panic("Invalid address reached Iob\n");
1767155Sgblack@eecs.umich.edu
1777155Sgblack@eecs.umich.edu
1787155Sgblack@eecs.umich.edu    pkt->makeAtomicResponse();
1797155Sgblack@eecs.umich.edu    return pioDelay;
1807155Sgblack@eecs.umich.edu}
1817155Sgblack@eecs.umich.edu
1827155Sgblack@eecs.umich.eduvoid
1837155Sgblack@eecs.umich.eduIob::writeIob(PacketPtr pkt)
1847155Sgblack@eecs.umich.edu{
1857155Sgblack@eecs.umich.edu        Addr accessAddr = pkt->getAddr() - iobManAddr;
1867155Sgblack@eecs.umich.edu        int index;
1877155Sgblack@eecs.umich.edu        uint64_t data;
1887155Sgblack@eecs.umich.edu
1897155Sgblack@eecs.umich.edu        if (accessAddr >= IntManAddr && accessAddr < IntManAddr + IntManSize) {
1907155Sgblack@eecs.umich.edu            index = (accessAddr - IntManAddr) >> 3;
1917155Sgblack@eecs.umich.edu            data = pkt->get<uint64_t>();
1927155Sgblack@eecs.umich.edu            intMan[index].cpu = bits(data,12,8);
1937155Sgblack@eecs.umich.edu            intMan[index].vector = bits(data,5,0);
1947155Sgblack@eecs.umich.edu            DPRINTF(Iob, "Wrote IntMan %d cpu %d, vec %d\n", index,
1957155Sgblack@eecs.umich.edu                    intMan[index].cpu, intMan[index].vector);
1967155Sgblack@eecs.umich.edu            return;
1977155Sgblack@eecs.umich.edu        }
1987155Sgblack@eecs.umich.edu
1997188Sgblack@eecs.umich.edu        if (accessAddr >= IntCtlAddr && accessAddr < IntCtlAddr + IntCtlSize) {
2007188Sgblack@eecs.umich.edu            index = (accessAddr - IntCtlAddr) >> 3;
2017188Sgblack@eecs.umich.edu            data = pkt->get<uint64_t>();
2027188Sgblack@eecs.umich.edu            intCtl[index].mask = bits(data,2,2);
2037188Sgblack@eecs.umich.edu            if (bits(data,1,1))
2047155Sgblack@eecs.umich.edu                intCtl[index].pend = false;
2057204Sgblack@eecs.umich.edu            DPRINTF(Iob, "Wrote IntCtl %d pend %d cleared %d\n", index,
2067204Sgblack@eecs.umich.edu                    intCtl[index].pend, bits(data,2,2));
2077204Sgblack@eecs.umich.edu            return;
2087204Sgblack@eecs.umich.edu        }
2097204Sgblack@eecs.umich.edu
2107155Sgblack@eecs.umich.edu        if (accessAddr == JIntVecAddr) {
2117204Sgblack@eecs.umich.edu            jIntVec = bits(pkt->get<uint64_t>(), 5,0);
2127204Sgblack@eecs.umich.edu            DPRINTF(Iob, "Wrote jIntVec %d\n", jIntVec);
2137204Sgblack@eecs.umich.edu            return;
2147204Sgblack@eecs.umich.edu        }
2157204Sgblack@eecs.umich.edu
2167155Sgblack@eecs.umich.edu        if (accessAddr >= IntVecDisAddr && accessAddr < IntVecDisAddr + IntVecDisSize) {
2177155Sgblack@eecs.umich.edu            Type type;
2187155Sgblack@eecs.umich.edu            int cpu_id;
2197155Sgblack@eecs.umich.edu            int vector;
2207155Sgblack@eecs.umich.edu            index = (accessAddr - IntManAddr) >> 3;
2217155Sgblack@eecs.umich.edu            data = pkt->get<uint64_t>();
2227155Sgblack@eecs.umich.edu            type = (Type)bits(data,17,16);
2237155Sgblack@eecs.umich.edu            cpu_id = bits(data, 12,8);
2247155Sgblack@eecs.umich.edu            vector = bits(data,5,0);
2257155Sgblack@eecs.umich.edu            generateIpi(type,cpu_id, vector);
2267155Sgblack@eecs.umich.edu            return;
2277155Sgblack@eecs.umich.edu        }
2287155Sgblack@eecs.umich.edu
2297155Sgblack@eecs.umich.edu        panic("Write to unknown IOB offset 0x%x\n", accessAddr);
2307155Sgblack@eecs.umich.edu}
2317155Sgblack@eecs.umich.edu
2327155Sgblack@eecs.umich.eduvoid
2337155Sgblack@eecs.umich.eduIob::writeJBus(PacketPtr pkt)
2347155Sgblack@eecs.umich.edu{
2357155Sgblack@eecs.umich.edu        Addr accessAddr = pkt->getAddr() - iobJBusAddr;
2367155Sgblack@eecs.umich.edu        int cpuid = pkt->req->contextId();
2377155Sgblack@eecs.umich.edu        int index;
2387155Sgblack@eecs.umich.edu        uint64_t data;
2397155Sgblack@eecs.umich.edu
2407155Sgblack@eecs.umich.edu        if (accessAddr >= JIntBusyAddr && accessAddr < JIntBusyAddr + JIntBusySize) {
2417155Sgblack@eecs.umich.edu            index = (accessAddr - JIntBusyAddr) >> 3;
2427155Sgblack@eecs.umich.edu            data = pkt->get<uint64_t>();
2437155Sgblack@eecs.umich.edu            jIntBusy[index].busy = bits(data,5,5);
2447155Sgblack@eecs.umich.edu            DPRINTF(Iob, "Wrote jIntBusy index %d busy: %d\n", index,
2457155Sgblack@eecs.umich.edu                    jIntBusy[index].busy);
2467155Sgblack@eecs.umich.edu            return;
2477155Sgblack@eecs.umich.edu        }
2487155Sgblack@eecs.umich.edu        if (accessAddr == JIntABusyAddr) {
2497155Sgblack@eecs.umich.edu            data = pkt->get<uint64_t>();
2507155Sgblack@eecs.umich.edu            jIntBusy[cpuid].busy = bits(data,5,5);
2517155Sgblack@eecs.umich.edu            DPRINTF(Iob, "Wrote jIntBusy index %d busy: %d\n", cpuid,
2527155Sgblack@eecs.umich.edu                    jIntBusy[cpuid].busy);
2537155Sgblack@eecs.umich.edu            return;
2547155Sgblack@eecs.umich.edu        };
2557155Sgblack@eecs.umich.edu
2567155Sgblack@eecs.umich.edu        panic("Write to unknown JBus offset 0x%x\n", accessAddr);
2577155Sgblack@eecs.umich.edu}
2587155Sgblack@eecs.umich.edu
2597155Sgblack@eecs.umich.eduvoid
2607154Sgblack@eecs.umich.eduIob::receiveDeviceInterrupt(DeviceId devid)
2617154Sgblack@eecs.umich.edu{
262    assert(devid < NumDeviceIds);
263    if (intCtl[devid].mask)
264        return;
265    intCtl[devid].mask = true;
266    intCtl[devid].pend = true;
267    DPRINTF(Iob, "Receiving Device interrupt: %d for cpu %d vec %d\n",
268            devid, intMan[devid].cpu, intMan[devid].vector);
269    ic->post(intMan[devid].cpu, SparcISA::IT_INT_VEC, intMan[devid].vector);
270}
271
272
273void
274Iob::generateIpi(Type type, int cpu_id, int vector)
275{
276    SparcISA::SparcFault<SparcISA::PowerOnReset> *por = new SparcISA::PowerOnReset();
277    if (cpu_id >= sys->numContexts())
278        return;
279
280    switch (type) {
281      case 0: // interrupt
282        DPRINTF(Iob, "Generating interrupt because of I/O write to cpu: %d vec %d\n",
283                cpu_id, vector);
284        ic->post(cpu_id, SparcISA::IT_INT_VEC, vector);
285        break;
286      case 1: // reset
287        warn("Sending reset to CPU: %d\n", cpu_id);
288        if (vector != por->trapType())
289            panic("Don't know how to set non-POR reset to cpu\n");
290        por->invoke(sys->threadContexts[cpu_id]);
291        sys->threadContexts[cpu_id]->activate();
292        break;
293      case 2: // idle -- this means stop executing and don't wake on interrupts
294        DPRINTF(Iob, "Idling CPU because of I/O write cpu: %d\n", cpu_id);
295        sys->threadContexts[cpu_id]->halt();
296        break;
297      case 3: // resume
298        DPRINTF(Iob, "Resuming CPU because of I/O write cpu: %d\n", cpu_id);
299        sys->threadContexts[cpu_id]->activate();
300        break;
301      default:
302        panic("Invalid type to generate ipi\n");
303    }
304}
305
306bool
307Iob::receiveJBusInterrupt(int cpu_id, int source, uint64_t d0, uint64_t d1)
308{
309    // If we are already dealing with an interrupt for that cpu we can't deal
310    // with another one right now... come back later
311    if (jIntBusy[cpu_id].busy)
312        return false;
313
314    DPRINTF(Iob, "Receiving jBus interrupt: %d for cpu %d vec %d\n",
315            source, cpu_id, jIntVec);
316
317    jIntBusy[cpu_id].busy = true;
318    jIntBusy[cpu_id].source = source;
319    jBusData0[cpu_id] = d0;
320    jBusData1[cpu_id] = d1;
321
322    ic->post(cpu_id, SparcISA::IT_INT_VEC, jIntVec);
323    return true;
324}
325
326AddrRangeList
327Iob::getAddrRanges() const
328{
329    AddrRangeList ranges;
330    ranges.push_back(RangeSize(iobManAddr, iobManSize));
331    ranges.push_back(RangeSize(iobJBusAddr, iobJBusSize));
332    return ranges;
333}
334
335
336void
337Iob::serialize(std::ostream &os)
338{
339
340    SERIALIZE_SCALAR(jIntVec);
341    SERIALIZE_ARRAY(jBusData0, MaxNiagaraProcs);
342    SERIALIZE_ARRAY(jBusData1, MaxNiagaraProcs);
343    for (int x = 0; x < NumDeviceIds; x++) {
344        nameOut(os, csprintf("%s.Int%d", name(), x));
345        paramOut(os, "cpu", intMan[x].cpu);
346        paramOut(os, "vector", intMan[x].vector);
347        paramOut(os, "mask", intCtl[x].mask);
348        paramOut(os, "pend", intCtl[x].pend);
349    };
350    for (int x = 0; x < MaxNiagaraProcs; x++) {
351        nameOut(os, csprintf("%s.jIntBusy%d", name(), x));
352        paramOut(os, "busy", jIntBusy[x].busy);
353        paramOut(os, "source", jIntBusy[x].source);
354    };
355}
356
357void
358Iob::unserialize(Checkpoint *cp, const std::string &section)
359{
360    UNSERIALIZE_SCALAR(jIntVec);
361    UNSERIALIZE_ARRAY(jBusData0, MaxNiagaraProcs);
362    UNSERIALIZE_ARRAY(jBusData1, MaxNiagaraProcs);
363    for (int x = 0; x < NumDeviceIds; x++) {
364        paramIn(cp, csprintf("%s.Int%d", name(), x), "cpu", intMan[x].cpu);
365        paramIn(cp, csprintf("%s.Int%d", name(), x), "vector", intMan[x].vector);
366        paramIn(cp, csprintf("%s.Int%d", name(), x), "mask", intCtl[x].mask);
367        paramIn(cp, csprintf("%s.Int%d", name(), x), "pend", intCtl[x].pend);
368    };
369    for (int x = 0; x < MaxNiagaraProcs; x++) {
370        paramIn(cp, csprintf("%s.jIntBusy%d", name(), x), "busy", jIntBusy[x].busy);
371        paramIn(cp, csprintf("%s.jIntBusy%d", name(), x), "source", jIntBusy[x].source);
372    };
373}
374
375Iob *
376IobParams::create()
377{
378    return new Iob(this);
379}
380