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