Use full 36-bit physical address space on SS10
[qemu] / exec.c
1 /*
2  *  virtual page mapping and translated block handling
3  * 
4  *  Copyright (c) 2003 Fabrice Bellard
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20 #include "config.h"
21 #ifdef _WIN32
22 #include <windows.h>
23 #else
24 #include <sys/types.h>
25 #include <sys/mman.h>
26 #endif
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <stdarg.h>
30 #include <string.h>
31 #include <errno.h>
32 #include <unistd.h>
33 #include <inttypes.h>
34
35 #include "cpu.h"
36 #include "exec-all.h"
37 #if defined(CONFIG_USER_ONLY)
38 #include <qemu.h>
39 #endif
40
41 //#define DEBUG_TB_INVALIDATE
42 //#define DEBUG_FLUSH
43 //#define DEBUG_TLB
44 //#define DEBUG_UNASSIGNED
45
46 /* make various TB consistency checks */
47 //#define DEBUG_TB_CHECK 
48 //#define DEBUG_TLB_CHECK 
49
50 //#define DEBUG_IOPORT
51
52 #if !defined(CONFIG_USER_ONLY)
53 /* TB consistency checks only implemented for usermode emulation.  */
54 #undef DEBUG_TB_CHECK
55 #endif
56
57 /* threshold to flush the translated code buffer */
58 #define CODE_GEN_BUFFER_MAX_SIZE (CODE_GEN_BUFFER_SIZE - CODE_GEN_MAX_SIZE)
59
60 #define SMC_BITMAP_USE_THRESHOLD 10
61
62 #define MMAP_AREA_START        0x00000000
63 #define MMAP_AREA_END          0xa8000000
64
65 #if defined(TARGET_SPARC64)
66 #define TARGET_PHYS_ADDR_SPACE_BITS 41
67 #elif defined(TARGET_SPARC)
68 #define TARGET_PHYS_ADDR_SPACE_BITS 36
69 #elif defined(TARGET_ALPHA)
70 #define TARGET_PHYS_ADDR_SPACE_BITS 42
71 #define TARGET_VIRT_ADDR_SPACE_BITS 42
72 #elif defined(TARGET_PPC64)
73 #define TARGET_PHYS_ADDR_SPACE_BITS 42
74 #else
75 /* Note: for compatibility with kqemu, we use 32 bits for x86_64 */
76 #define TARGET_PHYS_ADDR_SPACE_BITS 32
77 #endif
78
79 TranslationBlock tbs[CODE_GEN_MAX_BLOCKS];
80 TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE];
81 int nb_tbs;
82 /* any access to the tbs or the page table must use this lock */
83 spinlock_t tb_lock = SPIN_LOCK_UNLOCKED;
84
85 uint8_t code_gen_buffer[CODE_GEN_BUFFER_SIZE] __attribute__((aligned (32)));
86 uint8_t *code_gen_ptr;
87
88 int phys_ram_size;
89 int phys_ram_fd;
90 uint8_t *phys_ram_base;
91 uint8_t *phys_ram_dirty;
92 static ram_addr_t phys_ram_alloc_offset = 0;
93
94 CPUState *first_cpu;
95 /* current CPU in the current thread. It is only valid inside
96    cpu_exec() */
97 CPUState *cpu_single_env; 
98
99 typedef struct PageDesc {
100     /* list of TBs intersecting this ram page */
101     TranslationBlock *first_tb;
102     /* in order to optimize self modifying code, we count the number
103        of lookups we do to a given page to use a bitmap */
104     unsigned int code_write_count;
105     uint8_t *code_bitmap;
106 #if defined(CONFIG_USER_ONLY)
107     unsigned long flags;
108 #endif
109 } PageDesc;
110
111 typedef struct PhysPageDesc {
112     /* offset in host memory of the page + io_index in the low 12 bits */
113     uint32_t phys_offset;
114 } PhysPageDesc;
115
116 #define L2_BITS 10
117 #if defined(CONFIG_USER_ONLY) && defined(TARGET_VIRT_ADDR_SPACE_BITS)
118 /* XXX: this is a temporary hack for alpha target.
119  *      In the future, this is to be replaced by a multi-level table
120  *      to actually be able to handle the complete 64 bits address space.
121  */
122 #define L1_BITS (TARGET_VIRT_ADDR_SPACE_BITS - L2_BITS - TARGET_PAGE_BITS)
123 #else
124 #define L1_BITS (32 - L2_BITS - TARGET_PAGE_BITS)
125 #endif
126
127 #define L1_SIZE (1 << L1_BITS)
128 #define L2_SIZE (1 << L2_BITS)
129
130 static void io_mem_init(void);
131
132 unsigned long qemu_real_host_page_size;
133 unsigned long qemu_host_page_bits;
134 unsigned long qemu_host_page_size;
135 unsigned long qemu_host_page_mask;
136
137 /* XXX: for system emulation, it could just be an array */
138 static PageDesc *l1_map[L1_SIZE];
139 PhysPageDesc **l1_phys_map;
140
141 /* io memory support */
142 CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
143 CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
144 void *io_mem_opaque[IO_MEM_NB_ENTRIES];
145 static int io_mem_nb;
146 #if defined(CONFIG_SOFTMMU)
147 static int io_mem_watch;
148 #endif
149
150 /* log support */
151 char *logfilename = "/tmp/qemu.log";
152 FILE *logfile;
153 int loglevel;
154
155 /* statistics */
156 static int tlb_flush_count;
157 static int tb_flush_count;
158 static int tb_phys_invalidate_count;
159
160 static void page_init(void)
161 {
162     /* NOTE: we can always suppose that qemu_host_page_size >=
163        TARGET_PAGE_SIZE */
164 #ifdef _WIN32
165     {
166         SYSTEM_INFO system_info;
167         DWORD old_protect;
168         
169         GetSystemInfo(&system_info);
170         qemu_real_host_page_size = system_info.dwPageSize;
171         
172         VirtualProtect(code_gen_buffer, sizeof(code_gen_buffer),
173                        PAGE_EXECUTE_READWRITE, &old_protect);
174     }
175 #else
176     qemu_real_host_page_size = getpagesize();
177     {
178         unsigned long start, end;
179
180         start = (unsigned long)code_gen_buffer;
181         start &= ~(qemu_real_host_page_size - 1);
182         
183         end = (unsigned long)code_gen_buffer + sizeof(code_gen_buffer);
184         end += qemu_real_host_page_size - 1;
185         end &= ~(qemu_real_host_page_size - 1);
186         
187         mprotect((void *)start, end - start, 
188                  PROT_READ | PROT_WRITE | PROT_EXEC);
189     }
190 #endif
191
192     if (qemu_host_page_size == 0)
193         qemu_host_page_size = qemu_real_host_page_size;
194     if (qemu_host_page_size < TARGET_PAGE_SIZE)
195         qemu_host_page_size = TARGET_PAGE_SIZE;
196     qemu_host_page_bits = 0;
197     while ((1 << qemu_host_page_bits) < qemu_host_page_size)
198         qemu_host_page_bits++;
199     qemu_host_page_mask = ~(qemu_host_page_size - 1);
200     l1_phys_map = qemu_vmalloc(L1_SIZE * sizeof(void *));
201     memset(l1_phys_map, 0, L1_SIZE * sizeof(void *));
202 }
203
204 static inline PageDesc *page_find_alloc(unsigned int index)
205 {
206     PageDesc **lp, *p;
207
208     lp = &l1_map[index >> L2_BITS];
209     p = *lp;
210     if (!p) {
211         /* allocate if not found */
212         p = qemu_malloc(sizeof(PageDesc) * L2_SIZE);
213         memset(p, 0, sizeof(PageDesc) * L2_SIZE);
214         *lp = p;
215     }
216     return p + (index & (L2_SIZE - 1));
217 }
218
219 static inline PageDesc *page_find(unsigned int index)
220 {
221     PageDesc *p;
222
223     p = l1_map[index >> L2_BITS];
224     if (!p)
225         return 0;
226     return p + (index & (L2_SIZE - 1));
227 }
228
229 static PhysPageDesc *phys_page_find_alloc(target_phys_addr_t index, int alloc)
230 {
231     void **lp, **p;
232     PhysPageDesc *pd;
233
234     p = (void **)l1_phys_map;
235 #if TARGET_PHYS_ADDR_SPACE_BITS > 32
236
237 #if TARGET_PHYS_ADDR_SPACE_BITS > (32 + L1_BITS)
238 #error unsupported TARGET_PHYS_ADDR_SPACE_BITS
239 #endif
240     lp = p + ((index >> (L1_BITS + L2_BITS)) & (L1_SIZE - 1));
241     p = *lp;
242     if (!p) {
243         /* allocate if not found */
244         if (!alloc)
245             return NULL;
246         p = qemu_vmalloc(sizeof(void *) * L1_SIZE);
247         memset(p, 0, sizeof(void *) * L1_SIZE);
248         *lp = p;
249     }
250 #endif
251     lp = p + ((index >> L2_BITS) & (L1_SIZE - 1));
252     pd = *lp;
253     if (!pd) {
254         int i;
255         /* allocate if not found */
256         if (!alloc)
257             return NULL;
258         pd = qemu_vmalloc(sizeof(PhysPageDesc) * L2_SIZE);
259         *lp = pd;
260         for (i = 0; i < L2_SIZE; i++)
261           pd[i].phys_offset = IO_MEM_UNASSIGNED;
262     }
263     return ((PhysPageDesc *)pd) + (index & (L2_SIZE - 1));
264 }
265
266 static inline PhysPageDesc *phys_page_find(target_phys_addr_t index)
267 {
268     return phys_page_find_alloc(index, 0);
269 }
270
271 #if !defined(CONFIG_USER_ONLY)
272 static void tlb_protect_code(ram_addr_t ram_addr);
273 static void tlb_unprotect_code_phys(CPUState *env, ram_addr_t ram_addr, 
274                                     target_ulong vaddr);
275 #endif
276
277 void cpu_exec_init(CPUState *env)
278 {
279     CPUState **penv;
280     int cpu_index;
281
282     if (!code_gen_ptr) {
283         code_gen_ptr = code_gen_buffer;
284         page_init();
285         io_mem_init();
286     }
287     env->next_cpu = NULL;
288     penv = &first_cpu;
289     cpu_index = 0;
290     while (*penv != NULL) {
291         penv = (CPUState **)&(*penv)->next_cpu;
292         cpu_index++;
293     }
294     env->cpu_index = cpu_index;
295     env->nb_watchpoints = 0;
296     *penv = env;
297 }
298
299 static inline void invalidate_page_bitmap(PageDesc *p)
300 {
301     if (p->code_bitmap) {
302         qemu_free(p->code_bitmap);
303         p->code_bitmap = NULL;
304     }
305     p->code_write_count = 0;
306 }
307
308 /* set to NULL all the 'first_tb' fields in all PageDescs */
309 static void page_flush_tb(void)
310 {
311     int i, j;
312     PageDesc *p;
313
314     for(i = 0; i < L1_SIZE; i++) {
315         p = l1_map[i];
316         if (p) {
317             for(j = 0; j < L2_SIZE; j++) {
318                 p->first_tb = NULL;
319                 invalidate_page_bitmap(p);
320                 p++;
321             }
322         }
323     }
324 }
325
326 /* flush all the translation blocks */
327 /* XXX: tb_flush is currently not thread safe */
328 void tb_flush(CPUState *env1)
329 {
330     CPUState *env;
331 #if defined(DEBUG_FLUSH)
332     printf("qemu: flush code_size=%d nb_tbs=%d avg_tb_size=%d\n", 
333            code_gen_ptr - code_gen_buffer, 
334            nb_tbs, 
335            nb_tbs > 0 ? (code_gen_ptr - code_gen_buffer) / nb_tbs : 0);
336 #endif
337     nb_tbs = 0;
338     
339     for(env = first_cpu; env != NULL; env = env->next_cpu) {
340         memset (env->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof (void *));
341     }
342
343     memset (tb_phys_hash, 0, CODE_GEN_PHYS_HASH_SIZE * sizeof (void *));
344     page_flush_tb();
345
346     code_gen_ptr = code_gen_buffer;
347     /* XXX: flush processor icache at this point if cache flush is
348        expensive */
349     tb_flush_count++;
350 }
351
352 #ifdef DEBUG_TB_CHECK
353
354 static void tb_invalidate_check(target_ulong address)
355 {
356     TranslationBlock *tb;
357     int i;
358     address &= TARGET_PAGE_MASK;
359     for(i = 0;i < CODE_GEN_PHYS_HASH_SIZE; i++) {
360         for(tb = tb_phys_hash[i]; tb != NULL; tb = tb->phys_hash_next) {
361             if (!(address + TARGET_PAGE_SIZE <= tb->pc ||
362                   address >= tb->pc + tb->size)) {
363                 printf("ERROR invalidate: address=%08lx PC=%08lx size=%04x\n",
364                        address, (long)tb->pc, tb->size);
365             }
366         }
367     }
368 }
369
370 /* verify that all the pages have correct rights for code */
371 static void tb_page_check(void)
372 {
373     TranslationBlock *tb;
374     int i, flags1, flags2;
375     
376     for(i = 0;i < CODE_GEN_PHYS_HASH_SIZE; i++) {
377         for(tb = tb_phys_hash[i]; tb != NULL; tb = tb->phys_hash_next) {
378             flags1 = page_get_flags(tb->pc);
379             flags2 = page_get_flags(tb->pc + tb->size - 1);
380             if ((flags1 & PAGE_WRITE) || (flags2 & PAGE_WRITE)) {
381                 printf("ERROR page flags: PC=%08lx size=%04x f1=%x f2=%x\n",
382                        (long)tb->pc, tb->size, flags1, flags2);
383             }
384         }
385     }
386 }
387
388 void tb_jmp_check(TranslationBlock *tb)
389 {
390     TranslationBlock *tb1;
391     unsigned int n1;
392
393     /* suppress any remaining jumps to this TB */
394     tb1 = tb->jmp_first;
395     for(;;) {
396         n1 = (long)tb1 & 3;
397         tb1 = (TranslationBlock *)((long)tb1 & ~3);
398         if (n1 == 2)
399             break;
400         tb1 = tb1->jmp_next[n1];
401     }
402     /* check end of list */
403     if (tb1 != tb) {
404         printf("ERROR: jmp_list from 0x%08lx\n", (long)tb);
405     }
406 }
407
408 #endif
409
410 /* invalidate one TB */
411 static inline void tb_remove(TranslationBlock **ptb, TranslationBlock *tb,
412                              int next_offset)
413 {
414     TranslationBlock *tb1;
415     for(;;) {
416         tb1 = *ptb;
417         if (tb1 == tb) {
418             *ptb = *(TranslationBlock **)((char *)tb1 + next_offset);
419             break;
420         }
421         ptb = (TranslationBlock **)((char *)tb1 + next_offset);
422     }
423 }
424
425 static inline void tb_page_remove(TranslationBlock **ptb, TranslationBlock *tb)
426 {
427     TranslationBlock *tb1;
428     unsigned int n1;
429
430     for(;;) {
431         tb1 = *ptb;
432         n1 = (long)tb1 & 3;
433         tb1 = (TranslationBlock *)((long)tb1 & ~3);
434         if (tb1 == tb) {
435             *ptb = tb1->page_next[n1];
436             break;
437         }
438         ptb = &tb1->page_next[n1];
439     }
440 }
441
442 static inline void tb_jmp_remove(TranslationBlock *tb, int n)
443 {
444     TranslationBlock *tb1, **ptb;
445     unsigned int n1;
446
447     ptb = &tb->jmp_next[n];
448     tb1 = *ptb;
449     if (tb1) {
450         /* find tb(n) in circular list */
451         for(;;) {
452             tb1 = *ptb;
453             n1 = (long)tb1 & 3;
454             tb1 = (TranslationBlock *)((long)tb1 & ~3);
455             if (n1 == n && tb1 == tb)
456                 break;
457             if (n1 == 2) {
458                 ptb = &tb1->jmp_first;
459             } else {
460                 ptb = &tb1->jmp_next[n1];
461             }
462         }
463         /* now we can suppress tb(n) from the list */
464         *ptb = tb->jmp_next[n];
465
466         tb->jmp_next[n] = NULL;
467     }
468 }
469
470 /* reset the jump entry 'n' of a TB so that it is not chained to
471    another TB */
472 static inline void tb_reset_jump(TranslationBlock *tb, int n)
473 {
474     tb_set_jmp_target(tb, n, (unsigned long)(tb->tc_ptr + tb->tb_next_offset[n]));
475 }
476
477 static inline void tb_phys_invalidate(TranslationBlock *tb, unsigned int page_addr)
478 {
479     CPUState *env;
480     PageDesc *p;
481     unsigned int h, n1;
482     target_ulong phys_pc;
483     TranslationBlock *tb1, *tb2;
484     
485     /* remove the TB from the hash list */
486     phys_pc = tb->page_addr[0] + (tb->pc & ~TARGET_PAGE_MASK);
487     h = tb_phys_hash_func(phys_pc);
488     tb_remove(&tb_phys_hash[h], tb, 
489               offsetof(TranslationBlock, phys_hash_next));
490
491     /* remove the TB from the page list */
492     if (tb->page_addr[0] != page_addr) {
493         p = page_find(tb->page_addr[0] >> TARGET_PAGE_BITS);
494         tb_page_remove(&p->first_tb, tb);
495         invalidate_page_bitmap(p);
496     }
497     if (tb->page_addr[1] != -1 && tb->page_addr[1] != page_addr) {
498         p = page_find(tb->page_addr[1] >> TARGET_PAGE_BITS);
499         tb_page_remove(&p->first_tb, tb);
500         invalidate_page_bitmap(p);
501     }
502
503     tb_invalidated_flag = 1;
504
505     /* remove the TB from the hash list */
506     h = tb_jmp_cache_hash_func(tb->pc);
507     for(env = first_cpu; env != NULL; env = env->next_cpu) {
508         if (env->tb_jmp_cache[h] == tb)
509             env->tb_jmp_cache[h] = NULL;
510     }
511
512     /* suppress this TB from the two jump lists */
513     tb_jmp_remove(tb, 0);
514     tb_jmp_remove(tb, 1);
515
516     /* suppress any remaining jumps to this TB */
517     tb1 = tb->jmp_first;
518     for(;;) {
519         n1 = (long)tb1 & 3;
520         if (n1 == 2)
521             break;
522         tb1 = (TranslationBlock *)((long)tb1 & ~3);
523         tb2 = tb1->jmp_next[n1];
524         tb_reset_jump(tb1, n1);
525         tb1->jmp_next[n1] = NULL;
526         tb1 = tb2;
527     }
528     tb->jmp_first = (TranslationBlock *)((long)tb | 2); /* fail safe */
529
530     tb_phys_invalidate_count++;
531 }
532
533 static inline void set_bits(uint8_t *tab, int start, int len)
534 {
535     int end, mask, end1;
536
537     end = start + len;
538     tab += start >> 3;
539     mask = 0xff << (start & 7);
540     if ((start & ~7) == (end & ~7)) {
541         if (start < end) {
542             mask &= ~(0xff << (end & 7));
543             *tab |= mask;
544         }
545     } else {
546         *tab++ |= mask;
547         start = (start + 8) & ~7;
548         end1 = end & ~7;
549         while (start < end1) {
550             *tab++ = 0xff;
551             start += 8;
552         }
553         if (start < end) {
554             mask = ~(0xff << (end & 7));
555             *tab |= mask;
556         }
557     }
558 }
559
560 static void build_page_bitmap(PageDesc *p)
561 {
562     int n, tb_start, tb_end;
563     TranslationBlock *tb;
564     
565     p->code_bitmap = qemu_malloc(TARGET_PAGE_SIZE / 8);
566     if (!p->code_bitmap)
567         return;
568     memset(p->code_bitmap, 0, TARGET_PAGE_SIZE / 8);
569
570     tb = p->first_tb;
571     while (tb != NULL) {
572         n = (long)tb & 3;
573         tb = (TranslationBlock *)((long)tb & ~3);
574         /* NOTE: this is subtle as a TB may span two physical pages */
575         if (n == 0) {
576             /* NOTE: tb_end may be after the end of the page, but
577                it is not a problem */
578             tb_start = tb->pc & ~TARGET_PAGE_MASK;
579             tb_end = tb_start + tb->size;
580             if (tb_end > TARGET_PAGE_SIZE)
581                 tb_end = TARGET_PAGE_SIZE;
582         } else {
583             tb_start = 0;
584             tb_end = ((tb->pc + tb->size) & ~TARGET_PAGE_MASK);
585         }
586         set_bits(p->code_bitmap, tb_start, tb_end - tb_start);
587         tb = tb->page_next[n];
588     }
589 }
590
591 #ifdef TARGET_HAS_PRECISE_SMC
592
593 static void tb_gen_code(CPUState *env, 
594                         target_ulong pc, target_ulong cs_base, int flags,
595                         int cflags)
596 {
597     TranslationBlock *tb;
598     uint8_t *tc_ptr;
599     target_ulong phys_pc, phys_page2, virt_page2;
600     int code_gen_size;
601
602     phys_pc = get_phys_addr_code(env, pc);
603     tb = tb_alloc(pc);
604     if (!tb) {
605         /* flush must be done */
606         tb_flush(env);
607         /* cannot fail at this point */
608         tb = tb_alloc(pc);
609     }
610     tc_ptr = code_gen_ptr;
611     tb->tc_ptr = tc_ptr;
612     tb->cs_base = cs_base;
613     tb->flags = flags;
614     tb->cflags = cflags;
615     cpu_gen_code(env, tb, CODE_GEN_MAX_SIZE, &code_gen_size);
616     code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));
617     
618     /* check next page if needed */
619     virt_page2 = (pc + tb->size - 1) & TARGET_PAGE_MASK;
620     phys_page2 = -1;
621     if ((pc & TARGET_PAGE_MASK) != virt_page2) {
622         phys_page2 = get_phys_addr_code(env, virt_page2);
623     }
624     tb_link_phys(tb, phys_pc, phys_page2);
625 }
626 #endif
627     
628 /* invalidate all TBs which intersect with the target physical page
629    starting in range [start;end[. NOTE: start and end must refer to
630    the same physical page. 'is_cpu_write_access' should be true if called
631    from a real cpu write access: the virtual CPU will exit the current
632    TB if code is modified inside this TB. */
633 void tb_invalidate_phys_page_range(target_ulong start, target_ulong end, 
634                                    int is_cpu_write_access)
635 {
636     int n, current_tb_modified, current_tb_not_found, current_flags;
637     CPUState *env = cpu_single_env;
638     PageDesc *p;
639     TranslationBlock *tb, *tb_next, *current_tb, *saved_tb;
640     target_ulong tb_start, tb_end;
641     target_ulong current_pc, current_cs_base;
642
643     p = page_find(start >> TARGET_PAGE_BITS);
644     if (!p) 
645         return;
646     if (!p->code_bitmap && 
647         ++p->code_write_count >= SMC_BITMAP_USE_THRESHOLD &&
648         is_cpu_write_access) {
649         /* build code bitmap */
650         build_page_bitmap(p);
651     }
652
653     /* we remove all the TBs in the range [start, end[ */
654     /* XXX: see if in some cases it could be faster to invalidate all the code */
655     current_tb_not_found = is_cpu_write_access;
656     current_tb_modified = 0;
657     current_tb = NULL; /* avoid warning */
658     current_pc = 0; /* avoid warning */
659     current_cs_base = 0; /* avoid warning */
660     current_flags = 0; /* avoid warning */
661     tb = p->first_tb;
662     while (tb != NULL) {
663         n = (long)tb & 3;
664         tb = (TranslationBlock *)((long)tb & ~3);
665         tb_next = tb->page_next[n];
666         /* NOTE: this is subtle as a TB may span two physical pages */
667         if (n == 0) {
668             /* NOTE: tb_end may be after the end of the page, but
669                it is not a problem */
670             tb_start = tb->page_addr[0] + (tb->pc & ~TARGET_PAGE_MASK);
671             tb_end = tb_start + tb->size;
672         } else {
673             tb_start = tb->page_addr[1];
674             tb_end = tb_start + ((tb->pc + tb->size) & ~TARGET_PAGE_MASK);
675         }
676         if (!(tb_end <= start || tb_start >= end)) {
677 #ifdef TARGET_HAS_PRECISE_SMC
678             if (current_tb_not_found) {
679                 current_tb_not_found = 0;
680                 current_tb = NULL;
681                 if (env->mem_write_pc) {
682                     /* now we have a real cpu fault */
683                     current_tb = tb_find_pc(env->mem_write_pc);
684                 }
685             }
686             if (current_tb == tb &&
687                 !(current_tb->cflags & CF_SINGLE_INSN)) {
688                 /* If we are modifying the current TB, we must stop
689                 its execution. We could be more precise by checking
690                 that the modification is after the current PC, but it
691                 would require a specialized function to partially
692                 restore the CPU state */
693                 
694                 current_tb_modified = 1;
695                 cpu_restore_state(current_tb, env, 
696                                   env->mem_write_pc, NULL);
697 #if defined(TARGET_I386)
698                 current_flags = env->hflags;
699                 current_flags |= (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK));
700                 current_cs_base = (target_ulong)env->segs[R_CS].base;
701                 current_pc = current_cs_base + env->eip;
702 #else
703 #error unsupported CPU
704 #endif
705             }
706 #endif /* TARGET_HAS_PRECISE_SMC */
707             /* we need to do that to handle the case where a signal
708                occurs while doing tb_phys_invalidate() */
709             saved_tb = NULL;
710             if (env) {
711                 saved_tb = env->current_tb;
712                 env->current_tb = NULL;
713             }
714             tb_phys_invalidate(tb, -1);
715             if (env) {
716                 env->current_tb = saved_tb;
717                 if (env->interrupt_request && env->current_tb)
718                     cpu_interrupt(env, env->interrupt_request);
719             }
720         }
721         tb = tb_next;
722     }
723 #if !defined(CONFIG_USER_ONLY)
724     /* if no code remaining, no need to continue to use slow writes */
725     if (!p->first_tb) {
726         invalidate_page_bitmap(p);
727         if (is_cpu_write_access) {
728             tlb_unprotect_code_phys(env, start, env->mem_write_vaddr);
729         }
730     }
731 #endif
732 #ifdef TARGET_HAS_PRECISE_SMC
733     if (current_tb_modified) {
734         /* we generate a block containing just the instruction
735            modifying the memory. It will ensure that it cannot modify
736            itself */
737         env->current_tb = NULL;
738         tb_gen_code(env, current_pc, current_cs_base, current_flags, 
739                     CF_SINGLE_INSN);
740         cpu_resume_from_signal(env, NULL);
741     }
742 #endif
743 }
744
745 /* len must be <= 8 and start must be a multiple of len */
746 static inline void tb_invalidate_phys_page_fast(target_ulong start, int len)
747 {
748     PageDesc *p;
749     int offset, b;
750 #if 0
751     if (1) {
752         if (loglevel) {
753             fprintf(logfile, "modifying code at 0x%x size=%d EIP=%x PC=%08x\n", 
754                    cpu_single_env->mem_write_vaddr, len, 
755                    cpu_single_env->eip, 
756                    cpu_single_env->eip + (long)cpu_single_env->segs[R_CS].base);
757         }
758     }
759 #endif
760     p = page_find(start >> TARGET_PAGE_BITS);
761     if (!p) 
762         return;
763     if (p->code_bitmap) {
764         offset = start & ~TARGET_PAGE_MASK;
765         b = p->code_bitmap[offset >> 3] >> (offset & 7);
766         if (b & ((1 << len) - 1))
767             goto do_invalidate;
768     } else {
769     do_invalidate:
770         tb_invalidate_phys_page_range(start, start + len, 1);
771     }
772 }
773
774 #if !defined(CONFIG_SOFTMMU)
775 static void tb_invalidate_phys_page(target_ulong addr, 
776                                     unsigned long pc, void *puc)
777 {
778     int n, current_flags, current_tb_modified;
779     target_ulong current_pc, current_cs_base;
780     PageDesc *p;
781     TranslationBlock *tb, *current_tb;
782 #ifdef TARGET_HAS_PRECISE_SMC
783     CPUState *env = cpu_single_env;
784 #endif
785
786     addr &= TARGET_PAGE_MASK;
787     p = page_find(addr >> TARGET_PAGE_BITS);
788     if (!p) 
789         return;
790     tb = p->first_tb;
791     current_tb_modified = 0;
792     current_tb = NULL;
793     current_pc = 0; /* avoid warning */
794     current_cs_base = 0; /* avoid warning */
795     current_flags = 0; /* avoid warning */
796 #ifdef TARGET_HAS_PRECISE_SMC
797     if (tb && pc != 0) {
798         current_tb = tb_find_pc(pc);
799     }
800 #endif
801     while (tb != NULL) {
802         n = (long)tb & 3;
803         tb = (TranslationBlock *)((long)tb & ~3);
804 #ifdef TARGET_HAS_PRECISE_SMC
805         if (current_tb == tb &&
806             !(current_tb->cflags & CF_SINGLE_INSN)) {
807                 /* If we are modifying the current TB, we must stop
808                    its execution. We could be more precise by checking
809                    that the modification is after the current PC, but it
810                    would require a specialized function to partially
811                    restore the CPU state */
812             
813             current_tb_modified = 1;
814             cpu_restore_state(current_tb, env, pc, puc);
815 #if defined(TARGET_I386)
816             current_flags = env->hflags;
817             current_flags |= (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK));
818             current_cs_base = (target_ulong)env->segs[R_CS].base;
819             current_pc = current_cs_base + env->eip;
820 #else
821 #error unsupported CPU
822 #endif
823         }
824 #endif /* TARGET_HAS_PRECISE_SMC */
825         tb_phys_invalidate(tb, addr);
826         tb = tb->page_next[n];
827     }
828     p->first_tb = NULL;
829 #ifdef TARGET_HAS_PRECISE_SMC
830     if (current_tb_modified) {
831         /* we generate a block containing just the instruction
832            modifying the memory. It will ensure that it cannot modify
833            itself */
834         env->current_tb = NULL;
835         tb_gen_code(env, current_pc, current_cs_base, current_flags, 
836                     CF_SINGLE_INSN);
837         cpu_resume_from_signal(env, puc);
838     }
839 #endif
840 }
841 #endif
842
843 /* add the tb in the target page and protect it if necessary */
844 static inline void tb_alloc_page(TranslationBlock *tb, 
845                                  unsigned int n, target_ulong page_addr)
846 {
847     PageDesc *p;
848     TranslationBlock *last_first_tb;
849
850     tb->page_addr[n] = page_addr;
851     p = page_find_alloc(page_addr >> TARGET_PAGE_BITS);
852     tb->page_next[n] = p->first_tb;
853     last_first_tb = p->first_tb;
854     p->first_tb = (TranslationBlock *)((long)tb | n);
855     invalidate_page_bitmap(p);
856
857 #if defined(TARGET_HAS_SMC) || 1
858
859 #if defined(CONFIG_USER_ONLY)
860     if (p->flags & PAGE_WRITE) {
861         target_ulong addr;
862         PageDesc *p2;
863         int prot;
864
865         /* force the host page as non writable (writes will have a
866            page fault + mprotect overhead) */
867         page_addr &= qemu_host_page_mask;
868         prot = 0;
869         for(addr = page_addr; addr < page_addr + qemu_host_page_size;
870             addr += TARGET_PAGE_SIZE) {
871
872             p2 = page_find (addr >> TARGET_PAGE_BITS);
873             if (!p2)
874                 continue;
875             prot |= p2->flags;
876             p2->flags &= ~PAGE_WRITE;
877             page_get_flags(addr);
878           }
879         mprotect(g2h(page_addr), qemu_host_page_size, 
880                  (prot & PAGE_BITS) & ~PAGE_WRITE);
881 #ifdef DEBUG_TB_INVALIDATE
882         printf("protecting code page: 0x%08lx\n", 
883                page_addr);
884 #endif
885     }
886 #else
887     /* if some code is already present, then the pages are already
888        protected. So we handle the case where only the first TB is
889        allocated in a physical page */
890     if (!last_first_tb) {
891         tlb_protect_code(page_addr);
892     }
893 #endif
894
895 #endif /* TARGET_HAS_SMC */
896 }
897
898 /* Allocate a new translation block. Flush the translation buffer if
899    too many translation blocks or too much generated code. */
900 TranslationBlock *tb_alloc(target_ulong pc)
901 {
902     TranslationBlock *tb;
903
904     if (nb_tbs >= CODE_GEN_MAX_BLOCKS || 
905         (code_gen_ptr - code_gen_buffer) >= CODE_GEN_BUFFER_MAX_SIZE)
906         return NULL;
907     tb = &tbs[nb_tbs++];
908     tb->pc = pc;
909     tb->cflags = 0;
910     return tb;
911 }
912
913 /* add a new TB and link it to the physical page tables. phys_page2 is
914    (-1) to indicate that only one page contains the TB. */
915 void tb_link_phys(TranslationBlock *tb, 
916                   target_ulong phys_pc, target_ulong phys_page2)
917 {
918     unsigned int h;
919     TranslationBlock **ptb;
920
921     /* add in the physical hash table */
922     h = tb_phys_hash_func(phys_pc);
923     ptb = &tb_phys_hash[h];
924     tb->phys_hash_next = *ptb;
925     *ptb = tb;
926
927     /* add in the page list */
928     tb_alloc_page(tb, 0, phys_pc & TARGET_PAGE_MASK);
929     if (phys_page2 != -1)
930         tb_alloc_page(tb, 1, phys_page2);
931     else
932         tb->page_addr[1] = -1;
933
934     tb->jmp_first = (TranslationBlock *)((long)tb | 2);
935     tb->jmp_next[0] = NULL;
936     tb->jmp_next[1] = NULL;
937 #ifdef USE_CODE_COPY
938     tb->cflags &= ~CF_FP_USED;
939     if (tb->cflags & CF_TB_FP_USED)
940         tb->cflags |= CF_FP_USED;
941 #endif
942
943     /* init original jump addresses */
944     if (tb->tb_next_offset[0] != 0xffff)
945         tb_reset_jump(tb, 0);
946     if (tb->tb_next_offset[1] != 0xffff)
947         tb_reset_jump(tb, 1);
948
949 #ifdef DEBUG_TB_CHECK
950     tb_page_check();
951 #endif
952 }
953
954 /* find the TB 'tb' such that tb[0].tc_ptr <= tc_ptr <
955    tb[1].tc_ptr. Return NULL if not found */
956 TranslationBlock *tb_find_pc(unsigned long tc_ptr)
957 {
958     int m_min, m_max, m;
959     unsigned long v;
960     TranslationBlock *tb;
961
962     if (nb_tbs <= 0)
963         return NULL;
964     if (tc_ptr < (unsigned long)code_gen_buffer ||
965         tc_ptr >= (unsigned long)code_gen_ptr)
966         return NULL;
967     /* binary search (cf Knuth) */
968     m_min = 0;
969     m_max = nb_tbs - 1;
970     while (m_min <= m_max) {
971         m = (m_min + m_max) >> 1;
972         tb = &tbs[m];
973         v = (unsigned long)tb->tc_ptr;
974         if (v == tc_ptr)
975             return tb;
976         else if (tc_ptr < v) {
977             m_max = m - 1;
978         } else {
979             m_min = m + 1;
980         }
981     } 
982     return &tbs[m_max];
983 }
984
985 static void tb_reset_jump_recursive(TranslationBlock *tb);
986
987 static inline void tb_reset_jump_recursive2(TranslationBlock *tb, int n)
988 {
989     TranslationBlock *tb1, *tb_next, **ptb;
990     unsigned int n1;
991
992     tb1 = tb->jmp_next[n];
993     if (tb1 != NULL) {
994         /* find head of list */
995         for(;;) {
996             n1 = (long)tb1 & 3;
997             tb1 = (TranslationBlock *)((long)tb1 & ~3);
998             if (n1 == 2)
999                 break;
1000             tb1 = tb1->jmp_next[n1];
1001         }
1002         /* we are now sure now that tb jumps to tb1 */
1003         tb_next = tb1;
1004
1005         /* remove tb from the jmp_first list */
1006         ptb = &tb_next->jmp_first;
1007         for(;;) {
1008             tb1 = *ptb;
1009             n1 = (long)tb1 & 3;
1010             tb1 = (TranslationBlock *)((long)tb1 & ~3);
1011             if (n1 == n && tb1 == tb)
1012                 break;
1013             ptb = &tb1->jmp_next[n1];
1014         }
1015         *ptb = tb->jmp_next[n];
1016         tb->jmp_next[n] = NULL;
1017         
1018         /* suppress the jump to next tb in generated code */
1019         tb_reset_jump(tb, n);
1020
1021         /* suppress jumps in the tb on which we could have jumped */
1022         tb_reset_jump_recursive(tb_next);
1023     }
1024 }
1025
1026 static void tb_reset_jump_recursive(TranslationBlock *tb)
1027 {
1028     tb_reset_jump_recursive2(tb, 0);
1029     tb_reset_jump_recursive2(tb, 1);
1030 }
1031
1032 #if defined(TARGET_HAS_ICE)
1033 static void breakpoint_invalidate(CPUState *env, target_ulong pc)
1034 {
1035     target_phys_addr_t addr;
1036     target_ulong pd;
1037     ram_addr_t ram_addr;
1038     PhysPageDesc *p;
1039
1040     addr = cpu_get_phys_page_debug(env, pc);
1041     p = phys_page_find(addr >> TARGET_PAGE_BITS);
1042     if (!p) {
1043         pd = IO_MEM_UNASSIGNED;
1044     } else {
1045         pd = p->phys_offset;
1046     }
1047     ram_addr = (pd & TARGET_PAGE_MASK) | (pc & ~TARGET_PAGE_MASK);
1048     tb_invalidate_phys_page_range(ram_addr, ram_addr + 1, 0);
1049 }
1050 #endif
1051
1052 /* Add a watchpoint.  */
1053 int  cpu_watchpoint_insert(CPUState *env, target_ulong addr)
1054 {
1055     int i;
1056
1057     for (i = 0; i < env->nb_watchpoints; i++) {
1058         if (addr == env->watchpoint[i].vaddr)
1059             return 0;
1060     }
1061     if (env->nb_watchpoints >= MAX_WATCHPOINTS)
1062         return -1;
1063
1064     i = env->nb_watchpoints++;
1065     env->watchpoint[i].vaddr = addr;
1066     tlb_flush_page(env, addr);
1067     /* FIXME: This flush is needed because of the hack to make memory ops
1068        terminate the TB.  It can be removed once the proper IO trap and
1069        re-execute bits are in.  */
1070     tb_flush(env);
1071     return i;
1072 }
1073
1074 /* Remove a watchpoint.  */
1075 int cpu_watchpoint_remove(CPUState *env, target_ulong addr)
1076 {
1077     int i;
1078
1079     for (i = 0; i < env->nb_watchpoints; i++) {
1080         if (addr == env->watchpoint[i].vaddr) {
1081             env->nb_watchpoints--;
1082             env->watchpoint[i] = env->watchpoint[env->nb_watchpoints];
1083             tlb_flush_page(env, addr);
1084             return 0;
1085         }
1086     }
1087     return -1;
1088 }
1089
1090 /* add a breakpoint. EXCP_DEBUG is returned by the CPU loop if a
1091    breakpoint is reached */
1092 int cpu_breakpoint_insert(CPUState *env, target_ulong pc)
1093 {
1094 #if defined(TARGET_HAS_ICE)
1095     int i;
1096     
1097     for(i = 0; i < env->nb_breakpoints; i++) {
1098         if (env->breakpoints[i] == pc)
1099             return 0;
1100     }
1101
1102     if (env->nb_breakpoints >= MAX_BREAKPOINTS)
1103         return -1;
1104     env->breakpoints[env->nb_breakpoints++] = pc;
1105     
1106     breakpoint_invalidate(env, pc);
1107     return 0;
1108 #else
1109     return -1;
1110 #endif
1111 }
1112
1113 /* remove a breakpoint */
1114 int cpu_breakpoint_remove(CPUState *env, target_ulong pc)
1115 {
1116 #if defined(TARGET_HAS_ICE)
1117     int i;
1118     for(i = 0; i < env->nb_breakpoints; i++) {
1119         if (env->breakpoints[i] == pc)
1120             goto found;
1121     }
1122     return -1;
1123  found:
1124     env->nb_breakpoints--;
1125     if (i < env->nb_breakpoints)
1126       env->breakpoints[i] = env->breakpoints[env->nb_breakpoints];
1127
1128     breakpoint_invalidate(env, pc);
1129     return 0;
1130 #else
1131     return -1;
1132 #endif
1133 }
1134
1135 /* enable or disable single step mode. EXCP_DEBUG is returned by the
1136    CPU loop after each instruction */
1137 void cpu_single_step(CPUState *env, int enabled)
1138 {
1139 #if defined(TARGET_HAS_ICE)
1140     if (env->singlestep_enabled != enabled) {
1141         env->singlestep_enabled = enabled;
1142         /* must flush all the translated code to avoid inconsistancies */
1143         /* XXX: only flush what is necessary */
1144         tb_flush(env);
1145     }
1146 #endif
1147 }
1148
1149 /* enable or disable low levels log */
1150 void cpu_set_log(int log_flags)
1151 {
1152     loglevel = log_flags;
1153     if (loglevel && !logfile) {
1154         logfile = fopen(logfilename, "w");
1155         if (!logfile) {
1156             perror(logfilename);
1157             _exit(1);
1158         }
1159 #if !defined(CONFIG_SOFTMMU)
1160         /* must avoid mmap() usage of glibc by setting a buffer "by hand" */
1161         {
1162             static uint8_t logfile_buf[4096];
1163             setvbuf(logfile, logfile_buf, _IOLBF, sizeof(logfile_buf));
1164         }
1165 #else
1166         setvbuf(logfile, NULL, _IOLBF, 0);
1167 #endif
1168     }
1169 }
1170
1171 void cpu_set_log_filename(const char *filename)
1172 {
1173     logfilename = strdup(filename);
1174 }
1175
1176 /* mask must never be zero, except for A20 change call */
1177 void cpu_interrupt(CPUState *env, int mask)
1178 {
1179     TranslationBlock *tb;
1180     static int interrupt_lock;
1181
1182     env->interrupt_request |= mask;
1183     /* if the cpu is currently executing code, we must unlink it and
1184        all the potentially executing TB */
1185     tb = env->current_tb;
1186     if (tb && !testandset(&interrupt_lock)) {
1187         env->current_tb = NULL;
1188         tb_reset_jump_recursive(tb);
1189         interrupt_lock = 0;
1190     }
1191 }
1192
1193 void cpu_reset_interrupt(CPUState *env, int mask)
1194 {
1195     env->interrupt_request &= ~mask;
1196 }
1197
1198 CPULogItem cpu_log_items[] = {
1199     { CPU_LOG_TB_OUT_ASM, "out_asm", 
1200       "show generated host assembly code for each compiled TB" },
1201     { CPU_LOG_TB_IN_ASM, "in_asm",
1202       "show target assembly code for each compiled TB" },
1203     { CPU_LOG_TB_OP, "op", 
1204       "show micro ops for each compiled TB (only usable if 'in_asm' used)" },
1205 #ifdef TARGET_I386
1206     { CPU_LOG_TB_OP_OPT, "op_opt",
1207       "show micro ops after optimization for each compiled TB" },
1208 #endif
1209     { CPU_LOG_INT, "int",
1210       "show interrupts/exceptions in short format" },
1211     { CPU_LOG_EXEC, "exec",
1212       "show trace before each executed TB (lots of logs)" },
1213     { CPU_LOG_TB_CPU, "cpu",
1214       "show CPU state before bloc translation" },
1215 #ifdef TARGET_I386
1216     { CPU_LOG_PCALL, "pcall",
1217       "show protected mode far calls/returns/exceptions" },
1218 #endif
1219 #ifdef DEBUG_IOPORT
1220     { CPU_LOG_IOPORT, "ioport",
1221       "show all i/o ports accesses" },
1222 #endif
1223     { 0, NULL, NULL },
1224 };
1225
1226 static int cmp1(const char *s1, int n, const char *s2)
1227 {
1228     if (strlen(s2) != n)
1229         return 0;
1230     return memcmp(s1, s2, n) == 0;
1231 }
1232       
1233 /* takes a comma separated list of log masks. Return 0 if error. */
1234 int cpu_str_to_log_mask(const char *str)
1235 {
1236     CPULogItem *item;
1237     int mask;
1238     const char *p, *p1;
1239
1240     p = str;
1241     mask = 0;
1242     for(;;) {
1243         p1 = strchr(p, ',');
1244         if (!p1)
1245             p1 = p + strlen(p);
1246         if(cmp1(p,p1-p,"all")) {
1247                 for(item = cpu_log_items; item->mask != 0; item++) {
1248                         mask |= item->mask;
1249                 }
1250         } else {
1251         for(item = cpu_log_items; item->mask != 0; item++) {
1252             if (cmp1(p, p1 - p, item->name))
1253                 goto found;
1254         }
1255         return 0;
1256         }
1257     found:
1258         mask |= item->mask;
1259         if (*p1 != ',')
1260             break;
1261         p = p1 + 1;
1262     }
1263     return mask;
1264 }
1265
1266 void cpu_abort(CPUState *env, const char *fmt, ...)
1267 {
1268     va_list ap;
1269
1270     va_start(ap, fmt);
1271     fprintf(stderr, "qemu: fatal: ");
1272     vfprintf(stderr, fmt, ap);
1273     fprintf(stderr, "\n");
1274 #ifdef TARGET_I386
1275     cpu_dump_state(env, stderr, fprintf, X86_DUMP_FPU | X86_DUMP_CCOP);
1276 #else
1277     cpu_dump_state(env, stderr, fprintf, 0);
1278 #endif
1279     va_end(ap);
1280     abort();
1281 }
1282
1283 CPUState *cpu_copy(CPUState *env)
1284 {
1285     CPUState *new_env = cpu_init();
1286     /* preserve chaining and index */
1287     CPUState *next_cpu = new_env->next_cpu;
1288     int cpu_index = new_env->cpu_index;
1289     memcpy(new_env, env, sizeof(CPUState));
1290     new_env->next_cpu = next_cpu;
1291     new_env->cpu_index = cpu_index;
1292     return new_env;
1293 }
1294
1295 #if !defined(CONFIG_USER_ONLY)
1296
1297 /* NOTE: if flush_global is true, also flush global entries (not
1298    implemented yet) */
1299 void tlb_flush(CPUState *env, int flush_global)
1300 {
1301     int i;
1302
1303 #if defined(DEBUG_TLB)
1304     printf("tlb_flush:\n");
1305 #endif
1306     /* must reset current TB so that interrupts cannot modify the
1307        links while we are modifying them */
1308     env->current_tb = NULL;
1309
1310     for(i = 0; i < CPU_TLB_SIZE; i++) {
1311         env->tlb_table[0][i].addr_read = -1;
1312         env->tlb_table[0][i].addr_write = -1;
1313         env->tlb_table[0][i].addr_code = -1;
1314         env->tlb_table[1][i].addr_read = -1;
1315         env->tlb_table[1][i].addr_write = -1;
1316         env->tlb_table[1][i].addr_code = -1;
1317 #if (NB_MMU_MODES >= 3)
1318         env->tlb_table[2][i].addr_read = -1;
1319         env->tlb_table[2][i].addr_write = -1;
1320         env->tlb_table[2][i].addr_code = -1;
1321 #if (NB_MMU_MODES == 4)
1322         env->tlb_table[3][i].addr_read = -1;
1323         env->tlb_table[3][i].addr_write = -1;
1324         env->tlb_table[3][i].addr_code = -1;
1325 #endif
1326 #endif
1327     }
1328
1329     memset (env->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof (void *));
1330
1331 #if !defined(CONFIG_SOFTMMU)
1332     munmap((void *)MMAP_AREA_START, MMAP_AREA_END - MMAP_AREA_START);
1333 #endif
1334 #ifdef USE_KQEMU
1335     if (env->kqemu_enabled) {
1336         kqemu_flush(env, flush_global);
1337     }
1338 #endif
1339     tlb_flush_count++;
1340 }
1341
1342 static inline void tlb_flush_entry(CPUTLBEntry *tlb_entry, target_ulong addr)
1343 {
1344     if (addr == (tlb_entry->addr_read & 
1345                  (TARGET_PAGE_MASK | TLB_INVALID_MASK)) ||
1346         addr == (tlb_entry->addr_write & 
1347                  (TARGET_PAGE_MASK | TLB_INVALID_MASK)) ||
1348         addr == (tlb_entry->addr_code & 
1349                  (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
1350         tlb_entry->addr_read = -1;
1351         tlb_entry->addr_write = -1;
1352         tlb_entry->addr_code = -1;
1353     }
1354 }
1355
1356 void tlb_flush_page(CPUState *env, target_ulong addr)
1357 {
1358     int i;
1359     TranslationBlock *tb;
1360
1361 #if defined(DEBUG_TLB)
1362     printf("tlb_flush_page: " TARGET_FMT_lx "\n", addr);
1363 #endif
1364     /* must reset current TB so that interrupts cannot modify the
1365        links while we are modifying them */
1366     env->current_tb = NULL;
1367
1368     addr &= TARGET_PAGE_MASK;
1369     i = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
1370     tlb_flush_entry(&env->tlb_table[0][i], addr);
1371     tlb_flush_entry(&env->tlb_table[1][i], addr);
1372 #if (NB_MMU_MODES >= 3)
1373     tlb_flush_entry(&env->tlb_table[2][i], addr);
1374 #if (NB_MMU_MODES == 4)
1375     tlb_flush_entry(&env->tlb_table[3][i], addr);
1376 #endif
1377 #endif
1378
1379     /* Discard jump cache entries for any tb which might potentially
1380        overlap the flushed page.  */
1381     i = tb_jmp_cache_hash_page(addr - TARGET_PAGE_SIZE);
1382     memset (&env->tb_jmp_cache[i], 0, TB_JMP_PAGE_SIZE * sizeof(tb));
1383
1384     i = tb_jmp_cache_hash_page(addr);
1385     memset (&env->tb_jmp_cache[i], 0, TB_JMP_PAGE_SIZE * sizeof(tb));
1386
1387 #if !defined(CONFIG_SOFTMMU)
1388     if (addr < MMAP_AREA_END)
1389         munmap((void *)addr, TARGET_PAGE_SIZE);
1390 #endif
1391 #ifdef USE_KQEMU
1392     if (env->kqemu_enabled) {
1393         kqemu_flush_page(env, addr);
1394     }
1395 #endif
1396 }
1397
1398 /* update the TLBs so that writes to code in the virtual page 'addr'
1399    can be detected */
1400 static void tlb_protect_code(ram_addr_t ram_addr)
1401 {
1402     cpu_physical_memory_reset_dirty(ram_addr, 
1403                                     ram_addr + TARGET_PAGE_SIZE,
1404                                     CODE_DIRTY_FLAG);
1405 }
1406
1407 /* update the TLB so that writes in physical page 'phys_addr' are no longer
1408    tested for self modifying code */
1409 static void tlb_unprotect_code_phys(CPUState *env, ram_addr_t ram_addr, 
1410                                     target_ulong vaddr)
1411 {
1412     phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] |= CODE_DIRTY_FLAG;
1413 }
1414
1415 static inline void tlb_reset_dirty_range(CPUTLBEntry *tlb_entry, 
1416                                          unsigned long start, unsigned long length)
1417 {
1418     unsigned long addr;
1419     if ((tlb_entry->addr_write & ~TARGET_PAGE_MASK) == IO_MEM_RAM) {
1420         addr = (tlb_entry->addr_write & TARGET_PAGE_MASK) + tlb_entry->addend;
1421         if ((addr - start) < length) {
1422             tlb_entry->addr_write = (tlb_entry->addr_write & TARGET_PAGE_MASK) | IO_MEM_NOTDIRTY;
1423         }
1424     }
1425 }
1426
1427 void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
1428                                      int dirty_flags)
1429 {
1430     CPUState *env;
1431     unsigned long length, start1;
1432     int i, mask, len;
1433     uint8_t *p;
1434
1435     start &= TARGET_PAGE_MASK;
1436     end = TARGET_PAGE_ALIGN(end);
1437
1438     length = end - start;
1439     if (length == 0)
1440         return;
1441     len = length >> TARGET_PAGE_BITS;
1442 #ifdef USE_KQEMU
1443     /* XXX: should not depend on cpu context */
1444     env = first_cpu;
1445     if (env->kqemu_enabled) {
1446         ram_addr_t addr;
1447         addr = start;
1448         for(i = 0; i < len; i++) {
1449             kqemu_set_notdirty(env, addr);
1450             addr += TARGET_PAGE_SIZE;
1451         }
1452     }
1453 #endif
1454     mask = ~dirty_flags;
1455     p = phys_ram_dirty + (start >> TARGET_PAGE_BITS);
1456     for(i = 0; i < len; i++)
1457         p[i] &= mask;
1458
1459     /* we modify the TLB cache so that the dirty bit will be set again
1460        when accessing the range */
1461     start1 = start + (unsigned long)phys_ram_base;
1462     for(env = first_cpu; env != NULL; env = env->next_cpu) {
1463         for(i = 0; i < CPU_TLB_SIZE; i++)
1464             tlb_reset_dirty_range(&env->tlb_table[0][i], start1, length);
1465         for(i = 0; i < CPU_TLB_SIZE; i++)
1466             tlb_reset_dirty_range(&env->tlb_table[1][i], start1, length);
1467 #if (NB_MMU_MODES >= 3)
1468         for(i = 0; i < CPU_TLB_SIZE; i++)
1469             tlb_reset_dirty_range(&env->tlb_table[2][i], start1, length);
1470 #if (NB_MMU_MODES == 4)
1471         for(i = 0; i < CPU_TLB_SIZE; i++)
1472             tlb_reset_dirty_range(&env->tlb_table[3][i], start1, length);
1473 #endif
1474 #endif
1475     }
1476
1477 #if !defined(CONFIG_SOFTMMU)
1478     /* XXX: this is expensive */
1479     {
1480         VirtPageDesc *p;
1481         int j;
1482         target_ulong addr;
1483
1484         for(i = 0; i < L1_SIZE; i++) {
1485             p = l1_virt_map[i];
1486             if (p) {
1487                 addr = i << (TARGET_PAGE_BITS + L2_BITS);
1488                 for(j = 0; j < L2_SIZE; j++) {
1489                     if (p->valid_tag == virt_valid_tag &&
1490                         p->phys_addr >= start && p->phys_addr < end &&
1491                         (p->prot & PROT_WRITE)) {
1492                         if (addr < MMAP_AREA_END) {
1493                             mprotect((void *)addr, TARGET_PAGE_SIZE, 
1494                                      p->prot & ~PROT_WRITE);
1495                         }
1496                     }
1497                     addr += TARGET_PAGE_SIZE;
1498                     p++;
1499                 }
1500             }
1501         }
1502     }
1503 #endif
1504 }
1505
1506 static inline void tlb_update_dirty(CPUTLBEntry *tlb_entry)
1507 {
1508     ram_addr_t ram_addr;
1509
1510     if ((tlb_entry->addr_write & ~TARGET_PAGE_MASK) == IO_MEM_RAM) {
1511         ram_addr = (tlb_entry->addr_write & TARGET_PAGE_MASK) + 
1512             tlb_entry->addend - (unsigned long)phys_ram_base;
1513         if (!cpu_physical_memory_is_dirty(ram_addr)) {
1514             tlb_entry->addr_write |= IO_MEM_NOTDIRTY;
1515         }
1516     }
1517 }
1518
1519 /* update the TLB according to the current state of the dirty bits */
1520 void cpu_tlb_update_dirty(CPUState *env)
1521 {
1522     int i;
1523     for(i = 0; i < CPU_TLB_SIZE; i++)
1524         tlb_update_dirty(&env->tlb_table[0][i]);
1525     for(i = 0; i < CPU_TLB_SIZE; i++)
1526         tlb_update_dirty(&env->tlb_table[1][i]);
1527 #if (NB_MMU_MODES >= 3)
1528     for(i = 0; i < CPU_TLB_SIZE; i++)
1529         tlb_update_dirty(&env->tlb_table[2][i]);
1530 #if (NB_MMU_MODES == 4)
1531     for(i = 0; i < CPU_TLB_SIZE; i++)
1532         tlb_update_dirty(&env->tlb_table[3][i]);
1533 #endif
1534 #endif
1535 }
1536
1537 static inline void tlb_set_dirty1(CPUTLBEntry *tlb_entry, 
1538                                   unsigned long start)
1539 {
1540     unsigned long addr;
1541     if ((tlb_entry->addr_write & ~TARGET_PAGE_MASK) == IO_MEM_NOTDIRTY) {
1542         addr = (tlb_entry->addr_write & TARGET_PAGE_MASK) + tlb_entry->addend;
1543         if (addr == start) {
1544             tlb_entry->addr_write = (tlb_entry->addr_write & TARGET_PAGE_MASK) | IO_MEM_RAM;
1545         }
1546     }
1547 }
1548
1549 /* update the TLB corresponding to virtual page vaddr and phys addr
1550    addr so that it is no longer dirty */
1551 static inline void tlb_set_dirty(CPUState *env,
1552                                  unsigned long addr, target_ulong vaddr)
1553 {
1554     int i;
1555
1556     addr &= TARGET_PAGE_MASK;
1557     i = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
1558     tlb_set_dirty1(&env->tlb_table[0][i], addr);
1559     tlb_set_dirty1(&env->tlb_table[1][i], addr);
1560 #if (NB_MMU_MODES >= 3)
1561     tlb_set_dirty1(&env->tlb_table[2][i], addr);
1562 #if (NB_MMU_MODES == 4)
1563     tlb_set_dirty1(&env->tlb_table[3][i], addr);
1564 #endif
1565 #endif
1566 }
1567
1568 /* add a new TLB entry. At most one entry for a given virtual address
1569    is permitted. Return 0 if OK or 2 if the page could not be mapped
1570    (can only happen in non SOFTMMU mode for I/O pages or pages
1571    conflicting with the host address space). */
1572 int tlb_set_page_exec(CPUState *env, target_ulong vaddr, 
1573                       target_phys_addr_t paddr, int prot, 
1574                       int is_user, int is_softmmu)
1575 {
1576     PhysPageDesc *p;
1577     unsigned long pd;
1578     unsigned int index;
1579     target_ulong address;
1580     target_phys_addr_t addend;
1581     int ret;
1582     CPUTLBEntry *te;
1583     int i;
1584
1585     p = phys_page_find(paddr >> TARGET_PAGE_BITS);
1586     if (!p) {
1587         pd = IO_MEM_UNASSIGNED;
1588     } else {
1589         pd = p->phys_offset;
1590     }
1591 #if defined(DEBUG_TLB)
1592     printf("tlb_set_page: vaddr=" TARGET_FMT_lx " paddr=0x%08x prot=%x u=%d smmu=%d pd=0x%08lx\n",
1593            vaddr, (int)paddr, prot, is_user, is_softmmu, pd);
1594 #endif
1595
1596     ret = 0;
1597 #if !defined(CONFIG_SOFTMMU)
1598     if (is_softmmu) 
1599 #endif
1600     {
1601         if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) {
1602             /* IO memory case */
1603             address = vaddr | pd;
1604             addend = paddr;
1605         } else {
1606             /* standard memory */
1607             address = vaddr;
1608             addend = (unsigned long)phys_ram_base + (pd & TARGET_PAGE_MASK);
1609         }
1610
1611         /* Make accesses to pages with watchpoints go via the
1612            watchpoint trap routines.  */
1613         for (i = 0; i < env->nb_watchpoints; i++) {
1614             if (vaddr == (env->watchpoint[i].vaddr & TARGET_PAGE_MASK)) {
1615                 if (address & ~TARGET_PAGE_MASK) {
1616                     env->watchpoint[i].is_ram = 0;
1617                     address = vaddr | io_mem_watch;
1618                 } else {
1619                     env->watchpoint[i].is_ram = 1;
1620                     /* TODO: Figure out how to make read watchpoints coexist
1621                        with code.  */
1622                     pd = (pd & TARGET_PAGE_MASK) | io_mem_watch | IO_MEM_ROMD;
1623                 }
1624             }
1625         }
1626         
1627         index = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
1628         addend -= vaddr;
1629         te = &env->tlb_table[is_user][index];
1630         te->addend = addend;
1631         if (prot & PAGE_READ) {
1632             te->addr_read = address;
1633         } else {
1634             te->addr_read = -1;
1635         }
1636         if (prot & PAGE_EXEC) {
1637             te->addr_code = address;
1638         } else {
1639             te->addr_code = -1;
1640         }
1641         if (prot & PAGE_WRITE) {
1642             if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_ROM || 
1643                 (pd & IO_MEM_ROMD)) {
1644                 /* write access calls the I/O callback */
1645                 te->addr_write = vaddr | 
1646                     (pd & ~(TARGET_PAGE_MASK | IO_MEM_ROMD));
1647             } else if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_RAM && 
1648                        !cpu_physical_memory_is_dirty(pd)) {
1649                 te->addr_write = vaddr | IO_MEM_NOTDIRTY;
1650             } else {
1651                 te->addr_write = address;
1652             }
1653         } else {
1654             te->addr_write = -1;
1655         }
1656     }
1657 #if !defined(CONFIG_SOFTMMU)
1658     else {
1659         if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM) {
1660             /* IO access: no mapping is done as it will be handled by the
1661                soft MMU */
1662             if (!(env->hflags & HF_SOFTMMU_MASK))
1663                 ret = 2;
1664         } else {
1665             void *map_addr;
1666
1667             if (vaddr >= MMAP_AREA_END) {
1668                 ret = 2;
1669             } else {
1670                 if (prot & PROT_WRITE) {
1671                     if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_ROM || 
1672 #if defined(TARGET_HAS_SMC) || 1
1673                         first_tb ||
1674 #endif
1675                         ((pd & ~TARGET_PAGE_MASK) == IO_MEM_RAM && 
1676                          !cpu_physical_memory_is_dirty(pd))) {
1677                         /* ROM: we do as if code was inside */
1678                         /* if code is present, we only map as read only and save the
1679                            original mapping */
1680                         VirtPageDesc *vp;
1681                         
1682                         vp = virt_page_find_alloc(vaddr >> TARGET_PAGE_BITS, 1);
1683                         vp->phys_addr = pd;
1684                         vp->prot = prot;
1685                         vp->valid_tag = virt_valid_tag;
1686                         prot &= ~PAGE_WRITE;
1687                     }
1688                 }
1689                 map_addr = mmap((void *)vaddr, TARGET_PAGE_SIZE, prot, 
1690                                 MAP_SHARED | MAP_FIXED, phys_ram_fd, (pd & TARGET_PAGE_MASK));
1691                 if (map_addr == MAP_FAILED) {
1692                     cpu_abort(env, "mmap failed when mapped physical address 0x%08x to virtual address 0x%08x\n",
1693                               paddr, vaddr);
1694                 }
1695             }
1696         }
1697     }
1698 #endif
1699     return ret;
1700 }
1701
1702 /* called from signal handler: invalidate the code and unprotect the
1703    page. Return TRUE if the fault was succesfully handled. */
1704 int page_unprotect(target_ulong addr, unsigned long pc, void *puc)
1705 {
1706 #if !defined(CONFIG_SOFTMMU)
1707     VirtPageDesc *vp;
1708
1709 #if defined(DEBUG_TLB)
1710     printf("page_unprotect: addr=0x%08x\n", addr);
1711 #endif
1712     addr &= TARGET_PAGE_MASK;
1713
1714     /* if it is not mapped, no need to worry here */
1715     if (addr >= MMAP_AREA_END)
1716         return 0;
1717     vp = virt_page_find(addr >> TARGET_PAGE_BITS);
1718     if (!vp)
1719         return 0;
1720     /* NOTE: in this case, validate_tag is _not_ tested as it
1721        validates only the code TLB */
1722     if (vp->valid_tag != virt_valid_tag)
1723         return 0;
1724     if (!(vp->prot & PAGE_WRITE))
1725         return 0;
1726 #if defined(DEBUG_TLB)
1727     printf("page_unprotect: addr=0x%08x phys_addr=0x%08x prot=%x\n", 
1728            addr, vp->phys_addr, vp->prot);
1729 #endif
1730     if (mprotect((void *)addr, TARGET_PAGE_SIZE, vp->prot) < 0)
1731         cpu_abort(cpu_single_env, "error mprotect addr=0x%lx prot=%d\n",
1732                   (unsigned long)addr, vp->prot);
1733     /* set the dirty bit */
1734     phys_ram_dirty[vp->phys_addr >> TARGET_PAGE_BITS] = 0xff;
1735     /* flush the code inside */
1736     tb_invalidate_phys_page(vp->phys_addr, pc, puc);
1737     return 1;
1738 #else
1739     return 0;
1740 #endif
1741 }
1742
1743 #else
1744
1745 void tlb_flush(CPUState *env, int flush_global)
1746 {
1747 }
1748
1749 void tlb_flush_page(CPUState *env, target_ulong addr)
1750 {
1751 }
1752
1753 int tlb_set_page_exec(CPUState *env, target_ulong vaddr, 
1754                       target_phys_addr_t paddr, int prot, 
1755                       int is_user, int is_softmmu)
1756 {
1757     return 0;
1758 }
1759
1760 /* dump memory mappings */
1761 void page_dump(FILE *f)
1762 {
1763     unsigned long start, end;
1764     int i, j, prot, prot1;
1765     PageDesc *p;
1766
1767     fprintf(f, "%-8s %-8s %-8s %s\n",
1768             "start", "end", "size", "prot");
1769     start = -1;
1770     end = -1;
1771     prot = 0;
1772     for(i = 0; i <= L1_SIZE; i++) {
1773         if (i < L1_SIZE)
1774             p = l1_map[i];
1775         else
1776             p = NULL;
1777         for(j = 0;j < L2_SIZE; j++) {
1778             if (!p)
1779                 prot1 = 0;
1780             else
1781                 prot1 = p[j].flags;
1782             if (prot1 != prot) {
1783                 end = (i << (32 - L1_BITS)) | (j << TARGET_PAGE_BITS);
1784                 if (start != -1) {
1785                     fprintf(f, "%08lx-%08lx %08lx %c%c%c\n",
1786                             start, end, end - start, 
1787                             prot & PAGE_READ ? 'r' : '-',
1788                             prot & PAGE_WRITE ? 'w' : '-',
1789                             prot & PAGE_EXEC ? 'x' : '-');
1790                 }
1791                 if (prot1 != 0)
1792                     start = end;
1793                 else
1794                     start = -1;
1795                 prot = prot1;
1796             }
1797             if (!p)
1798                 break;
1799         }
1800     }
1801 }
1802
1803 int page_get_flags(target_ulong address)
1804 {
1805     PageDesc *p;
1806
1807     p = page_find(address >> TARGET_PAGE_BITS);
1808     if (!p)
1809         return 0;
1810     return p->flags;
1811 }
1812
1813 /* modify the flags of a page and invalidate the code if
1814    necessary. The flag PAGE_WRITE_ORG is positionned automatically
1815    depending on PAGE_WRITE */
1816 void page_set_flags(target_ulong start, target_ulong end, int flags)
1817 {
1818     PageDesc *p;
1819     target_ulong addr;
1820
1821     start = start & TARGET_PAGE_MASK;
1822     end = TARGET_PAGE_ALIGN(end);
1823     if (flags & PAGE_WRITE)
1824         flags |= PAGE_WRITE_ORG;
1825     spin_lock(&tb_lock);
1826     for(addr = start; addr < end; addr += TARGET_PAGE_SIZE) {
1827         p = page_find_alloc(addr >> TARGET_PAGE_BITS);
1828         /* if the write protection is set, then we invalidate the code
1829            inside */
1830         if (!(p->flags & PAGE_WRITE) && 
1831             (flags & PAGE_WRITE) &&
1832             p->first_tb) {
1833             tb_invalidate_phys_page(addr, 0, NULL);
1834         }
1835         p->flags = flags;
1836     }
1837     spin_unlock(&tb_lock);
1838 }
1839
1840 /* called from signal handler: invalidate the code and unprotect the
1841    page. Return TRUE if the fault was succesfully handled. */
1842 int page_unprotect(target_ulong address, unsigned long pc, void *puc)
1843 {
1844     unsigned int page_index, prot, pindex;
1845     PageDesc *p, *p1;
1846     target_ulong host_start, host_end, addr;
1847
1848     host_start = address & qemu_host_page_mask;
1849     page_index = host_start >> TARGET_PAGE_BITS;
1850     p1 = page_find(page_index);
1851     if (!p1)
1852         return 0;
1853     host_end = host_start + qemu_host_page_size;
1854     p = p1;
1855     prot = 0;
1856     for(addr = host_start;addr < host_end; addr += TARGET_PAGE_SIZE) {
1857         prot |= p->flags;
1858         p++;
1859     }
1860     /* if the page was really writable, then we change its
1861        protection back to writable */
1862     if (prot & PAGE_WRITE_ORG) {
1863         pindex = (address - host_start) >> TARGET_PAGE_BITS;
1864         if (!(p1[pindex].flags & PAGE_WRITE)) {
1865             mprotect((void *)g2h(host_start), qemu_host_page_size, 
1866                      (prot & PAGE_BITS) | PAGE_WRITE);
1867             p1[pindex].flags |= PAGE_WRITE;
1868             /* and since the content will be modified, we must invalidate
1869                the corresponding translated code. */
1870             tb_invalidate_phys_page(address, pc, puc);
1871 #ifdef DEBUG_TB_CHECK
1872             tb_invalidate_check(address);
1873 #endif
1874             return 1;
1875         }
1876     }
1877     return 0;
1878 }
1879
1880 /* call this function when system calls directly modify a memory area */
1881 /* ??? This should be redundant now we have lock_user.  */
1882 void page_unprotect_range(target_ulong data, target_ulong data_size)
1883 {
1884     target_ulong start, end, addr;
1885
1886     start = data;
1887     end = start + data_size;
1888     start &= TARGET_PAGE_MASK;
1889     end = TARGET_PAGE_ALIGN(end);
1890     for(addr = start; addr < end; addr += TARGET_PAGE_SIZE) {
1891         page_unprotect(addr, 0, NULL);
1892     }
1893 }
1894
1895 static inline void tlb_set_dirty(CPUState *env,
1896                                  unsigned long addr, target_ulong vaddr)
1897 {
1898 }
1899 #endif /* defined(CONFIG_USER_ONLY) */
1900
1901 /* register physical memory. 'size' must be a multiple of the target
1902    page size. If (phys_offset & ~TARGET_PAGE_MASK) != 0, then it is an
1903    io memory page */
1904 void cpu_register_physical_memory(target_phys_addr_t start_addr, 
1905                                   unsigned long size,
1906                                   unsigned long phys_offset)
1907 {
1908     target_phys_addr_t addr, end_addr;
1909     PhysPageDesc *p;
1910     CPUState *env;
1911
1912     size = (size + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK;
1913     end_addr = start_addr + size;
1914     for(addr = start_addr; addr != end_addr; addr += TARGET_PAGE_SIZE) {
1915         p = phys_page_find_alloc(addr >> TARGET_PAGE_BITS, 1);
1916         p->phys_offset = phys_offset;
1917         if ((phys_offset & ~TARGET_PAGE_MASK) <= IO_MEM_ROM ||
1918             (phys_offset & IO_MEM_ROMD))
1919             phys_offset += TARGET_PAGE_SIZE;
1920     }
1921     
1922     /* since each CPU stores ram addresses in its TLB cache, we must
1923        reset the modified entries */
1924     /* XXX: slow ! */
1925     for(env = first_cpu; env != NULL; env = env->next_cpu) {
1926         tlb_flush(env, 1);
1927     }
1928 }
1929
1930 /* XXX: temporary until new memory mapping API */
1931 uint32_t cpu_get_physical_page_desc(target_phys_addr_t addr)
1932 {
1933     PhysPageDesc *p;
1934
1935     p = phys_page_find(addr >> TARGET_PAGE_BITS);
1936     if (!p)
1937         return IO_MEM_UNASSIGNED;
1938     return p->phys_offset;
1939 }
1940
1941 /* XXX: better than nothing */
1942 ram_addr_t qemu_ram_alloc(unsigned int size)
1943 {
1944     ram_addr_t addr;
1945     if ((phys_ram_alloc_offset + size) >= phys_ram_size) {
1946         fprintf(stderr, "Not enough memory (requested_size = %u, max memory = %d)\n", 
1947                 size, phys_ram_size);
1948         abort();
1949     }
1950     addr = phys_ram_alloc_offset;
1951     phys_ram_alloc_offset = TARGET_PAGE_ALIGN(phys_ram_alloc_offset + size);
1952     return addr;
1953 }
1954
1955 void qemu_ram_free(ram_addr_t addr)
1956 {
1957 }
1958
1959 static uint32_t unassigned_mem_readb(void *opaque, target_phys_addr_t addr)
1960 {
1961 #ifdef DEBUG_UNASSIGNED
1962     printf("Unassigned mem read " TARGET_FMT_lx "\n", addr);
1963 #endif
1964 #ifdef TARGET_SPARC
1965     do_unassigned_access(addr, 0, 0, 0);
1966 #endif
1967     return 0;
1968 }
1969
1970 static void unassigned_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
1971 {
1972 #ifdef DEBUG_UNASSIGNED
1973     printf("Unassigned mem write " TARGET_FMT_lx " = 0x%x\n", addr, val);
1974 #endif
1975 #ifdef TARGET_SPARC
1976     do_unassigned_access(addr, 1, 0, 0);
1977 #endif
1978 }
1979
1980 static CPUReadMemoryFunc *unassigned_mem_read[3] = {
1981     unassigned_mem_readb,
1982     unassigned_mem_readb,
1983     unassigned_mem_readb,
1984 };
1985
1986 static CPUWriteMemoryFunc *unassigned_mem_write[3] = {
1987     unassigned_mem_writeb,
1988     unassigned_mem_writeb,
1989     unassigned_mem_writeb,
1990 };
1991
1992 static void notdirty_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
1993 {
1994     unsigned long ram_addr;
1995     int dirty_flags;
1996     ram_addr = addr - (unsigned long)phys_ram_base;
1997     dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
1998     if (!(dirty_flags & CODE_DIRTY_FLAG)) {
1999 #if !defined(CONFIG_USER_ONLY)
2000         tb_invalidate_phys_page_fast(ram_addr, 1);
2001         dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
2002 #endif
2003     }
2004     stb_p((uint8_t *)(long)addr, val);
2005 #ifdef USE_KQEMU
2006     if (cpu_single_env->kqemu_enabled &&
2007         (dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK)
2008         kqemu_modify_page(cpu_single_env, ram_addr);
2009 #endif
2010     dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
2011     phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags;
2012     /* we remove the notdirty callback only if the code has been
2013        flushed */
2014     if (dirty_flags == 0xff)
2015         tlb_set_dirty(cpu_single_env, addr, cpu_single_env->mem_write_vaddr);
2016 }
2017
2018 static void notdirty_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
2019 {
2020     unsigned long ram_addr;
2021     int dirty_flags;
2022     ram_addr = addr - (unsigned long)phys_ram_base;
2023     dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
2024     if (!(dirty_flags & CODE_DIRTY_FLAG)) {
2025 #if !defined(CONFIG_USER_ONLY)
2026         tb_invalidate_phys_page_fast(ram_addr, 2);
2027         dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
2028 #endif
2029     }
2030     stw_p((uint8_t *)(long)addr, val);
2031 #ifdef USE_KQEMU
2032     if (cpu_single_env->kqemu_enabled &&
2033         (dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK)
2034         kqemu_modify_page(cpu_single_env, ram_addr);
2035 #endif
2036     dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
2037     phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags;
2038     /* we remove the notdirty callback only if the code has been
2039        flushed */
2040     if (dirty_flags == 0xff)
2041         tlb_set_dirty(cpu_single_env, addr, cpu_single_env->mem_write_vaddr);
2042 }
2043
2044 static void notdirty_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
2045 {
2046     unsigned long ram_addr;
2047     int dirty_flags;
2048     ram_addr = addr - (unsigned long)phys_ram_base;
2049     dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
2050     if (!(dirty_flags & CODE_DIRTY_FLAG)) {
2051 #if !defined(CONFIG_USER_ONLY)
2052         tb_invalidate_phys_page_fast(ram_addr, 4);
2053         dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
2054 #endif
2055     }
2056     stl_p((uint8_t *)(long)addr, val);
2057 #ifdef USE_KQEMU
2058     if (cpu_single_env->kqemu_enabled &&
2059         (dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK)
2060         kqemu_modify_page(cpu_single_env, ram_addr);
2061 #endif
2062     dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
2063     phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags;
2064     /* we remove the notdirty callback only if the code has been
2065        flushed */
2066     if (dirty_flags == 0xff)
2067         tlb_set_dirty(cpu_single_env, addr, cpu_single_env->mem_write_vaddr);
2068 }
2069
2070 static CPUReadMemoryFunc *error_mem_read[3] = {
2071     NULL, /* never used */
2072     NULL, /* never used */
2073     NULL, /* never used */
2074 };
2075
2076 static CPUWriteMemoryFunc *notdirty_mem_write[3] = {
2077     notdirty_mem_writeb,
2078     notdirty_mem_writew,
2079     notdirty_mem_writel,
2080 };
2081
2082 #if defined(CONFIG_SOFTMMU)
2083 /* Watchpoint access routines.  Watchpoints are inserted using TLB tricks,
2084    so these check for a hit then pass through to the normal out-of-line
2085    phys routines.  */
2086 static uint32_t watch_mem_readb(void *opaque, target_phys_addr_t addr)
2087 {
2088     return ldub_phys(addr);
2089 }
2090
2091 static uint32_t watch_mem_readw(void *opaque, target_phys_addr_t addr)
2092 {
2093     return lduw_phys(addr);
2094 }
2095
2096 static uint32_t watch_mem_readl(void *opaque, target_phys_addr_t addr)
2097 {
2098     return ldl_phys(addr);
2099 }
2100
2101 /* Generate a debug exception if a watchpoint has been hit.
2102    Returns the real physical address of the access.  addr will be a host
2103    address in the is_ram case.  */
2104 static target_ulong check_watchpoint(target_phys_addr_t addr)
2105 {
2106     CPUState *env = cpu_single_env;
2107     target_ulong watch;
2108     target_ulong retaddr;
2109     int i;
2110
2111     retaddr = addr;
2112     for (i = 0; i < env->nb_watchpoints; i++) {
2113         watch = env->watchpoint[i].vaddr;
2114         if (((env->mem_write_vaddr ^ watch) & TARGET_PAGE_MASK) == 0) {
2115             if (env->watchpoint[i].is_ram)
2116                 retaddr = addr - (unsigned long)phys_ram_base;
2117             if (((addr ^ watch) & ~TARGET_PAGE_MASK) == 0) {
2118                 cpu_single_env->watchpoint_hit = i + 1;
2119                 cpu_interrupt(cpu_single_env, CPU_INTERRUPT_DEBUG);
2120                 break;
2121             }
2122         }
2123     }
2124     return retaddr;
2125 }
2126
2127 static void watch_mem_writeb(void *opaque, target_phys_addr_t addr,
2128                              uint32_t val)
2129 {
2130     addr = check_watchpoint(addr);
2131     stb_phys(addr, val);
2132 }
2133
2134 static void watch_mem_writew(void *opaque, target_phys_addr_t addr,
2135                              uint32_t val)
2136 {
2137     addr = check_watchpoint(addr);
2138     stw_phys(addr, val);
2139 }
2140
2141 static void watch_mem_writel(void *opaque, target_phys_addr_t addr,
2142                              uint32_t val)
2143 {
2144     addr = check_watchpoint(addr);
2145     stl_phys(addr, val);
2146 }
2147
2148 static CPUReadMemoryFunc *watch_mem_read[3] = {
2149     watch_mem_readb,
2150     watch_mem_readw,
2151     watch_mem_readl,
2152 };
2153
2154 static CPUWriteMemoryFunc *watch_mem_write[3] = {
2155     watch_mem_writeb,
2156     watch_mem_writew,
2157     watch_mem_writel,
2158 };
2159 #endif
2160
2161 static void io_mem_init(void)
2162 {
2163     cpu_register_io_memory(IO_MEM_ROM >> IO_MEM_SHIFT, error_mem_read, unassigned_mem_write, NULL);
2164     cpu_register_io_memory(IO_MEM_UNASSIGNED >> IO_MEM_SHIFT, unassigned_mem_read, unassigned_mem_write, NULL);
2165     cpu_register_io_memory(IO_MEM_NOTDIRTY >> IO_MEM_SHIFT, error_mem_read, notdirty_mem_write, NULL);
2166     io_mem_nb = 5;
2167
2168 #if defined(CONFIG_SOFTMMU)
2169     io_mem_watch = cpu_register_io_memory(-1, watch_mem_read,
2170                                           watch_mem_write, NULL);
2171 #endif
2172     /* alloc dirty bits array */
2173     phys_ram_dirty = qemu_vmalloc(phys_ram_size >> TARGET_PAGE_BITS);
2174     memset(phys_ram_dirty, 0xff, phys_ram_size >> TARGET_PAGE_BITS);
2175 }
2176
2177 /* mem_read and mem_write are arrays of functions containing the
2178    function to access byte (index 0), word (index 1) and dword (index
2179    2). All functions must be supplied. If io_index is non zero, the
2180    corresponding io zone is modified. If it is zero, a new io zone is
2181    allocated. The return value can be used with
2182    cpu_register_physical_memory(). (-1) is returned if error. */
2183 int cpu_register_io_memory(int io_index,
2184                            CPUReadMemoryFunc **mem_read,
2185                            CPUWriteMemoryFunc **mem_write,
2186                            void *opaque)
2187 {
2188     int i;
2189
2190     if (io_index <= 0) {
2191         if (io_mem_nb >= IO_MEM_NB_ENTRIES)
2192             return -1;
2193         io_index = io_mem_nb++;
2194     } else {
2195         if (io_index >= IO_MEM_NB_ENTRIES)
2196             return -1;
2197     }
2198
2199     for(i = 0;i < 3; i++) {
2200         io_mem_read[io_index][i] = mem_read[i];
2201         io_mem_write[io_index][i] = mem_write[i];
2202     }
2203     io_mem_opaque[io_index] = opaque;
2204     return io_index << IO_MEM_SHIFT;
2205 }
2206
2207 CPUWriteMemoryFunc **cpu_get_io_memory_write(int io_index)
2208 {
2209     return io_mem_write[io_index >> IO_MEM_SHIFT];
2210 }
2211
2212 CPUReadMemoryFunc **cpu_get_io_memory_read(int io_index)
2213 {
2214     return io_mem_read[io_index >> IO_MEM_SHIFT];
2215 }
2216
2217 /* physical memory access (slow version, mainly for debug) */
2218 #if defined(CONFIG_USER_ONLY)
2219 void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, 
2220                             int len, int is_write)
2221 {
2222     int l, flags;
2223     target_ulong page;
2224     void * p;
2225
2226     while (len > 0) {
2227         page = addr & TARGET_PAGE_MASK;
2228         l = (page + TARGET_PAGE_SIZE) - addr;
2229         if (l > len)
2230             l = len;
2231         flags = page_get_flags(page);
2232         if (!(flags & PAGE_VALID))
2233             return;
2234         if (is_write) {
2235             if (!(flags & PAGE_WRITE))
2236                 return;
2237             p = lock_user(addr, len, 0);
2238             memcpy(p, buf, len);
2239             unlock_user(p, addr, len);
2240         } else {
2241             if (!(flags & PAGE_READ))
2242                 return;
2243             p = lock_user(addr, len, 1);
2244             memcpy(buf, p, len);
2245             unlock_user(p, addr, 0);
2246         }
2247         len -= l;
2248         buf += l;
2249         addr += l;
2250     }
2251 }
2252
2253 #else
2254 void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, 
2255                             int len, int is_write)
2256 {
2257     int l, io_index;
2258     uint8_t *ptr;
2259     uint32_t val;
2260     target_phys_addr_t page;
2261     unsigned long pd;
2262     PhysPageDesc *p;
2263     
2264     while (len > 0) {
2265         page = addr & TARGET_PAGE_MASK;
2266         l = (page + TARGET_PAGE_SIZE) - addr;
2267         if (l > len)
2268             l = len;
2269         p = phys_page_find(page >> TARGET_PAGE_BITS);
2270         if (!p) {
2271             pd = IO_MEM_UNASSIGNED;
2272         } else {
2273             pd = p->phys_offset;
2274         }
2275         
2276         if (is_write) {
2277             if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) {
2278                 io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
2279                 /* XXX: could force cpu_single_env to NULL to avoid
2280                    potential bugs */
2281                 if (l >= 4 && ((addr & 3) == 0)) {
2282                     /* 32 bit write access */
2283                     val = ldl_p(buf);
2284                     io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val);
2285                     l = 4;
2286                 } else if (l >= 2 && ((addr & 1) == 0)) {
2287                     /* 16 bit write access */
2288                     val = lduw_p(buf);
2289                     io_mem_write[io_index][1](io_mem_opaque[io_index], addr, val);
2290                     l = 2;
2291                 } else {
2292                     /* 8 bit write access */
2293                     val = ldub_p(buf);
2294                     io_mem_write[io_index][0](io_mem_opaque[io_index], addr, val);
2295                     l = 1;
2296                 }
2297             } else {
2298                 unsigned long addr1;
2299                 addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
2300                 /* RAM case */
2301                 ptr = phys_ram_base + addr1;
2302                 memcpy(ptr, buf, l);
2303                 if (!cpu_physical_memory_is_dirty(addr1)) {
2304                     /* invalidate code */
2305                     tb_invalidate_phys_page_range(addr1, addr1 + l, 0);
2306                     /* set dirty bit */
2307                     phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] |= 
2308                         (0xff & ~CODE_DIRTY_FLAG);
2309                 }
2310             }
2311         } else {
2312             if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && 
2313                 !(pd & IO_MEM_ROMD)) {
2314                 /* I/O case */
2315                 io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
2316                 if (l >= 4 && ((addr & 3) == 0)) {
2317                     /* 32 bit read access */
2318                     val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr);
2319                     stl_p(buf, val);
2320                     l = 4;
2321                 } else if (l >= 2 && ((addr & 1) == 0)) {
2322                     /* 16 bit read access */
2323                     val = io_mem_read[io_index][1](io_mem_opaque[io_index], addr);
2324                     stw_p(buf, val);
2325                     l = 2;
2326                 } else {
2327                     /* 8 bit read access */
2328                     val = io_mem_read[io_index][0](io_mem_opaque[io_index], addr);
2329                     stb_p(buf, val);
2330                     l = 1;
2331                 }
2332             } else {
2333                 /* RAM case */
2334                 ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) + 
2335                     (addr & ~TARGET_PAGE_MASK);
2336                 memcpy(buf, ptr, l);
2337             }
2338         }
2339         len -= l;
2340         buf += l;
2341         addr += l;
2342     }
2343 }
2344
2345 /* used for ROM loading : can write in RAM and ROM */
2346 void cpu_physical_memory_write_rom(target_phys_addr_t addr, 
2347                                    const uint8_t *buf, int len)
2348 {
2349     int l;
2350     uint8_t *ptr;
2351     target_phys_addr_t page;
2352     unsigned long pd;
2353     PhysPageDesc *p;
2354     
2355     while (len > 0) {
2356         page = addr & TARGET_PAGE_MASK;
2357         l = (page + TARGET_PAGE_SIZE) - addr;
2358         if (l > len)
2359             l = len;
2360         p = phys_page_find(page >> TARGET_PAGE_BITS);
2361         if (!p) {
2362             pd = IO_MEM_UNASSIGNED;
2363         } else {
2364             pd = p->phys_offset;
2365         }
2366         
2367         if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM &&
2368             (pd & ~TARGET_PAGE_MASK) != IO_MEM_ROM &&
2369             !(pd & IO_MEM_ROMD)) {
2370             /* do nothing */
2371         } else {
2372             unsigned long addr1;
2373             addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
2374             /* ROM/RAM case */
2375             ptr = phys_ram_base + addr1;
2376             memcpy(ptr, buf, l);
2377         }
2378         len -= l;
2379         buf += l;
2380         addr += l;
2381     }
2382 }
2383
2384
2385 /* warning: addr must be aligned */
2386 uint32_t ldl_phys(target_phys_addr_t addr)
2387 {
2388     int io_index;
2389     uint8_t *ptr;
2390     uint32_t val;
2391     unsigned long pd;
2392     PhysPageDesc *p;
2393
2394     p = phys_page_find(addr >> TARGET_PAGE_BITS);
2395     if (!p) {
2396         pd = IO_MEM_UNASSIGNED;
2397     } else {
2398         pd = p->phys_offset;
2399     }
2400         
2401     if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && 
2402         !(pd & IO_MEM_ROMD)) {
2403         /* I/O case */
2404         io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
2405         val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr);
2406     } else {
2407         /* RAM case */
2408         ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) + 
2409             (addr & ~TARGET_PAGE_MASK);
2410         val = ldl_p(ptr);
2411     }
2412     return val;
2413 }
2414
2415 /* warning: addr must be aligned */
2416 uint64_t ldq_phys(target_phys_addr_t addr)
2417 {
2418     int io_index;
2419     uint8_t *ptr;
2420     uint64_t val;
2421     unsigned long pd;
2422     PhysPageDesc *p;
2423
2424     p = phys_page_find(addr >> TARGET_PAGE_BITS);
2425     if (!p) {
2426         pd = IO_MEM_UNASSIGNED;
2427     } else {
2428         pd = p->phys_offset;
2429     }
2430         
2431     if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM &&
2432         !(pd & IO_MEM_ROMD)) {
2433         /* I/O case */
2434         io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
2435 #ifdef TARGET_WORDS_BIGENDIAN
2436         val = (uint64_t)io_mem_read[io_index][2](io_mem_opaque[io_index], addr) << 32;
2437         val |= io_mem_read[io_index][2](io_mem_opaque[io_index], addr + 4);
2438 #else
2439         val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr);
2440         val |= (uint64_t)io_mem_read[io_index][2](io_mem_opaque[io_index], addr + 4) << 32;
2441 #endif
2442     } else {
2443         /* RAM case */
2444         ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) + 
2445             (addr & ~TARGET_PAGE_MASK);
2446         val = ldq_p(ptr);
2447     }
2448     return val;
2449 }
2450
2451 /* XXX: optimize */
2452 uint32_t ldub_phys(target_phys_addr_t addr)
2453 {
2454     uint8_t val;
2455     cpu_physical_memory_read(addr, &val, 1);
2456     return val;
2457 }
2458
2459 /* XXX: optimize */
2460 uint32_t lduw_phys(target_phys_addr_t addr)
2461 {
2462     uint16_t val;
2463     cpu_physical_memory_read(addr, (uint8_t *)&val, 2);
2464     return tswap16(val);
2465 }
2466
2467 /* warning: addr must be aligned. The ram page is not masked as dirty
2468    and the code inside is not invalidated. It is useful if the dirty
2469    bits are used to track modified PTEs */
2470 void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val)
2471 {
2472     int io_index;
2473     uint8_t *ptr;
2474     unsigned long pd;
2475     PhysPageDesc *p;
2476
2477     p = phys_page_find(addr >> TARGET_PAGE_BITS);
2478     if (!p) {
2479         pd = IO_MEM_UNASSIGNED;
2480     } else {
2481         pd = p->phys_offset;
2482     }
2483         
2484     if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) {
2485         io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
2486         io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val);
2487     } else {
2488         ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) + 
2489             (addr & ~TARGET_PAGE_MASK);
2490         stl_p(ptr, val);
2491     }
2492 }
2493
2494 void stq_phys_notdirty(target_phys_addr_t addr, uint64_t val)
2495 {
2496     int io_index;
2497     uint8_t *ptr;
2498     unsigned long pd;
2499     PhysPageDesc *p;
2500
2501     p = phys_page_find(addr >> TARGET_PAGE_BITS);
2502     if (!p) {
2503         pd = IO_MEM_UNASSIGNED;
2504     } else {
2505         pd = p->phys_offset;
2506     }
2507         
2508     if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) {
2509         io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
2510 #ifdef TARGET_WORDS_BIGENDIAN
2511         io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val >> 32);
2512         io_mem_write[io_index][2](io_mem_opaque[io_index], addr + 4, val);
2513 #else
2514         io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val);
2515         io_mem_write[io_index][2](io_mem_opaque[io_index], addr + 4, val >> 32);
2516 #endif
2517     } else {
2518         ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) + 
2519             (addr & ~TARGET_PAGE_MASK);
2520         stq_p(ptr, val);
2521     }
2522 }
2523
2524 /* warning: addr must be aligned */
2525 void stl_phys(target_phys_addr_t addr, uint32_t val)
2526 {
2527     int io_index;
2528     uint8_t *ptr;
2529     unsigned long pd;
2530     PhysPageDesc *p;
2531
2532     p = phys_page_find(addr >> TARGET_PAGE_BITS);
2533     if (!p) {
2534         pd = IO_MEM_UNASSIGNED;
2535     } else {
2536         pd = p->phys_offset;
2537     }
2538         
2539     if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) {
2540         io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
2541         io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val);
2542     } else {
2543         unsigned long addr1;
2544         addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
2545         /* RAM case */
2546         ptr = phys_ram_base + addr1;
2547         stl_p(ptr, val);
2548         if (!cpu_physical_memory_is_dirty(addr1)) {
2549             /* invalidate code */
2550             tb_invalidate_phys_page_range(addr1, addr1 + 4, 0);
2551             /* set dirty bit */
2552             phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] |=
2553                 (0xff & ~CODE_DIRTY_FLAG);
2554         }
2555     }
2556 }
2557
2558 /* XXX: optimize */
2559 void stb_phys(target_phys_addr_t addr, uint32_t val)
2560 {
2561     uint8_t v = val;
2562     cpu_physical_memory_write(addr, &v, 1);
2563 }
2564
2565 /* XXX: optimize */
2566 void stw_phys(target_phys_addr_t addr, uint32_t val)
2567 {
2568     uint16_t v = tswap16(val);
2569     cpu_physical_memory_write(addr, (const uint8_t *)&v, 2);
2570 }
2571
2572 /* XXX: optimize */
2573 void stq_phys(target_phys_addr_t addr, uint64_t val)
2574 {
2575     val = tswap64(val);
2576     cpu_physical_memory_write(addr, (const uint8_t *)&val, 8);
2577 }
2578
2579 #endif
2580
2581 /* virtual memory access for debug */
2582 int cpu_memory_rw_debug(CPUState *env, target_ulong addr, 
2583                         uint8_t *buf, int len, int is_write)
2584 {
2585     int l;
2586     target_phys_addr_t phys_addr;
2587     target_ulong page;
2588
2589     while (len > 0) {
2590         page = addr & TARGET_PAGE_MASK;
2591         phys_addr = cpu_get_phys_page_debug(env, page);
2592         /* if no physical page mapped, return an error */
2593         if (phys_addr == -1)
2594             return -1;
2595         l = (page + TARGET_PAGE_SIZE) - addr;
2596         if (l > len)
2597             l = len;
2598         cpu_physical_memory_rw(phys_addr + (addr & ~TARGET_PAGE_MASK), 
2599                                buf, l, is_write);
2600         len -= l;
2601         buf += l;
2602         addr += l;
2603     }
2604     return 0;
2605 }
2606
2607 void dump_exec_info(FILE *f,
2608                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
2609 {
2610     int i, target_code_size, max_target_code_size;
2611     int direct_jmp_count, direct_jmp2_count, cross_page;
2612     TranslationBlock *tb;
2613     
2614     target_code_size = 0;
2615     max_target_code_size = 0;
2616     cross_page = 0;
2617     direct_jmp_count = 0;
2618     direct_jmp2_count = 0;
2619     for(i = 0; i < nb_tbs; i++) {
2620         tb = &tbs[i];
2621         target_code_size += tb->size;
2622         if (tb->size > max_target_code_size)
2623             max_target_code_size = tb->size;
2624         if (tb->page_addr[1] != -1)
2625             cross_page++;
2626         if (tb->tb_next_offset[0] != 0xffff) {
2627             direct_jmp_count++;
2628             if (tb->tb_next_offset[1] != 0xffff) {
2629                 direct_jmp2_count++;
2630             }
2631         }
2632     }
2633     /* XXX: avoid using doubles ? */
2634     cpu_fprintf(f, "TB count            %d\n", nb_tbs);
2635     cpu_fprintf(f, "TB avg target size  %d max=%d bytes\n", 
2636                 nb_tbs ? target_code_size / nb_tbs : 0,
2637                 max_target_code_size);
2638     cpu_fprintf(f, "TB avg host size    %d bytes (expansion ratio: %0.1f)\n", 
2639                 nb_tbs ? (code_gen_ptr - code_gen_buffer) / nb_tbs : 0,
2640                 target_code_size ? (double) (code_gen_ptr - code_gen_buffer) / target_code_size : 0);
2641     cpu_fprintf(f, "cross page TB count %d (%d%%)\n", 
2642             cross_page, 
2643             nb_tbs ? (cross_page * 100) / nb_tbs : 0);
2644     cpu_fprintf(f, "direct jump count   %d (%d%%) (2 jumps=%d %d%%)\n",
2645                 direct_jmp_count, 
2646                 nb_tbs ? (direct_jmp_count * 100) / nb_tbs : 0,
2647                 direct_jmp2_count,
2648                 nb_tbs ? (direct_jmp2_count * 100) / nb_tbs : 0);
2649     cpu_fprintf(f, "TB flush count      %d\n", tb_flush_count);
2650     cpu_fprintf(f, "TB invalidate count %d\n", tb_phys_invalidate_count);
2651     cpu_fprintf(f, "TLB flush count     %d\n", tlb_flush_count);
2652 }
2653
2654 #if !defined(CONFIG_USER_ONLY) 
2655
2656 #define MMUSUFFIX _cmmu
2657 #define GETPC() NULL
2658 #define env cpu_single_env
2659 #define SOFTMMU_CODE_ACCESS
2660
2661 #define SHIFT 0
2662 #include "softmmu_template.h"
2663
2664 #define SHIFT 1
2665 #include "softmmu_template.h"
2666
2667 #define SHIFT 2
2668 #include "softmmu_template.h"
2669
2670 #define SHIFT 3
2671 #include "softmmu_template.h"
2672
2673 #undef env
2674
2675 #endif