1/* 2 * Copyright (c) 2009 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Gabe Black 29 */ 30 31#include "arch/sparc/isa.hh" 32 33#include "arch/sparc/asi.hh" 34#include "arch/sparc/decoder.hh" 35#include "base/bitfield.hh" 36#include "base/trace.hh" 37#include "cpu/base.hh" 38#include "cpu/thread_context.hh" 39#include "debug/MiscRegs.hh" 40#include "debug/Timer.hh" 41#include "params/SparcISA.hh" 42 43namespace SparcISA 44{ 45 46static PSTATE 47buildPstateMask() 48{ 49 PSTATE mask = 0; 50 mask.ie = 1; 51 mask.priv = 1; 52 mask.am = 1; 53 mask.pef = 1; 54 mask.mm = 3; 55 mask.tle = 1; 56 mask.cle = 1; 57 mask.pid1 = 1; 58 return mask; 59} 60 61static const PSTATE PstateMask = buildPstateMask(); 62 63ISA::ISA(Params *p) 64 : SimObject(p) 65{ 66 tickCompare = NULL; 67 sTickCompare = NULL; 68 hSTickCompare = NULL; 69 70 clear(); 71} 72 73const SparcISAParams * 74ISA::params() const 75{ 76 return dynamic_cast<const Params *>(_params); 77} 78 79void 80ISA::reloadRegMap() 81{ 82 installGlobals(gl, CurrentGlobalsOffset); 83 installWindow(cwp, CurrentWindowOffset); 84 // Microcode registers. 85 for (int i = 0; i < NumMicroIntRegs; i++) 86 intRegMap[MicroIntOffset + i] = i + TotalGlobals + NWindows * 16; 87 installGlobals(gl, NextGlobalsOffset); 88 installWindow(cwp - 1, NextWindowOffset); 89 installGlobals(gl, PreviousGlobalsOffset); 90 installWindow(cwp + 1, PreviousWindowOffset); 91} 92 93void 94ISA::installWindow(int cwp, int offset) 95{ 96 assert(offset >= 0 && offset + NumWindowedRegs <= NumIntRegs); 97 RegIndex *mapChunk = intRegMap + offset; 98 for (int i = 0; i < NumWindowedRegs; i++) 99 mapChunk[i] = TotalGlobals + 100 ((i - cwp * RegsPerWindow + TotalWindowed) % (TotalWindowed)); 101} 102 103void 104ISA::installGlobals(int gl, int offset) 105{ 106 assert(offset >= 0 && offset + NumGlobalRegs <= NumIntRegs); 107 RegIndex *mapChunk = intRegMap + offset; 108 mapChunk[0] = 0; 109 for (int i = 1; i < NumGlobalRegs; i++) 110 mapChunk[i] = i + gl * NumGlobalRegs; 111} 112 113void 114ISA::clear() 115{ 116 cwp = 0; 117 gl = 0; 118 reloadRegMap(); 119 120 // y = 0; 121 // ccr = 0; 122 asi = 0; 123 tick = ULL(1) << 63; 124 fprs = 0; 125 gsr = 0; 126 softint = 0; 127 tick_cmpr = 0; 128 stick = 0; 129 stick_cmpr = 0; 130 memset(tpc, 0, sizeof(tpc)); 131 memset(tnpc, 0, sizeof(tnpc)); 132 memset(tstate, 0, sizeof(tstate)); 133 memset(tt, 0, sizeof(tt)); 134 tba = 0; 135 pstate = 0; 136 tl = 0; 137 pil = 0; 138 // cansave = 0; 139 // canrestore = 0; 140 // cleanwin = 0; 141 // otherwin = 0; 142 // wstate = 0; 143 // In a T1, bit 11 is apparently always 1 144 hpstate = 0; 145 hpstate.id = 1; 146 memset(htstate, 0, sizeof(htstate)); 147 hintp = 0; 148 htba = 0; 149 hstick_cmpr = 0; 150 // This is set this way in Legion for some reason 151 strandStatusReg = 0x50000; 152 fsr = 0; 153 154 priContext = 0; 155 secContext = 0; 156 partId = 0; 157 lsuCtrlReg = 0; 158 159 memset(scratchPad, 0, sizeof(scratchPad)); 160 161 cpu_mondo_head = 0; 162 cpu_mondo_tail = 0; 163 dev_mondo_head = 0; 164 dev_mondo_tail = 0; 165 res_error_head = 0; 166 res_error_tail = 0; 167 nres_error_head = 0; 168 nres_error_tail = 0; 169 170 // If one of these events is active, it's not obvious to me how to get 171 // rid of it cleanly. For now we'll just assert that they're not. 172 if (tickCompare != NULL && sTickCompare != NULL && hSTickCompare != NULL) 173 panic("Tick comparison event active when clearing the ISA object.\n"); 174} 175 176RegVal 177ISA::readMiscRegNoEffect(int miscReg) const 178{ 179 180 // The three miscRegs are moved up from the switch statement 181 // due to more frequent calls. 182 183 if (miscReg == MISCREG_GL) 184 return gl; 185 if (miscReg == MISCREG_CWP) 186 return cwp; 187 if (miscReg == MISCREG_TLB_DATA) { 188 /* Package up all the data for the tlb: 189 * 6666555555555544444444443333333333222222222211111111110000000000 190 * 3210987654321098765432109876543210987654321098765432109876543210 191 * secContext | priContext | |tl|partid| |||||^hpriv 192 * ||||^red 193 * |||^priv 194 * ||^am 195 * |^lsuim 196 * ^lsudm 197 */ 198 return (uint64_t)hpstate.hpriv | 199 (uint64_t)hpstate.red << 1 | 200 (uint64_t)pstate.priv << 2 | 201 (uint64_t)pstate.am << 3 | 202 bits((uint64_t)lsuCtrlReg,3,2) << 4 | 203 bits((uint64_t)partId,7,0) << 8 | 204 bits((uint64_t)tl,2,0) << 16 | 205 (uint64_t)priContext << 32 | 206 (uint64_t)secContext << 48; 207 } 208 209 switch (miscReg) { 210 // case MISCREG_TLB_DATA: 211 // [original contents see above] 212 // case MISCREG_Y: 213 // return y; 214 // case MISCREG_CCR: 215 // return ccr; 216 case MISCREG_ASI: 217 return asi; 218 case MISCREG_FPRS: 219 return fprs; 220 case MISCREG_TICK: 221 return tick; 222 case MISCREG_PCR: 223 panic("PCR not implemented\n"); 224 case MISCREG_PIC: 225 panic("PIC not implemented\n"); 226 case MISCREG_GSR: 227 return gsr; 228 case MISCREG_SOFTINT: 229 return softint; 230 case MISCREG_TICK_CMPR: 231 return tick_cmpr; 232 case MISCREG_STICK: 233 return stick; 234 case MISCREG_STICK_CMPR: 235 return stick_cmpr; 236 237 /** Privilged Registers */ 238 case MISCREG_TPC: 239 return tpc[tl-1]; 240 case MISCREG_TNPC: 241 return tnpc[tl-1]; 242 case MISCREG_TSTATE: 243 return tstate[tl-1]; 244 case MISCREG_TT: 245 return tt[tl-1]; 246 case MISCREG_PRIVTICK: 247 panic("Priviliged access to tick registers not implemented\n"); 248 case MISCREG_TBA: 249 return tba; 250 case MISCREG_PSTATE: 251 return (RegVal)pstate; 252 case MISCREG_TL: 253 return tl; 254 case MISCREG_PIL: 255 return pil; 256 // CWP, GL moved 257 // case MISCREG_CWP: 258 // return cwp; 259 // case MISCREG_CANSAVE: 260 // return cansave; 261 // case MISCREG_CANRESTORE: 262 // return canrestore; 263 // case MISCREG_CLEANWIN: 264 // return cleanwin; 265 // case MISCREG_OTHERWIN: 266 // return otherwin; 267 // case MISCREG_WSTATE: 268 // return wstate; 269 // case MISCREG_GL: 270 // return gl; 271 272 /** Hyper privileged registers */ 273 case MISCREG_HPSTATE: 274 return (RegVal)hpstate; 275 case MISCREG_HTSTATE: 276 return htstate[tl-1]; 277 case MISCREG_HINTP: 278 return hintp; 279 case MISCREG_HTBA: 280 return htba; 281 case MISCREG_STRAND_STS_REG: 282 return strandStatusReg; 283 case MISCREG_HSTICK_CMPR: 284 return hstick_cmpr; 285 286 /** Floating Point Status Register */ 287 case MISCREG_FSR: 288 DPRINTF(MiscRegs, "FSR read as: %#x\n", fsr); 289 return fsr; 290 291 case MISCREG_MMU_P_CONTEXT: 292 return priContext; 293 case MISCREG_MMU_S_CONTEXT: 294 return secContext; 295 case MISCREG_MMU_PART_ID: 296 return partId; 297 case MISCREG_MMU_LSU_CTRL: 298 return lsuCtrlReg; 299 300 case MISCREG_SCRATCHPAD_R0: 301 return scratchPad[0]; 302 case MISCREG_SCRATCHPAD_R1: 303 return scratchPad[1]; 304 case MISCREG_SCRATCHPAD_R2: 305 return scratchPad[2]; 306 case MISCREG_SCRATCHPAD_R3: 307 return scratchPad[3]; 308 case MISCREG_SCRATCHPAD_R4: 309 return scratchPad[4]; 310 case MISCREG_SCRATCHPAD_R5: 311 return scratchPad[5]; 312 case MISCREG_SCRATCHPAD_R6: 313 return scratchPad[6]; 314 case MISCREG_SCRATCHPAD_R7: 315 return scratchPad[7]; 316 case MISCREG_QUEUE_CPU_MONDO_HEAD: 317 return cpu_mondo_head; 318 case MISCREG_QUEUE_CPU_MONDO_TAIL: 319 return cpu_mondo_tail; 320 case MISCREG_QUEUE_DEV_MONDO_HEAD: 321 return dev_mondo_head; 322 case MISCREG_QUEUE_DEV_MONDO_TAIL: 323 return dev_mondo_tail; 324 case MISCREG_QUEUE_RES_ERROR_HEAD: 325 return res_error_head; 326 case MISCREG_QUEUE_RES_ERROR_TAIL: 327 return res_error_tail; 328 case MISCREG_QUEUE_NRES_ERROR_HEAD: 329 return nres_error_head; 330 case MISCREG_QUEUE_NRES_ERROR_TAIL: 331 return nres_error_tail; 332 default: 333 panic("Miscellaneous register %d not implemented\n", miscReg); 334 } 335} 336 337RegVal 338ISA::readMiscReg(int miscReg, ThreadContext * tc) 339{ 340 switch (miscReg) { 341 // tick and stick are aliased to each other in niagra 342 // well store the tick data in stick and the interrupt bit in tick 343 case MISCREG_STICK: 344 case MISCREG_TICK: 345 case MISCREG_PRIVTICK: 346 // I'm not sure why legion ignores the lowest two bits, but we'll go 347 // with it 348 // change from curCycle() to instCount() until we're done with legion 349 DPRINTF(Timer, "Instruction Count when TICK read: %#X stick=%#X\n", 350 tc->getCpuPtr()->instCount(), stick); 351 return mbits(tc->getCpuPtr()->instCount() + (int64_t)stick,62,2) | 352 mbits(tick,63,63); 353 case MISCREG_FPRS: 354 // in legion if fp is enabled du and dl are set 355 return fprs | 0x3; 356 case MISCREG_PCR: 357 case MISCREG_PIC: 358 panic("Performance Instrumentation not impl\n"); 359 case MISCREG_SOFTINT_CLR: 360 case MISCREG_SOFTINT_SET: 361 panic("Can read from softint clr/set\n"); 362 case MISCREG_SOFTINT: 363 case MISCREG_TICK_CMPR: 364 case MISCREG_STICK_CMPR: 365 case MISCREG_HINTP: 366 case MISCREG_HTSTATE: 367 case MISCREG_HTBA: 368 case MISCREG_HVER: 369 case MISCREG_STRAND_STS_REG: 370 case MISCREG_HSTICK_CMPR: 371 case MISCREG_QUEUE_CPU_MONDO_HEAD: 372 case MISCREG_QUEUE_CPU_MONDO_TAIL: 373 case MISCREG_QUEUE_DEV_MONDO_HEAD: 374 case MISCREG_QUEUE_DEV_MONDO_TAIL: 375 case MISCREG_QUEUE_RES_ERROR_HEAD: 376 case MISCREG_QUEUE_RES_ERROR_TAIL: 377 case MISCREG_QUEUE_NRES_ERROR_HEAD: 378 case MISCREG_QUEUE_NRES_ERROR_TAIL: 379 case MISCREG_HPSTATE: 380 return readFSReg(miscReg, tc); 381 } 382 return readMiscRegNoEffect(miscReg); 383} 384 385void 386ISA::setMiscRegNoEffect(int miscReg, RegVal val) 387{ 388 switch (miscReg) { 389// case MISCREG_Y: 390// y = val; 391// break; 392// case MISCREG_CCR: 393// ccr = val; 394// break; 395 case MISCREG_ASI: 396 asi = val; 397 break; 398 case MISCREG_FPRS: 399 fprs = val; 400 break; 401 case MISCREG_TICK: 402 tick = val; 403 break; 404 case MISCREG_PCR: 405 panic("PCR not implemented\n"); 406 case MISCREG_PIC: 407 panic("PIC not implemented\n"); 408 case MISCREG_GSR: 409 gsr = val; 410 break; 411 case MISCREG_SOFTINT: 412 softint = val; 413 break; 414 case MISCREG_TICK_CMPR: 415 tick_cmpr = val; 416 break; 417 case MISCREG_STICK: 418 stick = val; 419 break; 420 case MISCREG_STICK_CMPR: 421 stick_cmpr = val; 422 break; 423 424 /** Privilged Registers */ 425 case MISCREG_TPC: 426 tpc[tl-1] = val; 427 break; 428 case MISCREG_TNPC: 429 tnpc[tl-1] = val; 430 break; 431 case MISCREG_TSTATE: 432 tstate[tl-1] = val; 433 break; 434 case MISCREG_TT: 435 tt[tl-1] = val; 436 break; 437 case MISCREG_PRIVTICK: 438 panic("Priviliged access to tick regesiters not implemented\n"); 439 case MISCREG_TBA: 440 // clear lower 7 bits on writes. 441 tba = val & ULL(~0x7FFF); 442 break; 443 case MISCREG_PSTATE: 444 pstate = (val & PstateMask); 445 break; 446 case MISCREG_TL: 447 tl = val; 448 break; 449 case MISCREG_PIL: 450 pil = val; 451 break; 452 case MISCREG_CWP: 453 cwp = val; 454 break; 455// case MISCREG_CANSAVE: 456// cansave = val; 457// break; 458// case MISCREG_CANRESTORE: 459// canrestore = val; 460// break; 461// case MISCREG_CLEANWIN: 462// cleanwin = val; 463// break; 464// case MISCREG_OTHERWIN: 465// otherwin = val; 466// break; 467// case MISCREG_WSTATE: 468// wstate = val; 469// break; 470 case MISCREG_GL: 471 gl = val; 472 break; 473 474 /** Hyper privileged registers */ 475 case MISCREG_HPSTATE: 476 hpstate = val; 477 break; 478 case MISCREG_HTSTATE: 479 htstate[tl-1] = val; 480 break; 481 case MISCREG_HINTP: 482 hintp = val; 483 break; 484 case MISCREG_HTBA: 485 htba = val; 486 break; 487 case MISCREG_STRAND_STS_REG: 488 strandStatusReg = val; 489 break; 490 case MISCREG_HSTICK_CMPR: 491 hstick_cmpr = val; 492 break; 493 494 /** Floating Point Status Register */ 495 case MISCREG_FSR: 496 fsr = val; 497 DPRINTF(MiscRegs, "FSR written with: %#x\n", fsr); 498 break; 499 500 case MISCREG_MMU_P_CONTEXT: 501 priContext = val; 502 break; 503 case MISCREG_MMU_S_CONTEXT: 504 secContext = val; 505 break; 506 case MISCREG_MMU_PART_ID: 507 partId = val; 508 break; 509 case MISCREG_MMU_LSU_CTRL: 510 lsuCtrlReg = val; 511 break; 512 513 case MISCREG_SCRATCHPAD_R0: 514 scratchPad[0] = val; 515 break; 516 case MISCREG_SCRATCHPAD_R1: 517 scratchPad[1] = val; 518 break; 519 case MISCREG_SCRATCHPAD_R2: 520 scratchPad[2] = val; 521 break; 522 case MISCREG_SCRATCHPAD_R3: 523 scratchPad[3] = val; 524 break; 525 case MISCREG_SCRATCHPAD_R4: 526 scratchPad[4] = val; 527 break; 528 case MISCREG_SCRATCHPAD_R5: 529 scratchPad[5] = val; 530 break; 531 case MISCREG_SCRATCHPAD_R6: 532 scratchPad[6] = val; 533 break; 534 case MISCREG_SCRATCHPAD_R7: 535 scratchPad[7] = val; 536 break; 537 case MISCREG_QUEUE_CPU_MONDO_HEAD: 538 cpu_mondo_head = val; 539 break; 540 case MISCREG_QUEUE_CPU_MONDO_TAIL: 541 cpu_mondo_tail = val; 542 break; 543 case MISCREG_QUEUE_DEV_MONDO_HEAD: 544 dev_mondo_head = val; 545 break; 546 case MISCREG_QUEUE_DEV_MONDO_TAIL: 547 dev_mondo_tail = val; 548 break; 549 case MISCREG_QUEUE_RES_ERROR_HEAD: 550 res_error_head = val; 551 break; 552 case MISCREG_QUEUE_RES_ERROR_TAIL: 553 res_error_tail = val; 554 break; 555 case MISCREG_QUEUE_NRES_ERROR_HEAD: 556 nres_error_head = val; 557 break; 558 case MISCREG_QUEUE_NRES_ERROR_TAIL: 559 nres_error_tail = val; 560 break; 561 default: 562 panic("Miscellaneous register %d not implemented\n", miscReg); 563 } 564} 565 566void 567ISA::setMiscReg(int miscReg, RegVal val, ThreadContext * tc) 568{ 569 RegVal new_val = val; 570 571 switch (miscReg) { 572 case MISCREG_ASI: 573 tc->getDecoderPtr()->setContext(val); 574 break; 575 case MISCREG_STICK: 576 case MISCREG_TICK: 577 // stick and tick are same thing on niagra 578 // use stick for offset and tick for holding intrrupt bit 579 stick = mbits(val,62,0) - tc->getCpuPtr()->instCount(); 580 tick = mbits(val,63,63); 581 DPRINTF(Timer, "Writing TICK=%#X\n", val); 582 break; 583 case MISCREG_FPRS: 584 // Configure the fpu based on the fprs 585 break; 586 case MISCREG_PCR: 587 // Set up performance counting based on pcr value 588 break; 589 case MISCREG_PSTATE: 590 pstate = val & PstateMask; 591 return; 592 case MISCREG_TL: 593 { 594 tl = val; 595 if (hpstate.tlz && tl == 0 && !hpstate.hpriv) 596 tc->getCpuPtr()->postInterrupt(0, IT_TRAP_LEVEL_ZERO, 0); 597 else 598 tc->getCpuPtr()->clearInterrupt(0, IT_TRAP_LEVEL_ZERO, 0); 599 return; 600 } 601 case MISCREG_CWP: 602 new_val = val >= NWindows ? NWindows - 1 : val; 603 if (val >= NWindows) 604 new_val = NWindows - 1; 605 606 installWindow(new_val, CurrentWindowOffset); 607 installWindow(new_val - 1, NextWindowOffset); 608 installWindow(new_val + 1, PreviousWindowOffset); 609 break; 610 case MISCREG_GL: 611 installGlobals(val, CurrentGlobalsOffset); 612 installGlobals(val, NextGlobalsOffset); 613 installGlobals(val, PreviousGlobalsOffset); 614 break; 615 case MISCREG_PIL: 616 case MISCREG_SOFTINT: 617 case MISCREG_SOFTINT_SET: 618 case MISCREG_SOFTINT_CLR: 619 case MISCREG_TICK_CMPR: 620 case MISCREG_STICK_CMPR: 621 case MISCREG_HINTP: 622 case MISCREG_HTSTATE: 623 case MISCREG_HTBA: 624 case MISCREG_HVER: 625 case MISCREG_STRAND_STS_REG: 626 case MISCREG_HSTICK_CMPR: 627 case MISCREG_QUEUE_CPU_MONDO_HEAD: 628 case MISCREG_QUEUE_CPU_MONDO_TAIL: 629 case MISCREG_QUEUE_DEV_MONDO_HEAD: 630 case MISCREG_QUEUE_DEV_MONDO_TAIL: 631 case MISCREG_QUEUE_RES_ERROR_HEAD: 632 case MISCREG_QUEUE_RES_ERROR_TAIL: 633 case MISCREG_QUEUE_NRES_ERROR_HEAD: 634 case MISCREG_QUEUE_NRES_ERROR_TAIL: 635 case MISCREG_HPSTATE: 636 setFSReg(miscReg, val, tc); 637 return; 638 } 639 setMiscRegNoEffect(miscReg, new_val); 640} 641 642void 643ISA::serialize(CheckpointOut &cp) const 644{ 645 SERIALIZE_SCALAR(asi); 646 SERIALIZE_SCALAR(tick); 647 SERIALIZE_SCALAR(fprs); 648 SERIALIZE_SCALAR(gsr); 649 SERIALIZE_SCALAR(softint); 650 SERIALIZE_SCALAR(tick_cmpr); 651 SERIALIZE_SCALAR(stick); 652 SERIALIZE_SCALAR(stick_cmpr); 653 SERIALIZE_ARRAY(tpc,MaxTL); 654 SERIALIZE_ARRAY(tnpc,MaxTL); 655 SERIALIZE_ARRAY(tstate,MaxTL); 656 SERIALIZE_ARRAY(tt,MaxTL); 657 SERIALIZE_SCALAR(tba); 658 SERIALIZE_SCALAR(pstate); 659 SERIALIZE_SCALAR(tl); 660 SERIALIZE_SCALAR(pil); 661 SERIALIZE_SCALAR(cwp); 662 SERIALIZE_SCALAR(gl); 663 SERIALIZE_SCALAR(hpstate); 664 SERIALIZE_ARRAY(htstate,MaxTL); 665 SERIALIZE_SCALAR(hintp); 666 SERIALIZE_SCALAR(htba); 667 SERIALIZE_SCALAR(hstick_cmpr); 668 SERIALIZE_SCALAR(strandStatusReg); 669 SERIALIZE_SCALAR(fsr); 670 SERIALIZE_SCALAR(priContext); 671 SERIALIZE_SCALAR(secContext); 672 SERIALIZE_SCALAR(partId); 673 SERIALIZE_SCALAR(lsuCtrlReg); 674 SERIALIZE_ARRAY(scratchPad,8); 675 SERIALIZE_SCALAR(cpu_mondo_head); 676 SERIALIZE_SCALAR(cpu_mondo_tail); 677 SERIALIZE_SCALAR(dev_mondo_head); 678 SERIALIZE_SCALAR(dev_mondo_tail); 679 SERIALIZE_SCALAR(res_error_head); 680 SERIALIZE_SCALAR(res_error_tail); 681 SERIALIZE_SCALAR(nres_error_head); 682 SERIALIZE_SCALAR(nres_error_tail); 683 Tick tick_cmp = 0, stick_cmp = 0, hstick_cmp = 0; 684 ThreadContext *tc = NULL; 685 BaseCPU *cpu = NULL; 686 int tc_num = 0; 687 bool tick_intr_sched = true; 688 689 if (tickCompare) 690 tc = tickCompare->getTC(); 691 else if (sTickCompare) 692 tc = sTickCompare->getTC(); 693 else if (hSTickCompare) 694 tc = hSTickCompare->getTC(); 695 else 696 tick_intr_sched = false; 697 698 SERIALIZE_SCALAR(tick_intr_sched); 699 700 if (tc) { 701 cpu = tc->getCpuPtr(); 702 tc_num = cpu->findContext(tc); 703 if (tickCompare && tickCompare->scheduled()) 704 tick_cmp = tickCompare->when(); 705 if (sTickCompare && sTickCompare->scheduled()) 706 stick_cmp = sTickCompare->when(); 707 if (hSTickCompare && hSTickCompare->scheduled()) 708 hstick_cmp = hSTickCompare->when(); 709 710 SERIALIZE_OBJPTR(cpu); 711 SERIALIZE_SCALAR(tc_num); 712 SERIALIZE_SCALAR(tick_cmp); 713 SERIALIZE_SCALAR(stick_cmp); 714 SERIALIZE_SCALAR(hstick_cmp); 715 } 716} 717 718void 719ISA::unserialize(CheckpointIn &cp) 720{ 721 UNSERIALIZE_SCALAR(asi); 722 UNSERIALIZE_SCALAR(tick); 723 UNSERIALIZE_SCALAR(fprs); 724 UNSERIALIZE_SCALAR(gsr); 725 UNSERIALIZE_SCALAR(softint); 726 UNSERIALIZE_SCALAR(tick_cmpr); 727 UNSERIALIZE_SCALAR(stick); 728 UNSERIALIZE_SCALAR(stick_cmpr); 729 UNSERIALIZE_ARRAY(tpc,MaxTL); 730 UNSERIALIZE_ARRAY(tnpc,MaxTL); 731 UNSERIALIZE_ARRAY(tstate,MaxTL); 732 UNSERIALIZE_ARRAY(tt,MaxTL); 733 UNSERIALIZE_SCALAR(tba); 734 { 735 uint16_t pstate; 736 UNSERIALIZE_SCALAR(pstate); 737 this->pstate = pstate; 738 } 739 UNSERIALIZE_SCALAR(tl); 740 UNSERIALIZE_SCALAR(pil); 741 UNSERIALIZE_SCALAR(cwp); 742 UNSERIALIZE_SCALAR(gl); 743 reloadRegMap(); 744 { 745 uint64_t hpstate; 746 UNSERIALIZE_SCALAR(hpstate); 747 this->hpstate = hpstate; 748 } 749 UNSERIALIZE_ARRAY(htstate,MaxTL); 750 UNSERIALIZE_SCALAR(hintp); 751 UNSERIALIZE_SCALAR(htba); 752 UNSERIALIZE_SCALAR(hstick_cmpr); 753 UNSERIALIZE_SCALAR(strandStatusReg); 754 UNSERIALIZE_SCALAR(fsr); 755 UNSERIALIZE_SCALAR(priContext); 756 UNSERIALIZE_SCALAR(secContext); 757 UNSERIALIZE_SCALAR(partId); 758 UNSERIALIZE_SCALAR(lsuCtrlReg); 759 UNSERIALIZE_ARRAY(scratchPad,8); 760 UNSERIALIZE_SCALAR(cpu_mondo_head); 761 UNSERIALIZE_SCALAR(cpu_mondo_tail); 762 UNSERIALIZE_SCALAR(dev_mondo_head); 763 UNSERIALIZE_SCALAR(dev_mondo_tail); 764 UNSERIALIZE_SCALAR(res_error_head); 765 UNSERIALIZE_SCALAR(res_error_tail); 766 UNSERIALIZE_SCALAR(nres_error_head); 767 UNSERIALIZE_SCALAR(nres_error_tail); 768 769 Tick tick_cmp = 0, stick_cmp = 0, hstick_cmp = 0; 770 ThreadContext *tc = NULL; 771 BaseCPU *cpu = NULL; 772 int tc_num; 773 bool tick_intr_sched; 774 UNSERIALIZE_SCALAR(tick_intr_sched); 775 if (tick_intr_sched) { 776 UNSERIALIZE_OBJPTR(cpu); 777 if (cpu) { 778 UNSERIALIZE_SCALAR(tc_num); 779 UNSERIALIZE_SCALAR(tick_cmp); 780 UNSERIALIZE_SCALAR(stick_cmp); 781 UNSERIALIZE_SCALAR(hstick_cmp); 782 tc = cpu->getContext(tc_num); 783 784 if (tick_cmp) { 785 tickCompare = new TickCompareEvent(this, tc); 786 schedule(tickCompare, tick_cmp); 787 } 788 if (stick_cmp) { 789 sTickCompare = new STickCompareEvent(this, tc); 790 schedule(sTickCompare, stick_cmp); 791 } 792 if (hstick_cmp) { 793 hSTickCompare = new HSTickCompareEvent(this, tc); 794 schedule(hSTickCompare, hstick_cmp); 795 } 796 } 797 } 798 799} 800 801} 802 803SparcISA::ISA * 804SparcISAParams::create() 805{ 806 return new SparcISA::ISA(this); 807} 808