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