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