On 3 July 2018 at 10:31, Stefan Hajnoczi <stefa...@gmail.com> wrote: > On Mon, Jul 02, 2018 at 01:18:35PM +0100, Peter Maydell wrote: >> It's not clear to me what this device is doing with its >> AddressSpace, though; comments that went into more detail >> about what the device is and what the "memory" property is >> for might help. > > I understand this issue now. It's the same as qtest. > > This device is only visible from cpu->as, it's not visible from > address_space_memory (system_memory). > > The NVMC needs access to the SoC's flash memory region, and that's what > mr/as achieve here. I agree that comments explaining the purpose of > mr/as would be useful.
I've fished out a copy of the NRF51 datasheet, which helps. Roughly, what we have is: [ CPU ] -+- [ NVM, either FICR, UICR or CODE ] | | \- [ NVMC ] where the CPU can talk to either the NVMC or the NVMs, and the NVMC also has a control connection to the NVM. (See the block diagram in the nRF51 manual.) The behaviour this allows is: * the CPU can directly read and execute from the NVMs (which it can see in its address space at 0x00000000, 0x10000000, 0x10001000) * the NVMC controls whether the CPU can write to the NVMs. If the NVMC CONFIG register permits writes then the CPU writes directly to the mapped NVMs, and gets the usual flash-memory behaviour that writes can turn 1s to 0s but not 0s to 1s. * the NVMC also has support for performing erases of either pages or entire NVMs (which writes them to all-1s) My suggestion for the best way to model this is: * the NVMs are (sysbus) devices which expose a MemoryRegion which they have created with memory_region_init_rom_device(). MRs of this sort can be directly read (from a ram block), but writes always go via a MemoryRegionOps write function. This will let us do fast execution and reading, but catch writes so we can make them behave correctly (be forbidden, not allow writing of 0->1, etc). * the NVMs should implement a QOM interface that defines how we model the "control connection" from the NVMC -- basically this will have some methods for "erase all", "erase this page", and "set the writes permitted flag". * the NVMC should have QOM link properties for its NVMCs, and the SoC code sets those link properties to pointers to the NVMCs * the NVMC implements an ordinary IO MemoryRegion for its register interface; guest writes to the registers may cause it to tell the NVMs what to do by calling methods on the NVMs (which it has pointers to via the link properties) * the SoC code maps the NVMs and the NVMC's registers into the right places in its address space There's nothing here that requires extra functionality from core QEMU code, but on the other hand it is quite complicated, so you might prefer to start by modelling the NVMs as plain ROM MRs (ie never-writable) and the NVMC as a register interface which just complains (LOG_UNIMP) if the guest tries to enable writes or erases, plus a comment giving a sketch of the design changes needed to add write/erase support later. (I would prefer that to the code in this patch which implements erases by writing to a single passed-in memory region which covers the whole address space.) thanks -- PMM