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 }