[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Why QEMU translates one instruction to a TB??
From: |
casmac |
Subject: |
Why QEMU translates one instruction to a TB?? |
Date: |
Thu, 17 Sep 2020 14:25:03 +0800 |
Hi all,
We try to add DSP architecure to QEMU 4.2. To load the
COFF format object file, we have added loader code to load content from
the object file. The rom_add_blob() function is used. We firstly
analyze the COFF file to figure out which sections are chained
together(so each chain forms a "memory blob"), and then allocate the memory blobs.
The psuedo code looks like:
for(i=0; i<BADTYPE; i++){
if(ary_sect_chain[i].exist) //there is a chain of sections to allocate
{
ary_sect_chain[i].mem_region = g_new(MemoryRegion, 1);
memory_region_init_ram(...);
memory_region_add_subregion(sysmem, ....);
rom_add_blob(....);
}
}
The COFF loader works functionally, but we then found that sometimes QEMU is
down-graded - it treats each instruction as one TB. In version 4.2,
debugging shows
that get_page_addr_code_host() from accel/tcg/cputlb.c returns -1, as shown below.
accel/tcg/cputlb.c:
tb_page_addr_t get_page_addr_code_hostp(CPUArchState *env, target_ulong addr,
void **hostp)
{
uintptr_t mmu_idx = cpu_mmu_index(env, true);
uintptr_t index = tlb_index(env, mmu_idx, addr);
CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
void *p;
//.....
if (unlikely(entry->addr_code & TLB_MMIO)) {
/* The region is not backed by RAM. */
if (hostp) {
*hostp = NULL;
}
return -1; /* debugging falls to this branch, after this point QEMU translate one instruction to a TB */
}
//.......
}
One intresting fact is that this somehow depends on the linker
command file. The object file generated by the following linker command
file(per_instr.lds)
will "trigger" the problem. But QEMU work well with the object file linked by the other linker command file (ok.lds).
What cause get_page_addr_code_hostp() function to return -1? I have no clue at all. Any advise is appreciated!!
best regards,
xiaolei
------------------------------------------------------
per_instr.lds file:
// .text is placed at 0x1000 (this is a word address)
MEMORY
{
ROM: org = 0x0 len = 0x1000 /* INTERNAL 4K ROM */
EXT0: org = 0x1000 len = 0x7FF000 /*EXTERNAL MEMORY */
RAM2: org = 0x800000 len = 0x7fff /* RAM BLOCK 2 */
RAM0: org = 0x809800 len = 0x400 /* RAM BLOCK 0 */
RAM1: org = 0x809C00 len = 0x3c0 /* RAM BLOCK 1 */
VECROR: org = 0x809fc1 len = 0x3f /* Interrupt Table*/
}
/* SPECIFY THE SECTIONS ALLOCATION INTO MEMORY */
SECTIONS
{
.cio: > RAM2 /* INITIALIZATION TABLES */
.const: > RAM2 /* CONSTANTS */
.cinit: > RAM2
.text{
*(.text)
} > EXT0 /* CODE */
.bss: > EXT0 /* VARIABLES */
.data: > RAM2
.stack: > RAM2 /* SYSTEM STACK */
.sysmem: > EXT0 /* DYNAMIC MEMORY - DELETE IF NOT USED */
.vector: > VECROR
}
------------------------------------------------------
ok.lds file:
MEMORY /* MEMORY directive */
{
ROM: origin = 000000h length = 001000h /* 4K 32-bit words on-chip ROM (C31/VC33) */
/* 256K 32-bit word off-chip SRAM (D.Module.VC33-150-S2) */
BIOS: origin = 001000h length = 000300h
CONF_UTL: origin = 001300h length = 000800h
FREE: origin = 001B00h length = 03F500h /* 259328 32-bit words */
RAM_0_1: origin = 809800h length = 000800h /* 2 x 1K 32-bit word on-chip SRAM (C31/VC33) */
RAM_2_3: origin = 800000h length = 008000h /* 2 x 16K 32-bit word on-chip SRAM (VC33 only) */
}
SECTIONS /* SECTIONS directive */
{
.firm :
{
*(.firm)
} > RAM_2_3
.text :
{
*(.text)
} > RAM_2_3
.const :
{
*(.const)
} > RAM_0_1
.bss :
{
*(.bss)
} > RAM_2_3
.cinit :
{
*(.cinit)
} > FREE
.data :
{
*(.data)
} > RAM_2_3
.stack :
{
*(.stack)
} > RAM_2_3
.sysmem :
{
*(.sysmem)
} > FREE
.cio :
{
*(.cio)
} > FREE
}
- Why QEMU translates one instruction to a TB??,
casmac <=