new physical memory access API (used by DMA accesses) - code copy FP fixes
[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 <stdlib.h>
21 #include <stdio.h>
22 #include <stdarg.h>
23 #include <string.h>
24 #include <errno.h>
25 #include <unistd.h>
26 #include <inttypes.h>
27 #include <sys/mman.h>
28
29 #include "config.h"
30 #include "cpu.h"
31 #include "exec-all.h"
32
33 //#define DEBUG_TB_INVALIDATE
34 //#define DEBUG_FLUSH
35 //#define DEBUG_TLB
36
37 /* make various TB consistency checks */
38 //#define DEBUG_TB_CHECK 
39 //#define DEBUG_TLB_CHECK 
40
41 /* threshold to flush the translated code buffer */
42 #define CODE_GEN_BUFFER_MAX_SIZE (CODE_GEN_BUFFER_SIZE - CODE_GEN_MAX_SIZE)
43
44 #define SMC_BITMAP_USE_THRESHOLD 10
45
46 #define MMAP_AREA_START        0x00000000
47 #define MMAP_AREA_END          0xa8000000
48
49 TranslationBlock tbs[CODE_GEN_MAX_BLOCKS];
50 TranslationBlock *tb_hash[CODE_GEN_HASH_SIZE];
51 TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE];
52 int nb_tbs;
53 /* any access to the tbs or the page table must use this lock */
54 spinlock_t tb_lock = SPIN_LOCK_UNLOCKED;
55
56 uint8_t code_gen_buffer[CODE_GEN_BUFFER_SIZE];
57 uint8_t *code_gen_ptr;
58
59 int phys_ram_size;
60 int phys_ram_fd;
61 uint8_t *phys_ram_base;
62 uint8_t *phys_ram_dirty;
63
64 typedef struct PageDesc {
65     /* offset in memory of the page + io_index in the low 12 bits */
66     unsigned long phys_offset;
67     /* list of TBs intersecting this physical page */
68     TranslationBlock *first_tb;
69     /* in order to optimize self modifying code, we count the number
70        of lookups we do to a given page to use a bitmap */
71     unsigned int code_write_count;
72     uint8_t *code_bitmap;
73 #if defined(CONFIG_USER_ONLY)
74     unsigned long flags;
75 #endif
76 } PageDesc;
77
78 typedef struct VirtPageDesc {
79     /* physical address of code page. It is valid only if 'valid_tag'
80        matches 'virt_valid_tag' */ 
81     target_ulong phys_addr; 
82     unsigned int valid_tag;
83 #if !defined(CONFIG_SOFTMMU)
84     /* original page access rights. It is valid only if 'valid_tag'
85        matches 'virt_valid_tag' */
86     unsigned int prot;
87 #endif
88 } VirtPageDesc;
89
90 #define L2_BITS 10
91 #define L1_BITS (32 - L2_BITS - TARGET_PAGE_BITS)
92
93 #define L1_SIZE (1 << L1_BITS)
94 #define L2_SIZE (1 << L2_BITS)
95
96 static void io_mem_init(void);
97
98 unsigned long real_host_page_size;
99 unsigned long host_page_bits;
100 unsigned long host_page_size;
101 unsigned long host_page_mask;
102
103 static PageDesc *l1_map[L1_SIZE];
104
105 #if !defined(CONFIG_USER_ONLY)
106 static VirtPageDesc *l1_virt_map[L1_SIZE];
107 static unsigned int virt_valid_tag;
108 #endif
109
110 /* io memory support */
111 CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
112 CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
113 static int io_mem_nb;
114
115 /* log support */
116 char *logfilename = "/tmp/qemu.log";
117 FILE *logfile;
118 int loglevel;
119
120 static void page_init(void)
121 {
122     /* NOTE: we can always suppose that host_page_size >=
123        TARGET_PAGE_SIZE */
124     real_host_page_size = getpagesize();
125     if (host_page_size == 0)
126         host_page_size = real_host_page_size;
127     if (host_page_size < TARGET_PAGE_SIZE)
128         host_page_size = TARGET_PAGE_SIZE;
129     host_page_bits = 0;
130     while ((1 << host_page_bits) < host_page_size)
131         host_page_bits++;
132     host_page_mask = ~(host_page_size - 1);
133 #if !defined(CONFIG_USER_ONLY)
134     virt_valid_tag = 1;
135 #endif
136 }
137
138 static inline PageDesc *page_find_alloc(unsigned int index)
139 {
140     PageDesc **lp, *p;
141
142     lp = &l1_map[index >> L2_BITS];
143     p = *lp;
144     if (!p) {
145         /* allocate if not found */
146         p = qemu_malloc(sizeof(PageDesc) * L2_SIZE);
147         memset(p, 0, sizeof(PageDesc) * L2_SIZE);
148         *lp = p;
149     }
150     return p + (index & (L2_SIZE - 1));
151 }
152
153 static inline PageDesc *page_find(unsigned int index)
154 {
155     PageDesc *p;
156
157     p = l1_map[index >> L2_BITS];
158     if (!p)
159         return 0;
160     return p + (index & (L2_SIZE - 1));
161 }
162
163 #if !defined(CONFIG_USER_ONLY)
164 static void tlb_protect_code(CPUState *env, uint32_t addr);
165 static void tlb_unprotect_code(CPUState *env, uint32_t addr);
166 static void tlb_unprotect_code_phys(CPUState *env, uint32_t phys_addr, target_ulong vaddr);
167
168 static inline VirtPageDesc *virt_page_find_alloc(unsigned int index)
169 {
170     VirtPageDesc **lp, *p;
171
172     lp = &l1_virt_map[index >> L2_BITS];
173     p = *lp;
174     if (!p) {
175         /* allocate if not found */
176         p = qemu_malloc(sizeof(VirtPageDesc) * L2_SIZE);
177         memset(p, 0, sizeof(VirtPageDesc) * L2_SIZE);
178         *lp = p;
179     }
180     return p + (index & (L2_SIZE - 1));
181 }
182
183 static inline VirtPageDesc *virt_page_find(unsigned int index)
184 {
185     VirtPageDesc *p;
186
187     p = l1_virt_map[index >> L2_BITS];
188     if (!p)
189         return 0;
190     return p + (index & (L2_SIZE - 1));
191 }
192
193 static void virt_page_flush(void)
194 {
195     int i, j;
196     VirtPageDesc *p;
197     
198     virt_valid_tag++;
199
200     if (virt_valid_tag == 0) {
201         virt_valid_tag = 1;
202         for(i = 0; i < L1_SIZE; i++) {
203             p = l1_virt_map[i];
204             if (p) {
205                 for(j = 0; j < L2_SIZE; j++)
206                     p[j].valid_tag = 0;
207             }
208         }
209     }
210 }
211 #else
212 static void virt_page_flush(void)
213 {
214 }
215 #endif
216
217 void cpu_exec_init(void)
218 {
219     if (!code_gen_ptr) {
220         code_gen_ptr = code_gen_buffer;
221         page_init();
222         io_mem_init();
223     }
224 }
225
226 static inline void invalidate_page_bitmap(PageDesc *p)
227 {
228     if (p->code_bitmap) {
229         qemu_free(p->code_bitmap);
230         p->code_bitmap = NULL;
231     }
232     p->code_write_count = 0;
233 }
234
235 /* set to NULL all the 'first_tb' fields in all PageDescs */
236 static void page_flush_tb(void)
237 {
238     int i, j;
239     PageDesc *p;
240
241     for(i = 0; i < L1_SIZE; i++) {
242         p = l1_map[i];
243         if (p) {
244             for(j = 0; j < L2_SIZE; j++) {
245                 p->first_tb = NULL;
246                 invalidate_page_bitmap(p);
247                 p++;
248             }
249         }
250     }
251 }
252
253 /* flush all the translation blocks */
254 /* XXX: tb_flush is currently not thread safe */
255 void tb_flush(CPUState *env)
256 {
257     int i;
258 #if defined(DEBUG_FLUSH)
259     printf("qemu: flush code_size=%d nb_tbs=%d avg_tb_size=%d\n", 
260            code_gen_ptr - code_gen_buffer, 
261            nb_tbs, 
262            nb_tbs > 0 ? (code_gen_ptr - code_gen_buffer) / nb_tbs : 0);
263 #endif
264     nb_tbs = 0;
265     for(i = 0;i < CODE_GEN_HASH_SIZE; i++)
266         tb_hash[i] = NULL;
267     virt_page_flush();
268
269     for(i = 0;i < CODE_GEN_PHYS_HASH_SIZE; i++)
270         tb_phys_hash[i] = NULL;
271     page_flush_tb();
272
273     code_gen_ptr = code_gen_buffer;
274     /* XXX: flush processor icache at this point if cache flush is
275        expensive */
276 }
277
278 #ifdef DEBUG_TB_CHECK
279
280 static void tb_invalidate_check(unsigned long address)
281 {
282     TranslationBlock *tb;
283     int i;
284     address &= TARGET_PAGE_MASK;
285     for(i = 0;i < CODE_GEN_HASH_SIZE; i++) {
286         for(tb = tb_hash[i]; tb != NULL; tb = tb->hash_next) {
287             if (!(address + TARGET_PAGE_SIZE <= tb->pc ||
288                   address >= tb->pc + tb->size)) {
289                 printf("ERROR invalidate: address=%08lx PC=%08lx size=%04x\n",
290                        address, tb->pc, tb->size);
291             }
292         }
293     }
294 }
295
296 /* verify that all the pages have correct rights for code */
297 static void tb_page_check(void)
298 {
299     TranslationBlock *tb;
300     int i, flags1, flags2;
301     
302     for(i = 0;i < CODE_GEN_HASH_SIZE; i++) {
303         for(tb = tb_hash[i]; tb != NULL; tb = tb->hash_next) {
304             flags1 = page_get_flags(tb->pc);
305             flags2 = page_get_flags(tb->pc + tb->size - 1);
306             if ((flags1 & PAGE_WRITE) || (flags2 & PAGE_WRITE)) {
307                 printf("ERROR page flags: PC=%08lx size=%04x f1=%x f2=%x\n",
308                        tb->pc, tb->size, flags1, flags2);
309             }
310         }
311     }
312 }
313
314 void tb_jmp_check(TranslationBlock *tb)
315 {
316     TranslationBlock *tb1;
317     unsigned int n1;
318
319     /* suppress any remaining jumps to this TB */
320     tb1 = tb->jmp_first;
321     for(;;) {
322         n1 = (long)tb1 & 3;
323         tb1 = (TranslationBlock *)((long)tb1 & ~3);
324         if (n1 == 2)
325             break;
326         tb1 = tb1->jmp_next[n1];
327     }
328     /* check end of list */
329     if (tb1 != tb) {
330         printf("ERROR: jmp_list from 0x%08lx\n", (long)tb);
331     }
332 }
333
334 #endif
335
336 /* invalidate one TB */
337 static inline void tb_remove(TranslationBlock **ptb, TranslationBlock *tb,
338                              int next_offset)
339 {
340     TranslationBlock *tb1;
341     for(;;) {
342         tb1 = *ptb;
343         if (tb1 == tb) {
344             *ptb = *(TranslationBlock **)((char *)tb1 + next_offset);
345             break;
346         }
347         ptb = (TranslationBlock **)((char *)tb1 + next_offset);
348     }
349 }
350
351 static inline void tb_page_remove(TranslationBlock **ptb, TranslationBlock *tb)
352 {
353     TranslationBlock *tb1;
354     unsigned int n1;
355
356     for(;;) {
357         tb1 = *ptb;
358         n1 = (long)tb1 & 3;
359         tb1 = (TranslationBlock *)((long)tb1 & ~3);
360         if (tb1 == tb) {
361             *ptb = tb1->page_next[n1];
362             break;
363         }
364         ptb = &tb1->page_next[n1];
365     }
366 }
367
368 static inline void tb_jmp_remove(TranslationBlock *tb, int n)
369 {
370     TranslationBlock *tb1, **ptb;
371     unsigned int n1;
372
373     ptb = &tb->jmp_next[n];
374     tb1 = *ptb;
375     if (tb1) {
376         /* find tb(n) in circular list */
377         for(;;) {
378             tb1 = *ptb;
379             n1 = (long)tb1 & 3;
380             tb1 = (TranslationBlock *)((long)tb1 & ~3);
381             if (n1 == n && tb1 == tb)
382                 break;
383             if (n1 == 2) {
384                 ptb = &tb1->jmp_first;
385             } else {
386                 ptb = &tb1->jmp_next[n1];
387             }
388         }
389         /* now we can suppress tb(n) from the list */
390         *ptb = tb->jmp_next[n];
391
392         tb->jmp_next[n] = NULL;
393     }
394 }
395
396 /* reset the jump entry 'n' of a TB so that it is not chained to
397    another TB */
398 static inline void tb_reset_jump(TranslationBlock *tb, int n)
399 {
400     tb_set_jmp_target(tb, n, (unsigned long)(tb->tc_ptr + tb->tb_next_offset[n]));
401 }
402
403 static inline void tb_invalidate(TranslationBlock *tb)
404 {
405     unsigned int h, n1;
406     TranslationBlock *tb1, *tb2, **ptb;
407     
408     tb_invalidated_flag = 1;
409
410     /* remove the TB from the hash list */
411     h = tb_hash_func(tb->pc);
412     ptb = &tb_hash[h];
413     for(;;) {
414         tb1 = *ptb;
415         /* NOTE: the TB is not necessarily linked in the hash. It
416            indicates that it is not currently used */
417         if (tb1 == NULL)
418             return;
419         if (tb1 == tb) {
420             *ptb = tb1->hash_next;
421             break;
422         }
423         ptb = &tb1->hash_next;
424     }
425
426     /* suppress this TB from the two jump lists */
427     tb_jmp_remove(tb, 0);
428     tb_jmp_remove(tb, 1);
429
430     /* suppress any remaining jumps to this TB */
431     tb1 = tb->jmp_first;
432     for(;;) {
433         n1 = (long)tb1 & 3;
434         if (n1 == 2)
435             break;
436         tb1 = (TranslationBlock *)((long)tb1 & ~3);
437         tb2 = tb1->jmp_next[n1];
438         tb_reset_jump(tb1, n1);
439         tb1->jmp_next[n1] = NULL;
440         tb1 = tb2;
441     }
442     tb->jmp_first = (TranslationBlock *)((long)tb | 2); /* fail safe */
443 }
444
445 static inline void tb_phys_invalidate(TranslationBlock *tb, unsigned int page_addr)
446 {
447     PageDesc *p;
448     unsigned int h;
449     target_ulong phys_pc;
450     
451     /* remove the TB from the hash list */
452     phys_pc = tb->page_addr[0] + (tb->pc & ~TARGET_PAGE_MASK);
453     h = tb_phys_hash_func(phys_pc);
454     tb_remove(&tb_phys_hash[h], tb, 
455               offsetof(TranslationBlock, phys_hash_next));
456
457     /* remove the TB from the page list */
458     if (tb->page_addr[0] != page_addr) {
459         p = page_find(tb->page_addr[0] >> TARGET_PAGE_BITS);
460         tb_page_remove(&p->first_tb, tb);
461         invalidate_page_bitmap(p);
462     }
463     if (tb->page_addr[1] != -1 && tb->page_addr[1] != page_addr) {
464         p = page_find(tb->page_addr[1] >> TARGET_PAGE_BITS);
465         tb_page_remove(&p->first_tb, tb);
466         invalidate_page_bitmap(p);
467     }
468
469     tb_invalidate(tb);
470 }
471
472 static inline void set_bits(uint8_t *tab, int start, int len)
473 {
474     int end, mask, end1;
475
476     end = start + len;
477     tab += start >> 3;
478     mask = 0xff << (start & 7);
479     if ((start & ~7) == (end & ~7)) {
480         if (start < end) {
481             mask &= ~(0xff << (end & 7));
482             *tab |= mask;
483         }
484     } else {
485         *tab++ |= mask;
486         start = (start + 8) & ~7;
487         end1 = end & ~7;
488         while (start < end1) {
489             *tab++ = 0xff;
490             start += 8;
491         }
492         if (start < end) {
493             mask = ~(0xff << (end & 7));
494             *tab |= mask;
495         }
496     }
497 }
498
499 static void build_page_bitmap(PageDesc *p)
500 {
501     int n, tb_start, tb_end;
502     TranslationBlock *tb;
503     
504     p->code_bitmap = qemu_malloc(TARGET_PAGE_SIZE / 8);
505     if (!p->code_bitmap)
506         return;
507     memset(p->code_bitmap, 0, TARGET_PAGE_SIZE / 8);
508
509     tb = p->first_tb;
510     while (tb != NULL) {
511         n = (long)tb & 3;
512         tb = (TranslationBlock *)((long)tb & ~3);
513         /* NOTE: this is subtle as a TB may span two physical pages */
514         if (n == 0) {
515             /* NOTE: tb_end may be after the end of the page, but
516                it is not a problem */
517             tb_start = tb->pc & ~TARGET_PAGE_MASK;
518             tb_end = tb_start + tb->size;
519             if (tb_end > TARGET_PAGE_SIZE)
520                 tb_end = TARGET_PAGE_SIZE;
521         } else {
522             tb_start = 0;
523             tb_end = ((tb->pc + tb->size) & ~TARGET_PAGE_MASK);
524         }
525         set_bits(p->code_bitmap, tb_start, tb_end - tb_start);
526         tb = tb->page_next[n];
527     }
528 }
529
530 /* invalidate all TBs which intersect with the target physical page
531    starting in range [start;end[. NOTE: start and end must refer to
532    the same physical page. 'vaddr' is a virtual address referencing
533    the physical page of code. It is only used an a hint if there is no
534    code left. */
535 static void tb_invalidate_phys_page_range(target_ulong start, target_ulong end, 
536                                           target_ulong vaddr)
537 {
538     int n;
539     PageDesc *p;
540     TranslationBlock *tb, *tb_next;
541     target_ulong tb_start, tb_end;
542
543     p = page_find(start >> TARGET_PAGE_BITS);
544     if (!p) 
545         return;
546     if (!p->code_bitmap && 
547         ++p->code_write_count >= SMC_BITMAP_USE_THRESHOLD) {
548         /* build code bitmap */
549         build_page_bitmap(p);
550     }
551
552     /* we remove all the TBs in the range [start, end[ */
553     /* XXX: see if in some cases it could be faster to invalidate all the code */
554     tb = p->first_tb;
555     while (tb != NULL) {
556         n = (long)tb & 3;
557         tb = (TranslationBlock *)((long)tb & ~3);
558         tb_next = tb->page_next[n];
559         /* NOTE: this is subtle as a TB may span two physical pages */
560         if (n == 0) {
561             /* NOTE: tb_end may be after the end of the page, but
562                it is not a problem */
563             tb_start = tb->page_addr[0] + (tb->pc & ~TARGET_PAGE_MASK);
564             tb_end = tb_start + tb->size;
565         } else {
566             tb_start = tb->page_addr[1];
567             tb_end = tb_start + ((tb->pc + tb->size) & ~TARGET_PAGE_MASK);
568         }
569         if (!(tb_end <= start || tb_start >= end)) {
570             tb_phys_invalidate(tb, -1);
571         }
572         tb = tb_next;
573     }
574 #if !defined(CONFIG_USER_ONLY)
575     /* if no code remaining, no need to continue to use slow writes */
576     if (!p->first_tb) {
577         invalidate_page_bitmap(p);
578         tlb_unprotect_code_phys(cpu_single_env, start, vaddr);
579     }
580 #endif
581 }
582
583 /* len must be <= 8 and start must be a multiple of len */
584 static inline void tb_invalidate_phys_page_fast(target_ulong start, int len, target_ulong vaddr)
585 {
586     PageDesc *p;
587     int offset, b;
588 #if 0
589     if (cpu_single_env->cr[0] & CR0_PE_MASK) {
590         printf("modifying code at 0x%x size=%d EIP=%x\n", 
591                (vaddr & TARGET_PAGE_MASK) | (start & ~TARGET_PAGE_MASK), len, 
592                cpu_single_env->eip);
593     }
594 #endif
595     p = page_find(start >> TARGET_PAGE_BITS);
596     if (!p) 
597         return;
598     if (p->code_bitmap) {
599         offset = start & ~TARGET_PAGE_MASK;
600         b = p->code_bitmap[offset >> 3] >> (offset & 7);
601         if (b & ((1 << len) - 1))
602             goto do_invalidate;
603     } else {
604     do_invalidate:
605         tb_invalidate_phys_page_range(start, start + len, vaddr);
606     }
607 }
608
609 /* invalidate all TBs which intersect with the target virtual page
610    starting in range [start;end[. This function is usually used when
611    the target processor flushes its I-cache. NOTE: start and end must
612    refer to the same physical page */
613 void tb_invalidate_page_range(target_ulong start, target_ulong end)
614 {
615     int n;
616     PageDesc *p;
617     TranslationBlock *tb, *tb_next;
618     target_ulong pc;
619     target_ulong phys_start;
620
621 #if !defined(CONFIG_USER_ONLY)
622     {
623         VirtPageDesc *vp;
624         vp = virt_page_find(start >> TARGET_PAGE_BITS);
625         if (!vp)
626             return;
627         if (vp->valid_tag != virt_valid_tag)
628             return;
629         phys_start = vp->phys_addr + (start & ~TARGET_PAGE_MASK);
630     }
631 #else
632     phys_start = start;
633 #endif    
634     p = page_find(phys_start >> TARGET_PAGE_BITS);
635     if (!p) 
636         return;
637     /* we remove all the TBs in the range [start, end[ */
638     /* XXX: see if in some cases it could be faster to invalidate all the code */
639     tb = p->first_tb;
640     while (tb != NULL) {
641         n = (long)tb & 3;
642         tb = (TranslationBlock *)((long)tb & ~3);
643         tb_next = tb->page_next[n];
644         pc = tb->pc;
645         if (!((pc + tb->size) <= start || pc >= end)) {
646             tb_phys_invalidate(tb, -1);
647         }
648         tb = tb_next;
649     }
650 #if !defined(CONFIG_USER_ONLY)
651     /* if no code remaining, no need to continue to use slow writes */
652     if (!p->first_tb)
653         tlb_unprotect_code(cpu_single_env, start);
654 #endif
655 }
656
657 #if !defined(CONFIG_SOFTMMU)
658 static void tb_invalidate_phys_page(target_ulong addr)
659 {
660     int n;
661     PageDesc *p;
662     TranslationBlock *tb;
663
664     addr &= TARGET_PAGE_MASK;
665     p = page_find(addr >> TARGET_PAGE_BITS);
666     if (!p) 
667         return;
668     tb = p->first_tb;
669     while (tb != NULL) {
670         n = (long)tb & 3;
671         tb = (TranslationBlock *)((long)tb & ~3);
672         tb_phys_invalidate(tb, addr);
673         tb = tb->page_next[n];
674     }
675     p->first_tb = NULL;
676 }
677 #endif
678
679 /* add the tb in the target page and protect it if necessary */
680 static inline void tb_alloc_page(TranslationBlock *tb, 
681                                  unsigned int n, unsigned int page_addr)
682 {
683     PageDesc *p;
684     TranslationBlock *last_first_tb;
685
686     tb->page_addr[n] = page_addr;
687     p = page_find(page_addr >> TARGET_PAGE_BITS);
688     tb->page_next[n] = p->first_tb;
689     last_first_tb = p->first_tb;
690     p->first_tb = (TranslationBlock *)((long)tb | n);
691     invalidate_page_bitmap(p);
692
693 #if defined(CONFIG_USER_ONLY)
694     if (p->flags & PAGE_WRITE) {
695         unsigned long host_start, host_end, addr;
696         int prot;
697
698         /* force the host page as non writable (writes will have a
699            page fault + mprotect overhead) */
700         host_start = page_addr & host_page_mask;
701         host_end = host_start + host_page_size;
702         prot = 0;
703         for(addr = host_start; addr < host_end; addr += TARGET_PAGE_SIZE)
704             prot |= page_get_flags(addr);
705         mprotect((void *)host_start, host_page_size, 
706                  (prot & PAGE_BITS) & ~PAGE_WRITE);
707 #ifdef DEBUG_TB_INVALIDATE
708         printf("protecting code page: 0x%08lx\n", 
709                host_start);
710 #endif
711         p->flags &= ~PAGE_WRITE;
712     }
713 #else
714     /* if some code is already present, then the pages are already
715        protected. So we handle the case where only the first TB is
716        allocated in a physical page */
717     if (!last_first_tb) {
718         target_ulong virt_addr;
719
720         virt_addr = (tb->pc & TARGET_PAGE_MASK) + (n << TARGET_PAGE_BITS);
721         tlb_protect_code(cpu_single_env, virt_addr);        
722     }
723 #endif
724 }
725
726 /* Allocate a new translation block. Flush the translation buffer if
727    too many translation blocks or too much generated code. */
728 TranslationBlock *tb_alloc(unsigned long pc)
729 {
730     TranslationBlock *tb;
731
732     if (nb_tbs >= CODE_GEN_MAX_BLOCKS || 
733         (code_gen_ptr - code_gen_buffer) >= CODE_GEN_BUFFER_MAX_SIZE)
734         return NULL;
735     tb = &tbs[nb_tbs++];
736     tb->pc = pc;
737     tb->cflags = 0;
738     return tb;
739 }
740
741 /* add a new TB and link it to the physical page tables. phys_page2 is
742    (-1) to indicate that only one page contains the TB. */
743 void tb_link_phys(TranslationBlock *tb, 
744                   target_ulong phys_pc, target_ulong phys_page2)
745 {
746     unsigned int h;
747     TranslationBlock **ptb;
748
749     /* add in the physical hash table */
750     h = tb_phys_hash_func(phys_pc);
751     ptb = &tb_phys_hash[h];
752     tb->phys_hash_next = *ptb;
753     *ptb = tb;
754
755     /* add in the page list */
756     tb_alloc_page(tb, 0, phys_pc & TARGET_PAGE_MASK);
757     if (phys_page2 != -1)
758         tb_alloc_page(tb, 1, phys_page2);
759     else
760         tb->page_addr[1] = -1;
761 #ifdef DEBUG_TB_CHECK
762     tb_page_check();
763 #endif
764 }
765
766 /* link the tb with the other TBs */
767 void tb_link(TranslationBlock *tb)
768 {
769 #if !defined(CONFIG_USER_ONLY)
770     {
771         VirtPageDesc *vp;
772         target_ulong addr;
773         
774         /* save the code memory mappings (needed to invalidate the code) */
775         addr = tb->pc & TARGET_PAGE_MASK;
776         vp = virt_page_find_alloc(addr >> TARGET_PAGE_BITS);
777 #ifdef DEBUG_TLB_CHECK 
778         if (vp->valid_tag == virt_valid_tag &&
779             vp->phys_addr != tb->page_addr[0]) {
780             printf("Error tb addr=0x%x phys=0x%x vp->phys_addr=0x%x\n",
781                    addr, tb->page_addr[0], vp->phys_addr);
782         }
783 #endif
784         vp->phys_addr = tb->page_addr[0];
785         if (vp->valid_tag != virt_valid_tag) {
786             vp->valid_tag = virt_valid_tag;
787 #if !defined(CONFIG_SOFTMMU)
788             vp->prot = 0;
789 #endif
790         }
791         
792         if (tb->page_addr[1] != -1) {
793             addr += TARGET_PAGE_SIZE;
794             vp = virt_page_find_alloc(addr >> TARGET_PAGE_BITS);
795 #ifdef DEBUG_TLB_CHECK 
796             if (vp->valid_tag == virt_valid_tag &&
797                 vp->phys_addr != tb->page_addr[1]) { 
798                 printf("Error tb addr=0x%x phys=0x%x vp->phys_addr=0x%x\n",
799                        addr, tb->page_addr[1], vp->phys_addr);
800             }
801 #endif
802             vp->phys_addr = tb->page_addr[1];
803             if (vp->valid_tag != virt_valid_tag) {
804                 vp->valid_tag = virt_valid_tag;
805 #if !defined(CONFIG_SOFTMMU)
806                 vp->prot = 0;
807 #endif
808             }
809         }
810     }
811 #endif
812
813     tb->jmp_first = (TranslationBlock *)((long)tb | 2);
814     tb->jmp_next[0] = NULL;
815     tb->jmp_next[1] = NULL;
816 #ifdef USE_CODE_COPY
817     tb->cflags &= ~CF_FP_USED;
818     if (tb->cflags & CF_TB_FP_USED)
819         tb->cflags |= CF_FP_USED;
820 #endif
821
822     /* init original jump addresses */
823     if (tb->tb_next_offset[0] != 0xffff)
824         tb_reset_jump(tb, 0);
825     if (tb->tb_next_offset[1] != 0xffff)
826         tb_reset_jump(tb, 1);
827 }
828
829 /* find the TB 'tb' such that tb[0].tc_ptr <= tc_ptr <
830    tb[1].tc_ptr. Return NULL if not found */
831 TranslationBlock *tb_find_pc(unsigned long tc_ptr)
832 {
833     int m_min, m_max, m;
834     unsigned long v;
835     TranslationBlock *tb;
836
837     if (nb_tbs <= 0)
838         return NULL;
839     if (tc_ptr < (unsigned long)code_gen_buffer ||
840         tc_ptr >= (unsigned long)code_gen_ptr)
841         return NULL;
842     /* binary search (cf Knuth) */
843     m_min = 0;
844     m_max = nb_tbs - 1;
845     while (m_min <= m_max) {
846         m = (m_min + m_max) >> 1;
847         tb = &tbs[m];
848         v = (unsigned long)tb->tc_ptr;
849         if (v == tc_ptr)
850             return tb;
851         else if (tc_ptr < v) {
852             m_max = m - 1;
853         } else {
854             m_min = m + 1;
855         }
856     } 
857     return &tbs[m_max];
858 }
859
860 static void tb_reset_jump_recursive(TranslationBlock *tb);
861
862 static inline void tb_reset_jump_recursive2(TranslationBlock *tb, int n)
863 {
864     TranslationBlock *tb1, *tb_next, **ptb;
865     unsigned int n1;
866
867     tb1 = tb->jmp_next[n];
868     if (tb1 != NULL) {
869         /* find head of list */
870         for(;;) {
871             n1 = (long)tb1 & 3;
872             tb1 = (TranslationBlock *)((long)tb1 & ~3);
873             if (n1 == 2)
874                 break;
875             tb1 = tb1->jmp_next[n1];
876         }
877         /* we are now sure now that tb jumps to tb1 */
878         tb_next = tb1;
879
880         /* remove tb from the jmp_first list */
881         ptb = &tb_next->jmp_first;
882         for(;;) {
883             tb1 = *ptb;
884             n1 = (long)tb1 & 3;
885             tb1 = (TranslationBlock *)((long)tb1 & ~3);
886             if (n1 == n && tb1 == tb)
887                 break;
888             ptb = &tb1->jmp_next[n1];
889         }
890         *ptb = tb->jmp_next[n];
891         tb->jmp_next[n] = NULL;
892         
893         /* suppress the jump to next tb in generated code */
894         tb_reset_jump(tb, n);
895
896         /* suppress jumps in the tb on which we could have jumped */
897         tb_reset_jump_recursive(tb_next);
898     }
899 }
900
901 static void tb_reset_jump_recursive(TranslationBlock *tb)
902 {
903     tb_reset_jump_recursive2(tb, 0);
904     tb_reset_jump_recursive2(tb, 1);
905 }
906
907 /* add a breakpoint. EXCP_DEBUG is returned by the CPU loop if a
908    breakpoint is reached */
909 int cpu_breakpoint_insert(CPUState *env, uint32_t pc)
910 {
911 #if defined(TARGET_I386)
912     int i;
913
914     for(i = 0; i < env->nb_breakpoints; i++) {
915         if (env->breakpoints[i] == pc)
916             return 0;
917     }
918
919     if (env->nb_breakpoints >= MAX_BREAKPOINTS)
920         return -1;
921     env->breakpoints[env->nb_breakpoints++] = pc;
922     tb_invalidate_page_range(pc, pc + 1);
923     return 0;
924 #else
925     return -1;
926 #endif
927 }
928
929 /* remove a breakpoint */
930 int cpu_breakpoint_remove(CPUState *env, uint32_t pc)
931 {
932 #if defined(TARGET_I386)
933     int i;
934     for(i = 0; i < env->nb_breakpoints; i++) {
935         if (env->breakpoints[i] == pc)
936             goto found;
937     }
938     return -1;
939  found:
940     memmove(&env->breakpoints[i], &env->breakpoints[i + 1],
941             (env->nb_breakpoints - (i + 1)) * sizeof(env->breakpoints[0]));
942     env->nb_breakpoints--;
943     tb_invalidate_page_range(pc, pc + 1);
944     return 0;
945 #else
946     return -1;
947 #endif
948 }
949
950 /* enable or disable single step mode. EXCP_DEBUG is returned by the
951    CPU loop after each instruction */
952 void cpu_single_step(CPUState *env, int enabled)
953 {
954 #if defined(TARGET_I386)
955     if (env->singlestep_enabled != enabled) {
956         env->singlestep_enabled = enabled;
957         /* must flush all the translated code to avoid inconsistancies */
958         /* XXX: only flush what is necessary */
959         tb_flush(env);
960     }
961 #endif
962 }
963
964 /* enable or disable low levels log */
965 void cpu_set_log(int log_flags)
966 {
967     loglevel = log_flags;
968     if (loglevel && !logfile) {
969         logfile = fopen(logfilename, "w");
970         if (!logfile) {
971             perror(logfilename);
972             _exit(1);
973         }
974 #if !defined(CONFIG_SOFTMMU)
975         /* must avoid mmap() usage of glibc by setting a buffer "by hand" */
976         {
977             static uint8_t logfile_buf[4096];
978             setvbuf(logfile, logfile_buf, _IOLBF, sizeof(logfile_buf));
979         }
980 #else
981         setvbuf(logfile, NULL, _IOLBF, 0);
982 #endif
983     }
984 }
985
986 void cpu_set_log_filename(const char *filename)
987 {
988     logfilename = strdup(filename);
989 }
990
991 /* mask must never be zero, except for A20 change call */
992 void cpu_interrupt(CPUState *env, int mask)
993 {
994     TranslationBlock *tb;
995     static int interrupt_lock;
996
997     env->interrupt_request |= mask;
998     /* if the cpu is currently executing code, we must unlink it and
999        all the potentially executing TB */
1000     tb = env->current_tb;
1001     if (tb && !testandset(&interrupt_lock)) {
1002         env->current_tb = NULL;
1003         tb_reset_jump_recursive(tb);
1004         interrupt_lock = 0;
1005     }
1006 }
1007
1008
1009 void cpu_abort(CPUState *env, const char *fmt, ...)
1010 {
1011     va_list ap;
1012
1013     va_start(ap, fmt);
1014     fprintf(stderr, "qemu: fatal: ");
1015     vfprintf(stderr, fmt, ap);
1016     fprintf(stderr, "\n");
1017 #ifdef TARGET_I386
1018     cpu_x86_dump_state(env, stderr, X86_DUMP_FPU | X86_DUMP_CCOP);
1019 #endif
1020     va_end(ap);
1021     abort();
1022 }
1023
1024 #if !defined(CONFIG_USER_ONLY)
1025
1026 /* NOTE: if flush_global is true, also flush global entries (not
1027    implemented yet) */
1028 void tlb_flush(CPUState *env, int flush_global)
1029 {
1030     int i;
1031
1032 #if defined(DEBUG_TLB)
1033     printf("tlb_flush:\n");
1034 #endif
1035     /* must reset current TB so that interrupts cannot modify the
1036        links while we are modifying them */
1037     env->current_tb = NULL;
1038
1039     for(i = 0; i < CPU_TLB_SIZE; i++) {
1040         env->tlb_read[0][i].address = -1;
1041         env->tlb_write[0][i].address = -1;
1042         env->tlb_read[1][i].address = -1;
1043         env->tlb_write[1][i].address = -1;
1044     }
1045
1046     virt_page_flush();
1047     for(i = 0;i < CODE_GEN_HASH_SIZE; i++)
1048         tb_hash[i] = NULL;
1049
1050 #if !defined(CONFIG_SOFTMMU)
1051     munmap((void *)MMAP_AREA_START, MMAP_AREA_END - MMAP_AREA_START);
1052 #endif
1053 }
1054
1055 static inline void tlb_flush_entry(CPUTLBEntry *tlb_entry, uint32_t addr)
1056 {
1057     if (addr == (tlb_entry->address & 
1058                  (TARGET_PAGE_MASK | TLB_INVALID_MASK)))
1059         tlb_entry->address = -1;
1060 }
1061
1062 void tlb_flush_page(CPUState *env, uint32_t addr)
1063 {
1064     int i, n;
1065     VirtPageDesc *vp;
1066     PageDesc *p;
1067     TranslationBlock *tb;
1068
1069 #if defined(DEBUG_TLB)
1070     printf("tlb_flush_page: 0x%08x\n", addr);
1071 #endif
1072     /* must reset current TB so that interrupts cannot modify the
1073        links while we are modifying them */
1074     env->current_tb = NULL;
1075
1076     addr &= TARGET_PAGE_MASK;
1077     i = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
1078     tlb_flush_entry(&env->tlb_read[0][i], addr);
1079     tlb_flush_entry(&env->tlb_write[0][i], addr);
1080     tlb_flush_entry(&env->tlb_read[1][i], addr);
1081     tlb_flush_entry(&env->tlb_write[1][i], addr);
1082
1083     /* remove from the virtual pc hash table all the TB at this
1084        virtual address */
1085     
1086     vp = virt_page_find(addr >> TARGET_PAGE_BITS);
1087     if (vp && vp->valid_tag == virt_valid_tag) {
1088         p = page_find(vp->phys_addr >> TARGET_PAGE_BITS);
1089         if (p) {
1090             /* we remove all the links to the TBs in this virtual page */
1091             tb = p->first_tb;
1092             while (tb != NULL) {
1093                 n = (long)tb & 3;
1094                 tb = (TranslationBlock *)((long)tb & ~3);
1095                 if ((tb->pc & TARGET_PAGE_MASK) == addr ||
1096                     ((tb->pc + tb->size - 1) & TARGET_PAGE_MASK) == addr) {
1097                     tb_invalidate(tb);
1098                 }
1099                 tb = tb->page_next[n];
1100             }
1101         }
1102         vp->valid_tag = 0;
1103     }
1104
1105 #if !defined(CONFIG_SOFTMMU)
1106     if (addr < MMAP_AREA_END)
1107         munmap((void *)addr, TARGET_PAGE_SIZE);
1108 #endif
1109 }
1110
1111 static inline void tlb_protect_code1(CPUTLBEntry *tlb_entry, uint32_t addr)
1112 {
1113     if (addr == (tlb_entry->address & 
1114                  (TARGET_PAGE_MASK | TLB_INVALID_MASK)) &&
1115         (tlb_entry->address & ~TARGET_PAGE_MASK) != IO_MEM_CODE &&
1116         (tlb_entry->address & ~TARGET_PAGE_MASK) != IO_MEM_ROM) {
1117         tlb_entry->address = (tlb_entry->address & TARGET_PAGE_MASK) | IO_MEM_CODE;
1118     }
1119 }
1120
1121 /* update the TLBs so that writes to code in the virtual page 'addr'
1122    can be detected */
1123 static void tlb_protect_code(CPUState *env, uint32_t addr)
1124 {
1125     int i;
1126
1127     addr &= TARGET_PAGE_MASK;
1128     i = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
1129     tlb_protect_code1(&env->tlb_write[0][i], addr);
1130     tlb_protect_code1(&env->tlb_write[1][i], addr);
1131 #if !defined(CONFIG_SOFTMMU)
1132     /* NOTE: as we generated the code for this page, it is already at
1133        least readable */
1134     if (addr < MMAP_AREA_END)
1135         mprotect((void *)addr, TARGET_PAGE_SIZE, PROT_READ);
1136 #endif
1137 }
1138
1139 static inline void tlb_unprotect_code1(CPUTLBEntry *tlb_entry, uint32_t addr)
1140 {
1141     if (addr == (tlb_entry->address & 
1142                  (TARGET_PAGE_MASK | TLB_INVALID_MASK)) &&
1143         (tlb_entry->address & ~TARGET_PAGE_MASK) == IO_MEM_CODE) {
1144         tlb_entry->address = (tlb_entry->address & TARGET_PAGE_MASK) | IO_MEM_NOTDIRTY;
1145     }
1146 }
1147
1148 /* update the TLB so that writes in virtual page 'addr' are no longer
1149    tested self modifying code */
1150 static void tlb_unprotect_code(CPUState *env, uint32_t addr)
1151 {
1152     int i;
1153
1154     addr &= TARGET_PAGE_MASK;
1155     i = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
1156     tlb_unprotect_code1(&env->tlb_write[0][i], addr);
1157     tlb_unprotect_code1(&env->tlb_write[1][i], addr);
1158 }
1159
1160 static inline void tlb_unprotect_code2(CPUTLBEntry *tlb_entry, 
1161                                        uint32_t phys_addr)
1162 {
1163     if ((tlb_entry->address & ~TARGET_PAGE_MASK) == IO_MEM_CODE &&
1164         ((tlb_entry->address & TARGET_PAGE_MASK) + tlb_entry->addend) == phys_addr) {
1165         tlb_entry->address = (tlb_entry->address & TARGET_PAGE_MASK) | IO_MEM_NOTDIRTY;
1166     }
1167 }
1168
1169 /* update the TLB so that writes in physical page 'phys_addr' are no longer
1170    tested self modifying code */
1171 static void tlb_unprotect_code_phys(CPUState *env, uint32_t phys_addr, target_ulong vaddr)
1172 {
1173     int i;
1174
1175     phys_addr &= TARGET_PAGE_MASK;
1176     phys_addr += (long)phys_ram_base;
1177     i = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
1178     tlb_unprotect_code2(&env->tlb_write[0][i], phys_addr);
1179     tlb_unprotect_code2(&env->tlb_write[1][i], phys_addr);
1180 }
1181
1182 static inline void tlb_reset_dirty_range(CPUTLBEntry *tlb_entry, 
1183                                          unsigned long start, unsigned long length)
1184 {
1185     unsigned long addr;
1186     if ((tlb_entry->address & ~TARGET_PAGE_MASK) == IO_MEM_RAM) {
1187         addr = (tlb_entry->address & TARGET_PAGE_MASK) + tlb_entry->addend;
1188         if ((addr - start) < length) {
1189             tlb_entry->address = (tlb_entry->address & TARGET_PAGE_MASK) | IO_MEM_NOTDIRTY;
1190         }
1191     }
1192 }
1193
1194 void cpu_physical_memory_reset_dirty(target_ulong start, target_ulong end)
1195 {
1196     CPUState *env;
1197     target_ulong length, start1;
1198     int i;
1199
1200     start &= TARGET_PAGE_MASK;
1201     end = TARGET_PAGE_ALIGN(end);
1202
1203     length = end - start;
1204     if (length == 0)
1205         return;
1206     memset(phys_ram_dirty + (start >> TARGET_PAGE_BITS), 0, length >> TARGET_PAGE_BITS);
1207
1208     env = cpu_single_env;
1209     /* we modify the TLB cache so that the dirty bit will be set again
1210        when accessing the range */
1211     start1 = start + (unsigned long)phys_ram_base;
1212     for(i = 0; i < CPU_TLB_SIZE; i++)
1213         tlb_reset_dirty_range(&env->tlb_write[0][i], start1, length);
1214     for(i = 0; i < CPU_TLB_SIZE; i++)
1215         tlb_reset_dirty_range(&env->tlb_write[1][i], start1, length);
1216
1217 #if !defined(CONFIG_SOFTMMU)
1218     /* XXX: this is expensive */
1219     {
1220         VirtPageDesc *p;
1221         int j;
1222         target_ulong addr;
1223
1224         for(i = 0; i < L1_SIZE; i++) {
1225             p = l1_virt_map[i];
1226             if (p) {
1227                 addr = i << (TARGET_PAGE_BITS + L2_BITS);
1228                 for(j = 0; j < L2_SIZE; j++) {
1229                     if (p->valid_tag == virt_valid_tag &&
1230                         p->phys_addr >= start && p->phys_addr < end &&
1231                         (p->prot & PROT_WRITE)) {
1232                         if (addr < MMAP_AREA_END) {
1233                             mprotect((void *)addr, TARGET_PAGE_SIZE, 
1234                                      p->prot & ~PROT_WRITE);
1235                         }
1236                     }
1237                     addr += TARGET_PAGE_SIZE;
1238                     p++;
1239                 }
1240             }
1241         }
1242     }
1243 #endif
1244 }
1245
1246 static inline void tlb_set_dirty1(CPUTLBEntry *tlb_entry, 
1247                                     unsigned long start)
1248 {
1249     unsigned long addr;
1250     if ((tlb_entry->address & ~TARGET_PAGE_MASK) == IO_MEM_NOTDIRTY) {
1251         addr = (tlb_entry->address & TARGET_PAGE_MASK) + tlb_entry->addend;
1252         if (addr == start) {
1253             tlb_entry->address = (tlb_entry->address & TARGET_PAGE_MASK) | IO_MEM_RAM;
1254         }
1255     }
1256 }
1257
1258 /* update the TLB corresponding to virtual page vaddr and phys addr
1259    addr so that it is no longer dirty */
1260 static inline void tlb_set_dirty(unsigned long addr, target_ulong vaddr)
1261 {
1262     CPUState *env = cpu_single_env;
1263     int i;
1264
1265     phys_ram_dirty[(addr - (unsigned long)phys_ram_base) >> TARGET_PAGE_BITS] = 1;
1266
1267     addr &= TARGET_PAGE_MASK;
1268     i = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
1269     tlb_set_dirty1(&env->tlb_write[0][i], addr);
1270     tlb_set_dirty1(&env->tlb_write[1][i], addr);
1271 }
1272
1273 /* add a new TLB entry. At most one entry for a given virtual address
1274    is permitted. Return 0 if OK or 2 if the page could not be mapped
1275    (can only happen in non SOFTMMU mode for I/O pages or pages
1276    conflicting with the host address space). */
1277 int tlb_set_page(CPUState *env, uint32_t vaddr, uint32_t paddr, int prot, 
1278                  int is_user, int is_softmmu)
1279 {
1280     PageDesc *p;
1281     target_ulong pd;
1282     TranslationBlock *first_tb;
1283     unsigned int index;
1284     target_ulong address, addend;
1285     int ret;
1286
1287     p = page_find(paddr >> TARGET_PAGE_BITS);
1288     if (!p) {
1289         pd = IO_MEM_UNASSIGNED;
1290         first_tb = NULL;
1291     } else {
1292         pd = p->phys_offset;
1293         first_tb = p->first_tb;
1294     }
1295 #if defined(DEBUG_TLB)
1296     printf("tlb_set_page: vaddr=0x%08x paddr=0x%08x prot=%x u=%d c=%d smmu=%d pd=0x%08x\n",
1297            vaddr, paddr, prot, is_user, (first_tb != NULL), is_softmmu, pd);
1298 #endif
1299
1300     ret = 0;
1301 #if !defined(CONFIG_SOFTMMU)
1302     if (is_softmmu) 
1303 #endif
1304     {
1305         if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM) {
1306             /* IO memory case */
1307             address = vaddr | pd;
1308             addend = paddr;
1309         } else {
1310             /* standard memory */
1311             address = vaddr;
1312             addend = (unsigned long)phys_ram_base + (pd & TARGET_PAGE_MASK);
1313         }
1314         
1315         index = (vaddr >> 12) & (CPU_TLB_SIZE - 1);
1316         addend -= vaddr;
1317         if (prot & PROT_READ) {
1318             env->tlb_read[is_user][index].address = address;
1319             env->tlb_read[is_user][index].addend = addend;
1320         } else {
1321             env->tlb_read[is_user][index].address = -1;
1322             env->tlb_read[is_user][index].addend = -1;
1323         }
1324         if (prot & PROT_WRITE) {
1325             if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_ROM) {
1326                 /* ROM: access is ignored (same as unassigned) */
1327                 env->tlb_write[is_user][index].address = vaddr | IO_MEM_ROM;
1328                 env->tlb_write[is_user][index].addend = addend;
1329             } else if (first_tb) {
1330                 /* if code is present, we use a specific memory
1331                    handler. It works only for physical memory access */
1332                 env->tlb_write[is_user][index].address = vaddr | IO_MEM_CODE;
1333                 env->tlb_write[is_user][index].addend = addend;
1334             } else if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_RAM && 
1335                        !cpu_physical_memory_is_dirty(pd)) {
1336                 env->tlb_write[is_user][index].address = vaddr | IO_MEM_NOTDIRTY;
1337                 env->tlb_write[is_user][index].addend = addend;
1338             } else {
1339                 env->tlb_write[is_user][index].address = address;
1340                 env->tlb_write[is_user][index].addend = addend;
1341             }
1342         } else {
1343             env->tlb_write[is_user][index].address = -1;
1344             env->tlb_write[is_user][index].addend = -1;
1345         }
1346     }
1347 #if !defined(CONFIG_SOFTMMU)
1348     else {
1349         if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM) {
1350             /* IO access: no mapping is done as it will be handled by the
1351                soft MMU */
1352             if (!(env->hflags & HF_SOFTMMU_MASK))
1353                 ret = 2;
1354         } else {
1355             void *map_addr;
1356
1357             if (vaddr >= MMAP_AREA_END) {
1358                 ret = 2;
1359             } else {
1360                 if (prot & PROT_WRITE) {
1361                     if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_ROM || 
1362                         first_tb ||
1363                         ((pd & ~TARGET_PAGE_MASK) == IO_MEM_RAM && 
1364                          !cpu_physical_memory_is_dirty(pd))) {
1365                         /* ROM: we do as if code was inside */
1366                         /* if code is present, we only map as read only and save the
1367                            original mapping */
1368                         VirtPageDesc *vp;
1369                         
1370                         vp = virt_page_find_alloc(vaddr >> TARGET_PAGE_BITS);
1371                         vp->phys_addr = pd;
1372                         vp->prot = prot;
1373                         vp->valid_tag = virt_valid_tag;
1374                         prot &= ~PAGE_WRITE;
1375                     }
1376                 }
1377                 map_addr = mmap((void *)vaddr, TARGET_PAGE_SIZE, prot, 
1378                                 MAP_SHARED | MAP_FIXED, phys_ram_fd, (pd & TARGET_PAGE_MASK));
1379                 if (map_addr == MAP_FAILED) {
1380                     cpu_abort(env, "mmap failed when mapped physical address 0x%08x to virtual address 0x%08x\n",
1381                               paddr, vaddr);
1382                 }
1383             }
1384         }
1385     }
1386 #endif
1387     return ret;
1388 }
1389
1390 /* called from signal handler: invalidate the code and unprotect the
1391    page. Return TRUE if the fault was succesfully handled. */
1392 int page_unprotect(unsigned long addr)
1393 {
1394 #if !defined(CONFIG_SOFTMMU)
1395     VirtPageDesc *vp;
1396
1397 #if defined(DEBUG_TLB)
1398     printf("page_unprotect: addr=0x%08x\n", addr);
1399 #endif
1400     addr &= TARGET_PAGE_MASK;
1401
1402     /* if it is not mapped, no need to worry here */
1403     if (addr >= MMAP_AREA_END)
1404         return 0;
1405     vp = virt_page_find(addr >> TARGET_PAGE_BITS);
1406     if (!vp)
1407         return 0;
1408     /* NOTE: in this case, validate_tag is _not_ tested as it
1409        validates only the code TLB */
1410     if (vp->valid_tag != virt_valid_tag)
1411         return 0;
1412     if (!(vp->prot & PAGE_WRITE))
1413         return 0;
1414 #if defined(DEBUG_TLB)
1415     printf("page_unprotect: addr=0x%08x phys_addr=0x%08x prot=%x\n", 
1416            addr, vp->phys_addr, vp->prot);
1417 #endif
1418     /* set the dirty bit */
1419     phys_ram_dirty[vp->phys_addr >> TARGET_PAGE_BITS] = 1;
1420     /* flush the code inside */
1421     tb_invalidate_phys_page(vp->phys_addr);
1422     if (mprotect((void *)addr, TARGET_PAGE_SIZE, vp->prot) < 0)
1423         cpu_abort(cpu_single_env, "error mprotect addr=0x%lx prot=%d\n",
1424                   (unsigned long)addr, vp->prot);
1425     return 1;
1426 #else
1427     return 0;
1428 #endif
1429 }
1430
1431 #else
1432
1433 void tlb_flush(CPUState *env, int flush_global)
1434 {
1435 }
1436
1437 void tlb_flush_page(CPUState *env, uint32_t addr)
1438 {
1439 }
1440
1441 void tlb_flush_page_write(CPUState *env, uint32_t addr)
1442 {
1443 }
1444
1445 int tlb_set_page(CPUState *env, uint32_t vaddr, uint32_t paddr, int prot, 
1446                  int is_user, int is_softmmu)
1447 {
1448     return 0;
1449 }
1450
1451 /* dump memory mappings */
1452 void page_dump(FILE *f)
1453 {
1454     unsigned long start, end;
1455     int i, j, prot, prot1;
1456     PageDesc *p;
1457
1458     fprintf(f, "%-8s %-8s %-8s %s\n",
1459             "start", "end", "size", "prot");
1460     start = -1;
1461     end = -1;
1462     prot = 0;
1463     for(i = 0; i <= L1_SIZE; i++) {
1464         if (i < L1_SIZE)
1465             p = l1_map[i];
1466         else
1467             p = NULL;
1468         for(j = 0;j < L2_SIZE; j++) {
1469             if (!p)
1470                 prot1 = 0;
1471             else
1472                 prot1 = p[j].flags;
1473             if (prot1 != prot) {
1474                 end = (i << (32 - L1_BITS)) | (j << TARGET_PAGE_BITS);
1475                 if (start != -1) {
1476                     fprintf(f, "%08lx-%08lx %08lx %c%c%c\n",
1477                             start, end, end - start, 
1478                             prot & PAGE_READ ? 'r' : '-',
1479                             prot & PAGE_WRITE ? 'w' : '-',
1480                             prot & PAGE_EXEC ? 'x' : '-');
1481                 }
1482                 if (prot1 != 0)
1483                     start = end;
1484                 else
1485                     start = -1;
1486                 prot = prot1;
1487             }
1488             if (!p)
1489                 break;
1490         }
1491     }
1492 }
1493
1494 int page_get_flags(unsigned long address)
1495 {
1496     PageDesc *p;
1497
1498     p = page_find(address >> TARGET_PAGE_BITS);
1499     if (!p)
1500         return 0;
1501     return p->flags;
1502 }
1503
1504 /* modify the flags of a page and invalidate the code if
1505    necessary. The flag PAGE_WRITE_ORG is positionned automatically
1506    depending on PAGE_WRITE */
1507 void page_set_flags(unsigned long start, unsigned long end, int flags)
1508 {
1509     PageDesc *p;
1510     unsigned long addr;
1511
1512     start = start & TARGET_PAGE_MASK;
1513     end = TARGET_PAGE_ALIGN(end);
1514     if (flags & PAGE_WRITE)
1515         flags |= PAGE_WRITE_ORG;
1516     spin_lock(&tb_lock);
1517     for(addr = start; addr < end; addr += TARGET_PAGE_SIZE) {
1518         p = page_find_alloc(addr >> TARGET_PAGE_BITS);
1519         /* if the write protection is set, then we invalidate the code
1520            inside */
1521         if (!(p->flags & PAGE_WRITE) && 
1522             (flags & PAGE_WRITE) &&
1523             p->first_tb) {
1524             tb_invalidate_phys_page(addr);
1525         }
1526         p->flags = flags;
1527     }
1528     spin_unlock(&tb_lock);
1529 }
1530
1531 /* called from signal handler: invalidate the code and unprotect the
1532    page. Return TRUE if the fault was succesfully handled. */
1533 int page_unprotect(unsigned long address)
1534 {
1535     unsigned int page_index, prot, pindex;
1536     PageDesc *p, *p1;
1537     unsigned long host_start, host_end, addr;
1538
1539     host_start = address & host_page_mask;
1540     page_index = host_start >> TARGET_PAGE_BITS;
1541     p1 = page_find(page_index);
1542     if (!p1)
1543         return 0;
1544     host_end = host_start + host_page_size;
1545     p = p1;
1546     prot = 0;
1547     for(addr = host_start;addr < host_end; addr += TARGET_PAGE_SIZE) {
1548         prot |= p->flags;
1549         p++;
1550     }
1551     /* if the page was really writable, then we change its
1552        protection back to writable */
1553     if (prot & PAGE_WRITE_ORG) {
1554         pindex = (address - host_start) >> TARGET_PAGE_BITS;
1555         if (!(p1[pindex].flags & PAGE_WRITE)) {
1556             mprotect((void *)host_start, host_page_size, 
1557                      (prot & PAGE_BITS) | PAGE_WRITE);
1558             p1[pindex].flags |= PAGE_WRITE;
1559             /* and since the content will be modified, we must invalidate
1560                the corresponding translated code. */
1561             tb_invalidate_phys_page(address);
1562 #ifdef DEBUG_TB_CHECK
1563             tb_invalidate_check(address);
1564 #endif
1565             return 1;
1566         }
1567     }
1568     return 0;
1569 }
1570
1571 /* call this function when system calls directly modify a memory area */
1572 void page_unprotect_range(uint8_t *data, unsigned long data_size)
1573 {
1574     unsigned long start, end, addr;
1575
1576     start = (unsigned long)data;
1577     end = start + data_size;
1578     start &= TARGET_PAGE_MASK;
1579     end = TARGET_PAGE_ALIGN(end);
1580     for(addr = start; addr < end; addr += TARGET_PAGE_SIZE) {
1581         page_unprotect(addr);
1582     }
1583 }
1584
1585 static inline void tlb_set_dirty(unsigned long addr, target_ulong vaddr)
1586 {
1587 }
1588
1589 #endif /* defined(CONFIG_USER_ONLY) */
1590
1591 /* register physical memory. 'size' must be a multiple of the target
1592    page size. If (phys_offset & ~TARGET_PAGE_MASK) != 0, then it is an
1593    io memory page */
1594 void cpu_register_physical_memory(unsigned long start_addr, unsigned long size,
1595                                   long phys_offset)
1596 {
1597     unsigned long addr, end_addr;
1598     PageDesc *p;
1599
1600     end_addr = start_addr + size;
1601     for(addr = start_addr; addr < end_addr; addr += TARGET_PAGE_SIZE) {
1602         p = page_find_alloc(addr >> TARGET_PAGE_BITS);
1603         p->phys_offset = phys_offset;
1604         if ((phys_offset & ~TARGET_PAGE_MASK) <= IO_MEM_ROM)
1605             phys_offset += TARGET_PAGE_SIZE;
1606     }
1607 }
1608
1609 static uint32_t unassigned_mem_readb(uint32_t addr)
1610 {
1611     return 0;
1612 }
1613
1614 static void unassigned_mem_writeb(uint32_t addr, uint32_t val, uint32_t vaddr)
1615 {
1616 }
1617
1618 static CPUReadMemoryFunc *unassigned_mem_read[3] = {
1619     unassigned_mem_readb,
1620     unassigned_mem_readb,
1621     unassigned_mem_readb,
1622 };
1623
1624 static CPUWriteMemoryFunc *unassigned_mem_write[3] = {
1625     unassigned_mem_writeb,
1626     unassigned_mem_writeb,
1627     unassigned_mem_writeb,
1628 };
1629
1630 /* self modifying code support in soft mmu mode : writing to a page
1631    containing code comes to these functions */
1632
1633 static void code_mem_writeb(uint32_t addr, uint32_t val, uint32_t vaddr)
1634 {
1635     unsigned long phys_addr;
1636
1637     phys_addr = addr - (long)phys_ram_base;
1638 #if !defined(CONFIG_USER_ONLY)
1639     tb_invalidate_phys_page_fast(phys_addr, 1, vaddr);
1640 #endif
1641     stb_raw((uint8_t *)addr, val);
1642     phys_ram_dirty[phys_addr >> TARGET_PAGE_BITS] = 1;
1643 }
1644
1645 static void code_mem_writew(uint32_t addr, uint32_t val, uint32_t vaddr)
1646 {
1647     unsigned long phys_addr;
1648
1649     phys_addr = addr - (long)phys_ram_base;
1650 #if !defined(CONFIG_USER_ONLY)
1651     tb_invalidate_phys_page_fast(phys_addr, 2, vaddr);
1652 #endif
1653     stw_raw((uint8_t *)addr, val);
1654     phys_ram_dirty[phys_addr >> TARGET_PAGE_BITS] = 1;
1655 }
1656
1657 static void code_mem_writel(uint32_t addr, uint32_t val, uint32_t vaddr)
1658 {
1659     unsigned long phys_addr;
1660
1661     phys_addr = addr - (long)phys_ram_base;
1662 #if !defined(CONFIG_USER_ONLY)
1663     tb_invalidate_phys_page_fast(phys_addr, 4, vaddr);
1664 #endif
1665     stl_raw((uint8_t *)addr, val);
1666     phys_ram_dirty[phys_addr >> TARGET_PAGE_BITS] = 1;
1667 }
1668
1669 static CPUReadMemoryFunc *code_mem_read[3] = {
1670     NULL, /* never used */
1671     NULL, /* never used */
1672     NULL, /* never used */
1673 };
1674
1675 static CPUWriteMemoryFunc *code_mem_write[3] = {
1676     code_mem_writeb,
1677     code_mem_writew,
1678     code_mem_writel,
1679 };
1680
1681 static void notdirty_mem_writeb(uint32_t addr, uint32_t val, uint32_t vaddr)
1682 {
1683     stb_raw((uint8_t *)addr, val);
1684     tlb_set_dirty(addr, vaddr);
1685 }
1686
1687 static void notdirty_mem_writew(uint32_t addr, uint32_t val, uint32_t vaddr)
1688 {
1689     stw_raw((uint8_t *)addr, val);
1690     tlb_set_dirty(addr, vaddr);
1691 }
1692
1693 static void notdirty_mem_writel(uint32_t addr, uint32_t val, uint32_t vaddr)
1694 {
1695     stl_raw((uint8_t *)addr, val);
1696     tlb_set_dirty(addr, vaddr);
1697 }
1698
1699 static CPUWriteMemoryFunc *notdirty_mem_write[3] = {
1700     notdirty_mem_writeb,
1701     notdirty_mem_writew,
1702     notdirty_mem_writel,
1703 };
1704
1705 static void io_mem_init(void)
1706 {
1707     cpu_register_io_memory(IO_MEM_ROM >> IO_MEM_SHIFT, code_mem_read, unassigned_mem_write);
1708     cpu_register_io_memory(IO_MEM_UNASSIGNED >> IO_MEM_SHIFT, unassigned_mem_read, unassigned_mem_write);
1709     cpu_register_io_memory(IO_MEM_CODE >> IO_MEM_SHIFT, code_mem_read, code_mem_write);
1710     cpu_register_io_memory(IO_MEM_NOTDIRTY >> IO_MEM_SHIFT, code_mem_read, notdirty_mem_write);
1711     io_mem_nb = 5;
1712
1713     /* alloc dirty bits array */
1714     phys_ram_dirty = qemu_malloc(phys_ram_size >> TARGET_PAGE_BITS);
1715 }
1716
1717 /* mem_read and mem_write are arrays of functions containing the
1718    function to access byte (index 0), word (index 1) and dword (index
1719    2). All functions must be supplied. If io_index is non zero, the
1720    corresponding io zone is modified. If it is zero, a new io zone is
1721    allocated. The return value can be used with
1722    cpu_register_physical_memory(). (-1) is returned if error. */
1723 int cpu_register_io_memory(int io_index,
1724                            CPUReadMemoryFunc **mem_read,
1725                            CPUWriteMemoryFunc **mem_write)
1726 {
1727     int i;
1728
1729     if (io_index <= 0) {
1730         if (io_index >= IO_MEM_NB_ENTRIES)
1731             return -1;
1732         io_index = io_mem_nb++;
1733     } else {
1734         if (io_index >= IO_MEM_NB_ENTRIES)
1735             return -1;
1736     }
1737     
1738     for(i = 0;i < 3; i++) {
1739         io_mem_read[io_index][i] = mem_read[i];
1740         io_mem_write[io_index][i] = mem_write[i];
1741     }
1742     return io_index << IO_MEM_SHIFT;
1743 }
1744
1745 /* physical memory access (slow version, mainly for debug) */
1746 #if defined(CONFIG_USER_ONLY)
1747 void cpu_physical_memory_rw(target_ulong addr, uint8_t *buf, 
1748                             int len, int is_write)
1749 {
1750     int l, flags;
1751     target_ulong page;
1752
1753     while (len > 0) {
1754         page = addr & TARGET_PAGE_MASK;
1755         l = (page + TARGET_PAGE_SIZE) - addr;
1756         if (l > len)
1757             l = len;
1758         flags = page_get_flags(page);
1759         if (!(flags & PAGE_VALID))
1760             return;
1761         if (is_write) {
1762             if (!(flags & PAGE_WRITE))
1763                 return;
1764             memcpy((uint8_t *)addr, buf, len);
1765         } else {
1766             if (!(flags & PAGE_READ))
1767                 return;
1768             memcpy(buf, (uint8_t *)addr, len);
1769         }
1770         len -= l;
1771         buf += l;
1772         addr += l;
1773     }
1774 }
1775 #else
1776 void cpu_physical_memory_rw(target_ulong addr, uint8_t *buf, 
1777                             int len, int is_write)
1778 {
1779     int l, io_index;
1780     uint8_t *ptr;
1781     uint32_t val;
1782     target_ulong page, pd;
1783     PageDesc *p;
1784     
1785     while (len > 0) {
1786         page = addr & TARGET_PAGE_MASK;
1787         l = (page + TARGET_PAGE_SIZE) - addr;
1788         if (l > len)
1789             l = len;
1790         p = page_find(page >> TARGET_PAGE_BITS);
1791         if (!p) {
1792             pd = IO_MEM_UNASSIGNED;
1793         } else {
1794             pd = p->phys_offset;
1795         }
1796         
1797         if (is_write) {
1798             if ((pd & ~TARGET_PAGE_MASK) != 0) {
1799                 io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
1800                 if (l >= 4 && ((addr & 3) == 0)) {
1801                     /* 32 bit read access */
1802                     val = ldl_raw(buf);
1803                     io_mem_write[io_index][2](addr, val, 0);
1804                     l = 4;
1805                 } else if (l >= 2 && ((addr & 1) == 0)) {
1806                     /* 16 bit read access */
1807                     val = lduw_raw(buf);
1808                     io_mem_write[io_index][1](addr, val, 0);
1809                     l = 2;
1810                 } else {
1811                     /* 8 bit access */
1812                     val = ldub_raw(buf);
1813                     io_mem_write[io_index][0](addr, val, 0);
1814                     l = 1;
1815                 }
1816             } else {
1817                 unsigned long addr1;
1818                 addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
1819                 /* RAM case */
1820                 ptr = phys_ram_base + addr1;
1821                 memcpy(ptr, buf, l);
1822                 /* invalidate code */
1823                 tb_invalidate_phys_page_range(addr1, addr1 + l, 0);
1824                 /* set dirty bit */
1825                 phys_ram_dirty[page >> TARGET_PAGE_BITS] = 1;                
1826             }
1827         } else {
1828             if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM &&
1829                 (pd & ~TARGET_PAGE_MASK) != IO_MEM_CODE) {
1830                 /* I/O case */
1831                 io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
1832                 if (l >= 4 && ((addr & 3) == 0)) {
1833                     /* 32 bit read access */
1834                     val = io_mem_read[io_index][2](addr);
1835                     stl_raw(buf, val);
1836                     l = 4;
1837                 } else if (l >= 2 && ((addr & 1) == 0)) {
1838                     /* 16 bit read access */
1839                     val = io_mem_read[io_index][1](addr);
1840                     stw_raw(buf, val);
1841                     l = 2;
1842                 } else {
1843                     /* 8 bit access */
1844                     val = io_mem_read[io_index][0](addr);
1845                     stb_raw(buf, val);
1846                     l = 1;
1847                 }
1848             } else {
1849                 /* RAM case */
1850                 ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) + 
1851                     (addr & ~TARGET_PAGE_MASK);
1852                 memcpy(buf, ptr, l);
1853             }
1854         }
1855         len -= l;
1856         buf += l;
1857         addr += l;
1858     }
1859 }
1860 #endif
1861
1862 /* virtual memory access for debug */
1863 int cpu_memory_rw_debug(CPUState *env, target_ulong addr, 
1864                         uint8_t *buf, int len, int is_write)
1865 {
1866     int l;
1867     target_ulong page, phys_addr;
1868
1869     while (len > 0) {
1870         page = addr & TARGET_PAGE_MASK;
1871         phys_addr = cpu_get_phys_page_debug(env, page);
1872         /* if no physical page mapped, return an error */
1873         if (phys_addr == -1)
1874             return -1;
1875         l = (page + TARGET_PAGE_SIZE) - addr;
1876         if (l > len)
1877             l = len;
1878         cpu_physical_memory_rw(phys_addr + (addr & ~TARGET_PAGE_MASK), 
1879                                buf, l, is_write);
1880         len -= l;
1881         buf += l;
1882         addr += l;
1883     }
1884     return 0;
1885 }
1886
1887 #if !defined(CONFIG_USER_ONLY) 
1888
1889 #define MMUSUFFIX _cmmu
1890 #define GETPC() NULL
1891 #define env cpu_single_env
1892
1893 #define SHIFT 0
1894 #include "softmmu_template.h"
1895
1896 #define SHIFT 1
1897 #include "softmmu_template.h"
1898
1899 #define SHIFT 2
1900 #include "softmmu_template.h"
1901
1902 #define SHIFT 3
1903 #include "softmmu_template.h"
1904
1905 #undef env
1906
1907 #endif