ua2005.cc revision 8778
17161Sgblack@eecs.umich.edu/* 27161Sgblack@eecs.umich.edu * Copyright (c) 2006 The Regents of The University of Michigan 37161Sgblack@eecs.umich.edu * All rights reserved. 47161Sgblack@eecs.umich.edu * 57161Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 67161Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 77161Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 87161Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 97161Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 107161Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 117161Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 127161Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 137161Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 147161Sgblack@eecs.umich.edu * this software without specific prior written permission. 157161Sgblack@eecs.umich.edu * 167161Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 177161Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 187161Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 197161Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 207161Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 217161Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 227161Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 237161Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 247161Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 257161Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 267161Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 277161Sgblack@eecs.umich.edu */ 287161Sgblack@eecs.umich.edu 297161Sgblack@eecs.umich.edu#include "arch/sparc/isa.hh" 307161Sgblack@eecs.umich.edu#include "arch/sparc/kernel_stats.hh" 317161Sgblack@eecs.umich.edu#include "arch/sparc/registers.hh" 327161Sgblack@eecs.umich.edu#include "base/bitfield.hh" 337161Sgblack@eecs.umich.edu#include "base/trace.hh" 347161Sgblack@eecs.umich.edu#include "cpu/base.hh" 357161Sgblack@eecs.umich.edu#include "cpu/thread_context.hh" 367161Sgblack@eecs.umich.edu#include "debug/Quiesce.hh" 377161Sgblack@eecs.umich.edu#include "debug/Timer.hh" 387161Sgblack@eecs.umich.edu#include "sim/system.hh" 397161Sgblack@eecs.umich.edu#include "sim/full_system.hh" 407161Sgblack@eecs.umich.edu 417161Sgblack@eecs.umich.eduusing namespace SparcISA; 427161Sgblack@eecs.umich.eduusing namespace std; 437161Sgblack@eecs.umich.edu 447161Sgblack@eecs.umich.edu 457161Sgblack@eecs.umich.eduvoid 467161Sgblack@eecs.umich.eduISA::checkSoftInt(ThreadContext *tc) 477161Sgblack@eecs.umich.edu{ 487161Sgblack@eecs.umich.edu BaseCPU *cpu = tc->getCpuPtr(); 497161Sgblack@eecs.umich.edu 507161Sgblack@eecs.umich.edu // If PIL < 14, copy over the tm and sm bits 517161Sgblack@eecs.umich.edu if (pil < 14 && softint & 0x10000) 527162Sgblack@eecs.umich.edu cpu->postInterrupt(IT_SOFT_INT, 16); 537161Sgblack@eecs.umich.edu else 547162Sgblack@eecs.umich.edu cpu->clearInterrupt(IT_SOFT_INT, 16); 557161Sgblack@eecs.umich.edu if (pil < 14 && softint & 0x1) 567161Sgblack@eecs.umich.edu cpu->postInterrupt(IT_SOFT_INT, 0); 577161Sgblack@eecs.umich.edu else 587162Sgblack@eecs.umich.edu cpu->clearInterrupt(IT_SOFT_INT, 0); 597161Sgblack@eecs.umich.edu 607162Sgblack@eecs.umich.edu // Copy over any of the other bits that are set 617161Sgblack@eecs.umich.edu for (int bit = 15; bit > 0; --bit) { 627161Sgblack@eecs.umich.edu if (1 << bit & softint && bit > pil) 637162Sgblack@eecs.umich.edu cpu->postInterrupt(IT_SOFT_INT, bit); 647161Sgblack@eecs.umich.edu else 657162Sgblack@eecs.umich.edu cpu->clearInterrupt(IT_SOFT_INT, bit); 667161Sgblack@eecs.umich.edu } 677161Sgblack@eecs.umich.edu} 687162Sgblack@eecs.umich.edu 697161Sgblack@eecs.umich.edu// These functions map register indices to names 707162Sgblack@eecs.umich.edustatic inline string 717161Sgblack@eecs.umich.edugetMiscRegName(RegIndex index) 727161Sgblack@eecs.umich.edu{ 737161Sgblack@eecs.umich.edu static string miscRegName[NumMiscRegs] = 747162Sgblack@eecs.umich.edu {/*"y", "ccr",*/ "asi", "tick", "fprs", "pcr", "pic", 757161Sgblack@eecs.umich.edu "gsr", "softint_set", "softint_clr", "softint", "tick_cmpr", 767162Sgblack@eecs.umich.edu "stick", "stick_cmpr", 777161Sgblack@eecs.umich.edu "tpc", "tnpc", "tstate", "tt", "privtick", "tba", "pstate", "tl", 787161Sgblack@eecs.umich.edu "pil", "cwp", /*"cansave", "canrestore", "cleanwin", "otherwin", 797161Sgblack@eecs.umich.edu "wstate",*/ "gl", 807162Sgblack@eecs.umich.edu "hpstate", "htstate", "hintp", "htba", "hver", "strand_sts_reg", 817161Sgblack@eecs.umich.edu "hstick_cmpr", 827162Sgblack@eecs.umich.edu "fsr", "prictx", "secctx", "partId", "lsuCtrlReg", 837161Sgblack@eecs.umich.edu "scratch0", "scratch1", "scratch2", "scratch3", "scratch4", 847161Sgblack@eecs.umich.edu "scratch5", "scratch6", "scratch7", "cpuMondoHead", "cpuMondoTail", 857161Sgblack@eecs.umich.edu "devMondoHead", "devMondoTail", "resErrorHead", "resErrorTail", 867162Sgblack@eecs.umich.edu "nresErrorHead", "nresErrorTail", "TlbData" }; 877161Sgblack@eecs.umich.edu return miscRegName[index]; 887162Sgblack@eecs.umich.edu} 897161Sgblack@eecs.umich.edu 907161Sgblack@eecs.umich.eduvoid 917161Sgblack@eecs.umich.eduISA::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc) 927161Sgblack@eecs.umich.edu{ 937161Sgblack@eecs.umich.edu BaseCPU *cpu = tc->getCpuPtr(); 947161Sgblack@eecs.umich.edu 957161Sgblack@eecs.umich.edu int64_t time; 967161Sgblack@eecs.umich.edu switch (miscReg) { 977161Sgblack@eecs.umich.edu /* Full system only ASRs */ 987161Sgblack@eecs.umich.edu case MISCREG_SOFTINT: 997161Sgblack@eecs.umich.edu setMiscRegNoEffect(miscReg, val);; 1007161Sgblack@eecs.umich.edu checkSoftInt(tc); 1017161Sgblack@eecs.umich.edu break; 1027161Sgblack@eecs.umich.edu case MISCREG_SOFTINT_CLR: 1037161Sgblack@eecs.umich.edu return setMiscReg(MISCREG_SOFTINT, ~val & softint, tc); 1047161Sgblack@eecs.umich.edu case MISCREG_SOFTINT_SET: 1057161Sgblack@eecs.umich.edu return setMiscReg(MISCREG_SOFTINT, val | softint, tc); 1067161Sgblack@eecs.umich.edu 1077161Sgblack@eecs.umich.edu case MISCREG_TICK_CMPR: 1087162Sgblack@eecs.umich.edu if (tickCompare == NULL) 1097161Sgblack@eecs.umich.edu tickCompare = new TickCompareEvent(this, tc); 1107162Sgblack@eecs.umich.edu setMiscRegNoEffect(miscReg, val); 1117161Sgblack@eecs.umich.edu if ((tick_cmpr & ~mask(63)) && tickCompare->scheduled()) 1127162Sgblack@eecs.umich.edu cpu->deschedule(tickCompare); 1137161Sgblack@eecs.umich.edu time = (tick_cmpr & mask(63)) - (tick & mask(63)); 1147162Sgblack@eecs.umich.edu if (!(tick_cmpr & ~mask(63)) && time > 0) { 1157161Sgblack@eecs.umich.edu if (tickCompare->scheduled()) 1167161Sgblack@eecs.umich.edu cpu->deschedule(tickCompare); 1177161Sgblack@eecs.umich.edu cpu->schedule(tickCompare, curTick() + time * cpu->ticks(1)); 1187161Sgblack@eecs.umich.edu } 1197162Sgblack@eecs.umich.edu panic("writing to TICK compare register %#X\n", val); 1207161Sgblack@eecs.umich.edu break; 1217162Sgblack@eecs.umich.edu 1227161Sgblack@eecs.umich.edu case MISCREG_STICK_CMPR: 1237161Sgblack@eecs.umich.edu if (sTickCompare == NULL) 1247161Sgblack@eecs.umich.edu sTickCompare = new STickCompareEvent(this, tc); 1257162Sgblack@eecs.umich.edu setMiscRegNoEffect(miscReg, val); 1267161Sgblack@eecs.umich.edu if ((stick_cmpr & ~mask(63)) && sTickCompare->scheduled()) 1277162Sgblack@eecs.umich.edu cpu->deschedule(sTickCompare); 1287161Sgblack@eecs.umich.edu time = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) - 1297161Sgblack@eecs.umich.edu cpu->instCount(); 1307161Sgblack@eecs.umich.edu if (!(stick_cmpr & ~mask(63)) && time > 0) { 1317161Sgblack@eecs.umich.edu if (sTickCompare->scheduled()) 1327161Sgblack@eecs.umich.edu cpu->deschedule(sTickCompare); 1337162Sgblack@eecs.umich.edu cpu->schedule(sTickCompare, curTick() + time * cpu->ticks(1)); 1347161Sgblack@eecs.umich.edu } 1357162Sgblack@eecs.umich.edu DPRINTF(Timer, "writing to sTICK compare register value %#X\n", val); 1367161Sgblack@eecs.umich.edu break; 1377162Sgblack@eecs.umich.edu 1387161Sgblack@eecs.umich.edu case MISCREG_PSTATE: 1397162Sgblack@eecs.umich.edu setMiscRegNoEffect(miscReg, val); 1407161Sgblack@eecs.umich.edu 1417161Sgblack@eecs.umich.edu case MISCREG_PIL: 1427161Sgblack@eecs.umich.edu setMiscRegNoEffect(miscReg, val); 1437161Sgblack@eecs.umich.edu checkSoftInt(tc); 1447162Sgblack@eecs.umich.edu break; 1457161Sgblack@eecs.umich.edu 1467162Sgblack@eecs.umich.edu case MISCREG_HVER: 1477161Sgblack@eecs.umich.edu panic("Shouldn't be writing HVER\n"); 1487162Sgblack@eecs.umich.edu 1497161Sgblack@eecs.umich.edu case MISCREG_HINTP: 1507162Sgblack@eecs.umich.edu setMiscRegNoEffect(miscReg, val); 1517161Sgblack@eecs.umich.edu if (hintp) 1527161Sgblack@eecs.umich.edu cpu->postInterrupt(IT_HINTP, 0); 1537161Sgblack@eecs.umich.edu else 1547161Sgblack@eecs.umich.edu cpu->clearInterrupt(IT_HINTP, 0); 1557161Sgblack@eecs.umich.edu break; 1567161Sgblack@eecs.umich.edu 1577161Sgblack@eecs.umich.edu case MISCREG_HTBA: 1587161Sgblack@eecs.umich.edu // clear lower 7 bits on writes. 1597161Sgblack@eecs.umich.edu setMiscRegNoEffect(miscReg, val & ULL(~0x7FFF)); 1607161Sgblack@eecs.umich.edu break; 1617161Sgblack@eecs.umich.edu 1627161Sgblack@eecs.umich.edu case MISCREG_QUEUE_CPU_MONDO_HEAD: 1637161Sgblack@eecs.umich.edu case MISCREG_QUEUE_CPU_MONDO_TAIL: 1647161Sgblack@eecs.umich.edu setMiscRegNoEffect(miscReg, val); 1657161Sgblack@eecs.umich.edu if (cpu_mondo_head != cpu_mondo_tail) 1667161Sgblack@eecs.umich.edu cpu->postInterrupt(IT_CPU_MONDO, 0); 1677161Sgblack@eecs.umich.edu else 1687161Sgblack@eecs.umich.edu cpu->clearInterrupt(IT_CPU_MONDO, 0); 1697161Sgblack@eecs.umich.edu break; 1707161Sgblack@eecs.umich.edu case MISCREG_QUEUE_DEV_MONDO_HEAD: 1717161Sgblack@eecs.umich.edu case MISCREG_QUEUE_DEV_MONDO_TAIL: 1727161Sgblack@eecs.umich.edu setMiscRegNoEffect(miscReg, val); 1737162Sgblack@eecs.umich.edu if (dev_mondo_head != dev_mondo_tail) 1747161Sgblack@eecs.umich.edu cpu->postInterrupt(IT_DEV_MONDO, 0); 1757162Sgblack@eecs.umich.edu else 1767161Sgblack@eecs.umich.edu cpu->clearInterrupt(IT_DEV_MONDO, 0); 1777161Sgblack@eecs.umich.edu break; 1787162Sgblack@eecs.umich.edu case MISCREG_QUEUE_RES_ERROR_HEAD: 1797161Sgblack@eecs.umich.edu case MISCREG_QUEUE_RES_ERROR_TAIL: 1807161Sgblack@eecs.umich.edu setMiscRegNoEffect(miscReg, val); 1817161Sgblack@eecs.umich.edu if (res_error_head != res_error_tail) 1827161Sgblack@eecs.umich.edu cpu->postInterrupt(IT_RES_ERROR, 0); 1837161Sgblack@eecs.umich.edu else 1847162Sgblack@eecs.umich.edu cpu->clearInterrupt(IT_RES_ERROR, 0); 1857161Sgblack@eecs.umich.edu break; 1867162Sgblack@eecs.umich.edu case MISCREG_QUEUE_NRES_ERROR_HEAD: 1877161Sgblack@eecs.umich.edu case MISCREG_QUEUE_NRES_ERROR_TAIL: 1887162Sgblack@eecs.umich.edu setMiscRegNoEffect(miscReg, val); 1897161Sgblack@eecs.umich.edu // This one doesn't have an interrupt to report to the guest OS 1907162Sgblack@eecs.umich.edu break; 1917161Sgblack@eecs.umich.edu 1927161Sgblack@eecs.umich.edu case MISCREG_HSTICK_CMPR: 1937161Sgblack@eecs.umich.edu if (hSTickCompare == NULL) 1947161Sgblack@eecs.umich.edu hSTickCompare = new HSTickCompareEvent(this, tc); 1957162Sgblack@eecs.umich.edu setMiscRegNoEffect(miscReg, val); 1967161Sgblack@eecs.umich.edu if ((hstick_cmpr & ~mask(63)) && hSTickCompare->scheduled()) 1977162Sgblack@eecs.umich.edu cpu->deschedule(hSTickCompare); 1987161Sgblack@eecs.umich.edu time = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) - 1997162Sgblack@eecs.umich.edu cpu->instCount(); 2007161Sgblack@eecs.umich.edu if (!(hstick_cmpr & ~mask(63)) && time > 0) { 2017162Sgblack@eecs.umich.edu if (hSTickCompare->scheduled()) 2027161Sgblack@eecs.umich.edu cpu->deschedule(hSTickCompare); 2037161Sgblack@eecs.umich.edu cpu->schedule(hSTickCompare, curTick() + time * cpu->ticks(1)); 2047161Sgblack@eecs.umich.edu } 2057161Sgblack@eecs.umich.edu DPRINTF(Timer, "writing to hsTICK compare register value %#X\n", val); 2067161Sgblack@eecs.umich.edu break; 2077162Sgblack@eecs.umich.edu 2087161Sgblack@eecs.umich.edu case MISCREG_HPSTATE: 2097162Sgblack@eecs.umich.edu // T1000 spec says impl. dependent val must always be 1 2107161Sgblack@eecs.umich.edu setMiscRegNoEffect(miscReg, val | HPSTATE::id); 2117161Sgblack@eecs.umich.edu if (hpstate & HPSTATE::tlz && tl == 0 && !(hpstate & HPSTATE::hpriv)) 2127161Sgblack@eecs.umich.edu cpu->postInterrupt(IT_TRAP_LEVEL_ZERO, 0); 2137162Sgblack@eecs.umich.edu else 2147161Sgblack@eecs.umich.edu cpu->clearInterrupt(IT_TRAP_LEVEL_ZERO, 0); 2157162Sgblack@eecs.umich.edu break; 2167161Sgblack@eecs.umich.edu case MISCREG_HTSTATE: 2177161Sgblack@eecs.umich.edu setMiscRegNoEffect(miscReg, val); 2187161Sgblack@eecs.umich.edu break; 2197161Sgblack@eecs.umich.edu 2207161Sgblack@eecs.umich.edu case MISCREG_STRAND_STS_REG: 2217162Sgblack@eecs.umich.edu if (bits(val,2,2)) 2227161Sgblack@eecs.umich.edu panic("No support for setting spec_en bit\n"); 2237162Sgblack@eecs.umich.edu setMiscRegNoEffect(miscReg, bits(val,0,0)); 2247161Sgblack@eecs.umich.edu if (!bits(val,0,0)) { 2257161Sgblack@eecs.umich.edu DPRINTF(Quiesce, "Cpu executed quiescing instruction\n"); 2267161Sgblack@eecs.umich.edu // Time to go to sleep 2277162Sgblack@eecs.umich.edu tc->suspend(); 2287161Sgblack@eecs.umich.edu if (FullSystem && tc->getKernelStats()) 2297162Sgblack@eecs.umich.edu tc->getKernelStats()->quiesce(); 2307161Sgblack@eecs.umich.edu } 2317161Sgblack@eecs.umich.edu break; 2327161Sgblack@eecs.umich.edu 2337161Sgblack@eecs.umich.edu default: 2347161Sgblack@eecs.umich.edu panic("Invalid write to FS misc register %s\n", 2357162Sgblack@eecs.umich.edu getMiscRegName(miscReg)); 2367161Sgblack@eecs.umich.edu } 2377162Sgblack@eecs.umich.edu} 2387161Sgblack@eecs.umich.edu 2397161Sgblack@eecs.umich.eduMiscReg 2407161Sgblack@eecs.umich.eduISA::readFSReg(int miscReg, ThreadContext * tc) 2417162Sgblack@eecs.umich.edu{ 2427161Sgblack@eecs.umich.edu uint64_t temp; 2437162Sgblack@eecs.umich.edu 2447161Sgblack@eecs.umich.edu switch (miscReg) { 2457161Sgblack@eecs.umich.edu /* Privileged registers. */ 2467161Sgblack@eecs.umich.edu case MISCREG_QUEUE_CPU_MONDO_HEAD: 2477161Sgblack@eecs.umich.edu case MISCREG_QUEUE_CPU_MONDO_TAIL: 2487161Sgblack@eecs.umich.edu case MISCREG_QUEUE_DEV_MONDO_HEAD: 2497162Sgblack@eecs.umich.edu case MISCREG_QUEUE_DEV_MONDO_TAIL: 2507161Sgblack@eecs.umich.edu case MISCREG_QUEUE_RES_ERROR_HEAD: 2517162Sgblack@eecs.umich.edu case MISCREG_QUEUE_RES_ERROR_TAIL: 2527161Sgblack@eecs.umich.edu case MISCREG_QUEUE_NRES_ERROR_HEAD: 2537161Sgblack@eecs.umich.edu case MISCREG_QUEUE_NRES_ERROR_TAIL: 2547161Sgblack@eecs.umich.edu case MISCREG_SOFTINT: 2557162Sgblack@eecs.umich.edu case MISCREG_TICK_CMPR: 2567161Sgblack@eecs.umich.edu case MISCREG_STICK_CMPR: 2577162Sgblack@eecs.umich.edu case MISCREG_PIL: 2587161Sgblack@eecs.umich.edu case MISCREG_HPSTATE: 2597161Sgblack@eecs.umich.edu case MISCREG_HINTP: 2607161Sgblack@eecs.umich.edu case MISCREG_HTSTATE: 2617161Sgblack@eecs.umich.edu case MISCREG_HSTICK_CMPR: 2627162Sgblack@eecs.umich.edu return readMiscRegNoEffect(miscReg) ; 2637161Sgblack@eecs.umich.edu 2647162Sgblack@eecs.umich.edu case MISCREG_HTBA: 2657161Sgblack@eecs.umich.edu return readMiscRegNoEffect(miscReg) & ULL(~0x7FFF); 2667161Sgblack@eecs.umich.edu case MISCREG_HVER: 2677161Sgblack@eecs.umich.edu // XXX set to match Legion 2687161Sgblack@eecs.umich.edu return ULL(0x3e) << 48 | 2697161Sgblack@eecs.umich.edu ULL(0x23) << 32 | 2707243Sgblack@eecs.umich.edu ULL(0x20) << 24 | 2717161Sgblack@eecs.umich.edu // MaxGL << 16 | XXX For some reason legion doesn't set GL 2727243Sgblack@eecs.umich.edu MaxTL << 8 | 2737161Sgblack@eecs.umich.edu (NWindows -1) << 0; 2747161Sgblack@eecs.umich.edu 2757161Sgblack@eecs.umich.edu case MISCREG_STRAND_STS_REG: 2767161Sgblack@eecs.umich.edu System *sys; 2777161Sgblack@eecs.umich.edu int x; 2787161Sgblack@eecs.umich.edu sys = tc->getSystemPtr(); 2797161Sgblack@eecs.umich.edu 2807161Sgblack@eecs.umich.edu temp = readMiscRegNoEffect(miscReg) & (STS::active | STS::speculative); 2817161Sgblack@eecs.umich.edu // Check that the CPU array is fully populated 2827161Sgblack@eecs.umich.edu // (by calling getNumCPus()) 2837161Sgblack@eecs.umich.edu assert(sys->numContexts() > tc->contextId()); 2847161Sgblack@eecs.umich.edu 2857161Sgblack@eecs.umich.edu temp |= tc->contextId() << STS::shft_id; 2867161Sgblack@eecs.umich.edu 2877161Sgblack@eecs.umich.edu for (x = tc->contextId() & ~3; x < sys->threadContexts.size(); x++) { 2887161Sgblack@eecs.umich.edu switch (sys->threadContexts[x]->status()) { 2897161Sgblack@eecs.umich.edu case ThreadContext::Active: 2907161Sgblack@eecs.umich.edu temp |= STS::st_run << (STS::shft_fsm0 - 2917162Sgblack@eecs.umich.edu ((x & 0x3) * (STS::shft_fsm0-STS::shft_fsm1))); 2927161Sgblack@eecs.umich.edu break; 2937161Sgblack@eecs.umich.edu case ThreadContext::Suspended: 2947161Sgblack@eecs.umich.edu // should this be idle? 2957161Sgblack@eecs.umich.edu temp |= STS::st_idle << (STS::shft_fsm0 - 2967161Sgblack@eecs.umich.edu ((x & 0x3) * (STS::shft_fsm0-STS::shft_fsm1))); 2977161Sgblack@eecs.umich.edu break; 2987161Sgblack@eecs.umich.edu case ThreadContext::Halted: 2997161Sgblack@eecs.umich.edu temp |= STS::st_halt << (STS::shft_fsm0 - 3007161Sgblack@eecs.umich.edu ((x & 0x3) * (STS::shft_fsm0-STS::shft_fsm1))); 3017162Sgblack@eecs.umich.edu break; 3027161Sgblack@eecs.umich.edu default: 3037161Sgblack@eecs.umich.edu panic("What state are we in?!\n"); 3047161Sgblack@eecs.umich.edu } // switch 3057161Sgblack@eecs.umich.edu } // for 3067161Sgblack@eecs.umich.edu 3077161Sgblack@eecs.umich.edu return temp; 3087161Sgblack@eecs.umich.edu default: 3097161Sgblack@eecs.umich.edu panic("Invalid read to FS misc register\n"); 3107161Sgblack@eecs.umich.edu } 3117162Sgblack@eecs.umich.edu} 3127161Sgblack@eecs.umich.edu 3137161Sgblack@eecs.umich.eduvoid 3147161Sgblack@eecs.umich.eduISA::processTickCompare(ThreadContext *tc) 3157162Sgblack@eecs.umich.edu{ 3167161Sgblack@eecs.umich.edu panic("tick compare not implemented\n"); 3177162Sgblack@eecs.umich.edu} 3187161Sgblack@eecs.umich.edu 3197162Sgblack@eecs.umich.eduvoid 3207161Sgblack@eecs.umich.eduISA::processSTickCompare(ThreadContext *tc) 3217162Sgblack@eecs.umich.edu{ 3227161Sgblack@eecs.umich.edu BaseCPU *cpu = tc->getCpuPtr(); 3237161Sgblack@eecs.umich.edu 3247161Sgblack@eecs.umich.edu // since our microcode instructions take two cycles we need to check if 3257162Sgblack@eecs.umich.edu // we're actually at the correct cycle or we need to wait a little while 3267161Sgblack@eecs.umich.edu // more 3277162Sgblack@eecs.umich.edu int ticks; 3287161Sgblack@eecs.umich.edu ticks = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) - 3297161Sgblack@eecs.umich.edu cpu->instCount(); 3307161Sgblack@eecs.umich.edu assert(ticks >= 0 && "stick compare missed interrupt cycle"); 3317161Sgblack@eecs.umich.edu 3327161Sgblack@eecs.umich.edu if (ticks == 0 || tc->status() == ThreadContext::Suspended) { 3337161Sgblack@eecs.umich.edu DPRINTF(Timer, "STick compare cycle reached at %#x\n", 3347162Sgblack@eecs.umich.edu (stick_cmpr & mask(63))); 3357161Sgblack@eecs.umich.edu if (!(tc->readMiscRegNoEffect(MISCREG_STICK_CMPR) & (ULL(1) << 63))) { 3367162Sgblack@eecs.umich.edu setMiscReg(MISCREG_SOFTINT, softint | (ULL(1) << 16), tc); 3377161Sgblack@eecs.umich.edu } 3387161Sgblack@eecs.umich.edu } else { 3397290Sgblack@eecs.umich.edu cpu->schedule(sTickCompare, curTick() + ticks * cpu->ticks(1)); 3407161Sgblack@eecs.umich.edu } 3417161Sgblack@eecs.umich.edu} 3427162Sgblack@eecs.umich.edu 3437161Sgblack@eecs.umich.eduvoid 3447162Sgblack@eecs.umich.eduISA::processHSTickCompare(ThreadContext *tc) 3457161Sgblack@eecs.umich.edu{ 3467161Sgblack@eecs.umich.edu BaseCPU *cpu = tc->getCpuPtr(); 3477161Sgblack@eecs.umich.edu 3487161Sgblack@eecs.umich.edu // since our microcode instructions take two cycles we need to check if 3497161Sgblack@eecs.umich.edu // we're actually at the correct cycle or we need to wait a little while 3507161Sgblack@eecs.umich.edu // more 3517161Sgblack@eecs.umich.edu int ticks; 3527161Sgblack@eecs.umich.edu if ( tc->status() == ThreadContext::Halted) 3537161Sgblack@eecs.umich.edu return; 3547161Sgblack@eecs.umich.edu 3557161Sgblack@eecs.umich.edu ticks = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) - 3567161Sgblack@eecs.umich.edu cpu->instCount(); 3577161Sgblack@eecs.umich.edu assert(ticks >= 0 && "hstick compare missed interrupt cycle"); 3587161Sgblack@eecs.umich.edu 3597161Sgblack@eecs.umich.edu if (ticks == 0 || tc->status() == ThreadContext::Suspended) { 3607161Sgblack@eecs.umich.edu DPRINTF(Timer, "HSTick compare cycle reached at %#x\n", 3617161Sgblack@eecs.umich.edu (stick_cmpr & mask(63))); 3627161Sgblack@eecs.umich.edu if (!(tc->readMiscRegNoEffect(MISCREG_HSTICK_CMPR) & (ULL(1) << 63))) { 3637161Sgblack@eecs.umich.edu setMiscReg(MISCREG_HINTP, 1, tc); 3647161Sgblack@eecs.umich.edu } 3657161Sgblack@eecs.umich.edu // Need to do something to cause interrupt to happen here !!! @todo 3667161Sgblack@eecs.umich.edu } else { 3677161Sgblack@eecs.umich.edu cpu->schedule(hSTickCompare, curTick() + ticks * cpu->ticks(1)); 3687161Sgblack@eecs.umich.edu } 3697161Sgblack@eecs.umich.edu} 3707162Sgblack@eecs.umich.edu 3717161Sgblack@eecs.umich.edu