Revision 41c1b1c9

b/cpu-exec.c
125 125
{
126 126
    TranslationBlock *tb, **ptb1;
127 127
    unsigned int h;
128
    target_ulong phys_pc, phys_page1, phys_page2, virt_page2;
128
    tb_page_addr_t phys_pc, phys_page1, phys_page2;
129
    target_ulong virt_page2;
129 130

  
130 131
    tb_invalidated_flag = 0;
131 132

  
132 133
    /* find translated block using physical mappings */
133
    phys_pc = get_phys_addr_code(env, pc);
134
    phys_pc = get_page_addr_code(env, pc);
134 135
    phys_page1 = phys_pc & TARGET_PAGE_MASK;
135 136
    phys_page2 = -1;
136 137
    h = tb_phys_hash_func(phys_pc);
......
147 148
            if (tb->page_addr[1] != -1) {
148 149
                virt_page2 = (pc & TARGET_PAGE_MASK) +
149 150
                    TARGET_PAGE_SIZE;
150
                phys_page2 = get_phys_addr_code(env, virt_page2);
151
                phys_page2 = get_page_addr_code(env, virt_page2);
151 152
                if (tb->page_addr[1] == phys_page2)
152 153
                    goto found;
153 154
            } else {
b/exec-all.h
25 25
/* allow to see translation results - the slowdown should be negligible, so we leave it */
26 26
#define DEBUG_DISAS
27 27

  
28
/* Page tracking code uses ram addresses in system mode, and virtual
29
   addresses in userspace mode.  Define tb_page_addr_t to be an appropriate
30
   type.  */
31
#if defined(CONFIG_USER_ONLY)
32
typedef target_ulong tb_page_addr_t;
33
#else
34
typedef ram_addr_t tb_page_addr_t;
35
#endif
36

  
28 37
/* is_jmp field values */
29 38
#define DISAS_NEXT    0 /* next instruction can be analyzed */
30 39
#define DISAS_JUMP    1 /* only pc was modified dynamically */
......
81 90
void cpu_exec_init(CPUState *env);
82 91
void QEMU_NORETURN cpu_loop_exit(void);
83 92
int page_unprotect(target_ulong address, unsigned long pc, void *puc);
84
void tb_invalidate_phys_page_range(target_phys_addr_t start, target_phys_addr_t end,
93
void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
85 94
                                   int is_cpu_write_access);
86 95
void tb_invalidate_page_range(target_ulong start, target_ulong end);
87 96
void tlb_flush_page(CPUState *env, target_ulong addr);
......
136 145
    /* first and second physical page containing code. The lower bit
137 146
       of the pointer tells the index in page_next[] */
138 147
    struct TranslationBlock *page_next[2];
139
    target_ulong page_addr[2];
148
    tb_page_addr_t page_addr[2];
140 149

  
141 150
    /* the following data are used to directly call another TB from
142 151
       the code of this one. */
......
170 179
	    | (tmp & TB_JMP_ADDR_MASK));
171 180
}
172 181

  
173
static inline unsigned int tb_phys_hash_func(unsigned long pc)
182
static inline unsigned int tb_phys_hash_func(tb_page_addr_t pc)
174 183
{
175 184
    return pc & (CODE_GEN_PHYS_HASH_SIZE - 1);
176 185
}
......
178 187
TranslationBlock *tb_alloc(target_ulong pc);
179 188
void tb_free(TranslationBlock *tb);
180 189
void tb_flush(CPUState *env);
181
void tb_link_phys(TranslationBlock *tb,
182
                  target_ulong phys_pc, target_ulong phys_page2);
183
void tb_phys_invalidate(TranslationBlock *tb, target_ulong page_addr);
190
void tb_link_page(TranslationBlock *tb,
191
                  tb_page_addr_t phys_pc, tb_page_addr_t phys_page2);
192
void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr);
184 193

  
185 194
extern TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE];
186 195
extern uint8_t *code_gen_ptr;
......
305 314
#endif
306 315

  
307 316
#if defined(CONFIG_USER_ONLY)
308
static inline target_ulong get_phys_addr_code(CPUState *env1, target_ulong addr)
317
static inline tb_page_addr_t get_page_addr_code(CPUState *env1, target_ulong addr)
309 318
{
310 319
    return addr;
311 320
}
......
313 322
/* NOTE: this function can trigger an exception */
314 323
/* NOTE2: the returned address is not exactly the physical address: it
315 324
   is the offset relative to phys_ram_base */
316
static inline target_ulong get_phys_addr_code(CPUState *env1, target_ulong addr)
325
static inline tb_page_addr_t get_page_addr_code(CPUState *env1, target_ulong addr)
317 326
{
318 327
    int mmu_idx, page_index, pd;
319 328
    void *p;
b/exec.c
135 135
#endif
136 136
} PageDesc;
137 137

  
138
typedef struct PhysPageDesc {
139
    /* offset in host memory of the page + io_index in the low bits */
140
    ram_addr_t phys_offset;
141
    ram_addr_t region_offset;
142
} PhysPageDesc;
143

  
144
/* In system mode we want L1_MAP to be based on physical addresses,
138
/* In system mode we want L1_MAP to be based on ram offsets,
145 139
   while in user mode we want it to be based on virtual addresses.  */
146 140
#if !defined(CONFIG_USER_ONLY)
141
#if HOST_LONG_BITS < TARGET_PHYS_ADDR_SPACE_BITS
142
# define L1_MAP_ADDR_SPACE_BITS  HOST_LONG_BITS
143
#else
147 144
# define L1_MAP_ADDR_SPACE_BITS  TARGET_PHYS_ADDR_SPACE_BITS
145
#endif
148 146
#else
149 147
# define L1_MAP_ADDR_SPACE_BITS  TARGET_VIRT_ADDR_SPACE_BITS
150 148
#endif
......
188 186
static void *l1_map[V_L1_SIZE];
189 187

  
190 188
#if !defined(CONFIG_USER_ONLY)
189
typedef struct PhysPageDesc {
190
    /* offset in host memory of the page + io_index in the low bits */
191
    ram_addr_t phys_offset;
192
    ram_addr_t region_offset;
193
} PhysPageDesc;
194

  
191 195
/* This is a multi-level map on the physical address space.
192 196
   The bottom level has pointers to PhysPageDesc.  */
193 197
static void *l1_phys_map[P_L1_SIZE];
......
301 305
#endif
302 306
}
303 307

  
304
static PageDesc *page_find_alloc(target_ulong index, int alloc)
308
static PageDesc *page_find_alloc(tb_page_addr_t index, int alloc)
305 309
{
310
    PageDesc *pd;
311
    void **lp;
312
    int i;
313

  
306 314
#if defined(CONFIG_USER_ONLY)
307 315
    /* We can't use qemu_malloc because it may recurse into a locked mutex.
308 316
       Neither can we record the new pages we reserve while allocating a
......
328 336
    do { P = qemu_mallocz(SIZE); } while (0)
329 337
#endif
330 338

  
331
    PageDesc *pd;
332
    void **lp;
333
    int i;
334

  
335 339
    /* Level 1.  Always allocated.  */
336 340
    lp = l1_map + ((index >> V_L1_SHIFT) & (V_L1_SIZE - 1));
337 341

  
......
374 378
    return pd + (index & (L2_SIZE - 1));
375 379
}
376 380

  
377
static inline PageDesc *page_find(target_ulong index)
381
static inline PageDesc *page_find(tb_page_addr_t index)
378 382
{
379 383
    return page_find_alloc(index, 0);
380 384
}
......
791 795
    tb_set_jmp_target(tb, n, (unsigned long)(tb->tc_ptr + tb->tb_next_offset[n]));
792 796
}
793 797

  
794
void tb_phys_invalidate(TranslationBlock *tb, target_ulong page_addr)
798
void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr)
795 799
{
796 800
    CPUState *env;
797 801
    PageDesc *p;
798 802
    unsigned int h, n1;
799
    target_phys_addr_t phys_pc;
803
    tb_page_addr_t phys_pc;
800 804
    TranslationBlock *tb1, *tb2;
801 805

  
802 806
    /* remove the TB from the hash list */
......
908 912
{
909 913
    TranslationBlock *tb;
910 914
    uint8_t *tc_ptr;
911
    target_ulong phys_pc, phys_page2, virt_page2;
915
    tb_page_addr_t phys_pc, phys_page2;
916
    target_ulong virt_page2;
912 917
    int code_gen_size;
913 918

  
914
    phys_pc = get_phys_addr_code(env, pc);
919
    phys_pc = get_page_addr_code(env, pc);
915 920
    tb = tb_alloc(pc);
916 921
    if (!tb) {
917 922
        /* flush must be done */
......
933 938
    virt_page2 = (pc + tb->size - 1) & TARGET_PAGE_MASK;
934 939
    phys_page2 = -1;
935 940
    if ((pc & TARGET_PAGE_MASK) != virt_page2) {
936
        phys_page2 = get_phys_addr_code(env, virt_page2);
941
        phys_page2 = get_page_addr_code(env, virt_page2);
937 942
    }
938
    tb_link_phys(tb, phys_pc, phys_page2);
943
    tb_link_page(tb, phys_pc, phys_page2);
939 944
    return tb;
940 945
}
941 946

  
......
944 949
   the same physical page. 'is_cpu_write_access' should be true if called
945 950
   from a real cpu write access: the virtual CPU will exit the current
946 951
   TB if code is modified inside this TB. */
947
void tb_invalidate_phys_page_range(target_phys_addr_t start, target_phys_addr_t end,
952
void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
948 953
                                   int is_cpu_write_access)
949 954
{
950 955
    TranslationBlock *tb, *tb_next, *saved_tb;
951 956
    CPUState *env = cpu_single_env;
952
    target_ulong tb_start, tb_end;
957
    tb_page_addr_t tb_start, tb_end;
953 958
    PageDesc *p;
954 959
    int n;
955 960
#ifdef TARGET_HAS_PRECISE_SMC
......
1051 1056
}
1052 1057

  
1053 1058
/* len must be <= 8 and start must be a multiple of len */
1054
static inline void tb_invalidate_phys_page_fast(target_phys_addr_t start, int len)
1059
static inline void tb_invalidate_phys_page_fast(tb_page_addr_t start, int len)
1055 1060
{
1056 1061
    PageDesc *p;
1057 1062
    int offset, b;
......
1078 1083
}
1079 1084

  
1080 1085
#if !defined(CONFIG_SOFTMMU)
1081
static void tb_invalidate_phys_page(target_phys_addr_t addr,
1086
static void tb_invalidate_phys_page(tb_page_addr_t addr,
1082 1087
                                    unsigned long pc, void *puc)
1083 1088
{
1084 1089
    TranslationBlock *tb;
......
1140 1145

  
1141 1146
/* add the tb in the target page and protect it if necessary */
1142 1147
static inline void tb_alloc_page(TranslationBlock *tb,
1143
                                 unsigned int n, target_ulong page_addr)
1148
                                 unsigned int n, tb_page_addr_t page_addr)
1144 1149
{
1145 1150
    PageDesc *p;
1146 1151
    TranslationBlock *last_first_tb;
......
1221 1226

  
1222 1227
/* add a new TB and link it to the physical page tables. phys_page2 is
1223 1228
   (-1) to indicate that only one page contains the TB. */
1224
void tb_link_phys(TranslationBlock *tb,
1225
                  target_ulong phys_pc, target_ulong phys_page2)
1229
void tb_link_page(TranslationBlock *tb,
1230
                  tb_page_addr_t phys_pc, tb_page_addr_t phys_page2)
1226 1231
{
1227 1232
    unsigned int h;
1228 1233
    TranslationBlock **ptb;

Also available in: Unified diff