[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [RFC v2] arm: Add NRF51 SOC non-volatile memory control
From: |
Peter Maydell |
Subject: |
Re: [Qemu-devel] [RFC v2] arm: Add NRF51 SOC non-volatile memory controller |
Date: |
Thu, 5 Jul 2018 17:35:09 +0100 |
On 3 July 2018 at 10:31, Stefan Hajnoczi <address@hidden> 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