isa.cc revision 6335:a08470cb53e5
110259SAndrew.Bardsley@arm.com/*
210259SAndrew.Bardsley@arm.com * Copyright (c) 2009 The Regents of The University of Michigan
310259SAndrew.Bardsley@arm.com * All rights reserved.
410259SAndrew.Bardsley@arm.com *
510259SAndrew.Bardsley@arm.com * Redistribution and use in source and binary forms, with or without
610259SAndrew.Bardsley@arm.com * modification, are permitted provided that the following conditions are
710259SAndrew.Bardsley@arm.com * met: redistributions of source code must retain the above copyright
810259SAndrew.Bardsley@arm.com * notice, this list of conditions and the following disclaimer;
910259SAndrew.Bardsley@arm.com * redistributions in binary form must reproduce the above copyright
1010259SAndrew.Bardsley@arm.com * notice, this list of conditions and the following disclaimer in the
1110259SAndrew.Bardsley@arm.com * documentation and/or other materials provided with the distribution;
1210259SAndrew.Bardsley@arm.com * neither the name of the copyright holders nor the names of its
1310259SAndrew.Bardsley@arm.com * contributors may be used to endorse or promote products derived from
1410259SAndrew.Bardsley@arm.com * this software without specific prior written permission.
1510259SAndrew.Bardsley@arm.com *
1610259SAndrew.Bardsley@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1710259SAndrew.Bardsley@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1810259SAndrew.Bardsley@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1910259SAndrew.Bardsley@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2010259SAndrew.Bardsley@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2110259SAndrew.Bardsley@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2210259SAndrew.Bardsley@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2310259SAndrew.Bardsley@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2410259SAndrew.Bardsley@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2510259SAndrew.Bardsley@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2610259SAndrew.Bardsley@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2710259SAndrew.Bardsley@arm.com *
2810259SAndrew.Bardsley@arm.com * Authors: Gabe Black
2910259SAndrew.Bardsley@arm.com */
3010259SAndrew.Bardsley@arm.com
3110259SAndrew.Bardsley@arm.com#include "arch/sparc/asi.hh"
3210259SAndrew.Bardsley@arm.com#include "arch/sparc/isa.hh"
3310259SAndrew.Bardsley@arm.com#include "base/bitfield.hh"
3410259SAndrew.Bardsley@arm.com#include "base/trace.hh"
3510259SAndrew.Bardsley@arm.com#include "config/full_system.hh"
3610259SAndrew.Bardsley@arm.com#include "cpu/base.hh"
3710259SAndrew.Bardsley@arm.com#include "cpu/thread_context.hh"
3810259SAndrew.Bardsley@arm.com
3910259SAndrew.Bardsley@arm.comnamespace SparcISA
4010259SAndrew.Bardsley@arm.com{
4110259SAndrew.Bardsley@arm.com
4210259SAndrew.Bardsley@arm.comenum RegMask
4310259SAndrew.Bardsley@arm.com{
4410259SAndrew.Bardsley@arm.com        PSTATE_MASK = (((1 << 4) - 1) << 1) | (((1 << 4) - 1) << 6) | (1 << 12)
4510259SAndrew.Bardsley@arm.com};
4610259SAndrew.Bardsley@arm.com
4710259SAndrew.Bardsley@arm.comvoid
4810259SAndrew.Bardsley@arm.comISA::clear()
4910259SAndrew.Bardsley@arm.com{
5010259SAndrew.Bardsley@arm.com    //y = 0;
5110259SAndrew.Bardsley@arm.com    //ccr = 0;
5210259SAndrew.Bardsley@arm.com    asi = 0;
5310259SAndrew.Bardsley@arm.com    tick = ULL(1) << 63;
5410259SAndrew.Bardsley@arm.com    fprs = 0;
5510259SAndrew.Bardsley@arm.com    gsr = 0;
5610259SAndrew.Bardsley@arm.com    softint = 0;
5710259SAndrew.Bardsley@arm.com    tick_cmpr = 0;
5810259SAndrew.Bardsley@arm.com    stick = 0;
5910905Sandreas.sandberg@arm.com    stick_cmpr = 0;
6010259SAndrew.Bardsley@arm.com    memset(tpc, 0, sizeof(tpc));
6110259SAndrew.Bardsley@arm.com    memset(tnpc, 0, sizeof(tnpc));
6210259SAndrew.Bardsley@arm.com    memset(tstate, 0, sizeof(tstate));
6310259SAndrew.Bardsley@arm.com    memset(tt, 0, sizeof(tt));
6410259SAndrew.Bardsley@arm.com    pstate = 0;
6510259SAndrew.Bardsley@arm.com    tl = 0;
6610259SAndrew.Bardsley@arm.com    pil = 0;
6710259SAndrew.Bardsley@arm.com    cwp = 0;
6810259SAndrew.Bardsley@arm.com    //cansave = 0;
6910259SAndrew.Bardsley@arm.com    //canrestore = 0;
7010259SAndrew.Bardsley@arm.com    //cleanwin = 0;
7110259SAndrew.Bardsley@arm.com    //otherwin = 0;
7210259SAndrew.Bardsley@arm.com    //wstate = 0;
7310259SAndrew.Bardsley@arm.com    gl = 0;
7410259SAndrew.Bardsley@arm.com    //In a T1, bit 11 is apparently always 1
7510259SAndrew.Bardsley@arm.com    hpstate = (1 << 11);
7610259SAndrew.Bardsley@arm.com    memset(htstate, 0, sizeof(htstate));
7710259SAndrew.Bardsley@arm.com    hintp = 0;
7810259SAndrew.Bardsley@arm.com    htba = 0;
7910464SAndreas.Sandberg@ARM.com    hstick_cmpr = 0;
8010259SAndrew.Bardsley@arm.com    //This is set this way in Legion for some reason
8110259SAndrew.Bardsley@arm.com    strandStatusReg = 0x50000;
8210259SAndrew.Bardsley@arm.com    fsr = 0;
8310259SAndrew.Bardsley@arm.com
8410259SAndrew.Bardsley@arm.com    priContext = 0;
8510259SAndrew.Bardsley@arm.com    secContext = 0;
8610259SAndrew.Bardsley@arm.com    partId = 0;
8710259SAndrew.Bardsley@arm.com    lsuCtrlReg = 0;
8810259SAndrew.Bardsley@arm.com
8910259SAndrew.Bardsley@arm.com    memset(scratchPad, 0, sizeof(scratchPad));
9010259SAndrew.Bardsley@arm.com#if FULL_SYSTEM
9110259SAndrew.Bardsley@arm.com    tickCompare = NULL;
9210259SAndrew.Bardsley@arm.com    sTickCompare = NULL;
9310259SAndrew.Bardsley@arm.com    hSTickCompare = NULL;
9410259SAndrew.Bardsley@arm.com#endif
9510259SAndrew.Bardsley@arm.com}
9610259SAndrew.Bardsley@arm.com
9710259SAndrew.Bardsley@arm.comMiscReg
9810259SAndrew.Bardsley@arm.comISA::readMiscRegNoEffect(int miscReg)
9910259SAndrew.Bardsley@arm.com{
10010259SAndrew.Bardsley@arm.com
10110259SAndrew.Bardsley@arm.com  // The three miscRegs are moved up from the switch statement
10210259SAndrew.Bardsley@arm.com  // due to more frequent calls.
10310259SAndrew.Bardsley@arm.com
10410259SAndrew.Bardsley@arm.com  if (miscReg == MISCREG_GL)
10510259SAndrew.Bardsley@arm.com    return gl;
10610259SAndrew.Bardsley@arm.com  if (miscReg == MISCREG_CWP)
10710259SAndrew.Bardsley@arm.com    return cwp;
10810259SAndrew.Bardsley@arm.com  if (miscReg == MISCREG_TLB_DATA) {
10910259SAndrew.Bardsley@arm.com    /* Package up all the data for the tlb:
11010259SAndrew.Bardsley@arm.com     * 6666555555555544444444443333333333222222222211111111110000000000
11110259SAndrew.Bardsley@arm.com     * 3210987654321098765432109876543210987654321098765432109876543210
11210259SAndrew.Bardsley@arm.com     *   secContext   | priContext    |             |tl|partid|  |||||^hpriv
11310259SAndrew.Bardsley@arm.com     *                                                           ||||^red
11410259SAndrew.Bardsley@arm.com     *                                                           |||^priv
11510259SAndrew.Bardsley@arm.com     *                                                           ||^am
11610259SAndrew.Bardsley@arm.com     *                                                           |^lsuim
11710259SAndrew.Bardsley@arm.com     *                                                           ^lsudm
11810259SAndrew.Bardsley@arm.com     */
11910259SAndrew.Bardsley@arm.com    return bits((uint64_t)hpstate,2,2) |
12010259SAndrew.Bardsley@arm.com           bits((uint64_t)hpstate,5,5) << 1 |
12110259SAndrew.Bardsley@arm.com           bits((uint64_t)pstate,3,2) << 2 |
12210259SAndrew.Bardsley@arm.com           bits((uint64_t)lsuCtrlReg,3,2) << 4 |
12310259SAndrew.Bardsley@arm.com           bits((uint64_t)partId,7,0) << 8 |
12410259SAndrew.Bardsley@arm.com           bits((uint64_t)tl,2,0) << 16 |
12510259SAndrew.Bardsley@arm.com                (uint64_t)priContext << 32 |
12610259SAndrew.Bardsley@arm.com                (uint64_t)secContext << 48;
12710259SAndrew.Bardsley@arm.com  }
12810259SAndrew.Bardsley@arm.com
12910259SAndrew.Bardsley@arm.com    switch (miscReg) {
13010259SAndrew.Bardsley@arm.com      //case MISCREG_TLB_DATA:
13110259SAndrew.Bardsley@arm.com      //  [original contents see above]
13210259SAndrew.Bardsley@arm.com      //case MISCREG_Y:
13310259SAndrew.Bardsley@arm.com      //  return y;
13410259SAndrew.Bardsley@arm.com      //case MISCREG_CCR:
13510259SAndrew.Bardsley@arm.com      //  return ccr;
13610464SAndreas.Sandberg@ARM.com      case MISCREG_ASI:
13710259SAndrew.Bardsley@arm.com        return asi;
13810259SAndrew.Bardsley@arm.com      case MISCREG_FPRS:
13910259SAndrew.Bardsley@arm.com        return fprs;
14010259SAndrew.Bardsley@arm.com      case MISCREG_TICK:
14110259SAndrew.Bardsley@arm.com        return tick;
14210259SAndrew.Bardsley@arm.com      case MISCREG_PCR:
14310259SAndrew.Bardsley@arm.com        panic("PCR not implemented\n");
14410259SAndrew.Bardsley@arm.com      case MISCREG_PIC:
14510259SAndrew.Bardsley@arm.com        panic("PIC not implemented\n");
14610259SAndrew.Bardsley@arm.com      case MISCREG_GSR:
14710259SAndrew.Bardsley@arm.com        return gsr;
14810259SAndrew.Bardsley@arm.com      case MISCREG_SOFTINT:
14910259SAndrew.Bardsley@arm.com        return softint;
15010259SAndrew.Bardsley@arm.com      case MISCREG_TICK_CMPR:
15110259SAndrew.Bardsley@arm.com        return tick_cmpr;
15210259SAndrew.Bardsley@arm.com      case MISCREG_STICK:
15310259SAndrew.Bardsley@arm.com        return stick;
15410259SAndrew.Bardsley@arm.com      case MISCREG_STICK_CMPR:
15510259SAndrew.Bardsley@arm.com        return stick_cmpr;
15610259SAndrew.Bardsley@arm.com
15710259SAndrew.Bardsley@arm.com        /** Privilged Registers */
15810259SAndrew.Bardsley@arm.com      case MISCREG_TPC:
15910259SAndrew.Bardsley@arm.com        return tpc[tl-1];
16010259SAndrew.Bardsley@arm.com      case MISCREG_TNPC:
16110259SAndrew.Bardsley@arm.com        return tnpc[tl-1];
16210259SAndrew.Bardsley@arm.com      case MISCREG_TSTATE:
16310259SAndrew.Bardsley@arm.com        return tstate[tl-1];
16410259SAndrew.Bardsley@arm.com      case MISCREG_TT:
16510259SAndrew.Bardsley@arm.com        return tt[tl-1];
16610259SAndrew.Bardsley@arm.com      case MISCREG_PRIVTICK:
16711168Sandreas.hansson@arm.com        panic("Priviliged access to tick registers not implemented\n");
16811168Sandreas.hansson@arm.com      case MISCREG_TBA:
16910259SAndrew.Bardsley@arm.com        return tba;
17010259SAndrew.Bardsley@arm.com      case MISCREG_PSTATE:
17110259SAndrew.Bardsley@arm.com        return pstate;
17210464SAndreas.Sandberg@ARM.com      case MISCREG_TL:
17310464SAndreas.Sandberg@ARM.com        return tl;
17410464SAndreas.Sandberg@ARM.com      case MISCREG_PIL:
17510464SAndreas.Sandberg@ARM.com        return pil;
17610464SAndreas.Sandberg@ARM.com      //CWP, GL moved
17710464SAndreas.Sandberg@ARM.com      //case MISCREG_CWP:
17810464SAndreas.Sandberg@ARM.com      //  return cwp;
17910464SAndreas.Sandberg@ARM.com      //case MISCREG_CANSAVE:
18010464SAndreas.Sandberg@ARM.com      //  return cansave;
18110464SAndreas.Sandberg@ARM.com      //case MISCREG_CANRESTORE:
18210464SAndreas.Sandberg@ARM.com      //  return canrestore;
18310464SAndreas.Sandberg@ARM.com      //case MISCREG_CLEANWIN:
18410464SAndreas.Sandberg@ARM.com      //  return cleanwin;
18510259SAndrew.Bardsley@arm.com      //case MISCREG_OTHERWIN:
18610259SAndrew.Bardsley@arm.com      //  return otherwin;
18710259SAndrew.Bardsley@arm.com      //case MISCREG_WSTATE:
18810259SAndrew.Bardsley@arm.com      //  return wstate;
18910259SAndrew.Bardsley@arm.com      //case MISCREG_GL:
19010259SAndrew.Bardsley@arm.com      //  return gl;
19110259SAndrew.Bardsley@arm.com
19210259SAndrew.Bardsley@arm.com        /** Hyper privileged registers */
19310259SAndrew.Bardsley@arm.com      case MISCREG_HPSTATE:
19410259SAndrew.Bardsley@arm.com        return hpstate;
19510259SAndrew.Bardsley@arm.com      case MISCREG_HTSTATE:
19610259SAndrew.Bardsley@arm.com        return htstate[tl-1];
19710259SAndrew.Bardsley@arm.com      case MISCREG_HINTP:
19810259SAndrew.Bardsley@arm.com        return hintp;
19910259SAndrew.Bardsley@arm.com      case MISCREG_HTBA:
20010259SAndrew.Bardsley@arm.com        return htba;
20111169Sandreas.hansson@arm.com      case MISCREG_STRAND_STS_REG:
20211168Sandreas.hansson@arm.com        return strandStatusReg;
20311168Sandreas.hansson@arm.com      case MISCREG_HSTICK_CMPR:
20410259SAndrew.Bardsley@arm.com        return hstick_cmpr;
20510259SAndrew.Bardsley@arm.com
20610259SAndrew.Bardsley@arm.com        /** Floating Point Status Register */
207      case MISCREG_FSR:
208        DPRINTF(MiscRegs, "FSR read as: %#x\n", fsr);
209        return fsr;
210
211      case MISCREG_MMU_P_CONTEXT:
212        return priContext;
213      case MISCREG_MMU_S_CONTEXT:
214        return secContext;
215      case MISCREG_MMU_PART_ID:
216        return partId;
217      case MISCREG_MMU_LSU_CTRL:
218        return lsuCtrlReg;
219
220      case MISCREG_SCRATCHPAD_R0:
221        return scratchPad[0];
222      case MISCREG_SCRATCHPAD_R1:
223        return scratchPad[1];
224      case MISCREG_SCRATCHPAD_R2:
225        return scratchPad[2];
226      case MISCREG_SCRATCHPAD_R3:
227        return scratchPad[3];
228      case MISCREG_SCRATCHPAD_R4:
229        return scratchPad[4];
230      case MISCREG_SCRATCHPAD_R5:
231        return scratchPad[5];
232      case MISCREG_SCRATCHPAD_R6:
233        return scratchPad[6];
234      case MISCREG_SCRATCHPAD_R7:
235        return scratchPad[7];
236      case MISCREG_QUEUE_CPU_MONDO_HEAD:
237        return cpu_mondo_head;
238      case MISCREG_QUEUE_CPU_MONDO_TAIL:
239        return cpu_mondo_tail;
240      case MISCREG_QUEUE_DEV_MONDO_HEAD:
241        return dev_mondo_head;
242      case MISCREG_QUEUE_DEV_MONDO_TAIL:
243        return dev_mondo_tail;
244      case MISCREG_QUEUE_RES_ERROR_HEAD:
245        return res_error_head;
246      case MISCREG_QUEUE_RES_ERROR_TAIL:
247        return res_error_tail;
248      case MISCREG_QUEUE_NRES_ERROR_HEAD:
249        return nres_error_head;
250      case MISCREG_QUEUE_NRES_ERROR_TAIL:
251        return nres_error_tail;
252      default:
253        panic("Miscellaneous register %d not implemented\n", miscReg);
254    }
255}
256
257MiscReg
258ISA::readMiscReg(int miscReg, ThreadContext * tc)
259{
260    switch (miscReg) {
261        // tick and stick are aliased to each other in niagra
262        // well store the tick data in stick and the interrupt bit in tick
263      case MISCREG_STICK:
264      case MISCREG_TICK:
265      case MISCREG_PRIVTICK:
266        // I'm not sure why legion ignores the lowest two bits, but we'll go
267        // with it
268        // change from curCycle() to instCount() until we're done with legion
269        DPRINTF(Timer, "Instruction Count when TICK read: %#X stick=%#X\n",
270                tc->getCpuPtr()->instCount(), stick);
271        return mbits(tc->getCpuPtr()->instCount() + (int64_t)stick,62,2) |
272               mbits(tick,63,63);
273      case MISCREG_FPRS:
274        // in legion if fp is enabled du and dl are set
275        return fprs | 0x3;
276      case MISCREG_PCR:
277      case MISCREG_PIC:
278        panic("Performance Instrumentation not impl\n");
279      case MISCREG_SOFTINT_CLR:
280      case MISCREG_SOFTINT_SET:
281        panic("Can read from softint clr/set\n");
282      case MISCREG_SOFTINT:
283      case MISCREG_TICK_CMPR:
284      case MISCREG_STICK_CMPR:
285      case MISCREG_HINTP:
286      case MISCREG_HTSTATE:
287      case MISCREG_HTBA:
288      case MISCREG_HVER:
289      case MISCREG_STRAND_STS_REG:
290      case MISCREG_HSTICK_CMPR:
291      case MISCREG_QUEUE_CPU_MONDO_HEAD:
292      case MISCREG_QUEUE_CPU_MONDO_TAIL:
293      case MISCREG_QUEUE_DEV_MONDO_HEAD:
294      case MISCREG_QUEUE_DEV_MONDO_TAIL:
295      case MISCREG_QUEUE_RES_ERROR_HEAD:
296      case MISCREG_QUEUE_RES_ERROR_TAIL:
297      case MISCREG_QUEUE_NRES_ERROR_HEAD:
298      case MISCREG_QUEUE_NRES_ERROR_TAIL:
299#if FULL_SYSTEM
300      case MISCREG_HPSTATE:
301        return readFSReg(miscReg, tc);
302#else
303      case MISCREG_HPSTATE:
304        //HPSTATE is special because because sometimes in privilege
305        //checks for instructions it will read HPSTATE to make sure
306        //the priv. level is ok So, we'll just have to tell it it
307        //isn't, instead of panicing.
308        return 0;
309
310      panic("Accessing Fullsystem register %d in SE mode\n", miscReg);
311#endif
312
313    }
314    return readMiscRegNoEffect(miscReg);
315}
316
317void
318ISA::setMiscRegNoEffect(int miscReg, MiscReg val)
319{
320    switch (miscReg) {
321//      case MISCREG_Y:
322//        y = val;
323//        break;
324//      case MISCREG_CCR:
325//        ccr = val;
326//        break;
327      case MISCREG_ASI:
328        asi = val;
329        break;
330      case MISCREG_FPRS:
331        fprs = val;
332        break;
333      case MISCREG_TICK:
334        tick = val;
335        break;
336      case MISCREG_PCR:
337        panic("PCR not implemented\n");
338      case MISCREG_PIC:
339        panic("PIC not implemented\n");
340      case MISCREG_GSR:
341        gsr = val;
342        break;
343      case MISCREG_SOFTINT:
344        softint = val;
345        break;
346      case MISCREG_TICK_CMPR:
347        tick_cmpr = val;
348        break;
349      case MISCREG_STICK:
350        stick = val;
351        break;
352      case MISCREG_STICK_CMPR:
353        stick_cmpr = val;
354        break;
355
356        /** Privilged Registers */
357      case MISCREG_TPC:
358        tpc[tl-1] = val;
359        break;
360      case MISCREG_TNPC:
361        tnpc[tl-1] = val;
362        break;
363      case MISCREG_TSTATE:
364        tstate[tl-1] = val;
365        break;
366      case MISCREG_TT:
367        tt[tl-1] = val;
368        break;
369      case MISCREG_PRIVTICK:
370        panic("Priviliged access to tick regesiters not implemented\n");
371      case MISCREG_TBA:
372        // clear lower 7 bits on writes.
373        tba = val & ULL(~0x7FFF);
374        break;
375      case MISCREG_PSTATE:
376        pstate = (val & PSTATE_MASK);
377        break;
378      case MISCREG_TL:
379        tl = val;
380        break;
381      case MISCREG_PIL:
382        pil = val;
383        break;
384      case MISCREG_CWP:
385        cwp = val;
386        break;
387//      case MISCREG_CANSAVE:
388//        cansave = val;
389//        break;
390//      case MISCREG_CANRESTORE:
391//        canrestore = val;
392//        break;
393//      case MISCREG_CLEANWIN:
394//        cleanwin = val;
395//        break;
396//      case MISCREG_OTHERWIN:
397//        otherwin = val;
398//        break;
399//      case MISCREG_WSTATE:
400//        wstate = val;
401//        break;
402      case MISCREG_GL:
403        gl = val;
404        break;
405
406        /** Hyper privileged registers */
407      case MISCREG_HPSTATE:
408        hpstate = val;
409        break;
410      case MISCREG_HTSTATE:
411        htstate[tl-1] = val;
412        break;
413      case MISCREG_HINTP:
414        hintp = val;
415      case MISCREG_HTBA:
416        htba = val;
417        break;
418      case MISCREG_STRAND_STS_REG:
419        strandStatusReg = val;
420        break;
421      case MISCREG_HSTICK_CMPR:
422        hstick_cmpr = val;
423        break;
424
425        /** Floating Point Status Register */
426      case MISCREG_FSR:
427        fsr = val;
428        DPRINTF(MiscRegs, "FSR written with: %#x\n", fsr);
429        break;
430
431      case MISCREG_MMU_P_CONTEXT:
432        priContext = val;
433        break;
434      case MISCREG_MMU_S_CONTEXT:
435        secContext = val;
436        break;
437      case MISCREG_MMU_PART_ID:
438        partId = val;
439        break;
440      case MISCREG_MMU_LSU_CTRL:
441        lsuCtrlReg = val;
442        break;
443
444      case MISCREG_SCRATCHPAD_R0:
445        scratchPad[0] = val;
446        break;
447      case MISCREG_SCRATCHPAD_R1:
448        scratchPad[1] = val;
449        break;
450      case MISCREG_SCRATCHPAD_R2:
451        scratchPad[2] = val;
452        break;
453      case MISCREG_SCRATCHPAD_R3:
454        scratchPad[3] = val;
455        break;
456      case MISCREG_SCRATCHPAD_R4:
457        scratchPad[4] = val;
458        break;
459      case MISCREG_SCRATCHPAD_R5:
460        scratchPad[5] = val;
461        break;
462      case MISCREG_SCRATCHPAD_R6:
463        scratchPad[6] = val;
464        break;
465      case MISCREG_SCRATCHPAD_R7:
466        scratchPad[7] = val;
467        break;
468      case MISCREG_QUEUE_CPU_MONDO_HEAD:
469        cpu_mondo_head = val;
470        break;
471      case MISCREG_QUEUE_CPU_MONDO_TAIL:
472        cpu_mondo_tail = val;
473        break;
474      case MISCREG_QUEUE_DEV_MONDO_HEAD:
475        dev_mondo_head = val;
476        break;
477      case MISCREG_QUEUE_DEV_MONDO_TAIL:
478        dev_mondo_tail = val;
479        break;
480      case MISCREG_QUEUE_RES_ERROR_HEAD:
481        res_error_head = val;
482        break;
483      case MISCREG_QUEUE_RES_ERROR_TAIL:
484        res_error_tail = val;
485        break;
486      case MISCREG_QUEUE_NRES_ERROR_HEAD:
487        nres_error_head = val;
488        break;
489      case MISCREG_QUEUE_NRES_ERROR_TAIL:
490        nres_error_tail = val;
491        break;
492      default:
493        panic("Miscellaneous register %d not implemented\n", miscReg);
494    }
495}
496
497void
498ISA::setMiscReg(int miscReg, MiscReg val, ThreadContext * tc)
499{
500    MiscReg new_val = val;
501
502    switch (miscReg) {
503      case MISCREG_STICK:
504      case MISCREG_TICK:
505        // stick and tick are same thing on niagra
506        // use stick for offset and tick for holding intrrupt bit
507        stick = mbits(val,62,0) - tc->getCpuPtr()->instCount();
508        tick = mbits(val,63,63);
509        DPRINTF(Timer, "Writing TICK=%#X\n", val);
510        break;
511      case MISCREG_FPRS:
512        //Configure the fpu based on the fprs
513        break;
514      case MISCREG_PCR:
515        //Set up performance counting based on pcr value
516        break;
517      case MISCREG_PSTATE:
518        pstate = val & PSTATE_MASK;
519        return;
520      case MISCREG_TL:
521        tl = val;
522#if FULL_SYSTEM
523        if (hpstate & HPSTATE::tlz && tl == 0 && !(hpstate & HPSTATE::hpriv))
524            tc->getCpuPtr()->postInterrupt(IT_TRAP_LEVEL_ZERO, 0);
525        else
526            tc->getCpuPtr()->clearInterrupt(IT_TRAP_LEVEL_ZERO, 0);
527#endif
528        return;
529      case MISCREG_CWP:
530        new_val = val >= NWindows ? NWindows - 1 : val;
531        if (val >= NWindows)
532            new_val = NWindows - 1;
533        break;
534      case MISCREG_GL:
535        break;
536      case MISCREG_PIL:
537      case MISCREG_SOFTINT:
538      case MISCREG_SOFTINT_SET:
539      case MISCREG_SOFTINT_CLR:
540      case MISCREG_TICK_CMPR:
541      case MISCREG_STICK_CMPR:
542      case MISCREG_HINTP:
543      case MISCREG_HTSTATE:
544      case MISCREG_HTBA:
545      case MISCREG_HVER:
546      case MISCREG_STRAND_STS_REG:
547      case MISCREG_HSTICK_CMPR:
548      case MISCREG_QUEUE_CPU_MONDO_HEAD:
549      case MISCREG_QUEUE_CPU_MONDO_TAIL:
550      case MISCREG_QUEUE_DEV_MONDO_HEAD:
551      case MISCREG_QUEUE_DEV_MONDO_TAIL:
552      case MISCREG_QUEUE_RES_ERROR_HEAD:
553      case MISCREG_QUEUE_RES_ERROR_TAIL:
554      case MISCREG_QUEUE_NRES_ERROR_HEAD:
555      case MISCREG_QUEUE_NRES_ERROR_TAIL:
556#if FULL_SYSTEM
557      case MISCREG_HPSTATE:
558        setFSReg(miscReg, val, tc);
559        return;
560#else
561      case MISCREG_HPSTATE:
562        //HPSTATE is special because normal trap processing saves HPSTATE when
563        //it goes into a trap, and restores it when it returns.
564        return;
565      panic("Accessing Fullsystem register %d to %#x in SE mode\n",
566              miscReg, val);
567#endif
568    }
569    setMiscRegNoEffect(miscReg, new_val);
570}
571
572void
573ISA::serialize(EventManager *em, std::ostream &os)
574{
575    SERIALIZE_SCALAR(asi);
576    SERIALIZE_SCALAR(tick);
577    SERIALIZE_SCALAR(fprs);
578    SERIALIZE_SCALAR(gsr);
579    SERIALIZE_SCALAR(softint);
580    SERIALIZE_SCALAR(tick_cmpr);
581    SERIALIZE_SCALAR(stick);
582    SERIALIZE_SCALAR(stick_cmpr);
583    SERIALIZE_ARRAY(tpc,MaxTL);
584    SERIALIZE_ARRAY(tnpc,MaxTL);
585    SERIALIZE_ARRAY(tstate,MaxTL);
586    SERIALIZE_ARRAY(tt,MaxTL);
587    SERIALIZE_SCALAR(tba);
588    SERIALIZE_SCALAR(pstate);
589    SERIALIZE_SCALAR(tl);
590    SERIALIZE_SCALAR(pil);
591    SERIALIZE_SCALAR(cwp);
592    SERIALIZE_SCALAR(gl);
593    SERIALIZE_SCALAR(hpstate);
594    SERIALIZE_ARRAY(htstate,MaxTL);
595    SERIALIZE_SCALAR(hintp);
596    SERIALIZE_SCALAR(htba);
597    SERIALIZE_SCALAR(hstick_cmpr);
598    SERIALIZE_SCALAR(strandStatusReg);
599    SERIALIZE_SCALAR(fsr);
600    SERIALIZE_SCALAR(priContext);
601    SERIALIZE_SCALAR(secContext);
602    SERIALIZE_SCALAR(partId);
603    SERIALIZE_SCALAR(lsuCtrlReg);
604    SERIALIZE_ARRAY(scratchPad,8);
605    SERIALIZE_SCALAR(cpu_mondo_head);
606    SERIALIZE_SCALAR(cpu_mondo_tail);
607    SERIALIZE_SCALAR(dev_mondo_head);
608    SERIALIZE_SCALAR(dev_mondo_tail);
609    SERIALIZE_SCALAR(res_error_head);
610    SERIALIZE_SCALAR(res_error_tail);
611    SERIALIZE_SCALAR(nres_error_head);
612    SERIALIZE_SCALAR(nres_error_tail);
613#if FULL_SYSTEM
614    Tick tick_cmp = 0, stick_cmp = 0, hstick_cmp = 0;
615    ThreadContext *tc = NULL;
616    BaseCPU *cpu = NULL;
617    int tc_num = 0;
618    bool tick_intr_sched = true;
619
620    if (tickCompare)
621        tc = tickCompare->getTC();
622    else if (sTickCompare)
623        tc = sTickCompare->getTC();
624    else if (hSTickCompare)
625        tc = hSTickCompare->getTC();
626    else
627        tick_intr_sched = false;
628
629    SERIALIZE_SCALAR(tick_intr_sched);
630
631    if (tc) {
632        cpu = tc->getCpuPtr();
633        tc_num = cpu->findContext(tc);
634        if (tickCompare && tickCompare->scheduled())
635            tick_cmp = tickCompare->when();
636        if (sTickCompare && sTickCompare->scheduled())
637            stick_cmp = sTickCompare->when();
638        if (hSTickCompare && hSTickCompare->scheduled())
639            hstick_cmp = hSTickCompare->when();
640
641        SERIALIZE_OBJPTR(cpu);
642        SERIALIZE_SCALAR(tc_num);
643        SERIALIZE_SCALAR(tick_cmp);
644        SERIALIZE_SCALAR(stick_cmp);
645        SERIALIZE_SCALAR(hstick_cmp);
646    }
647#endif
648}
649
650void
651ISA::unserialize(EventManager *em, Checkpoint *cp, const std::string &section)
652{
653    UNSERIALIZE_SCALAR(asi);
654    UNSERIALIZE_SCALAR(tick);
655    UNSERIALIZE_SCALAR(fprs);
656    UNSERIALIZE_SCALAR(gsr);
657    UNSERIALIZE_SCALAR(softint);
658    UNSERIALIZE_SCALAR(tick_cmpr);
659    UNSERIALIZE_SCALAR(stick);
660    UNSERIALIZE_SCALAR(stick_cmpr);
661    UNSERIALIZE_ARRAY(tpc,MaxTL);
662    UNSERIALIZE_ARRAY(tnpc,MaxTL);
663    UNSERIALIZE_ARRAY(tstate,MaxTL);
664    UNSERIALIZE_ARRAY(tt,MaxTL);
665    UNSERIALIZE_SCALAR(tba);
666    UNSERIALIZE_SCALAR(pstate);
667    UNSERIALIZE_SCALAR(tl);
668    UNSERIALIZE_SCALAR(pil);
669    UNSERIALIZE_SCALAR(cwp);
670    UNSERIALIZE_SCALAR(gl);
671    UNSERIALIZE_SCALAR(hpstate);
672    UNSERIALIZE_ARRAY(htstate,MaxTL);
673    UNSERIALIZE_SCALAR(hintp);
674    UNSERIALIZE_SCALAR(htba);
675    UNSERIALIZE_SCALAR(hstick_cmpr);
676    UNSERIALIZE_SCALAR(strandStatusReg);
677    UNSERIALIZE_SCALAR(fsr);
678    UNSERIALIZE_SCALAR(priContext);
679    UNSERIALIZE_SCALAR(secContext);
680    UNSERIALIZE_SCALAR(partId);
681    UNSERIALIZE_SCALAR(lsuCtrlReg);
682    UNSERIALIZE_ARRAY(scratchPad,8);
683    UNSERIALIZE_SCALAR(cpu_mondo_head);
684    UNSERIALIZE_SCALAR(cpu_mondo_tail);
685    UNSERIALIZE_SCALAR(dev_mondo_head);
686    UNSERIALIZE_SCALAR(dev_mondo_tail);
687    UNSERIALIZE_SCALAR(res_error_head);
688    UNSERIALIZE_SCALAR(res_error_tail);
689    UNSERIALIZE_SCALAR(nres_error_head);
690    UNSERIALIZE_SCALAR(nres_error_tail);
691
692#if FULL_SYSTEM
693    Tick tick_cmp = 0, stick_cmp = 0, hstick_cmp = 0;
694    ThreadContext *tc = NULL;
695    BaseCPU *cpu = NULL;
696    int tc_num;
697    bool tick_intr_sched;
698    UNSERIALIZE_SCALAR(tick_intr_sched);
699    if (tick_intr_sched) {
700        UNSERIALIZE_OBJPTR(cpu);
701        if (cpu) {
702            UNSERIALIZE_SCALAR(tc_num);
703            UNSERIALIZE_SCALAR(tick_cmp);
704            UNSERIALIZE_SCALAR(stick_cmp);
705            UNSERIALIZE_SCALAR(hstick_cmp);
706            tc = cpu->getContext(tc_num);
707
708            if (tick_cmp) {
709                tickCompare = new TickCompareEvent(this, tc);
710                em->schedule(tickCompare, tick_cmp);
711            }
712            if (stick_cmp)  {
713                sTickCompare = new STickCompareEvent(this, tc);
714                em->schedule(sTickCompare, stick_cmp);
715            }
716            if (hstick_cmp)  {
717                hSTickCompare = new HSTickCompareEvent(this, tc);
718                em->schedule(hSTickCompare, hstick_cmp);
719            }
720        }
721    }
722
723 #endif
724}
725
726int
727ISA::flattenIntIndex(int reg)
728{
729    int gl = readMiscRegNoEffect(MISCREG_GL);
730    int cwp = readMiscRegNoEffect(MISCREG_CWP);
731    //DPRINTF(RegisterWindows, "Global Level = %d, Current Window Pointer = %d\n", gl, cwp);
732    int newReg;
733    //The total number of global registers
734    int numGlobals = (MaxGL + 1) * 8;
735    if(reg < 8)
736    {
737        //Global register
738        //Put it in the appropriate set of globals
739        newReg = reg + gl * 8;
740    }
741    else if(reg < NumIntArchRegs)
742    {
743        //Regular windowed register
744        //Put it in the window pointed to by cwp
745        newReg = numGlobals +
746            ((reg - 8 - cwp * 16 + NWindows * 16) % (NWindows * 16));
747    }
748    else if(reg < NumIntArchRegs + NumMicroIntRegs)
749    {
750        //Microcode register
751        //Displace from the end of the regular registers
752        newReg = reg - NumIntArchRegs + numGlobals + NWindows * 16;
753    }
754    else if(reg < 2 * NumIntArchRegs + NumMicroIntRegs)
755    {
756        reg -= (NumIntArchRegs + NumMicroIntRegs);
757        if(reg < 8)
758        {
759            //Global register from the next window
760            //Put it in the appropriate set of globals
761            newReg = reg + gl * 8;
762        }
763        else
764        {
765            //Windowed register from the previous window
766            //Put it in the window before the one pointed to by cwp
767            newReg = numGlobals +
768                ((reg - 8 - (cwp - 1) * 16 + NWindows * 16) % (NWindows * 16));
769        }
770    }
771    else if(reg < 3 * NumIntArchRegs + NumMicroIntRegs)
772    {
773        reg -= (2 * NumIntArchRegs + NumMicroIntRegs);
774        if(reg < 8)
775        {
776            //Global register from the previous window
777            //Put it in the appropriate set of globals
778            newReg = reg + gl * 8;
779        }
780        else
781        {
782            //Windowed register from the next window
783            //Put it in the window after the one pointed to by cwp
784            newReg = numGlobals +
785                ((reg - 8 - (cwp + 1) * 16 + NWindows * 16) % (NWindows * 16));
786        }
787    }
788    else
789        panic("Tried to flatten invalid register index %d!\n", reg);
790    DPRINTF(RegisterWindows, "Flattened register %d to %d.\n", reg, newReg);
791    return newReg;
792}
793
794}
795