initial APIC support (only for x86_64 target now)
[qemu] / exec.c
diff --git a/exec.c b/exec.c
index 45b723f..a1553ba 100644 (file)
--- a/exec.c
+++ b/exec.c
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include "config.h"
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <sys/types.h>
+#include <sys/mman.h>
+#endif
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdarg.h>
@@ -25,9 +31,6 @@
 #include <errno.h>
 #include <unistd.h>
 #include <inttypes.h>
-#if !defined(CONFIG_SOFTMMU)
-#include <sys/mman.h>
-#endif
 
 #include "cpu.h"
 #include "exec-all.h"
@@ -100,10 +103,10 @@ typedef struct VirtPageDesc {
 
 static void io_mem_init(void);
 
-unsigned long real_host_page_size;
-unsigned long host_page_bits;
-unsigned long host_page_size;
-unsigned long host_page_mask;
+unsigned long qemu_real_host_page_size;
+unsigned long qemu_host_page_bits;
+unsigned long qemu_host_page_size;
+unsigned long qemu_host_page_mask;
 
 /* XXX: for system emulation, it could just be an array */
 static PageDesc *l1_map[L1_SIZE];
@@ -127,21 +130,44 @@ int loglevel;
 
 static void page_init(void)
 {
-    /* NOTE: we can always suppose that host_page_size >=
+    /* NOTE: we can always suppose that qemu_host_page_size >=
        TARGET_PAGE_SIZE */
 #ifdef _WIN32
-    real_host_page_size = 4096;
+    {
+        SYSTEM_INFO system_info;
+        DWORD old_protect;
+        
+        GetSystemInfo(&system_info);
+        qemu_real_host_page_size = system_info.dwPageSize;
+        
+        VirtualProtect(code_gen_buffer, sizeof(code_gen_buffer),
+                       PAGE_EXECUTE_READWRITE, &old_protect);
+    }
 #else
-    real_host_page_size = getpagesize();
+    qemu_real_host_page_size = getpagesize();
+    {
+        unsigned long start, end;
+
+        start = (unsigned long)code_gen_buffer;
+        start &= ~(qemu_real_host_page_size - 1);
+        
+        end = (unsigned long)code_gen_buffer + sizeof(code_gen_buffer);
+        end += qemu_real_host_page_size - 1;
+        end &= ~(qemu_real_host_page_size - 1);
+        
+        mprotect((void *)start, end - start, 
+                 PROT_READ | PROT_WRITE | PROT_EXEC);
+    }
 #endif
-    if (host_page_size == 0)
-        host_page_size = real_host_page_size;
-    if (host_page_size < TARGET_PAGE_SIZE)
-        host_page_size = TARGET_PAGE_SIZE;
-    host_page_bits = 0;
-    while ((1 << host_page_bits) < host_page_size)
-        host_page_bits++;
-    host_page_mask = ~(host_page_size - 1);
+
+    if (qemu_host_page_size == 0)
+        qemu_host_page_size = qemu_real_host_page_size;
+    if (qemu_host_page_size < TARGET_PAGE_SIZE)
+        qemu_host_page_size = TARGET_PAGE_SIZE;
+    qemu_host_page_bits = 0;
+    while ((1 << qemu_host_page_bits) < qemu_host_page_size)
+        qemu_host_page_bits++;
+    qemu_host_page_mask = ~(qemu_host_page_size - 1);
 #if !defined(CONFIG_USER_ONLY)
     virt_valid_tag = 1;
 #endif
@@ -290,7 +316,6 @@ static void page_flush_tb(void)
 /* XXX: tb_flush is currently not thread safe */
 void tb_flush(CPUState *env)
 {
-    int i;
 #if defined(DEBUG_FLUSH)
     printf("qemu: flush code_size=%d nb_tbs=%d avg_tb_size=%d\n", 
            code_gen_ptr - code_gen_buffer, 
@@ -298,12 +323,10 @@ void tb_flush(CPUState *env)
            nb_tbs > 0 ? (code_gen_ptr - code_gen_buffer) / nb_tbs : 0);
 #endif
     nb_tbs = 0;
-    for(i = 0;i < CODE_GEN_HASH_SIZE; i++)
-        tb_hash[i] = NULL;
+    memset (tb_hash, 0, CODE_GEN_HASH_SIZE * sizeof (void *));
     virt_page_flush();
 
-    for(i = 0;i < CODE_GEN_PHYS_HASH_SIZE; i++)
-        tb_phys_hash[i] = NULL;
+    memset (tb_phys_hash, 0, CODE_GEN_PHYS_HASH_SIZE * sizeof (void *));
     page_flush_tb();
 
     code_gen_ptr = code_gen_buffer;
@@ -822,7 +845,7 @@ static inline void tb_alloc_page(TranslationBlock *tb,
     p->first_tb = (TranslationBlock *)((long)tb | n);
     invalidate_page_bitmap(p);
 
-#ifdef TARGET_HAS_SMC
+#if defined(TARGET_HAS_SMC) || 1
 
 #if defined(CONFIG_USER_ONLY)
     if (p->flags & PAGE_WRITE) {
@@ -831,12 +854,12 @@ static inline void tb_alloc_page(TranslationBlock *tb,
 
         /* force the host page as non writable (writes will have a
            page fault + mprotect overhead) */
-        host_start = page_addr & host_page_mask;
-        host_end = host_start + host_page_size;
+        host_start = page_addr & qemu_host_page_mask;
+        host_end = host_start + qemu_host_page_size;
         prot = 0;
         for(addr = host_start; addr < host_end; addr += TARGET_PAGE_SIZE)
             prot |= page_get_flags(addr);
-        mprotect((void *)host_start, host_page_size, 
+        mprotect((void *)host_start, qemu_host_page_size, 
                  (prot & PAGE_BITS) & ~PAGE_WRITE);
 #ifdef DEBUG_TB_INVALIDATE
         printf("protecting code page: 0x%08lx\n", 
@@ -1052,7 +1075,7 @@ static void breakpoint_invalidate(CPUState *env, target_ulong pc)
    breakpoint is reached */
 int cpu_breakpoint_insert(CPUState *env, target_ulong pc)
 {
-#if defined(TARGET_I386) || defined(TARGET_PPC)
+#if defined(TARGET_I386) || defined(TARGET_PPC) || defined(TARGET_SPARC)
     int i;
     
     for(i = 0; i < env->nb_breakpoints; i++) {
@@ -1074,7 +1097,7 @@ int cpu_breakpoint_insert(CPUState *env, target_ulong pc)
 /* remove a breakpoint */
 int cpu_breakpoint_remove(CPUState *env, target_ulong pc)
 {
-#if defined(TARGET_I386) || defined(TARGET_PPC)
+#if defined(TARGET_I386) || defined(TARGET_PPC) || defined(TARGET_SPARC)
     int i;
     for(i = 0; i < env->nb_breakpoints; i++) {
         if (env->breakpoints[i] == pc)
@@ -1097,7 +1120,7 @@ int cpu_breakpoint_remove(CPUState *env, target_ulong pc)
    CPU loop after each instruction */
 void cpu_single_step(CPUState *env, int enabled)
 {
-#if defined(TARGET_I386) || defined(TARGET_PPC)
+#if defined(TARGET_I386) || defined(TARGET_PPC) || defined(TARGET_SPARC)
     if (env->singlestep_enabled != enabled) {
         env->singlestep_enabled = enabled;
         /* must flush all the translated code to avoid inconsistancies */
@@ -1177,8 +1200,10 @@ CPULogItem cpu_log_items[] = {
     { CPU_LOG_PCALL, "pcall",
       "show protected mode far calls/returns/exceptions" },
 #endif
+#ifdef DEBUG_IOPORT
     { CPU_LOG_IOPORT, "ioport",
       "show all i/o ports accesses" },
+#endif
     { 0, NULL, NULL },
 };
 
@@ -1202,11 +1227,17 @@ int cpu_str_to_log_mask(const char *str)
         p1 = strchr(p, ',');
         if (!p1)
             p1 = p + strlen(p);
+       if(cmp1(p,p1-p,"all")) {
+               for(item = cpu_log_items; item->mask != 0; item++) {
+                       mask |= item->mask;
+               }
+       } else {
         for(item = cpu_log_items; item->mask != 0; item++) {
             if (cmp1(p, p1 - p, item->name))
                 goto found;
         }
         return 0;
+       }
     found:
         mask |= item->mask;
         if (*p1 != ',')
@@ -1225,7 +1256,9 @@ void cpu_abort(CPUState *env, const char *fmt, ...)
     vfprintf(stderr, fmt, ap);
     fprintf(stderr, "\n");
 #ifdef TARGET_I386
-    cpu_x86_dump_state(env, stderr, X86_DUMP_FPU | X86_DUMP_CCOP);
+    cpu_dump_state(env, stderr, fprintf, X86_DUMP_FPU | X86_DUMP_CCOP);
+#else
+    cpu_dump_state(env, stderr, fprintf, 0);
 #endif
     va_end(ap);
     abort();
@@ -1254,8 +1287,7 @@ void tlb_flush(CPUState *env, int flush_global)
     }
 
     virt_page_flush();
-    for(i = 0;i < CODE_GEN_HASH_SIZE; i++)
-        tb_hash[i] = NULL;
+    memset (tb_hash, 0, CODE_GEN_HASH_SIZE * sizeof (void *));
 
 #if !defined(CONFIG_SOFTMMU)
     munmap((void *)MMAP_AREA_START, MMAP_AREA_END - MMAP_AREA_START);
@@ -1737,12 +1769,12 @@ int page_unprotect(unsigned long address, unsigned long pc, void *puc)
     PageDesc *p, *p1;
     unsigned long host_start, host_end, addr;
 
-    host_start = address & host_page_mask;
+    host_start = address & qemu_host_page_mask;
     page_index = host_start >> TARGET_PAGE_BITS;
     p1 = page_find(page_index);
     if (!p1)
         return 0;
-    host_end = host_start + host_page_size;
+    host_end = host_start + qemu_host_page_size;
     p = p1;
     prot = 0;
     for(addr = host_start;addr < host_end; addr += TARGET_PAGE_SIZE) {
@@ -1754,7 +1786,7 @@ int page_unprotect(unsigned long address, unsigned long pc, void *puc)
     if (prot & PAGE_WRITE_ORG) {
         pindex = (address - host_start) >> TARGET_PAGE_BITS;
         if (!(p1[pindex].flags & PAGE_WRITE)) {
-            mprotect((void *)host_start, host_page_size, 
+            mprotect((void *)host_start, qemu_host_page_size, 
                      (prot & PAGE_BITS) | PAGE_WRITE);
             p1[pindex].flags |= PAGE_WRITE;
             /* and since the content will be modified, we must invalidate
@@ -1946,6 +1978,16 @@ int cpu_register_io_memory(int io_index,
     return io_index << IO_MEM_SHIFT;
 }
 
+CPUWriteMemoryFunc **cpu_get_io_memory_write(int io_index)
+{
+    return io_mem_write[io_index >> IO_MEM_SHIFT];
+}
+
+CPUReadMemoryFunc **cpu_get_io_memory_read(int io_index)
+{
+    return io_mem_read[io_index >> IO_MEM_SHIFT];
+}
+
 /* physical memory access (slow version, mainly for debug) */
 #if defined(CONFIG_USER_ONLY)
 void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, 
@@ -2094,6 +2136,7 @@ int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
 #define MMUSUFFIX _cmmu
 #define GETPC() NULL
 #define env cpu_single_env
+#define SOFTMMU_CODE_ACCESS
 
 #define SHIFT 0
 #include "softmmu_template.h"