unicorn-engine / unicorn

Unicorn CPU emulator framework (ARM, AArch64, M68K, Mips, Sparc, PowerPC, RiscV, S390x, TriCore, X86)
http://www.unicorn-engine.org
GNU General Public License v2.0
7.53k stars 1.33k forks source link

Missing something risc-v delegable_ints env->miclaim #1854

Open mischievous opened 1 year ago

mischievous commented 1 year ago

Hello,

I appear to be missing something. I am trying to use Unicorn for a risc-v project and trying to set the mip register which calls qemu/target/riscv/csr.c and get to this line "target_ulong mask = write_mask & delegable_ints & ~env->miclaim;" where delegable_ints looks like it's set wrong, and env->miclaim is zero.

The only way I can see to change delegable_ints/miclaim is to change the source code which seems wrong to me. That means every time I want to use unicorn I need to either make a fork or create patches.

Am I missing something that is obvious to everyone else?

wtdcode commented 1 year ago

In most cases, we need a code snippet to understand your motivation. Could you elaborate what's not expected?

mischievous commented 1 year ago

Where the first printf for IP == 0, the second printf IP still == 0 and expected it to be 0x80 (timer interrupt).

Where above the mask == 0x0 because delegable_ints == 0x666 not 0xaaa.

Code snippet.. uint64_t virtualMachine::ticks ( uint64_t delta ) { //

define CAUSE (0x7)

//
delta = (delta == -1) ? tpi:delta;

//
cntr += delta; 

//
actual.mtime.raw += cntr / actual.prescale;             
cntr = cntr % actual.prescale;

//            
REG_STATUS status = { read ( UC_RISCV_REG_MSTATUS ) };
REG_IE     ie     = { read ( UC_RISCV_REG_MIE     ) };

//
if (!(ie.raw & status.raw & (1 << CAUSE)))
    return 0; 

//
uint64_t rtn;
if ((rtn = (actual.mtime.raw < actual.mtimecmp.raw) ? 0:1))
{
    uint32_t ip; 
    uc_reg_read ( cpu, UC_RISCV_REG_MIP, &ip); 

    printf ("ticks : %16lx [ %16lx ] : %ld : %08x : %08x\n", actual.mtime.raw, actual.mtimecmp.raw, rtn, ip, (uint32_t) nip ); getchar(); 

    //
    uint32_t ip = (1 << CAUSE); 
    uc_reg_write ( cpu, UC_RISCV_REG_MIP, &ip); 

    // CPUState *cs; 
    // cs = qemu_get_cpu_riscv32( cpu, 0xffffffff );

    uc_reg_read ( cpu, UC_RISCV_REG_MIP, &ip); 
    printf ("ticks : %16lx [ %16lx ] : %ld : %08x\n", actual.mtime.raw, actual.mtimecmp.raw, rtn, ip ); 
    // uc_emu_stop ( cpu ); 
}

//
return rtn; 

}

mischievous commented 1 year ago

I guess the bigger problem I have is I have to implement a timer interrupt (cause 0x80000007). Everything I have implemented so far causes the MIE to get fracked up either during the interrupt, or after the interrupt returns.