Commit | Line | Data |
---|---|---|
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 | ||
35 | class 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 |