72 |
72 |
|
73 |
73 |
#define SMC_BITMAP_USE_THRESHOLD 10
|
74 |
74 |
|
75 |
|
/* Code generation and translation blocks */
|
|
75 |
/* Translation blocks */
|
76 |
76 |
static TranslationBlock *tbs;
|
77 |
|
static int code_gen_max_blocks;
|
78 |
77 |
TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE];
|
79 |
78 |
static int nb_tbs;
|
80 |
79 |
/* any access to the tbs or the page table must use this lock */
|
81 |
80 |
spinlock_t tb_lock = SPIN_LOCK_UNLOCKED;
|
82 |
81 |
|
83 |
|
uint8_t *code_gen_prologue;
|
84 |
|
static uint8_t *code_gen_buffer;
|
85 |
|
static size_t code_gen_buffer_size;
|
86 |
|
/* threshold to flush the translated code buffer */
|
87 |
|
static size_t code_gen_buffer_max_size;
|
88 |
|
static uint8_t *code_gen_ptr;
|
89 |
|
|
90 |
82 |
typedef struct PageDesc {
|
91 |
83 |
/* list of TBs intersecting this ram page */
|
92 |
84 |
TranslationBlock *first_tb;
|
... | ... | |
514 |
506 |
if (tb_size > MAX_CODE_GEN_BUFFER_SIZE) {
|
515 |
507 |
tb_size = MAX_CODE_GEN_BUFFER_SIZE;
|
516 |
508 |
}
|
517 |
|
code_gen_buffer_size = tb_size;
|
|
509 |
tcg_ctx.code_gen_buffer_size = tb_size;
|
518 |
510 |
return tb_size;
|
519 |
511 |
}
|
520 |
512 |
|
... | ... | |
524 |
516 |
|
525 |
517 |
static inline void *alloc_code_gen_buffer(void)
|
526 |
518 |
{
|
527 |
|
map_exec(static_code_gen_buffer, code_gen_buffer_size);
|
|
519 |
map_exec(static_code_gen_buffer, tcg_ctx.code_gen_buffer_size);
|
528 |
520 |
return static_code_gen_buffer;
|
529 |
521 |
}
|
530 |
522 |
#elif defined(USE_MMAP)
|
... | ... | |
547 |
539 |
Leave the choice of exact location with the kernel. */
|
548 |
540 |
flags |= MAP_32BIT;
|
549 |
541 |
/* Cannot expect to map more than 800MB in low memory. */
|
550 |
|
if (code_gen_buffer_size > 800u * 1024 * 1024) {
|
551 |
|
code_gen_buffer_size = 800u * 1024 * 1024;
|
|
542 |
if (tcg_ctx.code_gen_buffer_size > 800u * 1024 * 1024) {
|
|
543 |
tcg_ctx.code_gen_buffer_size = 800u * 1024 * 1024;
|
552 |
544 |
}
|
553 |
545 |
# elif defined(__sparc__)
|
554 |
546 |
start = 0x40000000ul;
|
... | ... | |
556 |
548 |
start = 0x90000000ul;
|
557 |
549 |
# endif
|
558 |
550 |
|
559 |
|
buf = mmap((void *)start, code_gen_buffer_size,
|
|
551 |
buf = mmap((void *)start, tcg_ctx.code_gen_buffer_size,
|
560 |
552 |
PROT_WRITE | PROT_READ | PROT_EXEC, flags, -1, 0);
|
561 |
553 |
return buf == MAP_FAILED ? NULL : buf;
|
562 |
554 |
}
|
563 |
555 |
#else
|
564 |
556 |
static inline void *alloc_code_gen_buffer(void)
|
565 |
557 |
{
|
566 |
|
void *buf = g_malloc(code_gen_buffer_size);
|
|
558 |
void *buf = g_malloc(tcg_ctx.code_gen_buffer_size);
|
567 |
559 |
|
568 |
560 |
if (buf) {
|
569 |
|
map_exec(buf, code_gen_buffer_size);
|
|
561 |
map_exec(buf, tcg_ctx.code_gen_buffer_size);
|
570 |
562 |
}
|
571 |
563 |
return buf;
|
572 |
564 |
}
|
... | ... | |
574 |
566 |
|
575 |
567 |
static inline void code_gen_alloc(size_t tb_size)
|
576 |
568 |
{
|
577 |
|
code_gen_buffer_size = size_code_gen_buffer(tb_size);
|
578 |
|
code_gen_buffer = alloc_code_gen_buffer();
|
579 |
|
if (code_gen_buffer == NULL) {
|
|
569 |
tcg_ctx.code_gen_buffer_size = size_code_gen_buffer(tb_size);
|
|
570 |
tcg_ctx.code_gen_buffer = alloc_code_gen_buffer();
|
|
571 |
if (tcg_ctx.code_gen_buffer == NULL) {
|
580 |
572 |
fprintf(stderr, "Could not allocate dynamic translator buffer\n");
|
581 |
573 |
exit(1);
|
582 |
574 |
}
|
583 |
575 |
|
584 |
|
qemu_madvise(code_gen_buffer, code_gen_buffer_size, QEMU_MADV_HUGEPAGE);
|
|
576 |
qemu_madvise(tcg_ctx.code_gen_buffer, tcg_ctx.code_gen_buffer_size,
|
|
577 |
QEMU_MADV_HUGEPAGE);
|
585 |
578 |
|
586 |
579 |
/* Steal room for the prologue at the end of the buffer. This ensures
|
587 |
580 |
(via the MAX_CODE_GEN_BUFFER_SIZE limits above) that direct branches
|
588 |
581 |
from TB's to the prologue are going to be in range. It also means
|
589 |
582 |
that we don't need to mark (additional) portions of the data segment
|
590 |
583 |
as executable. */
|
591 |
|
code_gen_prologue = code_gen_buffer + code_gen_buffer_size - 1024;
|
592 |
|
code_gen_buffer_size -= 1024;
|
|
584 |
tcg_ctx.code_gen_prologue = tcg_ctx.code_gen_buffer +
|
|
585 |
tcg_ctx.code_gen_buffer_size - 1024;
|
|
586 |
tcg_ctx.code_gen_buffer_size -= 1024;
|
593 |
587 |
|
594 |
|
code_gen_buffer_max_size = code_gen_buffer_size -
|
|
588 |
tcg_ctx.code_gen_buffer_max_size = tcg_ctx.code_gen_buffer_size -
|
595 |
589 |
(TCG_MAX_OP_SIZE * OPC_BUF_SIZE);
|
596 |
|
code_gen_max_blocks = code_gen_buffer_size / CODE_GEN_AVG_BLOCK_SIZE;
|
597 |
|
tbs = g_malloc(code_gen_max_blocks * sizeof(TranslationBlock));
|
|
590 |
tcg_ctx.code_gen_max_blocks = tcg_ctx.code_gen_buffer_size /
|
|
591 |
CODE_GEN_AVG_BLOCK_SIZE;
|
|
592 |
tbs = g_malloc(tcg_ctx.code_gen_max_blocks * sizeof(TranslationBlock));
|
598 |
593 |
}
|
599 |
594 |
|
600 |
595 |
/* Must be called before using the QEMU cpus. 'tb_size' is the size
|
... | ... | |
604 |
599 |
{
|
605 |
600 |
cpu_gen_init();
|
606 |
601 |
code_gen_alloc(tb_size);
|
607 |
|
code_gen_ptr = code_gen_buffer;
|
608 |
|
tcg_register_jit(code_gen_buffer, code_gen_buffer_size);
|
|
602 |
tcg_ctx.code_gen_ptr = tcg_ctx.code_gen_buffer;
|
|
603 |
tcg_register_jit(tcg_ctx.code_gen_buffer, tcg_ctx.code_gen_buffer_size);
|
609 |
604 |
page_init();
|
610 |
605 |
#if !defined(CONFIG_USER_ONLY) || !defined(CONFIG_USE_GUEST_BASE)
|
611 |
606 |
/* There's no guest base to take into account, so go ahead and
|
... | ... | |
616 |
611 |
|
617 |
612 |
bool tcg_enabled(void)
|
618 |
613 |
{
|
619 |
|
return code_gen_buffer != NULL;
|
|
614 |
return tcg_ctx.code_gen_buffer != NULL;
|
620 |
615 |
}
|
621 |
616 |
|
622 |
617 |
/* Allocate a new translation block. Flush the translation buffer if
|
... | ... | |
625 |
620 |
{
|
626 |
621 |
TranslationBlock *tb;
|
627 |
622 |
|
628 |
|
if (nb_tbs >= code_gen_max_blocks ||
|
629 |
|
(code_gen_ptr - code_gen_buffer) >= code_gen_buffer_max_size) {
|
|
623 |
if (nb_tbs >= tcg_ctx.code_gen_max_blocks ||
|
|
624 |
(tcg_ctx.code_gen_ptr - tcg_ctx.code_gen_buffer) >=
|
|
625 |
tcg_ctx.code_gen_buffer_max_size) {
|
630 |
626 |
return NULL;
|
631 |
627 |
}
|
632 |
628 |
tb = &tbs[nb_tbs++];
|
... | ... | |
641 |
637 |
Ignore the hard cases and just back up if this TB happens to
|
642 |
638 |
be the last one generated. */
|
643 |
639 |
if (nb_tbs > 0 && tb == &tbs[nb_tbs - 1]) {
|
644 |
|
code_gen_ptr = tb->tc_ptr;
|
|
640 |
tcg_ctx.code_gen_ptr = tb->tc_ptr;
|
645 |
641 |
nb_tbs--;
|
646 |
642 |
}
|
647 |
643 |
}
|
... | ... | |
696 |
692 |
|
697 |
693 |
#if defined(DEBUG_FLUSH)
|
698 |
694 |
printf("qemu: flush code_size=%ld nb_tbs=%d avg_tb_size=%ld\n",
|
699 |
|
(unsigned long)(code_gen_ptr - code_gen_buffer),
|
|
695 |
(unsigned long)(tcg_ctx.code_gen_ptr - tcg_ctx.code_gen_buffer),
|
700 |
696 |
nb_tbs, nb_tbs > 0 ?
|
701 |
|
((unsigned long)(code_gen_ptr - code_gen_buffer)) / nb_tbs : 0);
|
|
697 |
((unsigned long)(tcg_ctx.code_gen_ptr - tcg_ctx.code_gen_buffer)) /
|
|
698 |
nb_tbs : 0);
|
702 |
699 |
#endif
|
703 |
|
if ((unsigned long)(code_gen_ptr - code_gen_buffer)
|
704 |
|
> code_gen_buffer_size) {
|
|
700 |
if ((unsigned long)(tcg_ctx.code_gen_ptr - tcg_ctx.code_gen_buffer)
|
|
701 |
> tcg_ctx.code_gen_buffer_size) {
|
705 |
702 |
cpu_abort(env1, "Internal error: code buffer overflow\n");
|
706 |
703 |
}
|
707 |
704 |
nb_tbs = 0;
|
... | ... | |
713 |
710 |
memset(tb_phys_hash, 0, CODE_GEN_PHYS_HASH_SIZE * sizeof(void *));
|
714 |
711 |
page_flush_tb();
|
715 |
712 |
|
716 |
|
code_gen_ptr = code_gen_buffer;
|
|
713 |
tcg_ctx.code_gen_ptr = tcg_ctx.code_gen_buffer;
|
717 |
714 |
/* XXX: flush processor icache at this point if cache flush is
|
718 |
715 |
expensive */
|
719 |
716 |
tb_flush_count++;
|
... | ... | |
960 |
957 |
/* Don't forget to invalidate previous TB info. */
|
961 |
958 |
tb_invalidated_flag = 1;
|
962 |
959 |
}
|
963 |
|
tc_ptr = code_gen_ptr;
|
|
960 |
tc_ptr = tcg_ctx.code_gen_ptr;
|
964 |
961 |
tb->tc_ptr = tc_ptr;
|
965 |
962 |
tb->cs_base = cs_base;
|
966 |
963 |
tb->flags = flags;
|
967 |
964 |
tb->cflags = cflags;
|
968 |
965 |
cpu_gen_code(env, tb, &code_gen_size);
|
969 |
|
code_gen_ptr = (void *)(((uintptr_t)code_gen_ptr + code_gen_size +
|
970 |
|
CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));
|
|
966 |
tcg_ctx.code_gen_ptr = (void *)(((uintptr_t)tcg_ctx.code_gen_ptr +
|
|
967 |
code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));
|
971 |
968 |
|
972 |
969 |
/* check next page if needed */
|
973 |
970 |
virt_page2 = (pc + tb->size - 1) & TARGET_PAGE_MASK;
|
... | ... | |
1312 |
1309 |
{
|
1313 |
1310 |
/* This can be called during code generation, code_gen_buffer_max_size
|
1314 |
1311 |
is used instead of code_gen_ptr for upper boundary checking */
|
1315 |
|
return (tc_ptr >= (uintptr_t)code_gen_buffer &&
|
1316 |
|
tc_ptr < (uintptr_t)(code_gen_buffer + code_gen_buffer_max_size));
|
|
1312 |
return (tc_ptr >= (uintptr_t)tcg_ctx.code_gen_buffer &&
|
|
1313 |
tc_ptr < (uintptr_t)(tcg_ctx.code_gen_buffer +
|
|
1314 |
tcg_ctx.code_gen_buffer_max_size));
|
1317 |
1315 |
}
|
1318 |
1316 |
#endif
|
1319 |
1317 |
|
... | ... | |
1328 |
1326 |
if (nb_tbs <= 0) {
|
1329 |
1327 |
return NULL;
|
1330 |
1328 |
}
|
1331 |
|
if (tc_ptr < (uintptr_t)code_gen_buffer ||
|
1332 |
|
tc_ptr >= (uintptr_t)code_gen_ptr) {
|
|
1329 |
if (tc_ptr < (uintptr_t)tcg_ctx.code_gen_buffer ||
|
|
1330 |
tc_ptr >= (uintptr_t)tcg_ctx.code_gen_ptr) {
|
1333 |
1331 |
return NULL;
|
1334 |
1332 |
}
|
1335 |
1333 |
/* binary search (cf Knuth) */
|
... | ... | |
1587 |
1585 |
/* XXX: avoid using doubles ? */
|
1588 |
1586 |
cpu_fprintf(f, "Translation buffer state:\n");
|
1589 |
1587 |
cpu_fprintf(f, "gen code size %td/%zd\n",
|
1590 |
|
code_gen_ptr - code_gen_buffer, code_gen_buffer_max_size);
|
|
1588 |
tcg_ctx.code_gen_ptr - tcg_ctx.code_gen_buffer,
|
|
1589 |
tcg_ctx.code_gen_buffer_max_size);
|
1591 |
1590 |
cpu_fprintf(f, "TB count %d/%d\n",
|
1592 |
|
nb_tbs, code_gen_max_blocks);
|
|
1591 |
nb_tbs, tcg_ctx.code_gen_max_blocks);
|
1593 |
1592 |
cpu_fprintf(f, "TB avg target size %d max=%d bytes\n",
|
1594 |
1593 |
nb_tbs ? target_code_size / nb_tbs : 0,
|
1595 |
1594 |
max_target_code_size);
|
1596 |
1595 |
cpu_fprintf(f, "TB avg host size %td bytes (expansion ratio: %0.1f)\n",
|
1597 |
|
nb_tbs ? (code_gen_ptr - code_gen_buffer) / nb_tbs : 0,
|
1598 |
|
target_code_size ? (double) (code_gen_ptr - code_gen_buffer)
|
1599 |
|
/ target_code_size : 0);
|
|
1596 |
nb_tbs ? (tcg_ctx.code_gen_ptr - tcg_ctx.code_gen_buffer) /
|
|
1597 |
nb_tbs : 0,
|
|
1598 |
target_code_size ?
|
|
1599 |
(double) (tcg_ctx.code_gen_ptr - tcg_ctx.code_gen_buffer) /
|
|
1600 |
target_code_size : 0);
|
1600 |
1601 |
cpu_fprintf(f, "cross page TB count %d (%d%%)\n",
|
1601 |
1602 |
cross_page,
|
1602 |
1603 |
nb_tbs ? (cross_page * 100) / nb_tbs : 0);
|