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
}