* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <errno.h>
#include <unistd.h>
#include <inttypes.h>
+#if !defined(CONFIG_SOFTMMU)
#include <sys/mman.h>
+#endif
-#include "config.h"
#include "cpu.h"
#include "exec-all.h"
{
/* NOTE: we can always suppose that host_page_size >=
TARGET_PAGE_SIZE */
+#ifdef _WIN32
+ real_host_page_size = 4096;
+#else
real_host_page_size = getpagesize();
+#endif
if (host_page_size == 0)
host_page_size = real_host_page_size;
if (host_page_size < TARGET_PAGE_SIZE)
return NULL;
tb = &tbs[nb_tbs++];
tb->pc = pc;
+ tb->cflags = 0;
return tb;
}
tb->jmp_first = (TranslationBlock *)((long)tb | 2);
tb->jmp_next[0] = NULL;
tb->jmp_next[1] = NULL;
+#ifdef USE_CODE_COPY
+ tb->cflags &= ~CF_FP_USED;
+ if (tb->cflags & CF_TB_FP_USED)
+ tb->cflags |= CF_FP_USED;
+#endif
/* init original jump addresses */
if (tb->tb_next_offset[0] != 0xffff)
breakpoint is reached */
int cpu_breakpoint_insert(CPUState *env, uint32_t pc)
{
-#if defined(TARGET_I386)
+#if defined(TARGET_I386) || defined(TARGET_PPC)
int i;
for(i = 0; i < env->nb_breakpoints; i++) {
/* remove a breakpoint */
int cpu_breakpoint_remove(CPUState *env, uint32_t pc)
{
-#if defined(TARGET_I386)
+#if defined(TARGET_I386) || defined(TARGET_PPC)
int i;
for(i = 0; i < env->nb_breakpoints; i++) {
if (env->breakpoints[i] == pc)
CPU loop after each instruction */
void cpu_single_step(CPUState *env, int enabled)
{
-#if defined(TARGET_I386)
+#if defined(TARGET_I386) || defined(TARGET_PPC)
if (env->singlestep_enabled != enabled) {
env->singlestep_enabled = enabled;
/* must flush all the translated code to avoid inconsistancies */
}
}
+CPULogItem cpu_log_items[] = {
+ { CPU_LOG_TB_OUT_ASM, "out_asm",
+ "show generated host assembly code for each compiled TB" },
+ { CPU_LOG_TB_IN_ASM, "in_asm",
+ "show target assembly code for each compiled TB" },
+ { CPU_LOG_TB_OP, "op",
+ "show micro ops for each compiled TB (only usable if 'in_asm' used)" },
+#ifdef TARGET_I386
+ { CPU_LOG_TB_OP_OPT, "op_opt",
+ "show micro ops after optimization for each compiled TB" },
+#endif
+ { CPU_LOG_INT, "int",
+ "show interrupts/exceptions in short format" },
+ { CPU_LOG_EXEC, "exec",
+ "show trace before each executed TB (lots of logs)" },
+#ifdef TARGET_I386
+ { CPU_LOG_PCALL, "pcall",
+ "show protected mode far calls/returns/exceptions" },
+#endif
+ { 0, NULL, NULL },
+};
+
+static int cmp1(const char *s1, int n, const char *s2)
+{
+ if (strlen(s2) != n)
+ return 0;
+ return memcmp(s1, s2, n) == 0;
+}
+
+/* takes a comma separated list of log masks. Return 0 if error. */
+int cpu_str_to_log_mask(const char *str)
+{
+ CPULogItem *item;
+ int mask;
+ const char *p, *p1;
+
+ p = str;
+ mask = 0;
+ for(;;) {
+ p1 = strchr(p, ',');
+ if (!p1)
+ p1 = p + strlen(p);
+ 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 != ',')
+ break;
+ p = p1 + 1;
+ }
+ return mask;
+}
void cpu_abort(CPUState *env, const char *fmt, ...)
{
index = (vaddr >> 12) & (CPU_TLB_SIZE - 1);
addend -= vaddr;
- if (prot & PROT_READ) {
+ if (prot & PAGE_READ) {
env->tlb_read[is_user][index].address = address;
env->tlb_read[is_user][index].addend = addend;
} else {
env->tlb_read[is_user][index].address = -1;
env->tlb_read[is_user][index].addend = -1;
}
- if (prot & PROT_WRITE) {
+ if (prot & PAGE_WRITE) {
if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_ROM) {
/* ROM: access is ignored (same as unassigned) */
env->tlb_write[is_user][index].address = vaddr | IO_MEM_ROM;
/* physical memory access (slow version, mainly for debug) */
#if defined(CONFIG_USER_ONLY)
-void cpu_physical_memory_rw(CPUState *env, uint8_t *buf, target_ulong addr,
+void cpu_physical_memory_rw(target_ulong addr, uint8_t *buf,
int len, int is_write)
{
int l, flags;
}
}
#else
-void cpu_physical_memory_rw(CPUState *env, uint8_t *buf, target_ulong addr,
+void cpu_physical_memory_rw(target_ulong addr, uint8_t *buf,
int len, int is_write)
{
int l, io_index;
l = 1;
}
} else {
+ unsigned long addr1;
+ addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
/* RAM case */
- ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
- (addr & ~TARGET_PAGE_MASK);
+ ptr = phys_ram_base + addr1;
memcpy(ptr, buf, l);
+ /* invalidate code */
+ tb_invalidate_phys_page_range(addr1, addr1 + l, 0);
+ /* set dirty bit */
+ phys_ram_dirty[page >> TARGET_PAGE_BITS] = 1;
}
} else {
if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM &&
#endif
/* virtual memory access for debug */
-int cpu_memory_rw_debug(CPUState *env,
- uint8_t *buf, target_ulong addr, int len, int is_write)
+int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
+ uint8_t *buf, int len, int is_write)
{
int l;
target_ulong page, phys_addr;
l = (page + TARGET_PAGE_SIZE) - addr;
if (l > len)
l = len;
- cpu_physical_memory_rw(env, buf,
- phys_addr + (addr & ~TARGET_PAGE_MASK), l,
- is_write);
+ cpu_physical_memory_rw(phys_addr + (addr & ~TARGET_PAGE_MASK),
+ buf, l, is_write);
len -= l;
buf += l;
addr += l;