Description
This issue is made to track/document how MIPS64 will fail to resolve memory address accesses larger than 0x7FFFFFFFUL
without UC_TLB_VIRTUAL. Without UC_TLB_VIRTUAL
, the code will use an emulated MMU which is described below.
#2111 allowed Unicorn to be instantiated with 64-bit MIPS architecture with the caveat that UC_TLB_VIRTUAL
must be enabled so that all virtual addresses map directly to physical addresses, and that it doesn't use any emulated MMU logic. Otherwise, the emulator will use an emulated MMU, which currently doesn't resolve memory addresses correctly and instead returns an error.
For some background, MIPS64 has some virtual address segmentation architecturally defined:
This is from page 29 in this MIPS reference: https://s3-eu-west-1.amazonaws.com/downloads-mips/documents/MD00091-2B-MIPS64PRA-AFP-05.04.pdf
Note that addresses in the inclusive range [0,0x3FFF_FFFF_FFFF_FFFF]
are defined for user space, and other mappings are reserved for kernel/supervisor mode with specific functionality described in the doc linked above.
Currently, attempts to access memory addresses above USEG_LIMIT
(which is 0x7FFFFFFFUL
) will call a function that emulates an MMU. The memory lookup starts here:
unicorn/qemu/target/mips/helper.c
Lines 254 to 274 in 0f45f15
The most relevant part starts at the #if defined(TARGET_MIPS64)
. Note that the UX variable comes from the MIPS status flag which indicates "user mode", which must be explicitly set via writing to the register (it is not enabled by default).
For example, you have to set the status register manually such as with the following snippet:
# The `1` at the 5th bit position indicates access to 64-bit User Segments (which go from address 0 to 0x3FFF_FFFF_FFFF_FFFF
status_register = 0b0100_0000_0000_0000_0010_0100
# I found the other `1` bits in this string to be necessary as well
emu.reg_write(UC_MIPS_REG_CP0_STATUS, status_register)
For more details on the MIPS 64 status register, check out https://s3-eu-west-1.amazonaws.com/downloads-mips/documents/MD00091-2B-MIPS64PRA-AFP-06.03.pdf where page 213 (section 9.33 Status Register) describes the bits of the register.
The env->tlb->map_address
is a function pointer to r4k_map_address
.
unicorn/qemu/target/mips/helper.c
Lines 68 to 72 in 0f45f15
This is where the MMU emulation currently fails. The function doesn't return a valid address, and returns TLBRET_NOMATCH
.
Possible fixes/changes:
- It's possible we just need to do some more setup to make this emulated MMU work (set some registers?)
- We should change the default value of the
CP0_STATUS
register so user memory is accessible by default.