qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Why QEMU treats each instruction as one translation block?


From: casmac
Subject: Why QEMU treats each instruction as one translation block?
Date: Thu, 17 Sep 2020 14:11:51 +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 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
}



reply via email to

[Prev in Thread] Current Thread [Next in Thread]