- added instructions how to update the online documentation
[bochs-mirror.git] / cpu / icache.h
blob99635bd52a99211fbc219b2ccf3068b8973f8b77
1 /////////////////////////////////////////////////////////////////////////
2 // $Id: icache.h,v 1.40 2008/10/14 17:23:53 sshwarts Exp $
3 /////////////////////////////////////////////////////////////////////////
4 //
5 // Copyright (c) 2007 Stanislav Shwartsman
6 // Written by Stanislav Shwartsman [sshwarts at sourceforge net]
7 //
8 // This library is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU Lesser General Public
10 // License as published by the Free Software Foundation; either
11 // version 2 of the License, or (at your option) any later version.
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Lesser General Public License for more details.
18 // You should have received a copy of the GNU Lesser General Public
19 // License along with this library; if not, write to the Free Software
20 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 /////////////////////////////////////////////////////////////////////////
24 #ifndef BX_ICACHE_H
25 #define BX_ICACHE_H
27 #if BX_SUPPORT_ICACHE
29 // bit31: 1=CS is 32/64-bit, 0=CS is 16-bit.
30 // bit30: 1=Long Mode, 0=not Long Mode.
31 // Combination bit31=1 & bit30=1 is invalid (data page)
32 const Bit32u ICacheWriteStampInvalid = 0xffffffff;
33 const Bit32u ICacheWriteStampStart = 0x3fffffff;
34 const Bit32u ICacheWriteStampFetchModeMask = ~ICacheWriteStampStart;
36 #if BX_SUPPORT_TRACE_CACHE
37 extern void handleSMC(void);
38 #endif
40 class bxPageWriteStampTable
42 // A table (dynamically allocated) to store write-stamp generation IDs.
43 // Each time a write occurs to a physical page, a generation ID is
44 // decremented. Only iCache entries which have write stamps matching
45 // the physical page write stamp are valid.
46 Bit32u *pageWriteStampTable;
48 #define PHY_MEM_PAGES (1024*1024)
50 public:
51 bxPageWriteStampTable() {
52 pageWriteStampTable = new Bit32u[PHY_MEM_PAGES];
53 resetWriteStamps();
55 ~bxPageWriteStampTable() { delete [] pageWriteStampTable; }
57 BX_CPP_INLINE Bit32u getPageWriteStamp(bx_phy_address pAddr) const
59 return pageWriteStampTable[pAddr>>12];
62 BX_CPP_INLINE const Bit32u *getPageWriteStampPtr(bx_phy_address pAddr) const
64 return &pageWriteStampTable[pAddr>>12];
67 BX_CPP_INLINE void setPageWriteStamp(bx_phy_address pAddr, Bit32u pageWriteStamp)
69 pageWriteStampTable[pAddr>>12] = pageWriteStamp;
72 BX_CPP_INLINE void decWriteStamp(bx_phy_address pAddr)
74 pAddr >>= 12;
75 #if BX_SUPPORT_TRACE_CACHE
76 if ((pageWriteStampTable[pAddr] & ICacheWriteStampFetchModeMask) != ICacheWriteStampFetchModeMask)
78 handleSMC(); // one of the CPUs might be running trace from this page
79 // Decrement page write stamp, so iCache entries with older stamps are
80 // effectively invalidated.
81 pageWriteStampTable[pAddr]--;
83 #endif
84 #if BX_DEBUGGER
85 BX_DBG_DIRTY_PAGE(pAddr);
86 #endif
89 BX_CPP_INLINE void resetWriteStamps(void);
90 BX_CPP_INLINE void purgeWriteStamps(void);
93 BX_CPP_INLINE void bxPageWriteStampTable::resetWriteStamps(void)
95 for (Bit32u i=0; i<PHY_MEM_PAGES; i++) {
96 pageWriteStampTable[i] = ICacheWriteStampInvalid;
100 BX_CPP_INLINE void bxPageWriteStampTable::purgeWriteStamps(void)
102 for (Bit32u i=0; i<PHY_MEM_PAGES; i++) {
103 pageWriteStampTable[i] |= ICacheWriteStampStart;
107 extern bxPageWriteStampTable pageWriteStampTable;
109 #define BxICacheEntries (64 * 1024) // Must be a power of 2.
110 #define BxICacheMemPool (384 * 1024)
112 #if BX_SUPPORT_TRACE_CACHE
113 #define BX_MAX_TRACE_LENGTH 32
114 #endif
116 struct bxICacheEntry_c
118 bx_phy_address pAddr; // Physical address of the instruction
119 Bit32u writeStamp; // Generation ID. Each write to a physical page
120 // decrements this value
121 #if BX_SUPPORT_TRACE_CACHE
122 Bit32u ilen; // Trace length in instructions
123 bxInstruction_c *i;
124 #else
125 // ... define as array of 1 to simplify merge with trace cache code
126 bxInstruction_c i[1];
127 #endif
130 class BOCHSAPI bxICache_c {
131 public:
132 bxICacheEntry_c entry[BxICacheEntries];
133 #if BX_SUPPORT_TRACE_CACHE
134 bxInstruction_c pool[BxICacheMemPool];
135 Bit32u mempool;
136 #endif
138 public:
139 bxICache_c() { flushICacheEntries(); }
141 BX_CPP_INLINE unsigned hash(bx_phy_address pAddr) const
143 // return (pAddr + (pAddr << 2) + (pAddr>>6)) & (BxICacheEntries-1);
144 return (pAddr) & (BxICacheEntries-1);
147 #if BX_SUPPORT_TRACE_CACHE
148 BX_CPP_INLINE void alloc_trace(bxICacheEntry_c *e)
150 if (mempool + BX_MAX_TRACE_LENGTH > BxICacheMemPool) {
151 flushICacheEntries();
153 e->i = &pool[mempool];
154 e->ilen = 0;
157 BX_CPP_INLINE void commit_trace(unsigned len) { mempool += len; }
158 #endif
160 BX_CPP_INLINE void purgeICacheEntries(void);
161 BX_CPP_INLINE void flushICacheEntries(void);
163 BX_CPP_INLINE bxICacheEntry_c* get_entry(bx_phy_address pAddr)
165 return &(entry[hash(pAddr)]);
170 BX_CPP_INLINE void bxICache_c::flushICacheEntries(void)
172 bxICacheEntry_c* e = entry;
173 for (unsigned i=0; i<BxICacheEntries; i++, e++) {
174 e->writeStamp = ICacheWriteStampInvalid;
176 #if BX_SUPPORT_TRACE_CACHE
177 mempool = 0;
178 #endif
181 // Since the write stamps may overflow if we always simply decrese them,
182 // this function has to be called often enough that we can reset them.
183 BX_CPP_INLINE void bxICache_c::purgeICacheEntries(void)
185 flushICacheEntries();
188 extern void purgeICaches(void);
189 extern void flushICaches(void);
191 #endif // BX_SUPPORT_ICACHE
193 #endif