filename | src/xlat/xltcache.h |
changeset | 1149:da6124fceec6 |
prev | 1091:186558374345 |
next | 1182:b38a327ad8fa |
author | nkeynes |
date | Wed Nov 10 08:37:42 2010 +1000 (13 years ago) |
permissions | -rw-r--r-- |
last change | Add chain pointer to the xlat cache, so that we can maintain multiple blocks for the same address. This prevents thrashing in cases where we would other keep retranslating the same blocks over and over again due to varying xlat_sh4_mode values |
view | annotate | diff | log | raw |
1 /**
2 * $Id$
3 *
4 * Translation cache support (architecture independent)
5 *
6 * Copyright (c) 2005 Nathan Keynes.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program 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
16 * GNU General Public License for more details.
17 */
19 #include "dream.h"
20 #include "mem.h"
22 #ifndef lxdream_xltcache_H
23 #define lxdream_xltcache_H 1
25 /**
26 * For now, recovery is purely a matter of mapping native pc => sh4 pc,
27 * and updating sh4r.pc & sh4r.slice_cycles accordingly. In future more
28 * detailed recovery may be required if the translator optimizes more
29 * agressively.
30 *
31 * The recovery table contains (at least) one entry per abortable instruction,
32 *
33 */
34 typedef struct xlat_recovery_record {
35 uint32_t xlat_offset; // native (translated) pc
36 uint32_t sh4_icount; // instruction number of the corresponding SH4 instruction
37 // (0 = first instruction, 1 = second instruction, ... )
38 } *xlat_recovery_record_t;
40 struct xlat_cache_block {
41 int active; /* 0 = deleted, 1 = normal. 2 = accessed (temp-space only) */
42 uint32_t size;
43 void **lut_entry; /* For deletion */
44 void *chain;
45 uint32_t xlat_sh4_mode; /* comparison with sh4r.xlat_sh4_mode */
46 uint32_t recover_table_offset; // Offset from code[0] of the recovery table;
47 uint32_t recover_table_size;
48 unsigned char code[0];
49 } __attribute__((packed));
51 typedef struct xlat_cache_block *xlat_cache_block_t;
53 #define XLAT_BLOCK_FOR_CODE(code) (((xlat_cache_block_t)code)-1)
55 #define XLAT_BLOCK_MODE(code) (XLAT_BLOCK_FOR_CODE(code)->xlat_sh4_mode)
56 #define XLAT_BLOCK_CHAIN(code) (XLAT_BLOCK_FOR_CODE(code)->chain)
57 #define XLAT_RECOVERY_TABLE(code) ((xlat_recovery_record_t)(((char *)code) + XLAT_BLOCK_FOR_CODE(code)->recover_table_offset))
59 /**
60 * Initialize the translation cache
61 */
62 void xlat_cache_init(void);
64 /**
65 * Returns the next block in the new cache list that can be written to by the
66 * translator.
67 */
68 xlat_cache_block_t xlat_start_block(sh4addr_t address);
70 /**
71 * Increases the current block size (only valid between calls to xlat_start_block()
72 * and xlat_commit_block()).
73 * @return the new block, which may be different from the old block.
74 */
75 xlat_cache_block_t xlat_extend_block( uint32_t newSize );
77 /**
78 * Commit the current translation block
79 * @param destsize final size of the translation in bytes.
80 * @param srcsize size of the original data that was translated in bytes
81 */
82 void xlat_commit_block( uint32_t destsize, uint32_t srcsize );
84 /**
85 * Dump the disassembly of the specified code block to a stream
86 * (primarily for debugging purposes)
87 * @param out The stream to write the output to
88 * @param code a translated block
89 */
90 void xlat_disasm_block( FILE *out, void *code );
93 /**
94 * Delete (deactivate) the specified block from the cache. Caller is responsible
95 * for ensuring that there really is a block there.
96 */
97 void xlat_delete_block( xlat_cache_block_t block );
99 /**
100 * Retrieve the entry point for the translated code corresponding to the given
101 * SH4 address, or NULL if there is no code for that address.
102 */
103 void * FASTCALL xlat_get_code( sh4addr_t address );
105 /**
106 * Retrieve the pre-instruction recovery record corresponding to the given
107 * native address, or NULL if there is no recovery code for the address.
108 * @param code The code block containing the recovery table.
109 * @param native_pc A pointer that must be within the currently executing
110 * return the first record before or equal to the given pc.
111 * translation block.
112 */
113 struct xlat_recovery_record *xlat_get_pre_recovery( void *code, void *native_pc );
116 /**
117 * Retrieve the entry point for the translated code corresponding to the given
118 * SH4 virtual address, or NULL if there is no code for the address.
119 * If the virtual address cannot be resolved, this method will raise a TLB miss
120 * exception, and return NULL.
121 */
122 void * FASTCALL xlat_get_code_by_vma( sh4vma_t address );
124 /**
125 * Retrieve the address of the lookup table entry corresponding to the
126 * given SH4 address.
127 */
128 void ** FASTCALL xlat_get_lut_entry( sh4addr_t address );
130 /**
131 * Retrieve the current host address of the running translated code block.
132 * @return the host PC, or null if there is no currently executing translated
133 * block (or the stack is corrupted)
134 * Note: the implementation of this method is host (and calling-convention) specific.
135 * @param block_start start of the block the PC should be in
136 * @param block_size size of the code block in bytes.
137 */
138 void *xlat_get_native_pc( void *block_start, uint32_t block_size );
140 /**
141 * Retrieve the size of the block starting at the specified pointer. If the
142 * pointer is not a valid code block, the return value is undefined.
143 */
144 uint32_t FASTCALL xlat_get_block_size( void *ptr );
146 /**
147 * Retrieve the size of the code in the block starting at the specified
148 * pointer. Effectively this is xlat_get_block_size() minus the size of
149 * the recovery table. If the pointer is not a valid code block, the
150 * return value is undefined.
151 */
152 uint32_t FASTCALL xlat_get_code_size( void *ptr );
154 /**
155 * Flush the code cache for the page containing the given address
156 */
157 void FASTCALL xlat_flush_page( sh4addr_t address );
159 void FASTCALL xlat_invalidate_word( sh4addr_t address );
160 void FASTCALL xlat_invalidate_long( sh4addr_t address );
163 /**
164 * Invalidate the code cache for a memory region
165 */
166 void FASTCALL xlat_invalidate_block( sh4addr_t address, size_t bytes );
168 /**
169 * Flush the entire code cache. This isn't as cheap as one might like
170 */
171 void xlat_flush_cache();
173 /**
174 * Test if the given pointer is within the translation cache, and (is likely)
175 * the start of a code block
176 */
177 gboolean xlat_is_code_pointer( void *p );
179 /**
180 * Check the internal integrity of the cache
181 */
182 void xlat_check_integrity();
184 #endif /* lxdream_xltcache_H */
.