[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] any suggestions for how to handle guests which expect t
Re: [Qemu-devel] any suggestions for how to handle guests which expect to be executing out of icache?
Sun, 19 Aug 2018 20:06:54 +0100
On 19 August 2018 at 18:44, Richard Henderson
> On 08/19/2018 03:19 AM, Peter Maydell wrote:
>> Hi; I've been playing around this weekend with writing a QEMU
>> model for a music player I have (an XDuoo X3). This has a MIPS
>> SoC, and its boot process is that the SoC's boot rom loads the
>> guest binary into the CPU's icache and dcache (by playing tricks
>> with the cache tag bits so that it appears to be precached content
>> for a particular physaddr range). The guest binary then runs
>> purely out of cache, until it can initialise the real SDRAM and
>> relocate itself into that.
>> Unfortunately this causes problems for QEMU, because the guest
>> binary expects that while it is running out of the icache at
>> addresses 0x80000000-0x80004000 it can happily write data to the
>> SDRAM at that address without overwriting its own code. Since
>> QEMU isn't modelling caches at all, the writes cause the guest
>> to corrupt its own code and it falls over.
>> Does anybody have any suggestions for how we could model this
>> kind of thing?
> I assume there are different virtual addresses, or different physical windows
> by which SDRAM is written while the relevant cache lines are pinned? If so,
> should be possible to create little ram segments that are mapped into the
> physical+virtual space somewhere with the cache pinning.
MIPS has the thing where vaddr 0x80000000..0x9fffffff is the
"unmapped cached" segment giving a view of the 0x00000000..0x1fffffff
physaddr space, and 0xa0000000..0xbfffffff is the "unmapped uncached"
segment view on to the same physaddrs. So it executes out of 0x80000000
and writes direct to the SDRAM (and to MMIO devices) via 0xa0000000.
I have a hack where the target/mips code maps in a RAM
memory region and then marks it enabled/disabled, and
also special-cases the virt-to-phys lookup so a lookup
of a vaddr at 0x80000000 resolves to a physaddr of
0x80000000 rather than 0 the way it usually would.
(It's hacky because I'm special-casing assuming the
whole 16K of cache is mapped this way or none is, and
also I've borrowed an IMPDEF 'cache' insn to signal
enabling the mapping and haven't yet figured out when
I should turn it off...but it's good enough to get me
past the bit of guest code that was a problem.)