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