Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / ss / lib / cpu / src / SS_InstrCache.h
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* OpenSPARC T2 Processor File: SS_InstrCache.h
5* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
6* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
7*
8* The above named program is free software; you can redistribute it and/or
9* modify it under the terms of the GNU General Public
10* License version 2 as published by the Free Software Foundation.
11*
12* The above named program is distributed in the hope that it will be
13* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15* General Public License for more details.
16*
17* You should have received a copy of the GNU General Public
18* License along with this work; if not, write to the Free Software
19* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20*
21* ========== Copyright Header End ============================================
22*/
23
24#ifndef __SS_InstrCache_h__
25#define __SS_InstrCache_h__
26
27#include "SS_Instr.h"
28#include "SS_PidContext.h"
29
30// SS_InstrCache is the decode cache (well actually instruction cache too)
31// were we keep decoded instructions and few other bits and pieces.
32// An instance of the class should have the opc element at offset 0 of the
33// this pointer, so no virtual methods allowed here.
34
35class SS_InstrCache
36{
37 public:
38 enum
39 {
40#if defined(COMPILE_FOR_COSIM) || defined(ARCH_V8)
41 BITS = 4,
42#else
43 BITS = 11,
44#endif
45 SIZE = 1 << BITS,
46 MASK = SIZE - 1,
47
48 LINE_BITS = 4,
49 LINE_SIZE = 1 << LINE_BITS,
50 LINE_MASK = LINE_SIZE - 1
51 };
52
53 // init() is called to initialise the decode cache. Note we do not use
54 // a constructor here, as that would cause all the SS_Instr guys to be
55 // called for the whole cache. We know that the initial cache is empty,
56 // and when we fill it when we initialise it.
57
58 void init( const char* _id, SS_Tte* tte )
59 {
60 id = _id;
61
62 pstate_am_flag = 0;
63 pstate_tct_flag = 0;
64 pstate_cle_flag = 0;
65 hpstate_ibe_flag = 0;
66
67 for (int l=0; l < SS_InstrCache::SIZE; l++)
68 {
69 tag[l].tte = tte;
70 tag[l].lnk.clean();
71
72 opc[l].lnk.clean();
73 for (int o=0; o < (SS_Instr::LINE_SIZE - 1); o++)
74 opc[l].stride2[o].clean();
75 }
76
77 inst_ctx.init();
78 data_ctx.init();
79 }
80
81 struct Tag
82 {
83 union
84 {
85 SS_Tte* tte; // The TTE associated with the cache line
86 uintptr_t tte_bits; // Integer access to tte for RAS_TTE_POISON
87 };
88 SS_Vaddr tag; // The tag of the cacheline
89 SS_Chain lnk;
90 };
91
92 SS_Instr opc[SIZE]; // Note LINE_SIZE SS_Instr are overlapping in the holes
93 Tag tag[SIZE]; // The tag (tte) of the cachelines
94
95 const char* id; // Identifier for debugging purposes
96
97 uint_t pstate_am_flag; // Current pstate.am() for this cache
98 uint_t pstate_tct_flag; // Current pstate.tct() for this cache
99 uint_t pstate_cle_flag; // Current pstate.cle() for this cache
100 uint_t hpstate_ibe_flag; // Current hpstate.ibe() for this cache
101 SS_PidContext inst_ctx; // Current partition id and primary contexts for this cache
102 SS_PidContext data_ctx; // Current primary and secondary contexts for this cache
103
104 // The decode cache is addressed by selecting fields from the PC. Note that
105 // the instruction cache line is striped (see SS_Instr).
106 //
107 // pc = xxxxxxxxllllllliiii00 where x=don'tcare l=linenumber i=lineindex
108
109 // pc_inst() returns a pointer to the instruction for given pc value
110 SS_Instr* pc_inst( SS_Vaddr pc )
111 {
112 SS_Vaddr base = pc << (SS_Instr::BITS - 2);
113 SS_Vaddr line = base & (MASK << (SS_Instr::BITS + LINE_BITS));
114 SS_Vaddr indx = (base >> SS_Instr::SKEW) & (LINE_MASK << (SS_Instr::BITS - SS_Instr::SKEW));
115 return (SS_Instr*)((char*)opc + line + indx);
116 }
117
118 // pc_line() returns a pointer to the cacheline for given pc value.
119 SS_Instr* pc_line( SS_Vaddr pc )
120 {
121 SS_Vaddr line = (pc << (SS_Instr::BITS - 2)) & (MASK << (SS_Instr::BITS + LINE_BITS));
122 return (SS_Instr*)((char*)opc + line);
123 }
124
125 // pc_tte() returns a pointer to the tte of the cacheline for given pc value.
126 SS_Tte* pc_tte( SS_Vaddr pc )
127 {
128 return tag[(pc >> (LINE_BITS + 2)) & MASK].tte;
129 }
130
131};
132
133#endif