tsunami_cchip.cc revision 2432
12623SN/A/* 22623SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan 32623SN/A * All rights reserved. 42623SN/A * 52623SN/A * Redistribution and use in source and binary forms, with or without 62623SN/A * modification, are permitted provided that the following conditions are 72623SN/A * met: redistributions of source code must retain the above copyright 82623SN/A * notice, this list of conditions and the following disclaimer; 92623SN/A * redistributions in binary form must reproduce the above copyright 102623SN/A * notice, this list of conditions and the following disclaimer in the 112623SN/A * documentation and/or other materials provided with the distribution; 122623SN/A * neither the name of the copyright holders nor the names of its 132623SN/A * contributors may be used to endorse or promote products derived from 142623SN/A * this software without specific prior written permission. 152623SN/A * 162623SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172623SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182623SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192623SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202623SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212623SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222623SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232623SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242623SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252623SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262623SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu */ 282665Ssaidi@eecs.umich.edu 292623SN/A/** @file 302623SN/A * Emulation of the Tsunami CChip CSRs 312623SN/A */ 322623SN/A 332623SN/A#include <deque> 342623SN/A#include <string> 356973Stjones1@inf.ed.ac.uk#include <vector> 362623SN/A 375529Snate@binkert.org#include "arch/alpha/ev5.hh" 385529Snate@binkert.org#include "base/trace.hh" 392623SN/A#include "dev/tsunami_cchip.hh" 402623SN/A#include "dev/tsunamireg.h" 412623SN/A#include "dev/tsunami.hh" 422623SN/A#include "mem/bus/bus.hh" 435529Snate@binkert.org#include "mem/bus/pio_interface.hh" 442623SN/A#include "mem/bus/pio_interface_impl.hh" 452623SN/A#include "mem/functional/memory_control.hh" 462623SN/A#include "cpu/exec_context.hh" 472623SN/A#include "cpu/intr_control.hh" 482623SN/A#include "sim/builder.hh" 492839Sktlim@umich.edu#include "sim/system.hh" 502798Sktlim@umich.edu 512623SN/Ausing namespace std; 522623SN/A//Should this be AlphaISA? 535728Sgblack@eecs.umich.eduusing namespace TheISA; 545728Sgblack@eecs.umich.edu 555728Sgblack@eecs.umich.eduTsunamiCChip::TsunamiCChip(const string &name, Tsunami *t, Addr a, 565728Sgblack@eecs.umich.edu MemoryController *mmu, HierParams *hier, 575728Sgblack@eecs.umich.edu Bus* pio_bus, Tick pio_latency) 585728Sgblack@eecs.umich.edu : PioDevice(name, t), addr(a), tsunami(t) 595728Sgblack@eecs.umich.edu{ 605728Sgblack@eecs.umich.edu mmu->add_child(this, RangeSize(addr, size)); 615728Sgblack@eecs.umich.edu 625728Sgblack@eecs.umich.edu if (pio_bus) { 635728Sgblack@eecs.umich.edu pioInterface = newPioInterface(name + ".pio", hier, pio_bus, this, 645728Sgblack@eecs.umich.edu &TsunamiCChip::cacheAccess); 655728Sgblack@eecs.umich.edu pioInterface->addAddrRange(RangeSize(addr, size)); 665728Sgblack@eecs.umich.edu pioLatency = pio_latency * pio_bus->clockRate; 675728Sgblack@eecs.umich.edu } 685728Sgblack@eecs.umich.edu 695728Sgblack@eecs.umich.edu drir = 0; 705728Sgblack@eecs.umich.edu ipint = 0; 715728Sgblack@eecs.umich.edu itint = 0; 725728Sgblack@eecs.umich.edu 735728Sgblack@eecs.umich.edu for (int x = 0; x < Tsunami::Max_CPUs; x++) 745728Sgblack@eecs.umich.edu { 755728Sgblack@eecs.umich.edu dim[x] = 0; 765728Sgblack@eecs.umich.edu dir[x] = 0; 775728Sgblack@eecs.umich.edu } 785728Sgblack@eecs.umich.edu 795728Sgblack@eecs.umich.edu //Put back pointer in tsunami 805728Sgblack@eecs.umich.edu tsunami->cchip = this; 815728Sgblack@eecs.umich.edu} 825728Sgblack@eecs.umich.edu 835728Sgblack@eecs.umich.eduFault 845728Sgblack@eecs.umich.eduTsunamiCChip::read(MemReqPtr &req, uint8_t *data) 855728Sgblack@eecs.umich.edu{ 865728Sgblack@eecs.umich.edu DPRINTF(Tsunami, "read va=%#x size=%d\n", req->vaddr, req->size); 875728Sgblack@eecs.umich.edu 885728Sgblack@eecs.umich.edu Addr regnum = (req->paddr - (addr & EV5::PAddrImplMask)) >> 6; 895728Sgblack@eecs.umich.edu Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)); 905728Sgblack@eecs.umich.edu 915728Sgblack@eecs.umich.edu ExecContext *xc = req->xc; 925728Sgblack@eecs.umich.edu 935728Sgblack@eecs.umich.edu switch (req->size) { 945728Sgblack@eecs.umich.edu 955728Sgblack@eecs.umich.edu case sizeof(uint64_t): 965728Sgblack@eecs.umich.edu if (daddr & TSDEV_CC_BDIMS) 975728Sgblack@eecs.umich.edu { 985728Sgblack@eecs.umich.edu *(uint64_t*)data = dim[(daddr >> 4) & 0x3F]; 995728Sgblack@eecs.umich.edu return NoFault; 1005894Sgblack@eecs.umich.edu } 1015894Sgblack@eecs.umich.edu 1025894Sgblack@eecs.umich.edu if (daddr & TSDEV_CC_BDIRS) 1035894Sgblack@eecs.umich.edu { 1045894Sgblack@eecs.umich.edu *(uint64_t*)data = dir[(daddr >> 4) & 0x3F]; 1055894Sgblack@eecs.umich.edu return NoFault; 1066023Snate@binkert.org } 1076023Snate@binkert.org 1085894Sgblack@eecs.umich.edu switch(regnum) { 1095894Sgblack@eecs.umich.edu case TSDEV_CC_CSR: 1106023Snate@binkert.org *(uint64_t*)data = 0x0; 1117944SGiacomo.Gabrielli@arm.com return NoFault; 1127945SAli.Saidi@ARM.com case TSDEV_CC_MTR: 1137945SAli.Saidi@ARM.com panic("TSDEV_CC_MTR not implemeted\n"); 1147945SAli.Saidi@ARM.com return NoFault; 1157945SAli.Saidi@ARM.com case TSDEV_CC_MISC: 1167944SGiacomo.Gabrielli@arm.com *(uint64_t*)data = (ipint << 8) & 0xF | 1177944SGiacomo.Gabrielli@arm.com (itint << 4) & 0xF | 1186023Snate@binkert.org (xc->readCpuId() & 0x3); 1196023Snate@binkert.org return NoFault; 1205894Sgblack@eecs.umich.edu case TSDEV_CC_AAR0: 1215894Sgblack@eecs.umich.edu case TSDEV_CC_AAR1: 1225894Sgblack@eecs.umich.edu case TSDEV_CC_AAR2: 1235894Sgblack@eecs.umich.edu case TSDEV_CC_AAR3: 1245894Sgblack@eecs.umich.edu *(uint64_t*)data = 0; 1255894Sgblack@eecs.umich.edu return NoFault; 1266973Stjones1@inf.ed.ac.uk case TSDEV_CC_DIM0: 1276973Stjones1@inf.ed.ac.uk *(uint64_t*)data = dim[0]; 1286973Stjones1@inf.ed.ac.uk return NoFault; 1295894Sgblack@eecs.umich.edu case TSDEV_CC_DIM1: 1305894Sgblack@eecs.umich.edu *(uint64_t*)data = dim[1]; 1315894Sgblack@eecs.umich.edu return NoFault; 1325894Sgblack@eecs.umich.edu case TSDEV_CC_DIM2: 1335894Sgblack@eecs.umich.edu *(uint64_t*)data = dim[2]; 1345894Sgblack@eecs.umich.edu return NoFault; 1355894Sgblack@eecs.umich.edu case TSDEV_CC_DIM3: 1365744Sgblack@eecs.umich.edu *(uint64_t*)data = dim[3]; 1375728Sgblack@eecs.umich.edu return NoFault; 1385728Sgblack@eecs.umich.edu case TSDEV_CC_DIR0: 1395728Sgblack@eecs.umich.edu *(uint64_t*)data = dir[0]; 1405728Sgblack@eecs.umich.edu return NoFault; 1412623SN/A case TSDEV_CC_DIR1: 1422623SN/A *(uint64_t*)data = dir[1]; 1432623SN/A return NoFault; 1442623SN/A case TSDEV_CC_DIR2: 1452948Ssaidi@eecs.umich.edu *(uint64_t*)data = dir[2]; 1462623SN/A return NoFault; 1472623SN/A case TSDEV_CC_DIR3: 1482623SN/A *(uint64_t*)data = dir[3]; 1492948Ssaidi@eecs.umich.edu return NoFault; 1507745SAli.Saidi@ARM.com case TSDEV_CC_DRIR: 1512623SN/A *(uint64_t*)data = drir; 1522623SN/A return NoFault; 1533647Srdreslin@umich.edu case TSDEV_CC_PRBEN: 1543647Srdreslin@umich.edu panic("TSDEV_CC_PRBEN not implemented\n"); 1552623SN/A return NoFault; 1562623SN/A case TSDEV_CC_IIC0: 1573349Sbinkertn@umich.edu case TSDEV_CC_IIC1: 1582623SN/A case TSDEV_CC_IIC2: 1593349Sbinkertn@umich.edu case TSDEV_CC_IIC3: 1602623SN/A panic("TSDEV_CC_IICx not implemented\n"); 1612623SN/A return NoFault; 1622623SN/A case TSDEV_CC_MPR0: 1632623SN/A case TSDEV_CC_MPR1: 1644475Sstever@eecs.umich.edu case TSDEV_CC_MPR2: 1654475Sstever@eecs.umich.edu case TSDEV_CC_MPR3: 1662948Ssaidi@eecs.umich.edu panic("TSDEV_CC_MPRx not implemented\n"); 1672948Ssaidi@eecs.umich.edu return NoFault; 1682948Ssaidi@eecs.umich.edu case TSDEV_CC_IPIR: 1693349Sbinkertn@umich.edu *(uint64_t*)data = ipint; 1702948Ssaidi@eecs.umich.edu return NoFault; 1717745SAli.Saidi@ARM.com case TSDEV_CC_ITIR: 1722948Ssaidi@eecs.umich.edu *(uint64_t*)data = itint; 1735606Snate@binkert.org return NoFault; 1745336Shines@cs.fsu.edu default: 1753349Sbinkertn@umich.edu panic("default in cchip read reached, accessing 0x%x\n"); 1762948Ssaidi@eecs.umich.edu } // uint64_t 1772948Ssaidi@eecs.umich.edu 1787745SAli.Saidi@ARM.com break; 1792623SN/A case sizeof(uint32_t): 1802623SN/A if (regnum == TSDEV_CC_DRIR) { 1812623SN/A warn("accessing DRIR with 32 bit read, " 1822623SN/A "hopefully your just reading this for timing"); 1832623SN/A *(uint32_t*)data = drir; 1842623SN/A } else 1852948Ssaidi@eecs.umich.edu panic("invalid access size(?) for tsunami register!\n"); 1862948Ssaidi@eecs.umich.edu return NoFault; 1872623SN/A case sizeof(uint16_t): 1882623SN/A case sizeof(uint8_t): 1892623SN/A default: 1902623SN/A panic("invalid access size(?) for tsunami register!\n"); 1913349Sbinkertn@umich.edu } 1922623SN/A DPRINTFN("Tsunami CChip ERROR: read regnum=%#x size=%d\n", regnum, req->size); 1932657Ssaidi@eecs.umich.edu 1942948Ssaidi@eecs.umich.edu return NoFault; 1952948Ssaidi@eecs.umich.edu} 1962948Ssaidi@eecs.umich.edu 1972948Ssaidi@eecs.umich.eduFault 1982948Ssaidi@eecs.umich.eduTsunamiCChip::write(MemReqPtr &req, const uint8_t *data) 1992948Ssaidi@eecs.umich.edu{ 2002948Ssaidi@eecs.umich.edu DPRINTF(Tsunami, "write - va=%#x value=%#x size=%d \n", 2015336Shines@cs.fsu.edu req->vaddr, *(uint64_t*)data, req->size); 2022948Ssaidi@eecs.umich.edu 2032948Ssaidi@eecs.umich.edu Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)); 2042948Ssaidi@eecs.umich.edu Addr regnum = (req->paddr - (addr & EV5::PAddrImplMask)) >> 6; 2052948Ssaidi@eecs.umich.edu 2062623SN/A bool supportedWrite = false; 2072623SN/A 2082623SN/A switch (req->size) { 2092623SN/A 2102623SN/A case sizeof(uint64_t): 2112623SN/A if (daddr & TSDEV_CC_BDIMS) 2122948Ssaidi@eecs.umich.edu { 2132948Ssaidi@eecs.umich.edu int number = (daddr >> 4) & 0x3F; 2142623SN/A 2152623SN/A uint64_t bitvector; 2164192Sktlim@umich.edu uint64_t olddim; 2174192Sktlim@umich.edu uint64_t olddir; 2182623SN/A 2192623SN/A olddim = dim[number]; 2203349Sbinkertn@umich.edu olddir = dir[number]; 2212623SN/A dim[number] = *(uint64_t*)data; 2222657Ssaidi@eecs.umich.edu dir[number] = dim[number] & drir; 2232948Ssaidi@eecs.umich.edu for(int x = 0; x < Tsunami::Max_CPUs; x++) 2242948Ssaidi@eecs.umich.edu { 2252948Ssaidi@eecs.umich.edu bitvector = ULL(1) << x; 2262948Ssaidi@eecs.umich.edu // Figure out which bits have changed 2272948Ssaidi@eecs.umich.edu if ((dim[number] & bitvector) != (olddim & bitvector)) 2282948Ssaidi@eecs.umich.edu { 2295336Shines@cs.fsu.edu // The bit is now set and it wasn't before (set) 2302948Ssaidi@eecs.umich.edu if((dim[number] & bitvector) && (dir[number] & bitvector)) 2312948Ssaidi@eecs.umich.edu { 2322948Ssaidi@eecs.umich.edu tsunami->intrctrl->post(number, TheISA::INTLEVEL_IRQ1, x); 2332948Ssaidi@eecs.umich.edu DPRINTF(Tsunami, "dim write resulting in posting dir" 2342623SN/A " interrupt to cpu %d\n", number); 2352623SN/A } 2362623SN/A else if ((olddir & bitvector) && 2372623SN/A !(dir[number] & bitvector)) 2382623SN/A { 2393349Sbinkertn@umich.edu // The bit was set and now its now clear and 2403349Sbinkertn@umich.edu // we were interrupting on that bit before 2412623SN/A tsunami->intrctrl->clear(number, TheISA::INTLEVEL_IRQ1, x); 2423222Sktlim@umich.edu DPRINTF(Tsunami, "dim write resulting in clear" 2433170Sstever@eecs.umich.edu " dir interrupt to cpu %d\n", number); 2442623SN/A 2452623SN/A } 2462856Srdreslin@umich.edu 2472856Srdreslin@umich.edu 2482623SN/A } 2492623SN/A } 2502623SN/A return NoFault; 2512901Ssaidi@eecs.umich.edu } 2522798Sktlim@umich.edu 2532798Sktlim@umich.edu switch(regnum) { 2542798Sktlim@umich.edu case TSDEV_CC_CSR: 2552623SN/A panic("TSDEV_CC_CSR write\n"); 2562623SN/A return NoFault; 2572623SN/A case TSDEV_CC_MTR: 2582623SN/A panic("TSDEV_CC_MTR write not implemented\n"); 2592623SN/A return NoFault; 2602623SN/A case TSDEV_CC_MISC: 2612623SN/A uint64_t ipreq; 2622623SN/A ipreq = (*(uint64_t*)data >> 12) & 0xF; 2637520Sgblack@eecs.umich.edu //If it is bit 12-15, this is an IPI post 2647520Sgblack@eecs.umich.edu if (ipreq) { 2652623SN/A reqIPI(ipreq); 2662623SN/A supportedWrite = true; 2672623SN/A } 2687520Sgblack@eecs.umich.edu 2697520Sgblack@eecs.umich.edu //If it is bit 8-11, this is an IPI clear 2707520Sgblack@eecs.umich.edu uint64_t ipintr; 2712623SN/A ipintr = (*(uint64_t*)data >> 8) & 0xF; 2725894Sgblack@eecs.umich.edu if (ipintr) { 2733349Sbinkertn@umich.edu clearIPI(ipintr); 2745894Sgblack@eecs.umich.edu supportedWrite = true; 2752644Sstever@eecs.umich.edu } 2764471Sstever@eecs.umich.edu 2775315Sstever@gmail.com //If it is the 4-7th bit, clear the RTC interrupt 2785315Sstever@gmail.com uint64_t itintr; 2795315Sstever@gmail.com itintr = (*(uint64_t*)data >> 4) & 0xF; 2805315Sstever@gmail.com if (itintr) { 2815315Sstever@gmail.com clearITI(itintr); 2825315Sstever@gmail.com supportedWrite = true; 2836973Stjones1@inf.ed.ac.uk } 2846973Stjones1@inf.ed.ac.uk 2856973Stjones1@inf.ed.ac.uk // ignore NXMs 2866973Stjones1@inf.ed.ac.uk if (*(uint64_t*)data & 0x10000000) 2876973Stjones1@inf.ed.ac.uk supportedWrite = true; 2886973Stjones1@inf.ed.ac.uk 2892798Sktlim@umich.edu if(!supportedWrite) 2904471Sstever@eecs.umich.edu panic("TSDEV_CC_MISC write not implemented\n"); 2917520Sgblack@eecs.umich.edu 2927520Sgblack@eecs.umich.edu return NoFault; 2937520Sgblack@eecs.umich.edu case TSDEV_CC_AAR0: 2947520Sgblack@eecs.umich.edu case TSDEV_CC_AAR1: 2957520Sgblack@eecs.umich.edu case TSDEV_CC_AAR2: 2964471Sstever@eecs.umich.edu case TSDEV_CC_AAR3: 2975710Scws3k@cs.virginia.edu panic("TSDEV_CC_AARx write not implemeted\n"); 2984471Sstever@eecs.umich.edu return NoFault; 2995103Ssaidi@eecs.umich.edu case TSDEV_CC_DIM0: 3005103Ssaidi@eecs.umich.edu case TSDEV_CC_DIM1: 3015103Ssaidi@eecs.umich.edu case TSDEV_CC_DIM2: 3025103Ssaidi@eecs.umich.edu case TSDEV_CC_DIM3: 3035103Ssaidi@eecs.umich.edu int number; 3045336Shines@cs.fsu.edu if(regnum == TSDEV_CC_DIM0) 3055103Ssaidi@eecs.umich.edu number = 0; 3065103Ssaidi@eecs.umich.edu else if(regnum == TSDEV_CC_DIM1) 3072839Sktlim@umich.edu number = 1; 3082623SN/A else if(regnum == TSDEV_CC_DIM2) 3092623SN/A number = 2; 3102623SN/A else 311 number = 3; 312 313 uint64_t bitvector; 314 uint64_t olddim; 315 uint64_t olddir; 316 317 olddim = dim[number]; 318 olddir = dir[number]; 319 dim[number] = *(uint64_t*)data; 320 dir[number] = dim[number] & drir; 321 for(int x = 0; x < 64; x++) 322 { 323 bitvector = ULL(1) << x; 324 // Figure out which bits have changed 325 if ((dim[number] & bitvector) != (olddim & bitvector)) 326 { 327 // The bit is now set and it wasn't before (set) 328 if((dim[number] & bitvector) && (dir[number] & bitvector)) 329 { 330 tsunami->intrctrl->post(number, TheISA::INTLEVEL_IRQ1, x); 331 DPRINTF(Tsunami, "posting dir interrupt to cpu 0\n"); 332 } 333 else if ((olddir & bitvector) && 334 !(dir[number] & bitvector)) 335 { 336 // The bit was set and now its now clear and 337 // we were interrupting on that bit before 338 tsunami->intrctrl->clear(number, TheISA::INTLEVEL_IRQ1, x); 339 DPRINTF(Tsunami, "dim write resulting in clear" 340 " dir interrupt to cpu %d\n", 341 x); 342 343 } 344 345 346 } 347 } 348 return NoFault; 349 case TSDEV_CC_DIR0: 350 case TSDEV_CC_DIR1: 351 case TSDEV_CC_DIR2: 352 case TSDEV_CC_DIR3: 353 panic("TSDEV_CC_DIR write not implemented\n"); 354 case TSDEV_CC_DRIR: 355 panic("TSDEV_CC_DRIR write not implemented\n"); 356 case TSDEV_CC_PRBEN: 357 panic("TSDEV_CC_PRBEN write not implemented\n"); 358 case TSDEV_CC_IIC0: 359 case TSDEV_CC_IIC1: 360 case TSDEV_CC_IIC2: 361 case TSDEV_CC_IIC3: 362 panic("TSDEV_CC_IICx write not implemented\n"); 363 case TSDEV_CC_MPR0: 364 case TSDEV_CC_MPR1: 365 case TSDEV_CC_MPR2: 366 case TSDEV_CC_MPR3: 367 panic("TSDEV_CC_MPRx write not implemented\n"); 368 case TSDEV_CC_IPIR: 369 clearIPI(*(uint64_t*)data); 370 return NoFault; 371 case TSDEV_CC_ITIR: 372 clearITI(*(uint64_t*)data); 373 return NoFault; 374 case TSDEV_CC_IPIQ: 375 reqIPI(*(uint64_t*)data); 376 return NoFault; 377 default: 378 panic("default in cchip read reached, accessing 0x%x\n"); 379 } 380 381 break; 382 case sizeof(uint32_t): 383 case sizeof(uint16_t): 384 case sizeof(uint8_t): 385 default: 386 panic("invalid access size(?) for tsunami register!\n"); 387 } 388 389 DPRINTFN("Tsunami ERROR: write daddr=%#x size=%d\n", daddr, req->size); 390 391 return NoFault; 392} 393 394void 395TsunamiCChip::clearIPI(uint64_t ipintr) 396{ 397 int numcpus = tsunami->intrctrl->cpu->system->execContexts.size(); 398 assert(numcpus <= Tsunami::Max_CPUs); 399 400 if (ipintr) { 401 for (int cpunum=0; cpunum < numcpus; cpunum++) { 402 // Check each cpu bit 403 uint64_t cpumask = ULL(1) << cpunum; 404 if (ipintr & cpumask) { 405 // Check if there is a pending ipi 406 if (ipint & cpumask) { 407 ipint &= ~cpumask; 408 tsunami->intrctrl->clear(cpunum, TheISA::INTLEVEL_IRQ3, 0); 409 DPRINTF(IPI, "clear IPI IPI cpu=%d\n", cpunum); 410 } 411 else 412 warn("clear IPI for CPU=%d, but NO IPI\n", cpunum); 413 } 414 } 415 } 416 else 417 panic("Big IPI Clear, but not processors indicated\n"); 418} 419 420void 421TsunamiCChip::clearITI(uint64_t itintr) 422{ 423 int numcpus = tsunami->intrctrl->cpu->system->execContexts.size(); 424 assert(numcpus <= Tsunami::Max_CPUs); 425 426 if (itintr) { 427 for (int i=0; i < numcpus; i++) { 428 uint64_t cpumask = ULL(1) << i; 429 if (itintr & cpumask & itint) { 430 tsunami->intrctrl->clear(i, TheISA::INTLEVEL_IRQ2, 0); 431 itint &= ~cpumask; 432 DPRINTF(Tsunami, "clearing rtc interrupt to cpu=%d\n", i); 433 } 434 } 435 } 436 else 437 panic("Big ITI Clear, but not processors indicated\n"); 438} 439 440void 441TsunamiCChip::reqIPI(uint64_t ipreq) 442{ 443 int numcpus = tsunami->intrctrl->cpu->system->execContexts.size(); 444 assert(numcpus <= Tsunami::Max_CPUs); 445 446 if (ipreq) { 447 for (int cpunum=0; cpunum < numcpus; cpunum++) { 448 // Check each cpu bit 449 uint64_t cpumask = ULL(1) << cpunum; 450 if (ipreq & cpumask) { 451 // Check if there is already an ipi (bits 8:11) 452 if (!(ipint & cpumask)) { 453 ipint |= cpumask; 454 tsunami->intrctrl->post(cpunum, TheISA::INTLEVEL_IRQ3, 0); 455 DPRINTF(IPI, "send IPI cpu=%d\n", cpunum); 456 } 457 else 458 warn("post IPI for CPU=%d, but IPI already\n", cpunum); 459 } 460 } 461 } 462 else 463 panic("Big IPI Request, but not processors indicated\n"); 464} 465 466 467void 468TsunamiCChip::postRTC() 469{ 470 int size = tsunami->intrctrl->cpu->system->execContexts.size(); 471 assert(size <= Tsunami::Max_CPUs); 472 473 for (int i = 0; i < size; i++) { 474 uint64_t cpumask = ULL(1) << i; 475 if (!(cpumask & itint)) { 476 itint |= cpumask; 477 tsunami->intrctrl->post(i, TheISA::INTLEVEL_IRQ2, 0); 478 DPRINTF(Tsunami, "Posting RTC interrupt to cpu=%d", i); 479 } 480 } 481 482} 483 484void 485TsunamiCChip::postDRIR(uint32_t interrupt) 486{ 487 uint64_t bitvector = ULL(1) << interrupt; 488 uint64_t size = tsunami->intrctrl->cpu->system->execContexts.size(); 489 assert(size <= Tsunami::Max_CPUs); 490 drir |= bitvector; 491 492 for(int i=0; i < size; i++) { 493 dir[i] = dim[i] & drir; 494 if (dim[i] & bitvector) { 495 tsunami->intrctrl->post(i, TheISA::INTLEVEL_IRQ1, interrupt); 496 DPRINTF(Tsunami, "posting dir interrupt to cpu %d," 497 "interrupt %d\n",i, interrupt); 498 } 499 } 500} 501 502void 503TsunamiCChip::clearDRIR(uint32_t interrupt) 504{ 505 uint64_t bitvector = ULL(1) << interrupt; 506 uint64_t size = tsunami->intrctrl->cpu->system->execContexts.size(); 507 assert(size <= Tsunami::Max_CPUs); 508 509 if (drir & bitvector) 510 { 511 drir &= ~bitvector; 512 for(int i=0; i < size; i++) { 513 if (dir[i] & bitvector) { 514 tsunami->intrctrl->clear(i, TheISA::INTLEVEL_IRQ1, interrupt); 515 DPRINTF(Tsunami, "clearing dir interrupt to cpu %d," 516 "interrupt %d\n",i, interrupt); 517 518 } 519 dir[i] = dim[i] & drir; 520 } 521 } 522 else 523 DPRINTF(Tsunami, "Spurrious clear? interrupt %d\n", interrupt); 524} 525 526Tick 527TsunamiCChip::cacheAccess(MemReqPtr &req) 528{ 529 return curTick + pioLatency; 530} 531 532 533void 534TsunamiCChip::serialize(std::ostream &os) 535{ 536 SERIALIZE_ARRAY(dim, Tsunami::Max_CPUs); 537 SERIALIZE_ARRAY(dir, Tsunami::Max_CPUs); 538 SERIALIZE_SCALAR(ipint); 539 SERIALIZE_SCALAR(itint); 540 SERIALIZE_SCALAR(drir); 541} 542 543void 544TsunamiCChip::unserialize(Checkpoint *cp, const std::string §ion) 545{ 546 UNSERIALIZE_ARRAY(dim, Tsunami::Max_CPUs); 547 UNSERIALIZE_ARRAY(dir, Tsunami::Max_CPUs); 548 UNSERIALIZE_SCALAR(ipint); 549 UNSERIALIZE_SCALAR(itint); 550 UNSERIALIZE_SCALAR(drir); 551} 552 553BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiCChip) 554 555 SimObjectParam<Tsunami *> tsunami; 556 SimObjectParam<MemoryController *> mmu; 557 Param<Addr> addr; 558 SimObjectParam<Bus*> pio_bus; 559 Param<Tick> pio_latency; 560 SimObjectParam<HierParams *> hier; 561 562END_DECLARE_SIM_OBJECT_PARAMS(TsunamiCChip) 563 564BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiCChip) 565 566 INIT_PARAM(tsunami, "Tsunami"), 567 INIT_PARAM(mmu, "Memory Controller"), 568 INIT_PARAM(addr, "Device Address"), 569 INIT_PARAM_DFLT(pio_bus, "The IO Bus to attach to", NULL), 570 INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1), 571 INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams) 572 573END_INIT_SIM_OBJECT_PARAMS(TsunamiCChip) 574 575CREATE_SIM_OBJECT(TsunamiCChip) 576{ 577 return new TsunamiCChip(getInstanceName(), tsunami, addr, mmu, hier, 578 pio_bus, pio_latency); 579} 580 581REGISTER_SIM_OBJECT("TsunamiCChip", TsunamiCChip) 582