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