exec.c revision 178d85b8274f9ac82fb553c80760bbbb4044401c
4ed92248676a091e0d73db61773d9059b36d0861stoddard * virtual page mapping and translated block handling
4ed92248676a091e0d73db61773d9059b36d0861stoddard * Copyright (c) 2003 Fabrice Bellard
4ed92248676a091e0d73db61773d9059b36d0861stoddard * This library is free software; you can redistribute it and/or
4ed92248676a091e0d73db61773d9059b36d0861stoddard * modify it under the terms of the GNU Lesser General Public
4ed92248676a091e0d73db61773d9059b36d0861stoddard * License as published by the Free Software Foundation; either
4ed92248676a091e0d73db61773d9059b36d0861stoddard * version 2 of the License, or (at your option) any later version.
b4b458e66e24979631466a69c4bae3090a7e50fewrowe * This library is distributed in the hope that it will be useful,
4ed92248676a091e0d73db61773d9059b36d0861stoddard * but WITHOUT ANY WARRANTY; without even the implied warranty of
fa29e798c69385995c601ddfe75cbd5cf29244efwrowe * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4ed92248676a091e0d73db61773d9059b36d0861stoddard * Lesser General Public License for more details.
752c83c97683b1fb9879ba874593a135155a043cwrowe * You should have received a copy of the GNU Lesser General Public
fa29e798c69385995c601ddfe75cbd5cf29244efwrowe * License along with this library; if not, write to the Free Software
6b441c81aae632befd971e634b4a36780c71d18ewrowe * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
9d134be9b7d1d6f0f9e910346a8075dac77b3d69ianh * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
c639d9d16cb8ac0ea8163c8c46e34ef9c6810ce2wrowe * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
c639d9d16cb8ac0ea8163c8c46e34ef9c6810ce2wrowe * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
cfab5b5b6dc82c578597b582f76491c96b86eeb7wrowe * a choice of LGPL license versions is made available with the language indicating
cfab5b5b6dc82c578597b582f76491c96b86eeb7wrowe * that LGPLv2 or any later version may be used, or where a choice of which version
a04a085d201d1620c077ba6ecaa7022b417b1cd5tdonovan * of the LGPL is applied is otherwise unspecified.
4c35be7cad99269afb697fccc1b9ba85dd2ce702wrowe#else /* VBOX */
4c35be7cad99269afb697fccc1b9ba85dd2ce702wrowe#endif /* VBOX */
6173077ec421fe85891d4b914c87175beb0a9293wrowe//#define DEBUG_TB_INVALIDATE
b4b458e66e24979631466a69c4bae3090a7e50fewrowe//#define DEBUG_FLUSH
945f023c83c2d18bf5145a5b9af48fc3216fbef6wrowe//#define DEBUG_TLB
a8f3504993ae9a401b6fc87c7a00b716b112e3d0wrowe//#define DEBUG_UNASSIGNED
6166dacd3c3d034394c1f8c131919ea7452835a7wrowe/* make various TB consistency checks */
a8f3504993ae9a401b6fc87c7a00b716b112e3d0wrowe//#define DEBUG_TB_CHECK
a8f3504993ae9a401b6fc87c7a00b716b112e3d0wrowe//#define DEBUG_TLB_CHECK
a8f3504993ae9a401b6fc87c7a00b716b112e3d0wrowe//#define DEBUG_IOPORT
60f8e9cbbfc2d757c71db17a35acb8566eebc0dawrowe//#define DEBUG_SUBPAGE
a8f3504993ae9a401b6fc87c7a00b716b112e3d0wrowe/* TB consistency checks only implemented for usermode emulation. */
032eeda9f618fa26f635c9e8dfd854c17e76262fwrowe/* Note: for compatibility with kqemu, we use 32 bits for x86_64 */
60f8e9cbbfc2d757c71db17a35acb8566eebc0dawroweTranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE];
92fb4b4faaea055db085fc0864950c2a5edd0de2jwoolley/* any access to the tbs or the page table must use this lock */
60f8e9cbbfc2d757c71db17a35acb8566eebc0dawrowe/* The prologue must be reachable with a direct jump. ARM and Sparc64
549b1f3d6860ae792e6a8c8d3a483140bdb857a5wrowe have limited branch ranges (possibly also PPC) so place it in a
60f8e9cbbfc2d757c71db17a35acb8566eebc0dawrowe section close to code segment. */
6a5b8f7bd9abe819babda806a7245a31cd0dd2fbwrowe#else /* VBOX */
a8f3504993ae9a401b6fc87c7a00b716b112e3d0wrowe#endif /* VBOX */
cfab5b5b6dc82c578597b582f76491c96b86eeb7wrowestatic unsigned long code_gen_buffer_size;
cfab5b5b6dc82c578597b582f76491c96b86eeb7wrowe/* threshold to flush the translated code buffer */
cfab5b5b6dc82c578597b582f76491c96b86eeb7wrowestatic unsigned long code_gen_buffer_max_size;
cfab5b5b6dc82c578597b582f76491c96b86eeb7wrowe#else /* VBOX */
cfab5b5b6dc82c578597b582f76491c96b86eeb7wrowe/* we have memory ranges (the high PC-BIOS mapping) which
cfab5b5b6dc82c578597b582f76491c96b86eeb7wrowe causes some pages to fall outside the dirty map here. */
071646a05417cc437fcffec9512588f75bd39a03wrowe#endif /* VBOX */
9cef38b3a87190d0c4dcd5b389573418af9de73cwrowe#if !defined(VBOX)
424303d026faabb9e9752310911d00fa737b603awrowe/* current CPU in the current thread. It is only valid inside
424303d026faabb9e9752310911d00fa737b603awrowe cpu_exec() */
9cef38b3a87190d0c4dcd5b389573418af9de73cwrowe/* 0 = Do not count executed instructions.
fa29e798c69385995c601ddfe75cbd5cf29244efwrowe 1 = Precise instruction counting.
f397bb616fba8b3a5a9b3c57a5c89ad0e254b673mturk 2 = Adaptive rate instruction counting. */
6b441c81aae632befd971e634b4a36780c71d18ewrowe/* Current instruction counter. While executing translated code this may
6b441c81aae632befd971e634b4a36780c71d18ewrowe include some instructions that have not yet been executed. */
9cef38b3a87190d0c4dcd5b389573418af9de73cwrowetypedef struct PageDesc {
9cef38b3a87190d0c4dcd5b389573418af9de73cwrowe /* list of TBs intersecting this ram page */
7ffdcdd65e145ef18d9193d89bffff10c5da4961wrowe /* in order to optimize self modifying code, we count the number
7ffdcdd65e145ef18d9193d89bffff10c5da4961wrowe of lookups we do to a given page to use a bitmap */
7ffdcdd65e145ef18d9193d89bffff10c5da4961wrowe unsigned long flags;
ea0acbc141b3ca2ef21666bd23bfea9af9a758aawrowetypedef struct PhysPageDesc {
9cef38b3a87190d0c4dcd5b389573418af9de73cwrowe /* offset in host memory of the page + io_index in the low bits */
50feafa397d01128b8cf94ad1602d3d78e1a4169wrowe#if defined(CONFIG_USER_ONLY) && defined(TARGET_VIRT_ADDR_SPACE_BITS)
ea0acbc141b3ca2ef21666bd23bfea9af9a758aawrowe/* XXX: this is a temporary hack for alpha target.
ea0acbc141b3ca2ef21666bd23bfea9af9a758aawrowe * In the future, this is to be replaced by a multi-level table
50feafa397d01128b8cf94ad1602d3d78e1a4169wrowe * to actually be able to handle the complete 64 bits address space.
ea0acbc141b3ca2ef21666bd23bfea9af9a758aawrowe#define L1_BITS (TARGET_VIRT_ADDR_SPACE_BITS - L2_BITS - TARGET_PAGE_BITS)
549b1f3d6860ae792e6a8c8d3a483140bdb857a5wrowe/* XXX: for system emulation, it could just be an array */
945f023c83c2d18bf5145a5b9af48fc3216fbef6wrowestatic unsigned l0_map_max_used = 0;
945f023c83c2d18bf5145a5b9af48fc3216fbef6wrowestatic void io_mem_init(void);
50feafa397d01128b8cf94ad1602d3d78e1a4169wrowe/* io memory support */
4ed92248676a091e0d73db61773d9059b36d0861stoddardCPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
4ed92248676a091e0d73db61773d9059b36d0861stoddardCPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
1e83c8de3aa48b316b28057d53995272baf1260cwrowe/* log support */
0ea0379ff6438182ac3c9d8f108deb3c82210319wrowe#endif /* !VBOX */
ea0acbc141b3ca2ef21666bd23bfea9af9a758aawrowestatic int log_append = 0;
d7f2b79379c5a3b849bf3d5dacf7180805ecba1fwrowe/* statistics */
d7f2b79379c5a3b849bf3d5dacf7180805ecba1fwrowe#else /* VBOX - Resettable U32 stats, see VBoxRecompiler.c. */
06bd11dc20356466f38185ddb47fc798b4508d5fwrowe#endif /* VBOX */
1e83c8de3aa48b316b28057d53995272baf1260cwrowetypedef struct subpage_t {
5158d1bbe54607d02bb5e5b2219e7aed4684e41btdonovan CPUWriteMemoryFunc **mem_write[TARGET_PAGE_SIZE][4];
34e753c9dba1e821f54f0d4179f8774f854123eecolm#else /* VBOX */
7c11b20dfccedb7381518b3cc3cc9ef9e6731cb1wrowe RTMEM_PROT_EXEC | RTMEM_PROT_READ | RTMEM_PROT_WRITE);
7c11b20dfccedb7381518b3cc3cc9ef9e6731cb1wrowe#endif /* VBOX */
14d5b1a7866541c4eb974f2d213d2aea59743c95wrowestatic void page_init(void)
14d5b1a7866541c4eb974f2d213d2aea59743c95wrowe /* NOTE: we can always suppose that qemu_host_page_size >=
7c11b20dfccedb7381518b3cc3cc9ef9e6731cb1wrowe TARGET_PAGE_SIZE */
0b64c3e5c7379284f90efc7193f16b373df39fe1wrowe RTMemProtect(code_gen_buffer, sizeof(code_gen_buffer),
1e83c8de3aa48b316b28057d53995272baf1260cwrowe RTMEM_PROT_EXEC | RTMEM_PROT_READ | RTMEM_PROT_WRITE);
1e83c8de3aa48b316b28057d53995272baf1260cwrowe#else /* !VBOX */
0b64c3e5c7379284f90efc7193f16b373df39fe1wrowe#endif /* !VBOX */
7c11b20dfccedb7381518b3cc3cc9ef9e6731cb1wrowe while ((1 << qemu_host_page_bits) < qemu_host_page_size)
0f488df653e7e8cf4ee0006a3138f9474ca1d375wrowe while ((1 << qemu_host_page_bits) < (int)qemu_host_page_size)
c639d9d16cb8ac0ea8163c8c46e34ef9c6810ce2wrowe /* We use other means to set reserved bit on our pages */
7c11b20dfccedb7381518b3cc3cc9ef9e6731cb1wrowe#else /* !VBOX */
60f8e9cbbfc2d757c71db17a35acb8566eebc0dawrowe n = fscanf (f, "%llx-%llx %*[^\n]\n", &startaddr, &endaddr);
255d4d329b2d41e4ac0c3ade5cfe528a078ef682wrowe if (n == 2) {
1e83c8de3aa48b316b28057d53995272baf1260cwrowe } while (!feof(f));
1e83c8de3aa48b316b28057d53995272baf1260cwrowe#endif /* !VBOX */
1e83c8de3aa48b316b28057d53995272baf1260cwrowe /* Host memory outside guest VM. For 32-bit targets we have already
1e83c8de3aa48b316b28057d53995272baf1260cwrowe excluded high addresses. */
1e83c8de3aa48b316b28057d53995272baf1260cwrowe#else /* VBOX */
995f5596d461cdd916f9ae5b7b4dcd27efbc3c2fwrowe AssertMsgReturn(index < (target_ulong)L2_SIZE * L1_SIZE * L0_SIZE,
0b64c3e5c7379284f90efc7193f16b373df39fe1wrowe ("index=%RGp >= %RGp; L1_SIZE=%#x L2_SIZE=%#x L0_SIZE=%#x\n",
0b64c3e5c7379284f90efc7193f16b373df39fe1wrowe (RTGCPHYS)index, (RTGCPHYS)L2_SIZE * L1_SIZE, L1_SIZE, L2_SIZE, L0_SIZE),
1e83c8de3aa48b316b28057d53995272baf1260cwrowe l0_map[i0] = l1_map = qemu_mallocz(sizeof(PageDesc *) * L1_SIZE);
1e83c8de3aa48b316b28057d53995272baf1260cwrowe#endif /* VBOX */
2d7d2ccd828d0424f046b62d57e5551cf8ee293fwrowestatic inline PageDesc *page_find_alloc(target_ulong index)
483ed5892604266e702d65db4d0b2b621c488a09wrowe /* allocate if not found */
483ed5892604266e702d65db4d0b2b621c488a09wrowe unsigned long addr;
483ed5892604266e702d65db4d0b2b621c488a09wrowe /* Don't use qemu_malloc because it may recurse. */
b56ce33e3fe5670a4562de222c60ade06fe1bce0wrowestatic PhysPageDesc *phys_page_find_alloc(target_phys_addr_t index, int alloc)
b56ce33e3fe5670a4562de222c60ade06fe1bce0wrowe void **lp, **p;
b56ce33e3fe5670a4562de222c60ade06fe1bce0wrowe p = (void **)l1_phys_map;
c639d9d16cb8ac0ea8163c8c46e34ef9c6810ce2wrowe lp = p + ((index >> (L1_BITS + L2_BITS)) & (L1_SIZE - 1));
b56ce33e3fe5670a4562de222c60ade06fe1bce0wrowe /* allocate if not found */
945f023c83c2d18bf5145a5b9af48fc3216fbef6wrowe#else /* VBOX */
9cef38b3a87190d0c4dcd5b389573418af9de73cwrowe /* level 0 lookup and lazy allocation of level 1 map. */
945f023c83c2d18bf5145a5b9af48fc3216fbef6wrowe if (RT_UNLIKELY(index >= (target_phys_addr_t)L2_SIZE * L1_SIZE * L0_SIZE))
634c70c6512b0ae61fb1ee130266e6e9af170803wrowe /* level 1 lookup and lazy allocation of level 2 map. */
7c11b20dfccedb7381518b3cc3cc9ef9e6731cb1wrowe#endif /* VBOX */
d7f2b79379c5a3b849bf3d5dacf7180805ecba1fwrowe /* allocate if not found */
743aeb835754aadabaec38c00742899668eb9dd1wrowe for (i = 0; i < L2_SIZE; i++)
9cef38b3a87190d0c4dcd5b389573418af9de73cwrowe return ((PhysPageDesc *)pd) + (index & (L2_SIZE - 1));
945f023c83c2d18bf5145a5b9af48fc3216fbef6wrowestatic inline PhysPageDesc *phys_page_find(target_phys_addr_t index)
6bc96ef510ce100bfdeefd80b8f05c010373ed13wrowestatic void tlb_unprotect_code_phys(CPUState *env, ram_addr_t ram_addr,
6bc96ef510ce100bfdeefd80b8f05c010373ed13wrowe#define mmap_lock() do { } while(0)
cfab5b5b6dc82c578597b582f76491c96b86eeb7wrowe#define mmap_unlock() do { } while(0)
cfab5b5b6dc82c578597b582f76491c96b86eeb7wrowe#ifdef VBOX /* We don't need such huge codegen buffer size, as execute
f71283367c234bf49ddc8ba7b23d3d3829db0d8dmturk most of the code in raw or hwacc mode. */
0bcc003d275c6b0a9060d43be89762b218cbc2c7wrowe#else /* !VBOX */
483ed5892604266e702d65db4d0b2b621c488a09wrowe#define DEFAULT_CODE_GEN_BUFFER_SIZE (32 * 1024 * 1024)
0bcc003d275c6b0a9060d43be89762b218cbc2c7wrowe#endif /* !VBOX */
0bcc003d275c6b0a9060d43be89762b218cbc2c7wrowe/* Currently it is not recommanded to allocate big chunks of data in
0bcc003d275c6b0a9060d43be89762b218cbc2c7wrowe user mode. It will change when a dedicated libc will be used */
7c11b20dfccedb7381518b3cc3cc9ef9e6731cb1wrowe/* VBox allocates codegen buffer dynamically */
0bcc003d275c6b0a9060d43be89762b218cbc2c7wrowestatic uint8_t static_code_gen_buffer[DEFAULT_CODE_GEN_BUFFER_SIZE];
483ed5892604266e702d65db4d0b2b621c488a09wrowe /* We cannot use phys_ram_size here, as it's 0 now,
483ed5892604266e702d65db4d0b2b621c488a09wrowe * it only gets initialized once RAM registration callback
ee8892ba26f52316734c59d8002ab349c2e3fdbdcolm * (REMR3NotifyPhysRamRegister()) called.
0f488df653e7e8cf4ee0006a3138f9474ca1d375wrowe /* in user mode, phys_ram_size is not meaningful */
483ed5892604266e702d65db4d0b2b621c488a09wrowe /* XXX: needs adjustments */
483ed5892604266e702d65db4d0b2b621c488a09wrowe code_gen_buffer_size = (unsigned long)(phys_ram_size / 4);
0bcc003d275c6b0a9060d43be89762b218cbc2c7wrowe#endif /* VBOX */
6a5b8f7bd9abe819babda806a7245a31cd0dd2fbwrowe /* The code gen buffer location may have constraints depending on
6a5b8f7bd9abe819babda806a7245a31cd0dd2fbwrowe the host cpu and OS */
0bcc003d275c6b0a9060d43be89762b218cbc2c7wrowe code_gen_buffer = RTMemExecAlloc(code_gen_buffer_size);
0bcc003d275c6b0a9060d43be89762b218cbc2c7wrowe#else //!VBOX
0bcc003d275c6b0a9060d43be89762b218cbc2c7wrowe /* Cannot map more than that */
0bcc003d275c6b0a9060d43be89762b218cbc2c7wrowe // Map the buffer below 2G, so we can use direct calls and branches
0bcc003d275c6b0a9060d43be89762b218cbc2c7wrowe fprintf(stderr, "Could not allocate dynamic translator buffer\n");
0bcc003d275c6b0a9060d43be89762b218cbc2c7wrowe /* FreeBSD doesn't have MAP_32BIT, use MAP_FIXED and assume
483ed5892604266e702d65db4d0b2b621c488a09wrowe * 0x40000000 is free */
483ed5892604266e702d65db4d0b2b621c488a09wrowe /* Cannot map more than that */
752c83c97683b1fb9879ba874593a135155a043cwrowe fprintf(stderr, "Could not allocate dynamic translator buffer\n");
c82ccb99a59cb210c31b096a567e393e59d558f3colm fprintf(stderr, "Could not allocate dynamic translator buffer\n");
0bcc003d275c6b0a9060d43be89762b218cbc2c7wrowe map_exec(code_gen_prologue, sizeof(code_gen_prologue));
0bcc003d275c6b0a9060d43be89762b218cbc2c7wrowe#endif /* !VBOX */
0bcc003d275c6b0a9060d43be89762b218cbc2c7wrowe#endif /* !USE_STATIC_CODE_GEN_BUFFER */
0bcc003d275c6b0a9060d43be89762b218cbc2c7wrowe map_exec(code_gen_prologue, sizeof(code_gen_prologue));
0bcc003d275c6b0a9060d43be89762b218cbc2c7wrowe code_gen_max_blocks = code_gen_buffer_size / CODE_GEN_AVG_BLOCK_SIZE;
0bcc003d275c6b0a9060d43be89762b218cbc2c7wrowe tbs = qemu_malloc(code_gen_max_blocks * sizeof(TranslationBlock));
18062914633d6aa27c5f07c6ed20e3d169714c89wrowe/* Must be called before using the QEMU cpus. 'tb_size' is the size
1462f24d09bed587fcdfb69abf1e858598a06382wrowe (in bytes) allocated to the translation buffer. Zero means default
1462f24d09bed587fcdfb69abf1e858598a06382wrowe#if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY)
a8f3504993ae9a401b6fc87c7a00b716b112e3d0wrowestatic int cpu_common_load(QEMUFile *f, void *opaque, int version_id)
60f8e9cbbfc2d757c71db17a35acb8566eebc0dawrowe#endif //!VBOX
823627d210d6c8bf02aec333587428584b29b6e2wrowe#if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY)
19725e678f8b916b0952a002356d2098301e9727wrowe register_savevm("cpu_common", cpu_index, CPU_COMMON_SAVE_VERSION,
f2f6daffb4236c6781e779e57561581c92a1f539wrowe#endif // !VBOX
032eeda9f618fa26f635c9e8dfd854c17e76262fwrowe/* set to NULL all the 'first_tb' fields in all PageDescs */
032eeda9f618fa26f635c9e8dfd854c17e76262fwrowestatic void page_flush_tb(void)
823627d210d6c8bf02aec333587428584b29b6e2wrowe while (k-- > 0) {
f1b8465dec39c934d4bef4a2366139ffdd021851wrowe for(i = 0; i < L1_SIZE; i++) {
60f8e9cbbfc2d757c71db17a35acb8566eebc0dawrowe for(j = 0; j < L2_SIZE; j++) {
60f8e9cbbfc2d757c71db17a35acb8566eebc0dawrowe/* flush all the translation blocks */
60f8e9cbbfc2d757c71db17a35acb8566eebc0dawrowe/* XXX: tb_flush is currently not thread safe */
f99d4fa2605925f385a184ba3789be3423690533wrowe printf("qemu: flush code_size=%ld nb_tbs=%d avg_tb_size=%ld\n",
8dda6d649a6e3be9888cd49f1d8c703d3740a06fwrowe ((unsigned long)(code_gen_ptr - code_gen_buffer)) / nb_tbs : 0);
f99d4fa2605925f385a184ba3789be3423690533wrowe if ((unsigned long)(code_gen_ptr - code_gen_buffer) > code_gen_buffer_size)
f99d4fa2605925f385a184ba3789be3423690533wrowe cpu_abort(env1, "Internal error: code buffer overflow\n");
0bcc003d275c6b0a9060d43be89762b218cbc2c7wrowe for(env = first_cpu; env != NULL; env = env->next_cpu) {
0bcc003d275c6b0a9060d43be89762b218cbc2c7wrowe memset (env->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof (void *));
0bcc003d275c6b0a9060d43be89762b218cbc2c7wrowe memset (tb_phys_hash, 0, CODE_GEN_PHYS_HASH_SIZE * sizeof (void *));
a901f6f8425b207639fe2d1e22b102d96f8e64ffwrowe /* XXX: flush processor icache at this point if cache flush is
0bcc003d275c6b0a9060d43be89762b218cbc2c7wrowe expensive */
72347cd608351452f99d5f4411d3e0c089d0293awrowe for(i = 0;i < CODE_GEN_PHYS_HASH_SIZE; i++) {
72347cd608351452f99d5f4411d3e0c089d0293awrowe for(tb = tb_phys_hash[i]; tb != NULL; tb = tb->phys_hash_next) {
c2e5fcbd499ae7b5093d4877ff42e6c5ec74352bwrowe printf("ERROR invalidate: address=%08lx PC=%08lx size=%04x\n",
9fb3226780b297bcc320cb19cc3ec23194fac8e1wrowe/* verify that all the pages have correct rights for code */
9fb3226780b297bcc320cb19cc3ec23194fac8e1wrowestatic void tb_page_check(void)
9fb3226780b297bcc320cb19cc3ec23194fac8e1wrowe for(i = 0;i < CODE_GEN_PHYS_HASH_SIZE; i++) {
9fb3226780b297bcc320cb19cc3ec23194fac8e1wrowe for(tb = tb_phys_hash[i]; tb != NULL; tb = tb->phys_hash_next) {
9fb3226780b297bcc320cb19cc3ec23194fac8e1wrowe printf("ERROR page flags: PC=%08lx size=%04x f1=%x f2=%x\n",
a19c94edefc000de60a6925b4ca15637e2f785f1wrowe unsigned int n1;
a19c94edefc000de60a6925b4ca15637e2f785f1wrowe /* suppress any remaining jumps to this TB */
0bcc003d275c6b0a9060d43be89762b218cbc2c7wrowe /* check end of list */
1f0a9798d1c29e1e0cbdb339a0262ba287a29ed4wrowe/* invalidate one TB */
1e83c8de3aa48b316b28057d53995272baf1260cwrowestatic inline void tb_remove(TranslationBlock **ptb, TranslationBlock *tb,
e3c59608a643aac0e86a0e8cf2d62f8ef655337fwrowe *ptb = *(TranslationBlock **)((char *)tb1 + next_offset);
unsigned int n1;
unsigned int n1;
if (tb1) {
PageDesc *p;
unsigned int h, n1;
#ifdef VBOX
flags);
if(tb)
# ifdef DEBUG
# ifdef VBOX_STRICT
return p ? p->phys_offset : 0;
if (!p->code_bitmap)
tb_start = 0;
int code_gen_size;
if (!tb) {
code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));
return tb;
int is_cpu_write_access)
PageDesc *p;
if (!p->code_bitmap &&
current_tb_modified = 0;
#ifdef TARGET_HAS_PRECISE_SMC
if (current_tb_not_found) {
current_tb_not_found = 0;
#if defined(TARGET_I386)
if (env) {
if (env) {
#if !defined(CONFIG_USER_ONLY)
if (!p->first_tb) {
if (is_cpu_write_access) {
#ifdef TARGET_HAS_PRECISE_SMC
if (current_tb_modified) {
PageDesc *p;
int offset, b;
if (loglevel) {
if (p->code_bitmap) {
goto do_invalidate;
#if !defined(CONFIG_SOFTMMU)
PageDesc *p;
#ifdef TARGET_HAS_PRECISE_SMC
current_tb_modified = 0;
#ifdef TARGET_HAS_PRECISE_SMC
#ifdef TARGET_HAS_PRECISE_SMC
#if defined(TARGET_I386)
#ifdef TARGET_HAS_PRECISE_SMC
if (current_tb_modified) {
PageDesc *p;
#if defined(CONFIG_USER_ONLY)
int prot;
prot = 0;
if (!p2)
#ifdef DEBUG_TB_INVALIDATE
if (!last_first_tb) {
#ifndef VBOX
return NULL;
return tb;
nb_tbs--;
mmap_lock();
#ifdef DEBUG_TB_CHECK
mmap_unlock();
if (nb_tbs <= 0)
return NULL;
return NULL;
m_min = 0;
if (v == tc_ptr)
return tb;
else if (tc_ptr < v) {
unsigned int n1;
#if defined(TARGET_HAS_ICE)
PhysPageDesc *p;
#if defined(TARGET_HAS_ICE)
#if defined(TARGET_HAS_ICE)
#if defined(TARGET_HAS_ICE)
goto found;
#if defined(TARGET_HAS_ICE)
#ifndef VBOX
if (!logfile) {
#if !defined(CONFIG_SOFTMMU)
if (logfile) {
#if !defined(USE_NPTL)
int old_mask;
#ifdef VBOX
#if defined(USE_NPTL)
if (use_icount) {
#ifndef CONFIG_USER_ONLY
#ifdef VBOX
* Note: the current implementation can be executed by another thread without problems; make sure this remains true
#ifndef VBOX
#ifdef TARGET_I386
"show interrupts/exceptions in short format" },
#ifdef TARGET_I386
"show protected mode far calls/returns/exceptions" },
#ifdef DEBUG_IOPORT
int mask;
const char *p, *p1;
p = str;
mask = 0;
if (!p1)
goto found;
return mask;
#ifdef TARGET_I386
if (logfile) {
#ifdef TARGET_I386
abort();
#ifndef VBOX
return new_env;
#if !defined(CONFIG_USER_ONLY)
#ifdef VBOX
#ifdef VBOX
#if defined(DEBUG_TLB)
for(i = 0; i < CPU_TLB_SIZE; i++) {
#ifdef VBOX
int mmu_idx;
#ifdef VBOX
#ifdef USE_KQEMU
#if defined(DEBUG_TLB)
#ifdef USE_KQEMU
#ifdef VBOX
unsigned long addr;
#ifdef VBOX
int dirty_flags)
uint8_t *p;
if (length == 0)
#ifdef USE_KQEMU
for(i = 0; i < len; i++) {
#ifdef VBOX
for(i = 0; i < len; i++)
p[i] &= mask;
start1 = (unsigned long)remR3TlbGCPhys2Ptr(first_cpu, start, 1 /*fWritable*/); /** @todo page replacing (sharing or read only) may cause trouble, fix interface/whatever. */
for(i = 0; i < CPU_TLB_SIZE; i++)
for(i = 0; i < CPU_TLB_SIZE; i++)
for(i = 0; i < CPU_TLB_SIZE; i++)
for(i = 0; i < CPU_TLB_SIZE; i++)
#ifndef VBOX
int cpu_physical_memory_get_dirty_tracking(void)
return in_migration;
for(i = 0; i < CPU_TLB_SIZE; i++)
for(i = 0; i < CPU_TLB_SIZE; i++)
for(i = 0; i < CPU_TLB_SIZE; i++)
for(i = 0; i < CPU_TLB_SIZE; i++)
for(i = 0; i < CPU_TLB_SIZE; i++)
for(i = 0; i < CPU_TLB_SIZE; i++)
for(i = 0; i < CPU_TLB_SIZE; i++)
for(i = 0; i < CPU_TLB_SIZE; i++)
PhysPageDesc *p;
unsigned long pd;
unsigned int index;
int ret;
#if defined(DEBUG_TLB)
ret = 0;
#ifdef VBOX
return ret;
#ifndef VBOX
PageDesc *p;
prot = 0;
for(i = 0; i <= L1_SIZE; i++) {
if (i < L1_SIZE)
p = l1_map[i];
p = NULL;
for(j = 0;j < L2_SIZE; j++) {
prot1 = 0;
if (prot1 != 0)
PageDesc *p;
return p->flags;
PageDesc *p;
#ifdef VBOX
AssertMsgFailed(("We shouldn't be here, and if we should, we must have an env to do the proper locking!\n"));
p->first_tb) {
PageDesc *p;
mmap_lock();
if (!p1) {
mmap_unlock();
p = p1;
prot = 0;
#ifdef DEBUG_TB_CHECK
mmap_unlock();
mmap_unlock();
#if !defined(CONFIG_USER_ONLY)
need_subpage) \
start_addr2 = 0; \
if (start_addr2 > 0) \
PhysPageDesc *p;
void *subpage;
#ifdef USE_KQEMU
int need_subpage = 0;
>> IO_MEM_SHIFT];
int need_subpage = 0;
PhysPageDesc *p;
return IO_MEM_UNASSIGNED;
return p->phys_offset;
#ifndef VBOX
abort();
return addr;
#ifdef DEBUG_UNASSIGNED
#ifdef DEBUG_UNASSIGNED
#ifdef DEBUG_UNASSIGNED
#ifdef DEBUG_UNASSIGNED
#ifdef DEBUG_UNASSIGNED
#ifdef DEBUG_UNASSIGNED
int dirty_flags;
#ifdef VBOX
#if !defined(CONFIG_USER_ONLY)
# ifdef VBOX
#ifdef USE_KQEMU
#ifdef VBOX
int dirty_flags;
#ifdef VBOX
#if !defined(CONFIG_USER_ONLY)
# ifdef VBOX
#ifdef USE_KQEMU
#ifdef VBOX
int dirty_flags;
#ifdef VBOX
#if !defined(CONFIG_USER_ONLY)
# ifdef VBOX
#ifdef USE_KQEMU
#ifdef VBOX
unsigned int len)
unsigned int idx;
#if defined(DEBUG_SUBPAGE)
return ret;
unsigned int idx;
#if defined(DEBUG_SUBPAGE)
#if defined(DEBUG_SUBPAGE)
#if defined(DEBUG_SUBPAGE)
#if defined(DEBUG_SUBPAGE)
#if defined(DEBUG_SUBPAGE)
#if defined(DEBUG_SUBPAGE)
#if defined(DEBUG_SUBPAGE)
#if defined(DEBUG_SUBPAGE)
int subpage_memory;
#if defined(DEBUG_SUBPAGE)
return mmio;
static void io_mem_init(void)
cpu_register_io_memory(IO_MEM_UNASSIGNED >> IO_MEM_SHIFT, unassigned_mem_read, unassigned_mem_write, NULL);
void *opaque)
int i, subwidth = 0;
if (io_index <= 0) {
#if defined(CONFIG_USER_ONLY)
int l, flags;
while (len > 0) {
if (l > len)
l = len;
if (is_write) {
len -= l;
buf += l;
addr += l;
int l, io_index;
unsigned long pd;
PhysPageDesc *p;
while (len > 0) {
if (l > len)
l = len;
if (is_write) {
unsigned long addr1;
#ifdef VBOX
#ifdef VBOX
#ifdef VBOX
len -= l;
buf += l;
addr += l;
#ifndef VBOX
unsigned long pd;
PhysPageDesc *p;
while (len > 0) {
if (l > len)
l = len;
unsigned long addr1;
len -= l;
buf += l;
addr += l;
int io_index;
unsigned long pd;
PhysPageDesc *p;
#ifndef VBOX
return val;
int io_index;
unsigned long pd;
PhysPageDesc *p;
#ifdef TARGET_WORDS_BIGENDIAN
#ifndef VBOX
return val;
return val;
int io_index;
unsigned long pd;
PhysPageDesc *p;
#ifndef VBOX
#ifndef VBOX
int io_index;
unsigned long pd;
PhysPageDesc *p;
#ifdef TARGET_WORDS_BIGENDIAN
#ifndef VBOX
int io_index;
unsigned long pd;
PhysPageDesc *p;
unsigned long addr1;
#ifndef VBOX
#ifdef VBOX
while (len > 0) {
if (l > len)
l = len;
len -= l;
buf += l;
addr += l;
if (!tb) {
retaddr);
#if defined(TARGET_MIPS)
if (n > CF_COUNT_MASK)
#ifndef VBOX
target_code_size = 0;
max_target_code_size = 0;
cross_page = 0;
direct_jmp_count = 0;
direct_jmp2_count = 0;
for(i = 0; i < nb_tbs; i++) {
cross_page++;
#if !defined(CONFIG_USER_ONLY)
#define SOFTMMU_CODE_ACCESS
#define SHIFT 0
#include "softmmu_template.h"
#include "softmmu_template.h"
#include "softmmu_template.h"
#include "softmmu_template.h"