From a5d412078b8e7478d81df03710eacc7a21096ba2 Mon Sep 17 00:00:00 2001 From: David 'Digit' Turner Date: Mon, 10 May 2010 18:37:10 -0700 Subject: Upstream: Replace sys-queue.h with qemu-queue.h Change-Id: I5c51f54a7fe2ea702420429bbf0c789ed6d8c534 --- exec.c | 218 ++++++++++++++++++++--------------------------------------------- 1 file changed, 67 insertions(+), 151 deletions(-) (limited to 'exec.c') diff --git a/exec.c b/exec.c index ce6aeda..f8cb9d6 100644 --- a/exec.c +++ b/exec.c @@ -14,8 +14,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA + * License along with this library; if not, see . */ #include "config.h" #ifdef _WIN32 @@ -75,12 +74,11 @@ #define TARGET_VIRT_ADDR_SPACE_BITS 42 #elif defined(TARGET_PPC64) #define TARGET_PHYS_ADDR_SPACE_BITS 42 -#elif defined(TARGET_X86_64) && !defined(CONFIG_KQEMU) +#elif defined(TARGET_X86_64) #define TARGET_PHYS_ADDR_SPACE_BITS 42 -#elif defined(TARGET_I386) && !defined(CONFIG_KQEMU) +#elif defined(TARGET_I386) #define TARGET_PHYS_ADDR_SPACE_BITS 36 #else -/* Note: for compatibility with kqemu, we use 32 bits for x86_64 */ #define TARGET_PHYS_ADDR_SPACE_BITS 32 #endif @@ -98,6 +96,10 @@ spinlock_t tb_lock = SPIN_LOCK_UNLOCKED; #define code_gen_section \ __attribute__((__section__(".gen_code"))) \ __attribute__((aligned (32))) +#elif defined(_WIN32) +/* Maximum alignment for Win32 is 16. */ +#define code_gen_section \ + __attribute__((aligned (16))) #else #define code_gen_section \ __attribute__((aligned (32))) @@ -194,7 +196,11 @@ static int io_mem_watch; #endif /* log support */ +#ifdef WIN32 +static const char *logfilename = "qemu.log"; +#else static const char *logfilename = "/tmp/qemu.log"; +#endif FILE *logfile; int loglevel; static int log_append = 0; @@ -317,7 +323,7 @@ static inline PageDesc *page_find_alloc(target_ulong index) #if defined(CONFIG_USER_ONLY) size_t len = sizeof(PageDesc) * L2_SIZE; /* Don't use qemu_malloc because it may recurse. */ - p = mmap(0, len, PROT_READ | PROT_WRITE, + p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); *lp = p; if (h2g_valid(p)) { @@ -342,8 +348,9 @@ static inline PageDesc *page_find(target_ulong index) return NULL; p = *lp; - if (!p) - return 0; + if (!p) { + return NULL; + } return p + (index & (L2_SIZE - 1)); } @@ -464,7 +471,7 @@ static void code_gen_alloc(unsigned long tb_size) exit(1); } } -#elif defined(__FreeBSD__) || defined(__DragonFly__) +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) { int flags; void *addr = NULL; @@ -575,8 +582,8 @@ void cpu_exec_init(CPUState *env) } env->cpu_index = cpu_index; env->numa_node = 0; - TAILQ_INIT(&env->breakpoints); - TAILQ_INIT(&env->watchpoints); + QTAILQ_INIT(&env->breakpoints); + QTAILQ_INIT(&env->watchpoints); *penv = env; #if defined(CONFIG_USER_ONLY) cpu_list_unlock(); @@ -667,7 +674,8 @@ static void tb_invalidate_check(target_ulong address) for(tb = tb_phys_hash[i]; tb != NULL; tb = tb->phys_hash_next) { if (!(address + TARGET_PAGE_SIZE <= tb->pc || address >= tb->pc + tb->size)) { - printf("ERROR invalidate: address=%08lx PC=%08lx size=%04x\n", + printf("ERROR invalidate: address=" TARGET_FMT_lx + " PC=%08lx size=%04x\n", address, (long)tb->pc, tb->size); } } @@ -692,26 +700,6 @@ static void tb_page_check(void) } } -static void tb_jmp_check(TranslationBlock *tb) -{ - TranslationBlock *tb1; - unsigned int n1; - - /* suppress any remaining jumps to this TB */ - tb1 = tb->jmp_first; - for(;;) { - n1 = (long)tb1 & 3; - tb1 = (TranslationBlock *)((long)tb1 & ~3); - if (n1 == 2) - break; - tb1 = tb1->jmp_next[n1]; - } - /* check end of list */ - if (tb1 != tb) { - printf("ERROR: jmp_list from 0x%08lx\n", (long)tb); - } -} - #endif /* invalidate one TB */ @@ -1384,9 +1372,9 @@ int cpu_watchpoint_insert(CPUState *env, target_ulong addr, target_ulong len, /* keep all GDB-injected watchpoints in front */ if (flags & BP_GDB) - TAILQ_INSERT_HEAD(&env->watchpoints, wp, entry); + QTAILQ_INSERT_HEAD(&env->watchpoints, wp, entry); else - TAILQ_INSERT_TAIL(&env->watchpoints, wp, entry); + QTAILQ_INSERT_TAIL(&env->watchpoints, wp, entry); tlb_flush_page(env, addr); @@ -1402,7 +1390,7 @@ int cpu_watchpoint_remove(CPUState *env, target_ulong addr, target_ulong len, target_ulong len_mask = ~(len - 1); CPUWatchpoint *wp; - TAILQ_FOREACH(wp, &env->watchpoints, entry) { + QTAILQ_FOREACH(wp, &env->watchpoints, entry) { if (addr == wp->vaddr && len_mask == wp->len_mask && flags == (wp->flags & ~BP_WATCHPOINT_HIT)) { cpu_watchpoint_remove_by_ref(env, wp); @@ -1415,7 +1403,7 @@ int cpu_watchpoint_remove(CPUState *env, target_ulong addr, target_ulong len, /* Remove a specific watchpoint by reference. */ void cpu_watchpoint_remove_by_ref(CPUState *env, CPUWatchpoint *watchpoint) { - TAILQ_REMOVE(&env->watchpoints, watchpoint, entry); + QTAILQ_REMOVE(&env->watchpoints, watchpoint, entry); tlb_flush_page(env, watchpoint->vaddr); @@ -1427,7 +1415,7 @@ void cpu_watchpoint_remove_all(CPUState *env, int mask) { CPUWatchpoint *wp, *next; - TAILQ_FOREACH_SAFE(wp, &env->watchpoints, entry, next) { + QTAILQ_FOREACH_SAFE(wp, &env->watchpoints, entry, next) { if (wp->flags & mask) cpu_watchpoint_remove_by_ref(env, wp); } @@ -1447,9 +1435,9 @@ int cpu_breakpoint_insert(CPUState *env, target_ulong pc, int flags, /* keep all GDB-injected breakpoints in front */ if (flags & BP_GDB) - TAILQ_INSERT_HEAD(&env->breakpoints, bp, entry); + QTAILQ_INSERT_HEAD(&env->breakpoints, bp, entry); else - TAILQ_INSERT_TAIL(&env->breakpoints, bp, entry); + QTAILQ_INSERT_TAIL(&env->breakpoints, bp, entry); breakpoint_invalidate(env, pc); @@ -1467,7 +1455,7 @@ int cpu_breakpoint_remove(CPUState *env, target_ulong pc, int flags) #if defined(TARGET_HAS_ICE) CPUBreakpoint *bp; - TAILQ_FOREACH(bp, &env->breakpoints, entry) { + QTAILQ_FOREACH(bp, &env->breakpoints, entry) { if (bp->pc == pc && bp->flags == flags) { cpu_breakpoint_remove_by_ref(env, bp); return 0; @@ -1483,7 +1471,7 @@ int cpu_breakpoint_remove(CPUState *env, target_ulong pc, int flags) void cpu_breakpoint_remove_by_ref(CPUState *env, CPUBreakpoint *breakpoint) { #if defined(TARGET_HAS_ICE) - TAILQ_REMOVE(&env->breakpoints, breakpoint, entry); + QTAILQ_REMOVE(&env->breakpoints, breakpoint, entry); breakpoint_invalidate(env, breakpoint->pc); @@ -1497,7 +1485,7 @@ void cpu_breakpoint_remove_all(CPUState *env, int mask) #if defined(TARGET_HAS_ICE) CPUBreakpoint *bp, *next; - TAILQ_FOREACH_SAFE(bp, &env->breakpoints, entry, next) { + QTAILQ_FOREACH_SAFE(bp, &env->breakpoints, entry, next) { if (bp->flags & mask) cpu_breakpoint_remove_by_ref(env, bp); } @@ -1538,7 +1526,8 @@ void cpu_set_log(int log_flags) static char logfile_buf[4096]; setvbuf(logfile, logfile_buf, _IOLBF, sizeof(logfile_buf)); } -#else +#elif !defined(_WIN32) + /* Win32 doesn't support line-buffering and requires size >= 2 */ setvbuf(logfile, NULL, _IOLBF, 0); #endif log_append = 1; @@ -1561,12 +1550,10 @@ void cpu_set_log_filename(const char *filename) static void cpu_unlink_tb(CPUState *env) { -#if defined(USE_NPTL) /* FIXME: TB unchaining isn't SMP safe. For now just ignore the problem and hope the cpu will stop of its own accord. For userspace emulation this often isn't actually as bad as it sounds. Often signals are used primarily to interrupt blocking syscalls. */ -#else TranslationBlock *tb; static spinlock_t interrupt_lock = SPIN_LOCK_UNLOCKED; @@ -1578,7 +1565,6 @@ static void cpu_unlink_tb(CPUState *env) tb_reset_jump_recursive(tb); resetlock(&interrupt_lock); } -#endif } /* mask must never be zero, except for A20 change call */ @@ -1747,13 +1733,13 @@ CPUState *cpu_copy(CPUState *env) /* Clone all break/watchpoints. Note: Once we support ptrace with hw-debug register access, make sure BP_CPU break/watchpoints are handled correctly on clone. */ - TAILQ_INIT(&env->breakpoints); - TAILQ_INIT(&env->watchpoints); + QTAILQ_INIT(&env->breakpoints); + QTAILQ_INIT(&env->watchpoints); #if defined(TARGET_HAS_ICE) - TAILQ_FOREACH(bp, &env->breakpoints, entry) { + QTAILQ_FOREACH(bp, &env->breakpoints, entry) { cpu_breakpoint_insert(new_env, bp->pc, bp->flags, NULL); } - TAILQ_FOREACH(wp, &env->watchpoints, entry) { + QTAILQ_FOREACH(wp, &env->watchpoints, entry) { cpu_watchpoint_insert(new_env, wp->vaddr, (~wp->len_mask) + 1, wp->flags, NULL); } @@ -1843,12 +1829,6 @@ void tlb_flush_page(CPUState *env, target_ulong addr) tlb_flush_entry(&env->tlb_table[mmu_idx][i], addr); tlb_flush_jmp_cache(env, addr); - -#ifdef CONFIG_KQEMU - if (env->kqemu_enabled) { - kqemu_flush_page(env, addr); - } -#endif } /* update the TLBs so that writes to code in the virtual page 'addr' @@ -1896,18 +1876,6 @@ void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end, if (length == 0) return; len = length >> TARGET_PAGE_BITS; -#ifdef CONFIG_KQEMU - /* XXX: should not depend on cpu context */ - env = first_cpu; - if (env->kqemu_enabled) { - ram_addr_t addr; - addr = start; - for(i = 0; i < len; i++) { - kqemu_set_notdirty(env, addr); - addr += TARGET_PAGE_SIZE; - } - } -#endif mask = ~dirty_flags; p = phys_ram_dirty + (start >> TARGET_PAGE_BITS); for(i = 0; i < len; i++) @@ -2064,7 +2032,7 @@ int tlb_set_page_exec(CPUState *env, target_ulong vaddr, code_address = address; /* Make accesses to pages with watchpoints go via the watchpoint trap routines. */ - TAILQ_FOREACH(wp, &env->watchpoints, entry) { + QTAILQ_FOREACH(wp, &env->watchpoints, entry) { if (vaddr == (wp->vaddr & TARGET_PAGE_MASK)) { iotlb = io_mem_watch + paddr; /* TODO: The memory case can be optimized by not trapping @@ -2377,8 +2345,9 @@ static void *subpage_init (target_phys_addr_t base, ram_addr_t *phys, } \ } while (0) -/* register physical memory. 'size' must be a multiple of the target - page size. If (phys_offset & ~TARGET_PAGE_MASK) != 0, then it is an +/* register physical memory. + For RAM, 'size' must be a multiple of the target page size. + If (phys_offset & ~TARGET_PAGE_MASK) != 0, then it is an io memory page. The address used when calling the IO function is the offset from the start of the region, plus region_offset. Both start_addr and region_offset are rounded down to a page boundary @@ -2395,13 +2364,6 @@ void cpu_register_physical_memory_offset(target_phys_addr_t start_addr, ram_addr_t orig_size = size; void *subpage; -#ifdef CONFIG_KQEMU - /* XXX: should not depend on cpu context */ - env = first_cpu; - if (env->kqemu_enabled) { - kqemu_set_phys_mem(start_addr, size, phys_offset); - } -#endif if (kvm_enabled()) kvm_set_phys_mem(start_addr, size, phys_offset); @@ -2496,36 +2458,23 @@ void qemu_unregister_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size) kvm_uncoalesce_mmio_region(addr, size); } -#ifdef CONFIG_KQEMU -/* XXX: better than nothing */ -static ram_addr_t kqemu_ram_alloc(ram_addr_t size) -{ - ram_addr_t addr; - if ((last_ram_offset + size) > kqemu_phys_ram_size) { - fprintf(stderr, "Not enough memory (requested_size = %" PRIu64 ", max memory = %" PRIu64 ")\n", - (uint64_t)size, (uint64_t)kqemu_phys_ram_size); - abort(); - } - addr = last_ram_offset; - last_ram_offset = TARGET_PAGE_ALIGN(last_ram_offset + size); - return addr; -} -#endif - ram_addr_t qemu_ram_alloc(ram_addr_t size) { RAMBlock *new_block; -#ifdef CONFIG_KQEMU - if (kqemu_phys_ram_base) { - return kqemu_ram_alloc(size); - } -#endif - size = TARGET_PAGE_ALIGN(size); new_block = qemu_malloc(sizeof(*new_block)); +#if defined(TARGET_S390X) && defined(CONFIG_KVM) + /* XXX S390 KVM requires the topmost vma of the RAM to be < 256GB */ + new_block->host = mmap((void*)0x1000000, size, PROT_EXEC|PROT_READ|PROT_WRITE, + MAP_SHARED | MAP_ANONYMOUS, -1, 0); +#else new_block->host = qemu_vmalloc(size); +#endif +#ifdef MADV_MERGEABLE + madvise(new_block->host, size, MADV_MERGEABLE); +#endif new_block->offset = last_ram_offset; new_block->length = size; @@ -2564,12 +2513,6 @@ void *qemu_get_ram_ptr(ram_addr_t addr) RAMBlock **prevp; RAMBlock *block; -#ifdef CONFIG_KQEMU - if (kqemu_phys_ram_base) { - return kqemu_phys_ram_base + addr; - } -#endif - prev = NULL; prevp = &ram_blocks; block = ram_blocks; @@ -2602,12 +2545,6 @@ ram_addr_t qemu_ram_addr_from_host(void *ptr) RAMBlock *block; uint8_t *host = ptr; -#ifdef CONFIG_KQEMU - if (kqemu_phys_ram_base) { - return host - kqemu_phys_ram_base; - } -#endif - prev = NULL; prevp = &ram_blocks; block = ram_blocks; @@ -2630,7 +2567,7 @@ static uint32_t unassigned_mem_readb(void *opaque, target_phys_addr_t addr) #ifdef DEBUG_UNASSIGNED printf("Unassigned mem read " TARGET_FMT_plx "\n", addr); #endif -#if defined(TARGET_SPARC) +#if defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE) do_unassigned_access(addr, 0, 0, 0, 1); #endif return 0; @@ -2641,7 +2578,7 @@ static uint32_t unassigned_mem_readw(void *opaque, target_phys_addr_t addr) #ifdef DEBUG_UNASSIGNED printf("Unassigned mem read " TARGET_FMT_plx "\n", addr); #endif -#if defined(TARGET_SPARC) +#if defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE) do_unassigned_access(addr, 0, 0, 0, 2); #endif return 0; @@ -2652,7 +2589,7 @@ static uint32_t unassigned_mem_readl(void *opaque, target_phys_addr_t addr) #ifdef DEBUG_UNASSIGNED printf("Unassigned mem read " TARGET_FMT_plx "\n", addr); #endif -#if defined(TARGET_SPARC) +#if defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE) do_unassigned_access(addr, 0, 0, 0, 4); #endif return 0; @@ -2663,7 +2600,7 @@ static void unassigned_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_ #ifdef DEBUG_UNASSIGNED printf("Unassigned mem write " TARGET_FMT_plx " = 0x%x\n", addr, val); #endif -#if defined(TARGET_SPARC) +#if defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE) do_unassigned_access(addr, 1, 0, 0, 1); #endif } @@ -2673,7 +2610,7 @@ static void unassigned_mem_writew(void *opaque, target_phys_addr_t addr, uint32_ #ifdef DEBUG_UNASSIGNED printf("Unassigned mem write " TARGET_FMT_plx " = 0x%x\n", addr, val); #endif -#if defined(TARGET_SPARC) +#if defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE) do_unassigned_access(addr, 1, 0, 0, 2); #endif } @@ -2683,7 +2620,7 @@ static void unassigned_mem_writel(void *opaque, target_phys_addr_t addr, uint32_ #ifdef DEBUG_UNASSIGNED printf("Unassigned mem write " TARGET_FMT_plx " = 0x%x\n", addr, val); #endif -#if defined(TARGET_SPARC) +#if defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE) do_unassigned_access(addr, 1, 0, 0, 4); #endif } @@ -2712,11 +2649,6 @@ static void notdirty_mem_writeb(void *opaque, target_phys_addr_t ram_addr, #endif } stb_p(qemu_get_ram_ptr(ram_addr), val); -#ifdef CONFIG_KQEMU - if (cpu_single_env->kqemu_enabled && - (dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK) - kqemu_modify_page(cpu_single_env, ram_addr); -#endif dirty_flags |= (0xff & ~CODE_DIRTY_FLAG); phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags; /* we remove the notdirty callback only if the code has been @@ -2737,11 +2669,6 @@ static void notdirty_mem_writew(void *opaque, target_phys_addr_t ram_addr, #endif } stw_p(qemu_get_ram_ptr(ram_addr), val); -#ifdef CONFIG_KQEMU - if (cpu_single_env->kqemu_enabled && - (dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK) - kqemu_modify_page(cpu_single_env, ram_addr); -#endif dirty_flags |= (0xff & ~CODE_DIRTY_FLAG); phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags; /* we remove the notdirty callback only if the code has been @@ -2762,11 +2689,6 @@ static void notdirty_mem_writel(void *opaque, target_phys_addr_t ram_addr, #endif } stl_p(qemu_get_ram_ptr(ram_addr), val); -#ifdef CONFIG_KQEMU - if (cpu_single_env->kqemu_enabled && - (dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK) - kqemu_modify_page(cpu_single_env, ram_addr); -#endif dirty_flags |= (0xff & ~CODE_DIRTY_FLAG); phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags; /* we remove the notdirty callback only if the code has been @@ -2805,7 +2727,7 @@ static void check_watchpoint(int offset, int len_mask, int flags) return; } vaddr = (env->mem_io_vaddr & TARGET_PAGE_MASK) + offset; - TAILQ_FOREACH(wp, &env->watchpoints, entry) { + QTAILQ_FOREACH(wp, &env->watchpoints, entry) { if ((vaddr == (wp->vaddr & len_mask) || (vaddr & wp->len_mask) == wp->vaddr) && (wp->flags & flags)) { wp->flags |= BP_WATCHPOINT_HIT; @@ -2995,7 +2917,7 @@ static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end, idx = SUBPAGE_IDX(start); eidx = SUBPAGE_IDX(end); #if defined(DEBUG_SUBPAGE) - printf("%s: %p start %08x end %08x idx %08x eidx %08x mem %d\n", __func__, + printf("%s: %p start %08x end %08x idx %08x eidx %08x mem %ld\n", __func__, mmio, start, end, idx, eidx, memory); #endif memory >>= IO_MEM_SHIFT; @@ -3047,7 +2969,7 @@ static int get_free_io_mem_idx(void) io_mem_used[i] = 1; return i; } - + fprintf(stderr, "RAN out out io_mem_idx, max %d !\n", IO_MEM_NB_ENTRIES); return -1; } @@ -3117,13 +3039,6 @@ static void io_mem_init(void) io_mem_watch = cpu_register_io_memory(watch_mem_read, watch_mem_write, NULL); -#ifdef CONFIG_KQEMU - if (kqemu_phys_ram_base) { - /* alloc dirty bits array */ - phys_ram_dirty = qemu_vmalloc(kqemu_phys_ram_size >> TARGET_PAGE_BITS); - memset(phys_ram_dirty, 0xff, kqemu_phys_ram_size >> TARGET_PAGE_BITS); - } -#endif } #endif /* !defined(CONFIG_USER_ONLY) */ @@ -3318,11 +3233,11 @@ static BounceBuffer bounce; typedef struct MapClient { void *opaque; void (*callback)(void *opaque); - LIST_ENTRY(MapClient) link; + QLIST_ENTRY(MapClient) link; } MapClient; -static LIST_HEAD(map_client_list, MapClient) map_client_list - = LIST_HEAD_INITIALIZER(map_client_list); +static QLIST_HEAD(map_client_list, MapClient) map_client_list + = QLIST_HEAD_INITIALIZER(map_client_list); void *cpu_register_map_client(void *opaque, void (*callback)(void *opaque)) { @@ -3330,7 +3245,7 @@ void *cpu_register_map_client(void *opaque, void (*callback)(void *opaque)) client->opaque = opaque; client->callback = callback; - LIST_INSERT_HEAD(&map_client_list, client, link); + QLIST_INSERT_HEAD(&map_client_list, client, link); return client; } @@ -3338,17 +3253,18 @@ void cpu_unregister_map_client(void *_client) { MapClient *client = (MapClient *)_client; - LIST_REMOVE(client, link); + QLIST_REMOVE(client, link); + qemu_free(client); } static void cpu_notify_map_clients(void) { MapClient *client; - while (!LIST_EMPTY(&map_client_list)) { - client = LIST_FIRST(&map_client_list); + while (!QLIST_EMPTY(&map_client_list)) { + client = QLIST_FIRST(&map_client_list); client->callback(client->opaque); - LIST_REMOVE(client, link); + QLIST_REMOVE(client, link); } } -- cgit v1.1