#include "kvm.h"
#include "hw/xen.h"
#include "qemu-timer.h"
+#include "memory.h"
+#include "exec-memory.h"
#if defined(CONFIG_USER_ONLY)
#include <qemu.h>
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
int phys_ram_fd;
static int in_migration;
-RAMList ram_list = { .blocks = QLIST_HEAD_INITIALIZER(ram_list) };
+RAMList ram_list = { .blocks = QLIST_HEAD_INITIALIZER(ram_list.blocks) };
+
+static MemoryRegion *system_memory;
+static MemoryRegion *system_io;
+
#endif
CPUState *first_cpu;
/* current CPU in the current thread. It is only valid inside
cpu_exec() */
-CPUState *cpu_single_env;
+DEFINE_TLS(CPUState *,cpu_single_env);
/* 0 = Do not count executed instructions.
1 = Precise instruction counting.
2 = Adaptive rate instruction counting. */
int use_icount = 0;
-/* Current instruction counter. While executing translated code this may
- include some instructions that have not yet been executed. */
-int64_t qemu_icount;
typedef struct PageDesc {
/* list of TBs intersecting this ram page */
#define V_L1_SHIFT (L1_MAP_ADDR_SPACE_BITS - TARGET_PAGE_BITS - V_L1_BITS)
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;
static void *l1_phys_map[P_L1_SIZE];
static void io_mem_init(void);
+static void memory_map_init(void);
/* io memory support */
CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
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_BSD) && defined(CONFIG_USER_ONLY)
int i;
#if defined(CONFIG_USER_ONLY)
- /* We can't use qemu_malloc because it may recurse into a locked mutex. */
+ /* We can't use g_malloc because it may recurse into a locked mutex. */
# define ALLOC(P, SIZE) \
do { \
P = mmap(NULL, SIZE, PROT_READ | PROT_WRITE, \
} while (0)
#else
# define ALLOC(P, SIZE) \
- do { P = qemu_mallocz(SIZE); } while (0)
+ do { P = g_malloc0(SIZE); } while (0)
#endif
/* Level 1. Always allocated. */
if (!alloc) {
return NULL;
}
- *lp = p = qemu_mallocz(sizeof(void *) * L2_SIZE);
+ *lp = p = g_malloc0(sizeof(void *) * L2_SIZE);
}
lp = p + ((index >> (i * L2_BITS)) & (L2_SIZE - 1));
}
return NULL;
}
- *lp = pd = qemu_malloc(sizeof(PhysPageDesc) * L2_SIZE);
+ *lp = pd = g_malloc(sizeof(PhysPageDesc) * L2_SIZE);
for (i = 0; i < L2_SIZE; i++) {
pd[i].phys_offset = IO_MEM_UNASSIGNED;
code_gen_buffer_size = tb_size;
if (code_gen_buffer_size == 0) {
#if defined(CONFIG_USER_ONLY)
- /* in user mode, phys_ram_size is not meaningful */
code_gen_buffer_size = DEFAULT_CODE_GEN_BUFFER_SIZE;
#else
/* XXX: needs adjustments */
}
}
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) \
- || defined(__DragonFly__) || defined(__OpenBSD__)
+ || defined(__DragonFly__) || defined(__OpenBSD__) \
+ || defined(__NetBSD__)
{
int flags;
void *addr = NULL;
}
}
#else
- code_gen_buffer = qemu_malloc(code_gen_buffer_size);
+ code_gen_buffer = g_malloc(code_gen_buffer_size);
map_exec(code_gen_buffer, code_gen_buffer_size);
#endif
#endif /* !USE_STATIC_CODE_GEN_BUFFER */
code_gen_buffer_max_size = code_gen_buffer_size -
(TCG_MAX_OP_SIZE * OPC_BUF_SIZE);
code_gen_max_blocks = code_gen_buffer_size / CODE_GEN_AVG_BLOCK_SIZE;
- tbs = qemu_malloc(code_gen_max_blocks * sizeof(TranslationBlock));
+ tbs = g_malloc(code_gen_max_blocks * sizeof(TranslationBlock));
}
/* Must be called before using the QEMU cpus. 'tb_size' is the size
(in bytes) allocated to the translation buffer. Zero means default
size. */
-void cpu_exec_init_all(unsigned long tb_size)
+void tcg_exec_init(unsigned long tb_size)
{
cpu_gen_init();
code_gen_alloc(tb_size);
code_gen_ptr = code_gen_buffer;
page_init();
-#if !defined(CONFIG_USER_ONLY)
- io_mem_init();
-#endif
#if !defined(CONFIG_USER_ONLY) || !defined(CONFIG_USE_GUEST_BASE)
/* There's no guest base to take into account, so go ahead and
initialize the prologue now. */
#endif
}
+bool tcg_enabled(void)
+{
+ return code_gen_buffer != NULL;
+}
+
+void cpu_exec_init_all(void)
+{
+#if !defined(CONFIG_USER_ONLY)
+ memory_map_init();
+ io_mem_init();
+#endif
+}
+
#if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY)
static int cpu_common_post_load(void *opaque, int version_id)
static inline void invalidate_page_bitmap(PageDesc *p)
{
if (p->code_bitmap) {
- qemu_free(p->code_bitmap);
+ g_free(p->code_bitmap);
p->code_bitmap = NULL;
}
p->code_write_count = 0;
int n, tb_start, tb_end;
TranslationBlock *tb;
- p->code_bitmap = qemu_mallocz(TARGET_PAGE_SIZE / 8);
+ p->code_bitmap = g_malloc0(TARGET_PAGE_SIZE / 8);
tb = p->first_tb;
while (tb != NULL) {
TARGET_FMT_lx ", len=" TARGET_FMT_lu "\n", addr, len);
return -EINVAL;
}
- wp = qemu_malloc(sizeof(*wp));
+ wp = g_malloc(sizeof(*wp));
wp->vaddr = addr;
wp->len_mask = len_mask;
tlb_flush_page(env, watchpoint->vaddr);
- qemu_free(watchpoint);
+ g_free(watchpoint);
}
/* Remove all matching watchpoints. */
#if defined(TARGET_HAS_ICE)
CPUBreakpoint *bp;
- bp = qemu_malloc(sizeof(*bp));
+ bp = g_malloc(sizeof(*bp));
bp->pc = pc;
bp->flags = flags;
breakpoint_invalidate(env, breakpoint->pc);
- qemu_free(breakpoint);
+ g_free(breakpoint);
#endif
}
static ram_addr_t find_ram_offset(ram_addr_t size)
{
RAMBlock *block, *next_block;
- ram_addr_t offset = 0, mingap = ULONG_MAX;
+ ram_addr_t offset = RAM_ADDR_MAX, mingap = RAM_ADDR_MAX;
if (QLIST_EMPTY(&ram_list.blocks))
return 0;
QLIST_FOREACH(block, &ram_list.blocks, next) {
- ram_addr_t end, next = ULONG_MAX;
+ ram_addr_t end, next = RAM_ADDR_MAX;
end = block->offset + block->length;
}
}
if (next - end >= size && next - end < mingap) {
- offset = end;
+ offset = end;
mingap = next - end;
}
}
+
+ if (offset == RAM_ADDR_MAX) {
+ fprintf(stderr, "Failed to find gap of requested size: %" PRIu64 "\n",
+ (uint64_t)size);
+ abort();
+ }
+
return offset;
}
RAMBlock *new_block, *block;
size = TARGET_PAGE_ALIGN(size);
- new_block = qemu_mallocz(sizeof(*new_block));
+ new_block = g_malloc0(sizeof(*new_block));
if (dev && dev->parent_bus && dev->parent_bus->info->get_dev_path) {
char *id = dev->parent_bus->info->get_dev_path(dev);
if (id) {
snprintf(new_block->idstr, sizeof(new_block->idstr), "%s/", id);
- qemu_free(id);
+ g_free(id);
}
}
pstrcat(new_block->idstr, sizeof(new_block->idstr), name);
QLIST_INSERT_HEAD(&ram_list.blocks, new_block, next);
- ram_list.phys_dirty = qemu_realloc(ram_list.phys_dirty,
+ ram_list.phys_dirty = g_realloc(ram_list.phys_dirty,
last_ram_offset() >> TARGET_PAGE_BITS);
memset(ram_list.phys_dirty + (new_block->offset >> TARGET_PAGE_BITS),
0xff, size >> TARGET_PAGE_BITS);
QLIST_FOREACH(block, &ram_list.blocks, next) {
if (addr == block->offset) {
QLIST_REMOVE(block, next);
- qemu_free(block);
+ g_free(block);
return;
}
}
}
#endif
}
- qemu_free(block);
+ g_free(block);
return;
}
}
#endif
}
if (area != vaddr) {
- fprintf(stderr, "Could not remap addr: %lx@%lx\n",
+ fprintf(stderr, "Could not remap addr: "
+ RAM_ADDR_FMT "@" RAM_ADDR_FMT "\n",
length, addr);
exit(1);
}
printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);
#endif
#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
- do_unassigned_access(addr, 0, 0, 0, 1);
+ cpu_unassigned_access(cpu_single_env, addr, 0, 0, 0, 1);
#endif
return 0;
}
printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);
#endif
#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
- do_unassigned_access(addr, 0, 0, 0, 2);
+ cpu_unassigned_access(cpu_single_env, addr, 0, 0, 0, 2);
#endif
return 0;
}
printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);
#endif
#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
- do_unassigned_access(addr, 0, 0, 0, 4);
+ cpu_unassigned_access(cpu_single_env, addr, 0, 0, 0, 4);
#endif
return 0;
}
printf("Unassigned mem write " TARGET_FMT_plx " = 0x%x\n", addr, val);
#endif
#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
- do_unassigned_access(addr, 1, 0, 0, 1);
+ cpu_unassigned_access(cpu_single_env, addr, 1, 0, 0, 1);
#endif
}
printf("Unassigned mem write " TARGET_FMT_plx " = 0x%x\n", addr, val);
#endif
#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
- do_unassigned_access(addr, 1, 0, 0, 2);
+ cpu_unassigned_access(cpu_single_env, addr, 1, 0, 0, 2);
#endif
}
printf("Unassigned mem write " TARGET_FMT_plx " = 0x%x\n", addr, val);
#endif
#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
- do_unassigned_access(addr, 1, 0, 0, 4);
+ cpu_unassigned_access(cpu_single_env, addr, 1, 0, 0, 4);
#endif
}
subpage_t *mmio;
int subpage_memory;
- mmio = qemu_mallocz(sizeof(subpage_t));
+ mmio = g_malloc0(sizeof(subpage_t));
mmio->base = base;
subpage_memory = cpu_register_io_memory(subpage_read, subpage_write, mmio,
static void swapendian_init(int io_index)
{
- SwapEndianContainer *c = qemu_malloc(sizeof(SwapEndianContainer));
+ SwapEndianContainer *c = g_malloc(sizeof(SwapEndianContainer));
int i;
/* Swap mmio for big endian targets */
static void swapendian_del(int io_index)
{
if (io_mem_read[io_index][0] == swapendian_readfn[0]) {
- qemu_free(io_mem_opaque[io_index]);
+ g_free(io_mem_opaque[io_index]);
}
}
DEVICE_NATIVE_ENDIAN);
}
+static void memory_map_init(void)
+{
+ system_memory = g_malloc(sizeof(*system_memory));
+ memory_region_init(system_memory, "system", INT64_MAX);
+ set_system_memory_map(system_memory);
+
+ system_io = g_malloc(sizeof(*system_io));
+ memory_region_init(system_io, "io", 65536);
+ set_system_io_map(system_io);
+}
+
+MemoryRegion *get_system_memory(void)
+{
+ return system_memory;
+}
+
+MemoryRegion *get_system_io(void)
+{
+ return system_io;
+}
+
#endif /* !defined(CONFIG_USER_ONLY) */
/* physical memory access (slow version, mainly for debug) */
uint8_t *ptr;
uint32_t val;
target_phys_addr_t page;
- unsigned long pd;
+ ram_addr_t pd;
PhysPageDesc *p;
while (len > 0) {
l = 1;
}
} else {
- unsigned long addr1;
+ ram_addr_t addr1;
addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
/* RAM case */
ptr = qemu_get_ram_ptr(addr1);
void *cpu_register_map_client(void *opaque, void (*callback)(void *opaque))
{
- MapClient *client = qemu_malloc(sizeof(*client));
+ MapClient *client = g_malloc(sizeof(*client));
client->opaque = opaque;
client->callback = callback;
MapClient *client = (MapClient *)_client;
QLIST_REMOVE(client, link);
- qemu_free(client);
+ g_free(client);
}
static void cpu_notify_map_clients(void)
target_phys_addr_t page;
unsigned long pd;
PhysPageDesc *p;
- ram_addr_t raddr = ULONG_MAX;
+ ram_addr_t raddr = RAM_ADDR_MAX;
ram_addr_t rlen;
void *ret;
}
#define MMUSUFFIX _cmmu
+#undef GETPC
#define GETPC() NULL
#define env cpu_single_env
#define SOFTMMU_CODE_ACCESS