A first small step to convert the CRIS translator to TCG.
[qemu/malc.git] / exec.c
blobe9a5918645a56a76a322799f0c67eac8ef32945d
1 /*
2 * virtual page mapping and translated block handling
4 * Copyright (c) 2003 Fabrice Bellard
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.
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.
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
20 #include "config.h"
21 #ifdef _WIN32
22 #define WIN32_LEAN_AND_MEAN
23 #include <windows.h>
24 #else
25 #include <sys/types.h>
26 #include <sys/mman.h>
27 #endif
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <stdarg.h>
31 #include <string.h>
32 #include <errno.h>
33 #include <unistd.h>
34 #include <inttypes.h>
36 #include "cpu.h"
37 #include "exec-all.h"
38 #if defined(CONFIG_USER_ONLY)
39 #include <qemu.h>
40 #endif
42 //#define DEBUG_TB_INVALIDATE
43 //#define DEBUG_FLUSH
44 //#define DEBUG_TLB
45 //#define DEBUG_UNASSIGNED
47 /* make various TB consistency checks */
48 //#define DEBUG_TB_CHECK
49 //#define DEBUG_TLB_CHECK
51 //#define DEBUG_IOPORT
52 //#define DEBUG_SUBPAGE
54 #if !defined(CONFIG_USER_ONLY)
55 /* TB consistency checks only implemented for usermode emulation. */
56 #undef DEBUG_TB_CHECK
57 #endif
59 /* threshold to flush the translated code buffer */
60 #define CODE_GEN_BUFFER_MAX_SIZE (CODE_GEN_BUFFER_SIZE - code_gen_max_block_size())
62 #define SMC_BITMAP_USE_THRESHOLD 10
64 #define MMAP_AREA_START 0x00000000
65 #define MMAP_AREA_END 0xa8000000
67 #if defined(TARGET_SPARC64)
68 #define TARGET_PHYS_ADDR_SPACE_BITS 41
69 #elif defined(TARGET_SPARC)
70 #define TARGET_PHYS_ADDR_SPACE_BITS 36
71 #elif defined(TARGET_ALPHA)
72 #define TARGET_PHYS_ADDR_SPACE_BITS 42
73 #define TARGET_VIRT_ADDR_SPACE_BITS 42
74 #elif defined(TARGET_PPC64)
75 #define TARGET_PHYS_ADDR_SPACE_BITS 42
76 #else
77 /* Note: for compatibility with kqemu, we use 32 bits for x86_64 */
78 #define TARGET_PHYS_ADDR_SPACE_BITS 32
79 #endif
81 TranslationBlock tbs[CODE_GEN_MAX_BLOCKS];
82 TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE];
83 int nb_tbs;
84 /* any access to the tbs or the page table must use this lock */
85 spinlock_t tb_lock = SPIN_LOCK_UNLOCKED;
87 uint8_t code_gen_buffer[CODE_GEN_BUFFER_SIZE] __attribute__((aligned (32)));
88 uint8_t *code_gen_ptr;
90 int phys_ram_size;
91 int phys_ram_fd;
92 uint8_t *phys_ram_base;
93 uint8_t *phys_ram_dirty;
94 static ram_addr_t phys_ram_alloc_offset = 0;
96 CPUState *first_cpu;
97 /* current CPU in the current thread. It is only valid inside
98 cpu_exec() */
99 CPUState *cpu_single_env;
101 typedef struct PageDesc {
102 /* list of TBs intersecting this ram page */
103 TranslationBlock *first_tb;
104 /* in order to optimize self modifying code, we count the number
105 of lookups we do to a given page to use a bitmap */
106 unsigned int code_write_count;
107 uint8_t *code_bitmap;
108 #if defined(CONFIG_USER_ONLY)
109 unsigned long flags;
110 #endif
111 } PageDesc;
113 typedef struct PhysPageDesc {
114 /* offset in host memory of the page + io_index in the low 12 bits */
115 uint32_t phys_offset;
116 } PhysPageDesc;
118 #define L2_BITS 10
119 #if defined(CONFIG_USER_ONLY) && defined(TARGET_VIRT_ADDR_SPACE_BITS)
120 /* XXX: this is a temporary hack for alpha target.
121 * In the future, this is to be replaced by a multi-level table
122 * to actually be able to handle the complete 64 bits address space.
124 #define L1_BITS (TARGET_VIRT_ADDR_SPACE_BITS - L2_BITS - TARGET_PAGE_BITS)
125 #else
126 #define L1_BITS (32 - L2_BITS - TARGET_PAGE_BITS)
127 #endif
129 #define L1_SIZE (1 << L1_BITS)
130 #define L2_SIZE (1 << L2_BITS)
132 static void io_mem_init(void);
134 unsigned long qemu_real_host_page_size;
135 unsigned long qemu_host_page_bits;
136 unsigned long qemu_host_page_size;
137 unsigned long qemu_host_page_mask;
139 /* XXX: for system emulation, it could just be an array */
140 static PageDesc *l1_map[L1_SIZE];
141 PhysPageDesc **l1_phys_map;
143 /* io memory support */
144 CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
145 CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
146 void *io_mem_opaque[IO_MEM_NB_ENTRIES];
147 static int io_mem_nb;
148 #if defined(CONFIG_SOFTMMU)
149 static int io_mem_watch;
150 #endif
152 /* log support */
153 char *logfilename = "/tmp/qemu.log";
154 FILE *logfile;
155 int loglevel;
156 static int log_append = 0;
158 /* statistics */
159 static int tlb_flush_count;
160 static int tb_flush_count;
161 static int tb_phys_invalidate_count;
163 #define SUBPAGE_IDX(addr) ((addr) & ~TARGET_PAGE_MASK)
164 typedef struct subpage_t {
165 target_phys_addr_t base;
166 CPUReadMemoryFunc **mem_read[TARGET_PAGE_SIZE][4];
167 CPUWriteMemoryFunc **mem_write[TARGET_PAGE_SIZE][4];
168 void *opaque[TARGET_PAGE_SIZE][2][4];
169 } subpage_t;
171 static void page_init(void)
173 /* NOTE: we can always suppose that qemu_host_page_size >=
174 TARGET_PAGE_SIZE */
175 #ifdef _WIN32
177 SYSTEM_INFO system_info;
178 DWORD old_protect;
180 GetSystemInfo(&system_info);
181 qemu_real_host_page_size = system_info.dwPageSize;
183 VirtualProtect(code_gen_buffer, sizeof(code_gen_buffer),
184 PAGE_EXECUTE_READWRITE, &old_protect);
186 #else
187 qemu_real_host_page_size = getpagesize();
189 unsigned long start, end;
191 start = (unsigned long)code_gen_buffer;
192 start &= ~(qemu_real_host_page_size - 1);
194 end = (unsigned long)code_gen_buffer + sizeof(code_gen_buffer);
195 end += qemu_real_host_page_size - 1;
196 end &= ~(qemu_real_host_page_size - 1);
198 mprotect((void *)start, end - start,
199 PROT_READ | PROT_WRITE | PROT_EXEC);
201 #endif
203 if (qemu_host_page_size == 0)
204 qemu_host_page_size = qemu_real_host_page_size;
205 if (qemu_host_page_size < TARGET_PAGE_SIZE)
206 qemu_host_page_size = TARGET_PAGE_SIZE;
207 qemu_host_page_bits = 0;
208 while ((1 << qemu_host_page_bits) < qemu_host_page_size)
209 qemu_host_page_bits++;
210 qemu_host_page_mask = ~(qemu_host_page_size - 1);
211 l1_phys_map = qemu_vmalloc(L1_SIZE * sizeof(void *));
212 memset(l1_phys_map, 0, L1_SIZE * sizeof(void *));
214 #if !defined(_WIN32) && defined(CONFIG_USER_ONLY)
216 long long startaddr, endaddr;
217 FILE *f;
218 int n;
220 f = fopen("/proc/self/maps", "r");
221 if (f) {
222 do {
223 n = fscanf (f, "%llx-%llx %*[^\n]\n", &startaddr, &endaddr);
224 if (n == 2) {
225 page_set_flags(TARGET_PAGE_ALIGN(startaddr),
226 TARGET_PAGE_ALIGN(endaddr),
227 PAGE_RESERVED);
229 } while (!feof(f));
230 fclose(f);
233 #endif
236 static inline PageDesc *page_find_alloc(unsigned int index)
238 PageDesc **lp, *p;
240 lp = &l1_map[index >> L2_BITS];
241 p = *lp;
242 if (!p) {
243 /* allocate if not found */
244 p = qemu_malloc(sizeof(PageDesc) * L2_SIZE);
245 memset(p, 0, sizeof(PageDesc) * L2_SIZE);
246 *lp = p;
248 return p + (index & (L2_SIZE - 1));
251 static inline PageDesc *page_find(unsigned int index)
253 PageDesc *p;
255 p = l1_map[index >> L2_BITS];
256 if (!p)
257 return 0;
258 return p + (index & (L2_SIZE - 1));
261 static PhysPageDesc *phys_page_find_alloc(target_phys_addr_t index, int alloc)
263 void **lp, **p;
264 PhysPageDesc *pd;
266 p = (void **)l1_phys_map;
267 #if TARGET_PHYS_ADDR_SPACE_BITS > 32
269 #if TARGET_PHYS_ADDR_SPACE_BITS > (32 + L1_BITS)
270 #error unsupported TARGET_PHYS_ADDR_SPACE_BITS
271 #endif
272 lp = p + ((index >> (L1_BITS + L2_BITS)) & (L1_SIZE - 1));
273 p = *lp;
274 if (!p) {
275 /* allocate if not found */
276 if (!alloc)
277 return NULL;
278 p = qemu_vmalloc(sizeof(void *) * L1_SIZE);
279 memset(p, 0, sizeof(void *) * L1_SIZE);
280 *lp = p;
282 #endif
283 lp = p + ((index >> L2_BITS) & (L1_SIZE - 1));
284 pd = *lp;
285 if (!pd) {
286 int i;
287 /* allocate if not found */
288 if (!alloc)
289 return NULL;
290 pd = qemu_vmalloc(sizeof(PhysPageDesc) * L2_SIZE);
291 *lp = pd;
292 for (i = 0; i < L2_SIZE; i++)
293 pd[i].phys_offset = IO_MEM_UNASSIGNED;
295 return ((PhysPageDesc *)pd) + (index & (L2_SIZE - 1));
298 static inline PhysPageDesc *phys_page_find(target_phys_addr_t index)
300 return phys_page_find_alloc(index, 0);
303 #if !defined(CONFIG_USER_ONLY)
304 static void tlb_protect_code(ram_addr_t ram_addr);
305 static void tlb_unprotect_code_phys(CPUState *env, ram_addr_t ram_addr,
306 target_ulong vaddr);
307 #endif
309 void cpu_exec_init(CPUState *env)
311 CPUState **penv;
312 int cpu_index;
314 if (!code_gen_ptr) {
315 cpu_gen_init();
316 code_gen_ptr = code_gen_buffer;
317 page_init();
318 io_mem_init();
320 env->next_cpu = NULL;
321 penv = &first_cpu;
322 cpu_index = 0;
323 while (*penv != NULL) {
324 penv = (CPUState **)&(*penv)->next_cpu;
325 cpu_index++;
327 env->cpu_index = cpu_index;
328 env->nb_watchpoints = 0;
329 *penv = env;
332 static inline void invalidate_page_bitmap(PageDesc *p)
334 if (p->code_bitmap) {
335 qemu_free(p->code_bitmap);
336 p->code_bitmap = NULL;
338 p->code_write_count = 0;
341 /* set to NULL all the 'first_tb' fields in all PageDescs */
342 static void page_flush_tb(void)
344 int i, j;
345 PageDesc *p;
347 for(i = 0; i < L1_SIZE; i++) {
348 p = l1_map[i];
349 if (p) {
350 for(j = 0; j < L2_SIZE; j++) {
351 p->first_tb = NULL;
352 invalidate_page_bitmap(p);
353 p++;
359 /* flush all the translation blocks */
360 /* XXX: tb_flush is currently not thread safe */
361 void tb_flush(CPUState *env1)
363 CPUState *env;
364 #if defined(DEBUG_FLUSH)
365 printf("qemu: flush code_size=%ld nb_tbs=%d avg_tb_size=%ld\n",
366 (unsigned long)(code_gen_ptr - code_gen_buffer),
367 nb_tbs, nb_tbs > 0 ?
368 ((unsigned long)(code_gen_ptr - code_gen_buffer)) / nb_tbs : 0);
369 #endif
370 nb_tbs = 0;
372 for(env = first_cpu; env != NULL; env = env->next_cpu) {
373 memset (env->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof (void *));
376 memset (tb_phys_hash, 0, CODE_GEN_PHYS_HASH_SIZE * sizeof (void *));
377 page_flush_tb();
379 code_gen_ptr = code_gen_buffer;
380 /* XXX: flush processor icache at this point if cache flush is
381 expensive */
382 tb_flush_count++;
385 #ifdef DEBUG_TB_CHECK
387 static void tb_invalidate_check(target_ulong address)
389 TranslationBlock *tb;
390 int i;
391 address &= TARGET_PAGE_MASK;
392 for(i = 0;i < CODE_GEN_PHYS_HASH_SIZE; i++) {
393 for(tb = tb_phys_hash[i]; tb != NULL; tb = tb->phys_hash_next) {
394 if (!(address + TARGET_PAGE_SIZE <= tb->pc ||
395 address >= tb->pc + tb->size)) {
396 printf("ERROR invalidate: address=%08lx PC=%08lx size=%04x\n",
397 address, (long)tb->pc, tb->size);
403 /* verify that all the pages have correct rights for code */
404 static void tb_page_check(void)
406 TranslationBlock *tb;
407 int i, flags1, flags2;
409 for(i = 0;i < CODE_GEN_PHYS_HASH_SIZE; i++) {
410 for(tb = tb_phys_hash[i]; tb != NULL; tb = tb->phys_hash_next) {
411 flags1 = page_get_flags(tb->pc);
412 flags2 = page_get_flags(tb->pc + tb->size - 1);
413 if ((flags1 & PAGE_WRITE) || (flags2 & PAGE_WRITE)) {
414 printf("ERROR page flags: PC=%08lx size=%04x f1=%x f2=%x\n",
415 (long)tb->pc, tb->size, flags1, flags2);
421 void tb_jmp_check(TranslationBlock *tb)
423 TranslationBlock *tb1;
424 unsigned int n1;
426 /* suppress any remaining jumps to this TB */
427 tb1 = tb->jmp_first;
428 for(;;) {
429 n1 = (long)tb1 & 3;
430 tb1 = (TranslationBlock *)((long)tb1 & ~3);
431 if (n1 == 2)
432 break;
433 tb1 = tb1->jmp_next[n1];
435 /* check end of list */
436 if (tb1 != tb) {
437 printf("ERROR: jmp_list from 0x%08lx\n", (long)tb);
441 #endif
443 /* invalidate one TB */
444 static inline void tb_remove(TranslationBlock **ptb, TranslationBlock *tb,
445 int next_offset)
447 TranslationBlock *tb1;
448 for(;;) {
449 tb1 = *ptb;
450 if (tb1 == tb) {
451 *ptb = *(TranslationBlock **)((char *)tb1 + next_offset);
452 break;
454 ptb = (TranslationBlock **)((char *)tb1 + next_offset);
458 static inline void tb_page_remove(TranslationBlock **ptb, TranslationBlock *tb)
460 TranslationBlock *tb1;
461 unsigned int n1;
463 for(;;) {
464 tb1 = *ptb;
465 n1 = (long)tb1 & 3;
466 tb1 = (TranslationBlock *)((long)tb1 & ~3);
467 if (tb1 == tb) {
468 *ptb = tb1->page_next[n1];
469 break;
471 ptb = &tb1->page_next[n1];
475 static inline void tb_jmp_remove(TranslationBlock *tb, int n)
477 TranslationBlock *tb1, **ptb;
478 unsigned int n1;
480 ptb = &tb->jmp_next[n];
481 tb1 = *ptb;
482 if (tb1) {
483 /* find tb(n) in circular list */
484 for(;;) {
485 tb1 = *ptb;
486 n1 = (long)tb1 & 3;
487 tb1 = (TranslationBlock *)((long)tb1 & ~3);
488 if (n1 == n && tb1 == tb)
489 break;
490 if (n1 == 2) {
491 ptb = &tb1->jmp_first;
492 } else {
493 ptb = &tb1->jmp_next[n1];
496 /* now we can suppress tb(n) from the list */
497 *ptb = tb->jmp_next[n];
499 tb->jmp_next[n] = NULL;
503 /* reset the jump entry 'n' of a TB so that it is not chained to
504 another TB */
505 static inline void tb_reset_jump(TranslationBlock *tb, int n)
507 tb_set_jmp_target(tb, n, (unsigned long)(tb->tc_ptr + tb->tb_next_offset[n]));
510 static inline void tb_phys_invalidate(TranslationBlock *tb, unsigned int page_addr)
512 CPUState *env;
513 PageDesc *p;
514 unsigned int h, n1;
515 target_ulong phys_pc;
516 TranslationBlock *tb1, *tb2;
518 /* remove the TB from the hash list */
519 phys_pc = tb->page_addr[0] + (tb->pc & ~TARGET_PAGE_MASK);
520 h = tb_phys_hash_func(phys_pc);
521 tb_remove(&tb_phys_hash[h], tb,
522 offsetof(TranslationBlock, phys_hash_next));
524 /* remove the TB from the page list */
525 if (tb->page_addr[0] != page_addr) {
526 p = page_find(tb->page_addr[0] >> TARGET_PAGE_BITS);
527 tb_page_remove(&p->first_tb, tb);
528 invalidate_page_bitmap(p);
530 if (tb->page_addr[1] != -1 && tb->page_addr[1] != page_addr) {
531 p = page_find(tb->page_addr[1] >> TARGET_PAGE_BITS);
532 tb_page_remove(&p->first_tb, tb);
533 invalidate_page_bitmap(p);
536 tb_invalidated_flag = 1;
538 /* remove the TB from the hash list */
539 h = tb_jmp_cache_hash_func(tb->pc);
540 for(env = first_cpu; env != NULL; env = env->next_cpu) {
541 if (env->tb_jmp_cache[h] == tb)
542 env->tb_jmp_cache[h] = NULL;
545 /* suppress this TB from the two jump lists */
546 tb_jmp_remove(tb, 0);
547 tb_jmp_remove(tb, 1);
549 /* suppress any remaining jumps to this TB */
550 tb1 = tb->jmp_first;
551 for(;;) {
552 n1 = (long)tb1 & 3;
553 if (n1 == 2)
554 break;
555 tb1 = (TranslationBlock *)((long)tb1 & ~3);
556 tb2 = tb1->jmp_next[n1];
557 tb_reset_jump(tb1, n1);
558 tb1->jmp_next[n1] = NULL;
559 tb1 = tb2;
561 tb->jmp_first = (TranslationBlock *)((long)tb | 2); /* fail safe */
563 tb_phys_invalidate_count++;
566 static inline void set_bits(uint8_t *tab, int start, int len)
568 int end, mask, end1;
570 end = start + len;
571 tab += start >> 3;
572 mask = 0xff << (start & 7);
573 if ((start & ~7) == (end & ~7)) {
574 if (start < end) {
575 mask &= ~(0xff << (end & 7));
576 *tab |= mask;
578 } else {
579 *tab++ |= mask;
580 start = (start + 8) & ~7;
581 end1 = end & ~7;
582 while (start < end1) {
583 *tab++ = 0xff;
584 start += 8;
586 if (start < end) {
587 mask = ~(0xff << (end & 7));
588 *tab |= mask;
593 static void build_page_bitmap(PageDesc *p)
595 int n, tb_start, tb_end;
596 TranslationBlock *tb;
598 p->code_bitmap = qemu_malloc(TARGET_PAGE_SIZE / 8);
599 if (!p->code_bitmap)
600 return;
601 memset(p->code_bitmap, 0, TARGET_PAGE_SIZE / 8);
603 tb = p->first_tb;
604 while (tb != NULL) {
605 n = (long)tb & 3;
606 tb = (TranslationBlock *)((long)tb & ~3);
607 /* NOTE: this is subtle as a TB may span two physical pages */
608 if (n == 0) {
609 /* NOTE: tb_end may be after the end of the page, but
610 it is not a problem */
611 tb_start = tb->pc & ~TARGET_PAGE_MASK;
612 tb_end = tb_start + tb->size;
613 if (tb_end > TARGET_PAGE_SIZE)
614 tb_end = TARGET_PAGE_SIZE;
615 } else {
616 tb_start = 0;
617 tb_end = ((tb->pc + tb->size) & ~TARGET_PAGE_MASK);
619 set_bits(p->code_bitmap, tb_start, tb_end - tb_start);
620 tb = tb->page_next[n];
624 #ifdef TARGET_HAS_PRECISE_SMC
626 static void tb_gen_code(CPUState *env,
627 target_ulong pc, target_ulong cs_base, int flags,
628 int cflags)
630 TranslationBlock *tb;
631 uint8_t *tc_ptr;
632 target_ulong phys_pc, phys_page2, virt_page2;
633 int code_gen_size;
635 phys_pc = get_phys_addr_code(env, pc);
636 tb = tb_alloc(pc);
637 if (!tb) {
638 /* flush must be done */
639 tb_flush(env);
640 /* cannot fail at this point */
641 tb = tb_alloc(pc);
643 tc_ptr = code_gen_ptr;
644 tb->tc_ptr = tc_ptr;
645 tb->cs_base = cs_base;
646 tb->flags = flags;
647 tb->cflags = cflags;
648 cpu_gen_code(env, tb, &code_gen_size);
649 code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));
651 /* check next page if needed */
652 virt_page2 = (pc + tb->size - 1) & TARGET_PAGE_MASK;
653 phys_page2 = -1;
654 if ((pc & TARGET_PAGE_MASK) != virt_page2) {
655 phys_page2 = get_phys_addr_code(env, virt_page2);
657 tb_link_phys(tb, phys_pc, phys_page2);
659 #endif
661 /* invalidate all TBs which intersect with the target physical page
662 starting in range [start;end[. NOTE: start and end must refer to
663 the same physical page. 'is_cpu_write_access' should be true if called
664 from a real cpu write access: the virtual CPU will exit the current
665 TB if code is modified inside this TB. */
666 void tb_invalidate_phys_page_range(target_ulong start, target_ulong end,
667 int is_cpu_write_access)
669 int n, current_tb_modified, current_tb_not_found, current_flags;
670 CPUState *env = cpu_single_env;
671 PageDesc *p;
672 TranslationBlock *tb, *tb_next, *current_tb, *saved_tb;
673 target_ulong tb_start, tb_end;
674 target_ulong current_pc, current_cs_base;
676 p = page_find(start >> TARGET_PAGE_BITS);
677 if (!p)
678 return;
679 if (!p->code_bitmap &&
680 ++p->code_write_count >= SMC_BITMAP_USE_THRESHOLD &&
681 is_cpu_write_access) {
682 /* build code bitmap */
683 build_page_bitmap(p);
686 /* we remove all the TBs in the range [start, end[ */
687 /* XXX: see if in some cases it could be faster to invalidate all the code */
688 current_tb_not_found = is_cpu_write_access;
689 current_tb_modified = 0;
690 current_tb = NULL; /* avoid warning */
691 current_pc = 0; /* avoid warning */
692 current_cs_base = 0; /* avoid warning */
693 current_flags = 0; /* avoid warning */
694 tb = p->first_tb;
695 while (tb != NULL) {
696 n = (long)tb & 3;
697 tb = (TranslationBlock *)((long)tb & ~3);
698 tb_next = tb->page_next[n];
699 /* NOTE: this is subtle as a TB may span two physical pages */
700 if (n == 0) {
701 /* NOTE: tb_end may be after the end of the page, but
702 it is not a problem */
703 tb_start = tb->page_addr[0] + (tb->pc & ~TARGET_PAGE_MASK);
704 tb_end = tb_start + tb->size;
705 } else {
706 tb_start = tb->page_addr[1];
707 tb_end = tb_start + ((tb->pc + tb->size) & ~TARGET_PAGE_MASK);
709 if (!(tb_end <= start || tb_start >= end)) {
710 #ifdef TARGET_HAS_PRECISE_SMC
711 if (current_tb_not_found) {
712 current_tb_not_found = 0;
713 current_tb = NULL;
714 if (env->mem_write_pc) {
715 /* now we have a real cpu fault */
716 current_tb = tb_find_pc(env->mem_write_pc);
719 if (current_tb == tb &&
720 !(current_tb->cflags & CF_SINGLE_INSN)) {
721 /* If we are modifying the current TB, we must stop
722 its execution. We could be more precise by checking
723 that the modification is after the current PC, but it
724 would require a specialized function to partially
725 restore the CPU state */
727 current_tb_modified = 1;
728 cpu_restore_state(current_tb, env,
729 env->mem_write_pc, NULL);
730 #if defined(TARGET_I386)
731 current_flags = env->hflags;
732 current_flags |= (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK));
733 current_cs_base = (target_ulong)env->segs[R_CS].base;
734 current_pc = current_cs_base + env->eip;
735 #else
736 #error unsupported CPU
737 #endif
739 #endif /* TARGET_HAS_PRECISE_SMC */
740 /* we need to do that to handle the case where a signal
741 occurs while doing tb_phys_invalidate() */
742 saved_tb = NULL;
743 if (env) {
744 saved_tb = env->current_tb;
745 env->current_tb = NULL;
747 tb_phys_invalidate(tb, -1);
748 if (env) {
749 env->current_tb = saved_tb;
750 if (env->interrupt_request && env->current_tb)
751 cpu_interrupt(env, env->interrupt_request);
754 tb = tb_next;
756 #if !defined(CONFIG_USER_ONLY)
757 /* if no code remaining, no need to continue to use slow writes */
758 if (!p->first_tb) {
759 invalidate_page_bitmap(p);
760 if (is_cpu_write_access) {
761 tlb_unprotect_code_phys(env, start, env->mem_write_vaddr);
764 #endif
765 #ifdef TARGET_HAS_PRECISE_SMC
766 if (current_tb_modified) {
767 /* we generate a block containing just the instruction
768 modifying the memory. It will ensure that it cannot modify
769 itself */
770 env->current_tb = NULL;
771 tb_gen_code(env, current_pc, current_cs_base, current_flags,
772 CF_SINGLE_INSN);
773 cpu_resume_from_signal(env, NULL);
775 #endif
778 /* len must be <= 8 and start must be a multiple of len */
779 static inline void tb_invalidate_phys_page_fast(target_ulong start, int len)
781 PageDesc *p;
782 int offset, b;
783 #if 0
784 if (1) {
785 if (loglevel) {
786 fprintf(logfile, "modifying code at 0x%x size=%d EIP=%x PC=%08x\n",
787 cpu_single_env->mem_write_vaddr, len,
788 cpu_single_env->eip,
789 cpu_single_env->eip + (long)cpu_single_env->segs[R_CS].base);
792 #endif
793 p = page_find(start >> TARGET_PAGE_BITS);
794 if (!p)
795 return;
796 if (p->code_bitmap) {
797 offset = start & ~TARGET_PAGE_MASK;
798 b = p->code_bitmap[offset >> 3] >> (offset & 7);
799 if (b & ((1 << len) - 1))
800 goto do_invalidate;
801 } else {
802 do_invalidate:
803 tb_invalidate_phys_page_range(start, start + len, 1);
807 #if !defined(CONFIG_SOFTMMU)
808 static void tb_invalidate_phys_page(target_ulong addr,
809 unsigned long pc, void *puc)
811 int n, current_flags, current_tb_modified;
812 target_ulong current_pc, current_cs_base;
813 PageDesc *p;
814 TranslationBlock *tb, *current_tb;
815 #ifdef TARGET_HAS_PRECISE_SMC
816 CPUState *env = cpu_single_env;
817 #endif
819 addr &= TARGET_PAGE_MASK;
820 p = page_find(addr >> TARGET_PAGE_BITS);
821 if (!p)
822 return;
823 tb = p->first_tb;
824 current_tb_modified = 0;
825 current_tb = NULL;
826 current_pc = 0; /* avoid warning */
827 current_cs_base = 0; /* avoid warning */
828 current_flags = 0; /* avoid warning */
829 #ifdef TARGET_HAS_PRECISE_SMC
830 if (tb && pc != 0) {
831 current_tb = tb_find_pc(pc);
833 #endif
834 while (tb != NULL) {
835 n = (long)tb & 3;
836 tb = (TranslationBlock *)((long)tb & ~3);
837 #ifdef TARGET_HAS_PRECISE_SMC
838 if (current_tb == tb &&
839 !(current_tb->cflags & CF_SINGLE_INSN)) {
840 /* If we are modifying the current TB, we must stop
841 its execution. We could be more precise by checking
842 that the modification is after the current PC, but it
843 would require a specialized function to partially
844 restore the CPU state */
846 current_tb_modified = 1;
847 cpu_restore_state(current_tb, env, pc, puc);
848 #if defined(TARGET_I386)
849 current_flags = env->hflags;
850 current_flags |= (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK));
851 current_cs_base = (target_ulong)env->segs[R_CS].base;
852 current_pc = current_cs_base + env->eip;
853 #else
854 #error unsupported CPU
855 #endif
857 #endif /* TARGET_HAS_PRECISE_SMC */
858 tb_phys_invalidate(tb, addr);
859 tb = tb->page_next[n];
861 p->first_tb = NULL;
862 #ifdef TARGET_HAS_PRECISE_SMC
863 if (current_tb_modified) {
864 /* we generate a block containing just the instruction
865 modifying the memory. It will ensure that it cannot modify
866 itself */
867 env->current_tb = NULL;
868 tb_gen_code(env, current_pc, current_cs_base, current_flags,
869 CF_SINGLE_INSN);
870 cpu_resume_from_signal(env, puc);
872 #endif
874 #endif
876 /* add the tb in the target page and protect it if necessary */
877 static inline void tb_alloc_page(TranslationBlock *tb,
878 unsigned int n, target_ulong page_addr)
880 PageDesc *p;
881 TranslationBlock *last_first_tb;
883 tb->page_addr[n] = page_addr;
884 p = page_find_alloc(page_addr >> TARGET_PAGE_BITS);
885 tb->page_next[n] = p->first_tb;
886 last_first_tb = p->first_tb;
887 p->first_tb = (TranslationBlock *)((long)tb | n);
888 invalidate_page_bitmap(p);
890 #if defined(TARGET_HAS_SMC) || 1
892 #if defined(CONFIG_USER_ONLY)
893 if (p->flags & PAGE_WRITE) {
894 target_ulong addr;
895 PageDesc *p2;
896 int prot;
898 /* force the host page as non writable (writes will have a
899 page fault + mprotect overhead) */
900 page_addr &= qemu_host_page_mask;
901 prot = 0;
902 for(addr = page_addr; addr < page_addr + qemu_host_page_size;
903 addr += TARGET_PAGE_SIZE) {
905 p2 = page_find (addr >> TARGET_PAGE_BITS);
906 if (!p2)
907 continue;
908 prot |= p2->flags;
909 p2->flags &= ~PAGE_WRITE;
910 page_get_flags(addr);
912 mprotect(g2h(page_addr), qemu_host_page_size,
913 (prot & PAGE_BITS) & ~PAGE_WRITE);
914 #ifdef DEBUG_TB_INVALIDATE
915 printf("protecting code page: 0x" TARGET_FMT_lx "\n",
916 page_addr);
917 #endif
919 #else
920 /* if some code is already present, then the pages are already
921 protected. So we handle the case where only the first TB is
922 allocated in a physical page */
923 if (!last_first_tb) {
924 tlb_protect_code(page_addr);
926 #endif
928 #endif /* TARGET_HAS_SMC */
931 /* Allocate a new translation block. Flush the translation buffer if
932 too many translation blocks or too much generated code. */
933 TranslationBlock *tb_alloc(target_ulong pc)
935 TranslationBlock *tb;
937 if (nb_tbs >= CODE_GEN_MAX_BLOCKS ||
938 (code_gen_ptr - code_gen_buffer) >= CODE_GEN_BUFFER_MAX_SIZE)
939 return NULL;
940 tb = &tbs[nb_tbs++];
941 tb->pc = pc;
942 tb->cflags = 0;
943 return tb;
946 /* add a new TB and link it to the physical page tables. phys_page2 is
947 (-1) to indicate that only one page contains the TB. */
948 void tb_link_phys(TranslationBlock *tb,
949 target_ulong phys_pc, target_ulong phys_page2)
951 unsigned int h;
952 TranslationBlock **ptb;
954 /* add in the physical hash table */
955 h = tb_phys_hash_func(phys_pc);
956 ptb = &tb_phys_hash[h];
957 tb->phys_hash_next = *ptb;
958 *ptb = tb;
960 /* add in the page list */
961 tb_alloc_page(tb, 0, phys_pc & TARGET_PAGE_MASK);
962 if (phys_page2 != -1)
963 tb_alloc_page(tb, 1, phys_page2);
964 else
965 tb->page_addr[1] = -1;
967 tb->jmp_first = (TranslationBlock *)((long)tb | 2);
968 tb->jmp_next[0] = NULL;
969 tb->jmp_next[1] = NULL;
971 /* init original jump addresses */
972 if (tb->tb_next_offset[0] != 0xffff)
973 tb_reset_jump(tb, 0);
974 if (tb->tb_next_offset[1] != 0xffff)
975 tb_reset_jump(tb, 1);
977 #ifdef DEBUG_TB_CHECK
978 tb_page_check();
979 #endif
982 /* find the TB 'tb' such that tb[0].tc_ptr <= tc_ptr <
983 tb[1].tc_ptr. Return NULL if not found */
984 TranslationBlock *tb_find_pc(unsigned long tc_ptr)
986 int m_min, m_max, m;
987 unsigned long v;
988 TranslationBlock *tb;
990 if (nb_tbs <= 0)
991 return NULL;
992 if (tc_ptr < (unsigned long)code_gen_buffer ||
993 tc_ptr >= (unsigned long)code_gen_ptr)
994 return NULL;
995 /* binary search (cf Knuth) */
996 m_min = 0;
997 m_max = nb_tbs - 1;
998 while (m_min <= m_max) {
999 m = (m_min + m_max) >> 1;
1000 tb = &tbs[m];
1001 v = (unsigned long)tb->tc_ptr;
1002 if (v == tc_ptr)
1003 return tb;
1004 else if (tc_ptr < v) {
1005 m_max = m - 1;
1006 } else {
1007 m_min = m + 1;
1010 return &tbs[m_max];
1013 static void tb_reset_jump_recursive(TranslationBlock *tb);
1015 static inline void tb_reset_jump_recursive2(TranslationBlock *tb, int n)
1017 TranslationBlock *tb1, *tb_next, **ptb;
1018 unsigned int n1;
1020 tb1 = tb->jmp_next[n];
1021 if (tb1 != NULL) {
1022 /* find head of list */
1023 for(;;) {
1024 n1 = (long)tb1 & 3;
1025 tb1 = (TranslationBlock *)((long)tb1 & ~3);
1026 if (n1 == 2)
1027 break;
1028 tb1 = tb1->jmp_next[n1];
1030 /* we are now sure now that tb jumps to tb1 */
1031 tb_next = tb1;
1033 /* remove tb from the jmp_first list */
1034 ptb = &tb_next->jmp_first;
1035 for(;;) {
1036 tb1 = *ptb;
1037 n1 = (long)tb1 & 3;
1038 tb1 = (TranslationBlock *)((long)tb1 & ~3);
1039 if (n1 == n && tb1 == tb)
1040 break;
1041 ptb = &tb1->jmp_next[n1];
1043 *ptb = tb->jmp_next[n];
1044 tb->jmp_next[n] = NULL;
1046 /* suppress the jump to next tb in generated code */
1047 tb_reset_jump(tb, n);
1049 /* suppress jumps in the tb on which we could have jumped */
1050 tb_reset_jump_recursive(tb_next);
1054 static void tb_reset_jump_recursive(TranslationBlock *tb)
1056 tb_reset_jump_recursive2(tb, 0);
1057 tb_reset_jump_recursive2(tb, 1);
1060 #if defined(TARGET_HAS_ICE)
1061 static void breakpoint_invalidate(CPUState *env, target_ulong pc)
1063 target_phys_addr_t addr;
1064 target_ulong pd;
1065 ram_addr_t ram_addr;
1066 PhysPageDesc *p;
1068 addr = cpu_get_phys_page_debug(env, pc);
1069 p = phys_page_find(addr >> TARGET_PAGE_BITS);
1070 if (!p) {
1071 pd = IO_MEM_UNASSIGNED;
1072 } else {
1073 pd = p->phys_offset;
1075 ram_addr = (pd & TARGET_PAGE_MASK) | (pc & ~TARGET_PAGE_MASK);
1076 tb_invalidate_phys_page_range(ram_addr, ram_addr + 1, 0);
1078 #endif
1080 /* Add a watchpoint. */
1081 int cpu_watchpoint_insert(CPUState *env, target_ulong addr)
1083 int i;
1085 for (i = 0; i < env->nb_watchpoints; i++) {
1086 if (addr == env->watchpoint[i].vaddr)
1087 return 0;
1089 if (env->nb_watchpoints >= MAX_WATCHPOINTS)
1090 return -1;
1092 i = env->nb_watchpoints++;
1093 env->watchpoint[i].vaddr = addr;
1094 tlb_flush_page(env, addr);
1095 /* FIXME: This flush is needed because of the hack to make memory ops
1096 terminate the TB. It can be removed once the proper IO trap and
1097 re-execute bits are in. */
1098 tb_flush(env);
1099 return i;
1102 /* Remove a watchpoint. */
1103 int cpu_watchpoint_remove(CPUState *env, target_ulong addr)
1105 int i;
1107 for (i = 0; i < env->nb_watchpoints; i++) {
1108 if (addr == env->watchpoint[i].vaddr) {
1109 env->nb_watchpoints--;
1110 env->watchpoint[i] = env->watchpoint[env->nb_watchpoints];
1111 tlb_flush_page(env, addr);
1112 return 0;
1115 return -1;
1118 /* add a breakpoint. EXCP_DEBUG is returned by the CPU loop if a
1119 breakpoint is reached */
1120 int cpu_breakpoint_insert(CPUState *env, target_ulong pc)
1122 #if defined(TARGET_HAS_ICE)
1123 int i;
1125 for(i = 0; i < env->nb_breakpoints; i++) {
1126 if (env->breakpoints[i] == pc)
1127 return 0;
1130 if (env->nb_breakpoints >= MAX_BREAKPOINTS)
1131 return -1;
1132 env->breakpoints[env->nb_breakpoints++] = pc;
1134 breakpoint_invalidate(env, pc);
1135 return 0;
1136 #else
1137 return -1;
1138 #endif
1141 /* remove a breakpoint */
1142 int cpu_breakpoint_remove(CPUState *env, target_ulong pc)
1144 #if defined(TARGET_HAS_ICE)
1145 int i;
1146 for(i = 0; i < env->nb_breakpoints; i++) {
1147 if (env->breakpoints[i] == pc)
1148 goto found;
1150 return -1;
1151 found:
1152 env->nb_breakpoints--;
1153 if (i < env->nb_breakpoints)
1154 env->breakpoints[i] = env->breakpoints[env->nb_breakpoints];
1156 breakpoint_invalidate(env, pc);
1157 return 0;
1158 #else
1159 return -1;
1160 #endif
1163 /* enable or disable single step mode. EXCP_DEBUG is returned by the
1164 CPU loop after each instruction */
1165 void cpu_single_step(CPUState *env, int enabled)
1167 #if defined(TARGET_HAS_ICE)
1168 if (env->singlestep_enabled != enabled) {
1169 env->singlestep_enabled = enabled;
1170 /* must flush all the translated code to avoid inconsistancies */
1171 /* XXX: only flush what is necessary */
1172 tb_flush(env);
1174 #endif
1177 /* enable or disable low levels log */
1178 void cpu_set_log(int log_flags)
1180 loglevel = log_flags;
1181 if (loglevel && !logfile) {
1182 logfile = fopen(logfilename, log_append ? "a" : "w");
1183 if (!logfile) {
1184 perror(logfilename);
1185 _exit(1);
1187 #if !defined(CONFIG_SOFTMMU)
1188 /* must avoid mmap() usage of glibc by setting a buffer "by hand" */
1190 static uint8_t logfile_buf[4096];
1191 setvbuf(logfile, logfile_buf, _IOLBF, sizeof(logfile_buf));
1193 #else
1194 setvbuf(logfile, NULL, _IOLBF, 0);
1195 #endif
1196 log_append = 1;
1198 if (!loglevel && logfile) {
1199 fclose(logfile);
1200 logfile = NULL;
1204 void cpu_set_log_filename(const char *filename)
1206 logfilename = strdup(filename);
1207 if (logfile) {
1208 fclose(logfile);
1209 logfile = NULL;
1211 cpu_set_log(loglevel);
1214 /* mask must never be zero, except for A20 change call */
1215 void cpu_interrupt(CPUState *env, int mask)
1217 TranslationBlock *tb;
1218 static int interrupt_lock;
1220 env->interrupt_request |= mask;
1221 /* if the cpu is currently executing code, we must unlink it and
1222 all the potentially executing TB */
1223 tb = env->current_tb;
1224 if (tb && !testandset(&interrupt_lock)) {
1225 env->current_tb = NULL;
1226 tb_reset_jump_recursive(tb);
1227 interrupt_lock = 0;
1231 void cpu_reset_interrupt(CPUState *env, int mask)
1233 env->interrupt_request &= ~mask;
1236 CPULogItem cpu_log_items[] = {
1237 { CPU_LOG_TB_OUT_ASM, "out_asm",
1238 "show generated host assembly code for each compiled TB" },
1239 { CPU_LOG_TB_IN_ASM, "in_asm",
1240 "show target assembly code for each compiled TB" },
1241 { CPU_LOG_TB_OP, "op",
1242 "show micro ops for each compiled TB" },
1243 #ifdef TARGET_I386
1244 { CPU_LOG_TB_OP_OPT, "op_opt",
1245 "show micro ops before eflags optimization" },
1246 #endif
1247 { CPU_LOG_INT, "int",
1248 "show interrupts/exceptions in short format" },
1249 { CPU_LOG_EXEC, "exec",
1250 "show trace before each executed TB (lots of logs)" },
1251 { CPU_LOG_TB_CPU, "cpu",
1252 "show CPU state before block translation" },
1253 #ifdef TARGET_I386
1254 { CPU_LOG_PCALL, "pcall",
1255 "show protected mode far calls/returns/exceptions" },
1256 #endif
1257 #ifdef DEBUG_IOPORT
1258 { CPU_LOG_IOPORT, "ioport",
1259 "show all i/o ports accesses" },
1260 #endif
1261 { 0, NULL, NULL },
1264 static int cmp1(const char *s1, int n, const char *s2)
1266 if (strlen(s2) != n)
1267 return 0;
1268 return memcmp(s1, s2, n) == 0;
1271 /* takes a comma separated list of log masks. Return 0 if error. */
1272 int cpu_str_to_log_mask(const char *str)
1274 CPULogItem *item;
1275 int mask;
1276 const char *p, *p1;
1278 p = str;
1279 mask = 0;
1280 for(;;) {
1281 p1 = strchr(p, ',');
1282 if (!p1)
1283 p1 = p + strlen(p);
1284 if(cmp1(p,p1-p,"all")) {
1285 for(item = cpu_log_items; item->mask != 0; item++) {
1286 mask |= item->mask;
1288 } else {
1289 for(item = cpu_log_items; item->mask != 0; item++) {
1290 if (cmp1(p, p1 - p, item->name))
1291 goto found;
1293 return 0;
1295 found:
1296 mask |= item->mask;
1297 if (*p1 != ',')
1298 break;
1299 p = p1 + 1;
1301 return mask;
1304 void cpu_abort(CPUState *env, const char *fmt, ...)
1306 va_list ap;
1307 va_list ap2;
1309 va_start(ap, fmt);
1310 va_copy(ap2, ap);
1311 fprintf(stderr, "qemu: fatal: ");
1312 vfprintf(stderr, fmt, ap);
1313 fprintf(stderr, "\n");
1314 #ifdef TARGET_I386
1315 if(env->intercept & INTERCEPT_SVM_MASK) {
1316 /* most probably the virtual machine should not
1317 be shut down but rather caught by the VMM */
1318 vmexit(SVM_EXIT_SHUTDOWN, 0);
1320 cpu_dump_state(env, stderr, fprintf, X86_DUMP_FPU | X86_DUMP_CCOP);
1321 #else
1322 cpu_dump_state(env, stderr, fprintf, 0);
1323 #endif
1324 if (logfile) {
1325 fprintf(logfile, "qemu: fatal: ");
1326 vfprintf(logfile, fmt, ap2);
1327 fprintf(logfile, "\n");
1328 #ifdef TARGET_I386
1329 cpu_dump_state(env, logfile, fprintf, X86_DUMP_FPU | X86_DUMP_CCOP);
1330 #else
1331 cpu_dump_state(env, logfile, fprintf, 0);
1332 #endif
1333 fflush(logfile);
1334 fclose(logfile);
1336 va_end(ap2);
1337 va_end(ap);
1338 abort();
1341 CPUState *cpu_copy(CPUState *env)
1343 CPUState *new_env = cpu_init(env->cpu_model_str);
1344 /* preserve chaining and index */
1345 CPUState *next_cpu = new_env->next_cpu;
1346 int cpu_index = new_env->cpu_index;
1347 memcpy(new_env, env, sizeof(CPUState));
1348 new_env->next_cpu = next_cpu;
1349 new_env->cpu_index = cpu_index;
1350 return new_env;
1353 #if !defined(CONFIG_USER_ONLY)
1355 /* NOTE: if flush_global is true, also flush global entries (not
1356 implemented yet) */
1357 void tlb_flush(CPUState *env, int flush_global)
1359 int i;
1361 #if defined(DEBUG_TLB)
1362 printf("tlb_flush:\n");
1363 #endif
1364 /* must reset current TB so that interrupts cannot modify the
1365 links while we are modifying them */
1366 env->current_tb = NULL;
1368 for(i = 0; i < CPU_TLB_SIZE; i++) {
1369 env->tlb_table[0][i].addr_read = -1;
1370 env->tlb_table[0][i].addr_write = -1;
1371 env->tlb_table[0][i].addr_code = -1;
1372 env->tlb_table[1][i].addr_read = -1;
1373 env->tlb_table[1][i].addr_write = -1;
1374 env->tlb_table[1][i].addr_code = -1;
1375 #if (NB_MMU_MODES >= 3)
1376 env->tlb_table[2][i].addr_read = -1;
1377 env->tlb_table[2][i].addr_write = -1;
1378 env->tlb_table[2][i].addr_code = -1;
1379 #if (NB_MMU_MODES == 4)
1380 env->tlb_table[3][i].addr_read = -1;
1381 env->tlb_table[3][i].addr_write = -1;
1382 env->tlb_table[3][i].addr_code = -1;
1383 #endif
1384 #endif
1387 memset (env->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof (void *));
1389 #if !defined(CONFIG_SOFTMMU)
1390 munmap((void *)MMAP_AREA_START, MMAP_AREA_END - MMAP_AREA_START);
1391 #endif
1392 #ifdef USE_KQEMU
1393 if (env->kqemu_enabled) {
1394 kqemu_flush(env, flush_global);
1396 #endif
1397 tlb_flush_count++;
1400 static inline void tlb_flush_entry(CPUTLBEntry *tlb_entry, target_ulong addr)
1402 if (addr == (tlb_entry->addr_read &
1403 (TARGET_PAGE_MASK | TLB_INVALID_MASK)) ||
1404 addr == (tlb_entry->addr_write &
1405 (TARGET_PAGE_MASK | TLB_INVALID_MASK)) ||
1406 addr == (tlb_entry->addr_code &
1407 (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
1408 tlb_entry->addr_read = -1;
1409 tlb_entry->addr_write = -1;
1410 tlb_entry->addr_code = -1;
1414 void tlb_flush_page(CPUState *env, target_ulong addr)
1416 int i;
1417 TranslationBlock *tb;
1419 #if defined(DEBUG_TLB)
1420 printf("tlb_flush_page: " TARGET_FMT_lx "\n", addr);
1421 #endif
1422 /* must reset current TB so that interrupts cannot modify the
1423 links while we are modifying them */
1424 env->current_tb = NULL;
1426 addr &= TARGET_PAGE_MASK;
1427 i = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
1428 tlb_flush_entry(&env->tlb_table[0][i], addr);
1429 tlb_flush_entry(&env->tlb_table[1][i], addr);
1430 #if (NB_MMU_MODES >= 3)
1431 tlb_flush_entry(&env->tlb_table[2][i], addr);
1432 #if (NB_MMU_MODES == 4)
1433 tlb_flush_entry(&env->tlb_table[3][i], addr);
1434 #endif
1435 #endif
1437 /* Discard jump cache entries for any tb which might potentially
1438 overlap the flushed page. */
1439 i = tb_jmp_cache_hash_page(addr - TARGET_PAGE_SIZE);
1440 memset (&env->tb_jmp_cache[i], 0, TB_JMP_PAGE_SIZE * sizeof(tb));
1442 i = tb_jmp_cache_hash_page(addr);
1443 memset (&env->tb_jmp_cache[i], 0, TB_JMP_PAGE_SIZE * sizeof(tb));
1445 #if !defined(CONFIG_SOFTMMU)
1446 if (addr < MMAP_AREA_END)
1447 munmap((void *)addr, TARGET_PAGE_SIZE);
1448 #endif
1449 #ifdef USE_KQEMU
1450 if (env->kqemu_enabled) {
1451 kqemu_flush_page(env, addr);
1453 #endif
1456 /* update the TLBs so that writes to code in the virtual page 'addr'
1457 can be detected */
1458 static void tlb_protect_code(ram_addr_t ram_addr)
1460 cpu_physical_memory_reset_dirty(ram_addr,
1461 ram_addr + TARGET_PAGE_SIZE,
1462 CODE_DIRTY_FLAG);
1465 /* update the TLB so that writes in physical page 'phys_addr' are no longer
1466 tested for self modifying code */
1467 static void tlb_unprotect_code_phys(CPUState *env, ram_addr_t ram_addr,
1468 target_ulong vaddr)
1470 phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] |= CODE_DIRTY_FLAG;
1473 static inline void tlb_reset_dirty_range(CPUTLBEntry *tlb_entry,
1474 unsigned long start, unsigned long length)
1476 unsigned long addr;
1477 if ((tlb_entry->addr_write & ~TARGET_PAGE_MASK) == IO_MEM_RAM) {
1478 addr = (tlb_entry->addr_write & TARGET_PAGE_MASK) + tlb_entry->addend;
1479 if ((addr - start) < length) {
1480 tlb_entry->addr_write = (tlb_entry->addr_write & TARGET_PAGE_MASK) | IO_MEM_NOTDIRTY;
1485 void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
1486 int dirty_flags)
1488 CPUState *env;
1489 unsigned long length, start1;
1490 int i, mask, len;
1491 uint8_t *p;
1493 start &= TARGET_PAGE_MASK;
1494 end = TARGET_PAGE_ALIGN(end);
1496 length = end - start;
1497 if (length == 0)
1498 return;
1499 len = length >> TARGET_PAGE_BITS;
1500 #ifdef USE_KQEMU
1501 /* XXX: should not depend on cpu context */
1502 env = first_cpu;
1503 if (env->kqemu_enabled) {
1504 ram_addr_t addr;
1505 addr = start;
1506 for(i = 0; i < len; i++) {
1507 kqemu_set_notdirty(env, addr);
1508 addr += TARGET_PAGE_SIZE;
1511 #endif
1512 mask = ~dirty_flags;
1513 p = phys_ram_dirty + (start >> TARGET_PAGE_BITS);
1514 for(i = 0; i < len; i++)
1515 p[i] &= mask;
1517 /* we modify the TLB cache so that the dirty bit will be set again
1518 when accessing the range */
1519 start1 = start + (unsigned long)phys_ram_base;
1520 for(env = first_cpu; env != NULL; env = env->next_cpu) {
1521 for(i = 0; i < CPU_TLB_SIZE; i++)
1522 tlb_reset_dirty_range(&env->tlb_table[0][i], start1, length);
1523 for(i = 0; i < CPU_TLB_SIZE; i++)
1524 tlb_reset_dirty_range(&env->tlb_table[1][i], start1, length);
1525 #if (NB_MMU_MODES >= 3)
1526 for(i = 0; i < CPU_TLB_SIZE; i++)
1527 tlb_reset_dirty_range(&env->tlb_table[2][i], start1, length);
1528 #if (NB_MMU_MODES == 4)
1529 for(i = 0; i < CPU_TLB_SIZE; i++)
1530 tlb_reset_dirty_range(&env->tlb_table[3][i], start1, length);
1531 #endif
1532 #endif
1535 #if !defined(CONFIG_SOFTMMU)
1536 /* XXX: this is expensive */
1538 VirtPageDesc *p;
1539 int j;
1540 target_ulong addr;
1542 for(i = 0; i < L1_SIZE; i++) {
1543 p = l1_virt_map[i];
1544 if (p) {
1545 addr = i << (TARGET_PAGE_BITS + L2_BITS);
1546 for(j = 0; j < L2_SIZE; j++) {
1547 if (p->valid_tag == virt_valid_tag &&
1548 p->phys_addr >= start && p->phys_addr < end &&
1549 (p->prot & PROT_WRITE)) {
1550 if (addr < MMAP_AREA_END) {
1551 mprotect((void *)addr, TARGET_PAGE_SIZE,
1552 p->prot & ~PROT_WRITE);
1555 addr += TARGET_PAGE_SIZE;
1556 p++;
1561 #endif
1564 static inline void tlb_update_dirty(CPUTLBEntry *tlb_entry)
1566 ram_addr_t ram_addr;
1568 if ((tlb_entry->addr_write & ~TARGET_PAGE_MASK) == IO_MEM_RAM) {
1569 ram_addr = (tlb_entry->addr_write & TARGET_PAGE_MASK) +
1570 tlb_entry->addend - (unsigned long)phys_ram_base;
1571 if (!cpu_physical_memory_is_dirty(ram_addr)) {
1572 tlb_entry->addr_write |= IO_MEM_NOTDIRTY;
1577 /* update the TLB according to the current state of the dirty bits */
1578 void cpu_tlb_update_dirty(CPUState *env)
1580 int i;
1581 for(i = 0; i < CPU_TLB_SIZE; i++)
1582 tlb_update_dirty(&env->tlb_table[0][i]);
1583 for(i = 0; i < CPU_TLB_SIZE; i++)
1584 tlb_update_dirty(&env->tlb_table[1][i]);
1585 #if (NB_MMU_MODES >= 3)
1586 for(i = 0; i < CPU_TLB_SIZE; i++)
1587 tlb_update_dirty(&env->tlb_table[2][i]);
1588 #if (NB_MMU_MODES == 4)
1589 for(i = 0; i < CPU_TLB_SIZE; i++)
1590 tlb_update_dirty(&env->tlb_table[3][i]);
1591 #endif
1592 #endif
1595 static inline void tlb_set_dirty1(CPUTLBEntry *tlb_entry,
1596 unsigned long start)
1598 unsigned long addr;
1599 if ((tlb_entry->addr_write & ~TARGET_PAGE_MASK) == IO_MEM_NOTDIRTY) {
1600 addr = (tlb_entry->addr_write & TARGET_PAGE_MASK) + tlb_entry->addend;
1601 if (addr == start) {
1602 tlb_entry->addr_write = (tlb_entry->addr_write & TARGET_PAGE_MASK) | IO_MEM_RAM;
1607 /* update the TLB corresponding to virtual page vaddr and phys addr
1608 addr so that it is no longer dirty */
1609 static inline void tlb_set_dirty(CPUState *env,
1610 unsigned long addr, target_ulong vaddr)
1612 int i;
1614 addr &= TARGET_PAGE_MASK;
1615 i = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
1616 tlb_set_dirty1(&env->tlb_table[0][i], addr);
1617 tlb_set_dirty1(&env->tlb_table[1][i], addr);
1618 #if (NB_MMU_MODES >= 3)
1619 tlb_set_dirty1(&env->tlb_table[2][i], addr);
1620 #if (NB_MMU_MODES == 4)
1621 tlb_set_dirty1(&env->tlb_table[3][i], addr);
1622 #endif
1623 #endif
1626 /* add a new TLB entry. At most one entry for a given virtual address
1627 is permitted. Return 0 if OK or 2 if the page could not be mapped
1628 (can only happen in non SOFTMMU mode for I/O pages or pages
1629 conflicting with the host address space). */
1630 int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
1631 target_phys_addr_t paddr, int prot,
1632 int mmu_idx, int is_softmmu)
1634 PhysPageDesc *p;
1635 unsigned long pd;
1636 unsigned int index;
1637 target_ulong address;
1638 target_phys_addr_t addend;
1639 int ret;
1640 CPUTLBEntry *te;
1641 int i;
1643 p = phys_page_find(paddr >> TARGET_PAGE_BITS);
1644 if (!p) {
1645 pd = IO_MEM_UNASSIGNED;
1646 } else {
1647 pd = p->phys_offset;
1649 #if defined(DEBUG_TLB)
1650 printf("tlb_set_page: vaddr=" TARGET_FMT_lx " paddr=0x%08x prot=%x idx=%d smmu=%d pd=0x%08lx\n",
1651 vaddr, (int)paddr, prot, mmu_idx, is_softmmu, pd);
1652 #endif
1654 ret = 0;
1655 #if !defined(CONFIG_SOFTMMU)
1656 if (is_softmmu)
1657 #endif
1659 if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) {
1660 /* IO memory case */
1661 address = vaddr | pd;
1662 addend = paddr;
1663 } else {
1664 /* standard memory */
1665 address = vaddr;
1666 addend = (unsigned long)phys_ram_base + (pd & TARGET_PAGE_MASK);
1669 /* Make accesses to pages with watchpoints go via the
1670 watchpoint trap routines. */
1671 for (i = 0; i < env->nb_watchpoints; i++) {
1672 if (vaddr == (env->watchpoint[i].vaddr & TARGET_PAGE_MASK)) {
1673 if (address & ~TARGET_PAGE_MASK) {
1674 env->watchpoint[i].addend = 0;
1675 address = vaddr | io_mem_watch;
1676 } else {
1677 env->watchpoint[i].addend = pd - paddr +
1678 (unsigned long) phys_ram_base;
1679 /* TODO: Figure out how to make read watchpoints coexist
1680 with code. */
1681 pd = (pd & TARGET_PAGE_MASK) | io_mem_watch | IO_MEM_ROMD;
1686 index = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
1687 addend -= vaddr;
1688 te = &env->tlb_table[mmu_idx][index];
1689 te->addend = addend;
1690 if (prot & PAGE_READ) {
1691 te->addr_read = address;
1692 } else {
1693 te->addr_read = -1;
1695 if (prot & PAGE_EXEC) {
1696 te->addr_code = address;
1697 } else {
1698 te->addr_code = -1;
1700 if (prot & PAGE_WRITE) {
1701 if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_ROM ||
1702 (pd & IO_MEM_ROMD)) {
1703 /* write access calls the I/O callback */
1704 te->addr_write = vaddr |
1705 (pd & ~(TARGET_PAGE_MASK | IO_MEM_ROMD));
1706 } else if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_RAM &&
1707 !cpu_physical_memory_is_dirty(pd)) {
1708 te->addr_write = vaddr | IO_MEM_NOTDIRTY;
1709 } else {
1710 te->addr_write = address;
1712 } else {
1713 te->addr_write = -1;
1716 #if !defined(CONFIG_SOFTMMU)
1717 else {
1718 if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM) {
1719 /* IO access: no mapping is done as it will be handled by the
1720 soft MMU */
1721 if (!(env->hflags & HF_SOFTMMU_MASK))
1722 ret = 2;
1723 } else {
1724 void *map_addr;
1726 if (vaddr >= MMAP_AREA_END) {
1727 ret = 2;
1728 } else {
1729 if (prot & PROT_WRITE) {
1730 if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_ROM ||
1731 #if defined(TARGET_HAS_SMC) || 1
1732 first_tb ||
1733 #endif
1734 ((pd & ~TARGET_PAGE_MASK) == IO_MEM_RAM &&
1735 !cpu_physical_memory_is_dirty(pd))) {
1736 /* ROM: we do as if code was inside */
1737 /* if code is present, we only map as read only and save the
1738 original mapping */
1739 VirtPageDesc *vp;
1741 vp = virt_page_find_alloc(vaddr >> TARGET_PAGE_BITS, 1);
1742 vp->phys_addr = pd;
1743 vp->prot = prot;
1744 vp->valid_tag = virt_valid_tag;
1745 prot &= ~PAGE_WRITE;
1748 map_addr = mmap((void *)vaddr, TARGET_PAGE_SIZE, prot,
1749 MAP_SHARED | MAP_FIXED, phys_ram_fd, (pd & TARGET_PAGE_MASK));
1750 if (map_addr == MAP_FAILED) {
1751 cpu_abort(env, "mmap failed when mapped physical address 0x%08x to virtual address 0x%08x\n",
1752 paddr, vaddr);
1757 #endif
1758 return ret;
1761 /* called from signal handler: invalidate the code and unprotect the
1762 page. Return TRUE if the fault was succesfully handled. */
1763 int page_unprotect(target_ulong addr, unsigned long pc, void *puc)
1765 #if !defined(CONFIG_SOFTMMU)
1766 VirtPageDesc *vp;
1768 #if defined(DEBUG_TLB)
1769 printf("page_unprotect: addr=0x%08x\n", addr);
1770 #endif
1771 addr &= TARGET_PAGE_MASK;
1773 /* if it is not mapped, no need to worry here */
1774 if (addr >= MMAP_AREA_END)
1775 return 0;
1776 vp = virt_page_find(addr >> TARGET_PAGE_BITS);
1777 if (!vp)
1778 return 0;
1779 /* NOTE: in this case, validate_tag is _not_ tested as it
1780 validates only the code TLB */
1781 if (vp->valid_tag != virt_valid_tag)
1782 return 0;
1783 if (!(vp->prot & PAGE_WRITE))
1784 return 0;
1785 #if defined(DEBUG_TLB)
1786 printf("page_unprotect: addr=0x%08x phys_addr=0x%08x prot=%x\n",
1787 addr, vp->phys_addr, vp->prot);
1788 #endif
1789 if (mprotect((void *)addr, TARGET_PAGE_SIZE, vp->prot) < 0)
1790 cpu_abort(cpu_single_env, "error mprotect addr=0x%lx prot=%d\n",
1791 (unsigned long)addr, vp->prot);
1792 /* set the dirty bit */
1793 phys_ram_dirty[vp->phys_addr >> TARGET_PAGE_BITS] = 0xff;
1794 /* flush the code inside */
1795 tb_invalidate_phys_page(vp->phys_addr, pc, puc);
1796 return 1;
1797 #else
1798 return 0;
1799 #endif
1802 #else
1804 void tlb_flush(CPUState *env, int flush_global)
1808 void tlb_flush_page(CPUState *env, target_ulong addr)
1812 int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
1813 target_phys_addr_t paddr, int prot,
1814 int mmu_idx, int is_softmmu)
1816 return 0;
1819 /* dump memory mappings */
1820 void page_dump(FILE *f)
1822 unsigned long start, end;
1823 int i, j, prot, prot1;
1824 PageDesc *p;
1826 fprintf(f, "%-8s %-8s %-8s %s\n",
1827 "start", "end", "size", "prot");
1828 start = -1;
1829 end = -1;
1830 prot = 0;
1831 for(i = 0; i <= L1_SIZE; i++) {
1832 if (i < L1_SIZE)
1833 p = l1_map[i];
1834 else
1835 p = NULL;
1836 for(j = 0;j < L2_SIZE; j++) {
1837 if (!p)
1838 prot1 = 0;
1839 else
1840 prot1 = p[j].flags;
1841 if (prot1 != prot) {
1842 end = (i << (32 - L1_BITS)) | (j << TARGET_PAGE_BITS);
1843 if (start != -1) {
1844 fprintf(f, "%08lx-%08lx %08lx %c%c%c\n",
1845 start, end, end - start,
1846 prot & PAGE_READ ? 'r' : '-',
1847 prot & PAGE_WRITE ? 'w' : '-',
1848 prot & PAGE_EXEC ? 'x' : '-');
1850 if (prot1 != 0)
1851 start = end;
1852 else
1853 start = -1;
1854 prot = prot1;
1856 if (!p)
1857 break;
1862 int page_get_flags(target_ulong address)
1864 PageDesc *p;
1866 p = page_find(address >> TARGET_PAGE_BITS);
1867 if (!p)
1868 return 0;
1869 return p->flags;
1872 /* modify the flags of a page and invalidate the code if
1873 necessary. The flag PAGE_WRITE_ORG is positionned automatically
1874 depending on PAGE_WRITE */
1875 void page_set_flags(target_ulong start, target_ulong end, int flags)
1877 PageDesc *p;
1878 target_ulong addr;
1880 start = start & TARGET_PAGE_MASK;
1881 end = TARGET_PAGE_ALIGN(end);
1882 if (flags & PAGE_WRITE)
1883 flags |= PAGE_WRITE_ORG;
1884 spin_lock(&tb_lock);
1885 for(addr = start; addr < end; addr += TARGET_PAGE_SIZE) {
1886 p = page_find_alloc(addr >> TARGET_PAGE_BITS);
1887 /* if the write protection is set, then we invalidate the code
1888 inside */
1889 if (!(p->flags & PAGE_WRITE) &&
1890 (flags & PAGE_WRITE) &&
1891 p->first_tb) {
1892 tb_invalidate_phys_page(addr, 0, NULL);
1894 p->flags = flags;
1896 spin_unlock(&tb_lock);
1899 int page_check_range(target_ulong start, target_ulong len, int flags)
1901 PageDesc *p;
1902 target_ulong end;
1903 target_ulong addr;
1905 end = TARGET_PAGE_ALIGN(start+len); /* must do before we loose bits in the next step */
1906 start = start & TARGET_PAGE_MASK;
1908 if( end < start )
1909 /* we've wrapped around */
1910 return -1;
1911 for(addr = start; addr < end; addr += TARGET_PAGE_SIZE) {
1912 p = page_find(addr >> TARGET_PAGE_BITS);
1913 if( !p )
1914 return -1;
1915 if( !(p->flags & PAGE_VALID) )
1916 return -1;
1918 if ((flags & PAGE_READ) && !(p->flags & PAGE_READ))
1919 return -1;
1920 if (flags & PAGE_WRITE) {
1921 if (!(p->flags & PAGE_WRITE_ORG))
1922 return -1;
1923 /* unprotect the page if it was put read-only because it
1924 contains translated code */
1925 if (!(p->flags & PAGE_WRITE)) {
1926 if (!page_unprotect(addr, 0, NULL))
1927 return -1;
1929 return 0;
1932 return 0;
1935 /* called from signal handler: invalidate the code and unprotect the
1936 page. Return TRUE if the fault was succesfully handled. */
1937 int page_unprotect(target_ulong address, unsigned long pc, void *puc)
1939 unsigned int page_index, prot, pindex;
1940 PageDesc *p, *p1;
1941 target_ulong host_start, host_end, addr;
1943 host_start = address & qemu_host_page_mask;
1944 page_index = host_start >> TARGET_PAGE_BITS;
1945 p1 = page_find(page_index);
1946 if (!p1)
1947 return 0;
1948 host_end = host_start + qemu_host_page_size;
1949 p = p1;
1950 prot = 0;
1951 for(addr = host_start;addr < host_end; addr += TARGET_PAGE_SIZE) {
1952 prot |= p->flags;
1953 p++;
1955 /* if the page was really writable, then we change its
1956 protection back to writable */
1957 if (prot & PAGE_WRITE_ORG) {
1958 pindex = (address - host_start) >> TARGET_PAGE_BITS;
1959 if (!(p1[pindex].flags & PAGE_WRITE)) {
1960 mprotect((void *)g2h(host_start), qemu_host_page_size,
1961 (prot & PAGE_BITS) | PAGE_WRITE);
1962 p1[pindex].flags |= PAGE_WRITE;
1963 /* and since the content will be modified, we must invalidate
1964 the corresponding translated code. */
1965 tb_invalidate_phys_page(address, pc, puc);
1966 #ifdef DEBUG_TB_CHECK
1967 tb_invalidate_check(address);
1968 #endif
1969 return 1;
1972 return 0;
1975 static inline void tlb_set_dirty(CPUState *env,
1976 unsigned long addr, target_ulong vaddr)
1979 #endif /* defined(CONFIG_USER_ONLY) */
1981 static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end,
1982 int memory);
1983 static void *subpage_init (target_phys_addr_t base, uint32_t *phys,
1984 int orig_memory);
1985 #define CHECK_SUBPAGE(addr, start_addr, start_addr2, end_addr, end_addr2, \
1986 need_subpage) \
1987 do { \
1988 if (addr > start_addr) \
1989 start_addr2 = 0; \
1990 else { \
1991 start_addr2 = start_addr & ~TARGET_PAGE_MASK; \
1992 if (start_addr2 > 0) \
1993 need_subpage = 1; \
1996 if ((start_addr + orig_size) - addr >= TARGET_PAGE_SIZE) \
1997 end_addr2 = TARGET_PAGE_SIZE - 1; \
1998 else { \
1999 end_addr2 = (start_addr + orig_size - 1) & ~TARGET_PAGE_MASK; \
2000 if (end_addr2 < TARGET_PAGE_SIZE - 1) \
2001 need_subpage = 1; \
2003 } while (0)
2005 /* register physical memory. 'size' must be a multiple of the target
2006 page size. If (phys_offset & ~TARGET_PAGE_MASK) != 0, then it is an
2007 io memory page */
2008 void cpu_register_physical_memory(target_phys_addr_t start_addr,
2009 unsigned long size,
2010 unsigned long phys_offset)
2012 target_phys_addr_t addr, end_addr;
2013 PhysPageDesc *p;
2014 CPUState *env;
2015 unsigned long orig_size = size;
2016 void *subpage;
2018 size = (size + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK;
2019 end_addr = start_addr + (target_phys_addr_t)size;
2020 for(addr = start_addr; addr != end_addr; addr += TARGET_PAGE_SIZE) {
2021 p = phys_page_find(addr >> TARGET_PAGE_BITS);
2022 if (p && p->phys_offset != IO_MEM_UNASSIGNED) {
2023 unsigned long orig_memory = p->phys_offset;
2024 target_phys_addr_t start_addr2, end_addr2;
2025 int need_subpage = 0;
2027 CHECK_SUBPAGE(addr, start_addr, start_addr2, end_addr, end_addr2,
2028 need_subpage);
2029 if (need_subpage || phys_offset & IO_MEM_SUBWIDTH) {
2030 if (!(orig_memory & IO_MEM_SUBPAGE)) {
2031 subpage = subpage_init((addr & TARGET_PAGE_MASK),
2032 &p->phys_offset, orig_memory);
2033 } else {
2034 subpage = io_mem_opaque[(orig_memory & ~TARGET_PAGE_MASK)
2035 >> IO_MEM_SHIFT];
2037 subpage_register(subpage, start_addr2, end_addr2, phys_offset);
2038 } else {
2039 p->phys_offset = phys_offset;
2040 if ((phys_offset & ~TARGET_PAGE_MASK) <= IO_MEM_ROM ||
2041 (phys_offset & IO_MEM_ROMD))
2042 phys_offset += TARGET_PAGE_SIZE;
2044 } else {
2045 p = phys_page_find_alloc(addr >> TARGET_PAGE_BITS, 1);
2046 p->phys_offset = phys_offset;
2047 if ((phys_offset & ~TARGET_PAGE_MASK) <= IO_MEM_ROM ||
2048 (phys_offset & IO_MEM_ROMD))
2049 phys_offset += TARGET_PAGE_SIZE;
2050 else {
2051 target_phys_addr_t start_addr2, end_addr2;
2052 int need_subpage = 0;
2054 CHECK_SUBPAGE(addr, start_addr, start_addr2, end_addr,
2055 end_addr2, need_subpage);
2057 if (need_subpage || phys_offset & IO_MEM_SUBWIDTH) {
2058 subpage = subpage_init((addr & TARGET_PAGE_MASK),
2059 &p->phys_offset, IO_MEM_UNASSIGNED);
2060 subpage_register(subpage, start_addr2, end_addr2,
2061 phys_offset);
2067 /* since each CPU stores ram addresses in its TLB cache, we must
2068 reset the modified entries */
2069 /* XXX: slow ! */
2070 for(env = first_cpu; env != NULL; env = env->next_cpu) {
2071 tlb_flush(env, 1);
2075 /* XXX: temporary until new memory mapping API */
2076 uint32_t cpu_get_physical_page_desc(target_phys_addr_t addr)
2078 PhysPageDesc *p;
2080 p = phys_page_find(addr >> TARGET_PAGE_BITS);
2081 if (!p)
2082 return IO_MEM_UNASSIGNED;
2083 return p->phys_offset;
2086 /* XXX: better than nothing */
2087 ram_addr_t qemu_ram_alloc(unsigned int size)
2089 ram_addr_t addr;
2090 if ((phys_ram_alloc_offset + size) >= phys_ram_size) {
2091 fprintf(stderr, "Not enough memory (requested_size = %u, max memory = %d)\n",
2092 size, phys_ram_size);
2093 abort();
2095 addr = phys_ram_alloc_offset;
2096 phys_ram_alloc_offset = TARGET_PAGE_ALIGN(phys_ram_alloc_offset + size);
2097 return addr;
2100 void qemu_ram_free(ram_addr_t addr)
2104 static uint32_t unassigned_mem_readb(void *opaque, target_phys_addr_t addr)
2106 #ifdef DEBUG_UNASSIGNED
2107 printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);
2108 #endif
2109 #ifdef TARGET_SPARC
2110 do_unassigned_access(addr, 0, 0, 0);
2111 #elif TARGET_CRIS
2112 do_unassigned_access(addr, 0, 0, 0);
2113 #endif
2114 return 0;
2117 static void unassigned_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
2119 #ifdef DEBUG_UNASSIGNED
2120 printf("Unassigned mem write " TARGET_FMT_plx " = 0x%x\n", addr, val);
2121 #endif
2122 #ifdef TARGET_SPARC
2123 do_unassigned_access(addr, 1, 0, 0);
2124 #elif TARGET_CRIS
2125 do_unassigned_access(addr, 1, 0, 0);
2126 #endif
2129 static CPUReadMemoryFunc *unassigned_mem_read[3] = {
2130 unassigned_mem_readb,
2131 unassigned_mem_readb,
2132 unassigned_mem_readb,
2135 static CPUWriteMemoryFunc *unassigned_mem_write[3] = {
2136 unassigned_mem_writeb,
2137 unassigned_mem_writeb,
2138 unassigned_mem_writeb,
2141 static void notdirty_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
2143 unsigned long ram_addr;
2144 int dirty_flags;
2145 ram_addr = addr - (unsigned long)phys_ram_base;
2146 dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
2147 if (!(dirty_flags & CODE_DIRTY_FLAG)) {
2148 #if !defined(CONFIG_USER_ONLY)
2149 tb_invalidate_phys_page_fast(ram_addr, 1);
2150 dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
2151 #endif
2153 stb_p((uint8_t *)(long)addr, val);
2154 #ifdef USE_KQEMU
2155 if (cpu_single_env->kqemu_enabled &&
2156 (dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK)
2157 kqemu_modify_page(cpu_single_env, ram_addr);
2158 #endif
2159 dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
2160 phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags;
2161 /* we remove the notdirty callback only if the code has been
2162 flushed */
2163 if (dirty_flags == 0xff)
2164 tlb_set_dirty(cpu_single_env, addr, cpu_single_env->mem_write_vaddr);
2167 static void notdirty_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
2169 unsigned long ram_addr;
2170 int dirty_flags;
2171 ram_addr = addr - (unsigned long)phys_ram_base;
2172 dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
2173 if (!(dirty_flags & CODE_DIRTY_FLAG)) {
2174 #if !defined(CONFIG_USER_ONLY)
2175 tb_invalidate_phys_page_fast(ram_addr, 2);
2176 dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
2177 #endif
2179 stw_p((uint8_t *)(long)addr, val);
2180 #ifdef USE_KQEMU
2181 if (cpu_single_env->kqemu_enabled &&
2182 (dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK)
2183 kqemu_modify_page(cpu_single_env, ram_addr);
2184 #endif
2185 dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
2186 phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags;
2187 /* we remove the notdirty callback only if the code has been
2188 flushed */
2189 if (dirty_flags == 0xff)
2190 tlb_set_dirty(cpu_single_env, addr, cpu_single_env->mem_write_vaddr);
2193 static void notdirty_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
2195 unsigned long ram_addr;
2196 int dirty_flags;
2197 ram_addr = addr - (unsigned long)phys_ram_base;
2198 dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
2199 if (!(dirty_flags & CODE_DIRTY_FLAG)) {
2200 #if !defined(CONFIG_USER_ONLY)
2201 tb_invalidate_phys_page_fast(ram_addr, 4);
2202 dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
2203 #endif
2205 stl_p((uint8_t *)(long)addr, val);
2206 #ifdef USE_KQEMU
2207 if (cpu_single_env->kqemu_enabled &&
2208 (dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK)
2209 kqemu_modify_page(cpu_single_env, ram_addr);
2210 #endif
2211 dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
2212 phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags;
2213 /* we remove the notdirty callback only if the code has been
2214 flushed */
2215 if (dirty_flags == 0xff)
2216 tlb_set_dirty(cpu_single_env, addr, cpu_single_env->mem_write_vaddr);
2219 static CPUReadMemoryFunc *error_mem_read[3] = {
2220 NULL, /* never used */
2221 NULL, /* never used */
2222 NULL, /* never used */
2225 static CPUWriteMemoryFunc *notdirty_mem_write[3] = {
2226 notdirty_mem_writeb,
2227 notdirty_mem_writew,
2228 notdirty_mem_writel,
2231 #if defined(CONFIG_SOFTMMU)
2232 /* Watchpoint access routines. Watchpoints are inserted using TLB tricks,
2233 so these check for a hit then pass through to the normal out-of-line
2234 phys routines. */
2235 static uint32_t watch_mem_readb(void *opaque, target_phys_addr_t addr)
2237 return ldub_phys(addr);
2240 static uint32_t watch_mem_readw(void *opaque, target_phys_addr_t addr)
2242 return lduw_phys(addr);
2245 static uint32_t watch_mem_readl(void *opaque, target_phys_addr_t addr)
2247 return ldl_phys(addr);
2250 /* Generate a debug exception if a watchpoint has been hit.
2251 Returns the real physical address of the access. addr will be a host
2252 address in case of a RAM location. */
2253 static target_ulong check_watchpoint(target_phys_addr_t addr)
2255 CPUState *env = cpu_single_env;
2256 target_ulong watch;
2257 target_ulong retaddr;
2258 int i;
2260 retaddr = addr;
2261 for (i = 0; i < env->nb_watchpoints; i++) {
2262 watch = env->watchpoint[i].vaddr;
2263 if (((env->mem_write_vaddr ^ watch) & TARGET_PAGE_MASK) == 0) {
2264 retaddr = addr - env->watchpoint[i].addend;
2265 if (((addr ^ watch) & ~TARGET_PAGE_MASK) == 0) {
2266 cpu_single_env->watchpoint_hit = i + 1;
2267 cpu_interrupt(cpu_single_env, CPU_INTERRUPT_DEBUG);
2268 break;
2272 return retaddr;
2275 static void watch_mem_writeb(void *opaque, target_phys_addr_t addr,
2276 uint32_t val)
2278 addr = check_watchpoint(addr);
2279 stb_phys(addr, val);
2282 static void watch_mem_writew(void *opaque, target_phys_addr_t addr,
2283 uint32_t val)
2285 addr = check_watchpoint(addr);
2286 stw_phys(addr, val);
2289 static void watch_mem_writel(void *opaque, target_phys_addr_t addr,
2290 uint32_t val)
2292 addr = check_watchpoint(addr);
2293 stl_phys(addr, val);
2296 static CPUReadMemoryFunc *watch_mem_read[3] = {
2297 watch_mem_readb,
2298 watch_mem_readw,
2299 watch_mem_readl,
2302 static CPUWriteMemoryFunc *watch_mem_write[3] = {
2303 watch_mem_writeb,
2304 watch_mem_writew,
2305 watch_mem_writel,
2307 #endif
2309 static inline uint32_t subpage_readlen (subpage_t *mmio, target_phys_addr_t addr,
2310 unsigned int len)
2312 uint32_t ret;
2313 unsigned int idx;
2315 idx = SUBPAGE_IDX(addr - mmio->base);
2316 #if defined(DEBUG_SUBPAGE)
2317 printf("%s: subpage %p len %d addr " TARGET_FMT_plx " idx %d\n", __func__,
2318 mmio, len, addr, idx);
2319 #endif
2320 ret = (**mmio->mem_read[idx][len])(mmio->opaque[idx][0][len], addr);
2322 return ret;
2325 static inline void subpage_writelen (subpage_t *mmio, target_phys_addr_t addr,
2326 uint32_t value, unsigned int len)
2328 unsigned int idx;
2330 idx = SUBPAGE_IDX(addr - mmio->base);
2331 #if defined(DEBUG_SUBPAGE)
2332 printf("%s: subpage %p len %d addr " TARGET_FMT_plx " idx %d value %08x\n", __func__,
2333 mmio, len, addr, idx, value);
2334 #endif
2335 (**mmio->mem_write[idx][len])(mmio->opaque[idx][1][len], addr, value);
2338 static uint32_t subpage_readb (void *opaque, target_phys_addr_t addr)
2340 #if defined(DEBUG_SUBPAGE)
2341 printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
2342 #endif
2344 return subpage_readlen(opaque, addr, 0);
2347 static void subpage_writeb (void *opaque, target_phys_addr_t addr,
2348 uint32_t value)
2350 #if defined(DEBUG_SUBPAGE)
2351 printf("%s: addr " TARGET_FMT_plx " val %08x\n", __func__, addr, value);
2352 #endif
2353 subpage_writelen(opaque, addr, value, 0);
2356 static uint32_t subpage_readw (void *opaque, target_phys_addr_t addr)
2358 #if defined(DEBUG_SUBPAGE)
2359 printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
2360 #endif
2362 return subpage_readlen(opaque, addr, 1);
2365 static void subpage_writew (void *opaque, target_phys_addr_t addr,
2366 uint32_t value)
2368 #if defined(DEBUG_SUBPAGE)
2369 printf("%s: addr " TARGET_FMT_plx " val %08x\n", __func__, addr, value);
2370 #endif
2371 subpage_writelen(opaque, addr, value, 1);
2374 static uint32_t subpage_readl (void *opaque, target_phys_addr_t addr)
2376 #if defined(DEBUG_SUBPAGE)
2377 printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
2378 #endif
2380 return subpage_readlen(opaque, addr, 2);
2383 static void subpage_writel (void *opaque,
2384 target_phys_addr_t addr, uint32_t value)
2386 #if defined(DEBUG_SUBPAGE)
2387 printf("%s: addr " TARGET_FMT_plx " val %08x\n", __func__, addr, value);
2388 #endif
2389 subpage_writelen(opaque, addr, value, 2);
2392 static CPUReadMemoryFunc *subpage_read[] = {
2393 &subpage_readb,
2394 &subpage_readw,
2395 &subpage_readl,
2398 static CPUWriteMemoryFunc *subpage_write[] = {
2399 &subpage_writeb,
2400 &subpage_writew,
2401 &subpage_writel,
2404 static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end,
2405 int memory)
2407 int idx, eidx;
2408 unsigned int i;
2410 if (start >= TARGET_PAGE_SIZE || end >= TARGET_PAGE_SIZE)
2411 return -1;
2412 idx = SUBPAGE_IDX(start);
2413 eidx = SUBPAGE_IDX(end);
2414 #if defined(DEBUG_SUBPAGE)
2415 printf("%s: %p start %08x end %08x idx %08x eidx %08x mem %d\n", __func__,
2416 mmio, start, end, idx, eidx, memory);
2417 #endif
2418 memory >>= IO_MEM_SHIFT;
2419 for (; idx <= eidx; idx++) {
2420 for (i = 0; i < 4; i++) {
2421 if (io_mem_read[memory][i]) {
2422 mmio->mem_read[idx][i] = &io_mem_read[memory][i];
2423 mmio->opaque[idx][0][i] = io_mem_opaque[memory];
2425 if (io_mem_write[memory][i]) {
2426 mmio->mem_write[idx][i] = &io_mem_write[memory][i];
2427 mmio->opaque[idx][1][i] = io_mem_opaque[memory];
2432 return 0;
2435 static void *subpage_init (target_phys_addr_t base, uint32_t *phys,
2436 int orig_memory)
2438 subpage_t *mmio;
2439 int subpage_memory;
2441 mmio = qemu_mallocz(sizeof(subpage_t));
2442 if (mmio != NULL) {
2443 mmio->base = base;
2444 subpage_memory = cpu_register_io_memory(0, subpage_read, subpage_write, mmio);
2445 #if defined(DEBUG_SUBPAGE)
2446 printf("%s: %p base " TARGET_FMT_plx " len %08x %d\n", __func__,
2447 mmio, base, TARGET_PAGE_SIZE, subpage_memory);
2448 #endif
2449 *phys = subpage_memory | IO_MEM_SUBPAGE;
2450 subpage_register(mmio, 0, TARGET_PAGE_SIZE - 1, orig_memory);
2453 return mmio;
2456 static void io_mem_init(void)
2458 cpu_register_io_memory(IO_MEM_ROM >> IO_MEM_SHIFT, error_mem_read, unassigned_mem_write, NULL);
2459 cpu_register_io_memory(IO_MEM_UNASSIGNED >> IO_MEM_SHIFT, unassigned_mem_read, unassigned_mem_write, NULL);
2460 cpu_register_io_memory(IO_MEM_NOTDIRTY >> IO_MEM_SHIFT, error_mem_read, notdirty_mem_write, NULL);
2461 io_mem_nb = 5;
2463 #if defined(CONFIG_SOFTMMU)
2464 io_mem_watch = cpu_register_io_memory(-1, watch_mem_read,
2465 watch_mem_write, NULL);
2466 #endif
2467 /* alloc dirty bits array */
2468 phys_ram_dirty = qemu_vmalloc(phys_ram_size >> TARGET_PAGE_BITS);
2469 memset(phys_ram_dirty, 0xff, phys_ram_size >> TARGET_PAGE_BITS);
2472 /* mem_read and mem_write are arrays of functions containing the
2473 function to access byte (index 0), word (index 1) and dword (index
2474 2). Functions can be omitted with a NULL function pointer. The
2475 registered functions may be modified dynamically later.
2476 If io_index is non zero, the corresponding io zone is
2477 modified. If it is zero, a new io zone is allocated. The return
2478 value can be used with cpu_register_physical_memory(). (-1) is
2479 returned if error. */
2480 int cpu_register_io_memory(int io_index,
2481 CPUReadMemoryFunc **mem_read,
2482 CPUWriteMemoryFunc **mem_write,
2483 void *opaque)
2485 int i, subwidth = 0;
2487 if (io_index <= 0) {
2488 if (io_mem_nb >= IO_MEM_NB_ENTRIES)
2489 return -1;
2490 io_index = io_mem_nb++;
2491 } else {
2492 if (io_index >= IO_MEM_NB_ENTRIES)
2493 return -1;
2496 for(i = 0;i < 3; i++) {
2497 if (!mem_read[i] || !mem_write[i])
2498 subwidth = IO_MEM_SUBWIDTH;
2499 io_mem_read[io_index][i] = mem_read[i];
2500 io_mem_write[io_index][i] = mem_write[i];
2502 io_mem_opaque[io_index] = opaque;
2503 return (io_index << IO_MEM_SHIFT) | subwidth;
2506 CPUWriteMemoryFunc **cpu_get_io_memory_write(int io_index)
2508 return io_mem_write[io_index >> IO_MEM_SHIFT];
2511 CPUReadMemoryFunc **cpu_get_io_memory_read(int io_index)
2513 return io_mem_read[io_index >> IO_MEM_SHIFT];
2516 /* physical memory access (slow version, mainly for debug) */
2517 #if defined(CONFIG_USER_ONLY)
2518 void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
2519 int len, int is_write)
2521 int l, flags;
2522 target_ulong page;
2523 void * p;
2525 while (len > 0) {
2526 page = addr & TARGET_PAGE_MASK;
2527 l = (page + TARGET_PAGE_SIZE) - addr;
2528 if (l > len)
2529 l = len;
2530 flags = page_get_flags(page);
2531 if (!(flags & PAGE_VALID))
2532 return;
2533 if (is_write) {
2534 if (!(flags & PAGE_WRITE))
2535 return;
2536 /* XXX: this code should not depend on lock_user */
2537 if (!(p = lock_user(VERIFY_WRITE, addr, len, 0)))
2538 /* FIXME - should this return an error rather than just fail? */
2539 return;
2540 memcpy(p, buf, len);
2541 unlock_user(p, addr, len);
2542 } else {
2543 if (!(flags & PAGE_READ))
2544 return;
2545 /* XXX: this code should not depend on lock_user */
2546 if (!(p = lock_user(VERIFY_READ, addr, len, 1)))
2547 /* FIXME - should this return an error rather than just fail? */
2548 return;
2549 memcpy(buf, p, len);
2550 unlock_user(p, addr, 0);
2552 len -= l;
2553 buf += l;
2554 addr += l;
2558 #else
2559 void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
2560 int len, int is_write)
2562 int l, io_index;
2563 uint8_t *ptr;
2564 uint32_t val;
2565 target_phys_addr_t page;
2566 unsigned long pd;
2567 PhysPageDesc *p;
2569 while (len > 0) {
2570 page = addr & TARGET_PAGE_MASK;
2571 l = (page + TARGET_PAGE_SIZE) - addr;
2572 if (l > len)
2573 l = len;
2574 p = phys_page_find(page >> TARGET_PAGE_BITS);
2575 if (!p) {
2576 pd = IO_MEM_UNASSIGNED;
2577 } else {
2578 pd = p->phys_offset;
2581 if (is_write) {
2582 if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) {
2583 io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
2584 /* XXX: could force cpu_single_env to NULL to avoid
2585 potential bugs */
2586 if (l >= 4 && ((addr & 3) == 0)) {
2587 /* 32 bit write access */
2588 val = ldl_p(buf);
2589 io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val);
2590 l = 4;
2591 } else if (l >= 2 && ((addr & 1) == 0)) {
2592 /* 16 bit write access */
2593 val = lduw_p(buf);
2594 io_mem_write[io_index][1](io_mem_opaque[io_index], addr, val);
2595 l = 2;
2596 } else {
2597 /* 8 bit write access */
2598 val = ldub_p(buf);
2599 io_mem_write[io_index][0](io_mem_opaque[io_index], addr, val);
2600 l = 1;
2602 } else {
2603 unsigned long addr1;
2604 addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
2605 /* RAM case */
2606 ptr = phys_ram_base + addr1;
2607 memcpy(ptr, buf, l);
2608 if (!cpu_physical_memory_is_dirty(addr1)) {
2609 /* invalidate code */
2610 tb_invalidate_phys_page_range(addr1, addr1 + l, 0);
2611 /* set dirty bit */
2612 phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] |=
2613 (0xff & ~CODE_DIRTY_FLAG);
2616 } else {
2617 if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM &&
2618 !(pd & IO_MEM_ROMD)) {
2619 /* I/O case */
2620 io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
2621 if (l >= 4 && ((addr & 3) == 0)) {
2622 /* 32 bit read access */
2623 val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr);
2624 stl_p(buf, val);
2625 l = 4;
2626 } else if (l >= 2 && ((addr & 1) == 0)) {
2627 /* 16 bit read access */
2628 val = io_mem_read[io_index][1](io_mem_opaque[io_index], addr);
2629 stw_p(buf, val);
2630 l = 2;
2631 } else {
2632 /* 8 bit read access */
2633 val = io_mem_read[io_index][0](io_mem_opaque[io_index], addr);
2634 stb_p(buf, val);
2635 l = 1;
2637 } else {
2638 /* RAM case */
2639 ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
2640 (addr & ~TARGET_PAGE_MASK);
2641 memcpy(buf, ptr, l);
2644 len -= l;
2645 buf += l;
2646 addr += l;
2650 /* used for ROM loading : can write in RAM and ROM */
2651 void cpu_physical_memory_write_rom(target_phys_addr_t addr,
2652 const uint8_t *buf, int len)
2654 int l;
2655 uint8_t *ptr;
2656 target_phys_addr_t page;
2657 unsigned long pd;
2658 PhysPageDesc *p;
2660 while (len > 0) {
2661 page = addr & TARGET_PAGE_MASK;
2662 l = (page + TARGET_PAGE_SIZE) - addr;
2663 if (l > len)
2664 l = len;
2665 p = phys_page_find(page >> TARGET_PAGE_BITS);
2666 if (!p) {
2667 pd = IO_MEM_UNASSIGNED;
2668 } else {
2669 pd = p->phys_offset;
2672 if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM &&
2673 (pd & ~TARGET_PAGE_MASK) != IO_MEM_ROM &&
2674 !(pd & IO_MEM_ROMD)) {
2675 /* do nothing */
2676 } else {
2677 unsigned long addr1;
2678 addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
2679 /* ROM/RAM case */
2680 ptr = phys_ram_base + addr1;
2681 memcpy(ptr, buf, l);
2683 len -= l;
2684 buf += l;
2685 addr += l;
2690 /* warning: addr must be aligned */
2691 uint32_t ldl_phys(target_phys_addr_t addr)
2693 int io_index;
2694 uint8_t *ptr;
2695 uint32_t val;
2696 unsigned long pd;
2697 PhysPageDesc *p;
2699 p = phys_page_find(addr >> TARGET_PAGE_BITS);
2700 if (!p) {
2701 pd = IO_MEM_UNASSIGNED;
2702 } else {
2703 pd = p->phys_offset;
2706 if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM &&
2707 !(pd & IO_MEM_ROMD)) {
2708 /* I/O case */
2709 io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
2710 val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr);
2711 } else {
2712 /* RAM case */
2713 ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
2714 (addr & ~TARGET_PAGE_MASK);
2715 val = ldl_p(ptr);
2717 return val;
2720 /* warning: addr must be aligned */
2721 uint64_t ldq_phys(target_phys_addr_t addr)
2723 int io_index;
2724 uint8_t *ptr;
2725 uint64_t val;
2726 unsigned long pd;
2727 PhysPageDesc *p;
2729 p = phys_page_find(addr >> TARGET_PAGE_BITS);
2730 if (!p) {
2731 pd = IO_MEM_UNASSIGNED;
2732 } else {
2733 pd = p->phys_offset;
2736 if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM &&
2737 !(pd & IO_MEM_ROMD)) {
2738 /* I/O case */
2739 io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
2740 #ifdef TARGET_WORDS_BIGENDIAN
2741 val = (uint64_t)io_mem_read[io_index][2](io_mem_opaque[io_index], addr) << 32;
2742 val |= io_mem_read[io_index][2](io_mem_opaque[io_index], addr + 4);
2743 #else
2744 val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr);
2745 val |= (uint64_t)io_mem_read[io_index][2](io_mem_opaque[io_index], addr + 4) << 32;
2746 #endif
2747 } else {
2748 /* RAM case */
2749 ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
2750 (addr & ~TARGET_PAGE_MASK);
2751 val = ldq_p(ptr);
2753 return val;
2756 /* XXX: optimize */
2757 uint32_t ldub_phys(target_phys_addr_t addr)
2759 uint8_t val;
2760 cpu_physical_memory_read(addr, &val, 1);
2761 return val;
2764 /* XXX: optimize */
2765 uint32_t lduw_phys(target_phys_addr_t addr)
2767 uint16_t val;
2768 cpu_physical_memory_read(addr, (uint8_t *)&val, 2);
2769 return tswap16(val);
2772 /* warning: addr must be aligned. The ram page is not masked as dirty
2773 and the code inside is not invalidated. It is useful if the dirty
2774 bits are used to track modified PTEs */
2775 void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val)
2777 int io_index;
2778 uint8_t *ptr;
2779 unsigned long pd;
2780 PhysPageDesc *p;
2782 p = phys_page_find(addr >> TARGET_PAGE_BITS);
2783 if (!p) {
2784 pd = IO_MEM_UNASSIGNED;
2785 } else {
2786 pd = p->phys_offset;
2789 if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) {
2790 io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
2791 io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val);
2792 } else {
2793 ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
2794 (addr & ~TARGET_PAGE_MASK);
2795 stl_p(ptr, val);
2799 void stq_phys_notdirty(target_phys_addr_t addr, uint64_t val)
2801 int io_index;
2802 uint8_t *ptr;
2803 unsigned long pd;
2804 PhysPageDesc *p;
2806 p = phys_page_find(addr >> TARGET_PAGE_BITS);
2807 if (!p) {
2808 pd = IO_MEM_UNASSIGNED;
2809 } else {
2810 pd = p->phys_offset;
2813 if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) {
2814 io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
2815 #ifdef TARGET_WORDS_BIGENDIAN
2816 io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val >> 32);
2817 io_mem_write[io_index][2](io_mem_opaque[io_index], addr + 4, val);
2818 #else
2819 io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val);
2820 io_mem_write[io_index][2](io_mem_opaque[io_index], addr + 4, val >> 32);
2821 #endif
2822 } else {
2823 ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
2824 (addr & ~TARGET_PAGE_MASK);
2825 stq_p(ptr, val);
2829 /* warning: addr must be aligned */
2830 void stl_phys(target_phys_addr_t addr, uint32_t val)
2832 int io_index;
2833 uint8_t *ptr;
2834 unsigned long pd;
2835 PhysPageDesc *p;
2837 p = phys_page_find(addr >> TARGET_PAGE_BITS);
2838 if (!p) {
2839 pd = IO_MEM_UNASSIGNED;
2840 } else {
2841 pd = p->phys_offset;
2844 if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) {
2845 io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
2846 io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val);
2847 } else {
2848 unsigned long addr1;
2849 addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
2850 /* RAM case */
2851 ptr = phys_ram_base + addr1;
2852 stl_p(ptr, val);
2853 if (!cpu_physical_memory_is_dirty(addr1)) {
2854 /* invalidate code */
2855 tb_invalidate_phys_page_range(addr1, addr1 + 4, 0);
2856 /* set dirty bit */
2857 phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] |=
2858 (0xff & ~CODE_DIRTY_FLAG);
2863 /* XXX: optimize */
2864 void stb_phys(target_phys_addr_t addr, uint32_t val)
2866 uint8_t v = val;
2867 cpu_physical_memory_write(addr, &v, 1);
2870 /* XXX: optimize */
2871 void stw_phys(target_phys_addr_t addr, uint32_t val)
2873 uint16_t v = tswap16(val);
2874 cpu_physical_memory_write(addr, (const uint8_t *)&v, 2);
2877 /* XXX: optimize */
2878 void stq_phys(target_phys_addr_t addr, uint64_t val)
2880 val = tswap64(val);
2881 cpu_physical_memory_write(addr, (const uint8_t *)&val, 8);
2884 #endif
2886 /* virtual memory access for debug */
2887 int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
2888 uint8_t *buf, int len, int is_write)
2890 int l;
2891 target_phys_addr_t phys_addr;
2892 target_ulong page;
2894 while (len > 0) {
2895 page = addr & TARGET_PAGE_MASK;
2896 phys_addr = cpu_get_phys_page_debug(env, page);
2897 /* if no physical page mapped, return an error */
2898 if (phys_addr == -1)
2899 return -1;
2900 l = (page + TARGET_PAGE_SIZE) - addr;
2901 if (l > len)
2902 l = len;
2903 cpu_physical_memory_rw(phys_addr + (addr & ~TARGET_PAGE_MASK),
2904 buf, l, is_write);
2905 len -= l;
2906 buf += l;
2907 addr += l;
2909 return 0;
2912 void dump_exec_info(FILE *f,
2913 int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
2915 int i, target_code_size, max_target_code_size;
2916 int direct_jmp_count, direct_jmp2_count, cross_page;
2917 TranslationBlock *tb;
2919 target_code_size = 0;
2920 max_target_code_size = 0;
2921 cross_page = 0;
2922 direct_jmp_count = 0;
2923 direct_jmp2_count = 0;
2924 for(i = 0; i < nb_tbs; i++) {
2925 tb = &tbs[i];
2926 target_code_size += tb->size;
2927 if (tb->size > max_target_code_size)
2928 max_target_code_size = tb->size;
2929 if (tb->page_addr[1] != -1)
2930 cross_page++;
2931 if (tb->tb_next_offset[0] != 0xffff) {
2932 direct_jmp_count++;
2933 if (tb->tb_next_offset[1] != 0xffff) {
2934 direct_jmp2_count++;
2938 /* XXX: avoid using doubles ? */
2939 cpu_fprintf(f, "Translation buffer state:\n");
2940 cpu_fprintf(f, "TB count %d\n", nb_tbs);
2941 cpu_fprintf(f, "TB avg target size %d max=%d bytes\n",
2942 nb_tbs ? target_code_size / nb_tbs : 0,
2943 max_target_code_size);
2944 cpu_fprintf(f, "TB avg host size %d bytes (expansion ratio: %0.1f)\n",
2945 nb_tbs ? (code_gen_ptr - code_gen_buffer) / nb_tbs : 0,
2946 target_code_size ? (double) (code_gen_ptr - code_gen_buffer) / target_code_size : 0);
2947 cpu_fprintf(f, "cross page TB count %d (%d%%)\n",
2948 cross_page,
2949 nb_tbs ? (cross_page * 100) / nb_tbs : 0);
2950 cpu_fprintf(f, "direct jump count %d (%d%%) (2 jumps=%d %d%%)\n",
2951 direct_jmp_count,
2952 nb_tbs ? (direct_jmp_count * 100) / nb_tbs : 0,
2953 direct_jmp2_count,
2954 nb_tbs ? (direct_jmp2_count * 100) / nb_tbs : 0);
2955 cpu_fprintf(f, "\nStatistics:\n");
2956 cpu_fprintf(f, "TB flush count %d\n", tb_flush_count);
2957 cpu_fprintf(f, "TB invalidate count %d\n", tb_phys_invalidate_count);
2958 cpu_fprintf(f, "TLB flush count %d\n", tlb_flush_count);
2959 #ifdef CONFIG_PROFILER
2961 int64_t tot;
2962 tot = dyngen_interm_time + dyngen_code_time;
2963 cpu_fprintf(f, "JIT cycles %" PRId64 " (%0.3f s at 2.4 GHz)\n",
2964 tot, tot / 2.4e9);
2965 cpu_fprintf(f, "translated TBs %" PRId64 " (aborted=%" PRId64 " %0.1f%%)\n",
2966 dyngen_tb_count,
2967 dyngen_tb_count1 - dyngen_tb_count,
2968 dyngen_tb_count1 ? (double)(dyngen_tb_count1 - dyngen_tb_count) / dyngen_tb_count1 * 100.0 : 0);
2969 cpu_fprintf(f, "avg ops/TB %0.1f max=%d\n",
2970 dyngen_tb_count ? (double)dyngen_op_count / dyngen_tb_count : 0, dyngen_op_count_max);
2971 cpu_fprintf(f, "old ops/total ops %0.1f%%\n",
2972 dyngen_op_count ? (double)dyngen_old_op_count / dyngen_op_count * 100.0 : 0);
2973 cpu_fprintf(f, "deleted ops/TB %0.2f\n",
2974 dyngen_tb_count ?
2975 (double)dyngen_tcg_del_op_count / dyngen_tb_count : 0);
2976 cpu_fprintf(f, "cycles/op %0.1f\n",
2977 dyngen_op_count ? (double)tot / dyngen_op_count : 0);
2978 cpu_fprintf(f, "cycles/in byte %0.1f\n",
2979 dyngen_code_in_len ? (double)tot / dyngen_code_in_len : 0);
2980 cpu_fprintf(f, "cycles/out byte %0.1f\n",
2981 dyngen_code_out_len ? (double)tot / dyngen_code_out_len : 0);
2982 if (tot == 0)
2983 tot = 1;
2984 cpu_fprintf(f, " gen_interm time %0.1f%%\n",
2985 (double)dyngen_interm_time / tot * 100.0);
2986 cpu_fprintf(f, " gen_code time %0.1f%%\n",
2987 (double)dyngen_code_time / tot * 100.0);
2988 cpu_fprintf(f, "cpu_restore count %" PRId64 "\n",
2989 dyngen_restore_count);
2990 cpu_fprintf(f, " avg cycles %0.1f\n",
2991 dyngen_restore_count ? (double)dyngen_restore_time / dyngen_restore_count : 0);
2993 extern void dump_op_count(void);
2994 dump_op_count();
2997 #endif
3000 #if !defined(CONFIG_USER_ONLY)
3002 #define MMUSUFFIX _cmmu
3003 #define GETPC() NULL
3004 #define env cpu_single_env
3005 #define SOFTMMU_CODE_ACCESS
3007 #define SHIFT 0
3008 #include "softmmu_template.h"
3010 #define SHIFT 1
3011 #include "softmmu_template.h"
3013 #define SHIFT 2
3014 #include "softmmu_template.h"
3016 #define SHIFT 3
3017 #include "softmmu_template.h"
3019 #undef env
3021 #endif