On 08/08/2017 12:44, Peter Maydell wrote:
> +``cpu_{ld,st}_*``
> +~~~~~~~~~~~~~~~~~
> +
> +These functions operate on a guest virtual address. Be aware
> +that these functions may cause a guest CPU exception to be
> +taken (eg for an alignment fault or MMU fault) which will
> +result in guest CPU state being updated and control longjumping
> +out of the function call. They should therefore only be used
> +in code that is implementing emulation of the target CPU.
>
> +``cpu_{ld,st}_*_ra``
> +~~~~~~~~~~~~~~~~~~~~
> +
> +Thes functions work like the ``cpu_{ld,st}_*`` functions except
> +that they also take a ``retaddr`` argument.
> +
> +**TODO**: when should these be used and what should ``retaddr`` be?

They should always be used instead of the non-ra version in helpers (or
code that is called from helpers).  retaddr is GETPC() in the helper_*
functions and in tlb_fill, and must be propagated down from there.

This means that the non-ra versions should only be called from
translation, if I understand correctly.  You can use them after
cpu_restore_state, but it seems simpler to me to just say "don't use
them at all" and leave cpu_restore_state for special cases.

> +``helper_*_{ld,st}*mmu``
> +~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +These functions are intended primarily to be called by the code
> +generated by the TCG backend. They may also be called by target
> +CPU helper function code. (XXX why, and when this vs cpu_{ld,st}_* ?)
> +
> +**TODO** tcg.h claims the target-endian helper_ret* are temporary and
> +will go away?

It seems indeed that we have:

- helper_ret_ldub_mmu/helper_ret_ldsb_mmu that can be changed to remove
the "ret_" since there's no endianness there

- some uses in target/mips of helper_ret_{lduw,ldul,ldq,stw,stl,stq}_mmu

> +**TODO** why is "target endian" "ret" anyway?

That "_ret" is like the "_ra" at the end of cpu functions, so perhaps
these should be renamed to helper_{le,be}_{ld,st}*mmu_ra?

They should only be used if the MMU index is not a constant and is not
the active one.

> +``{ld,st}*_phys``
> +~~~~~~~~~~~~~~~~~
> +
> +These are functions which are identical to
> +``address_space_{ld,st}*``, except that they always pass
> +``MEMTXATTRS_UNSPECIFIED`` for the transaction attributes, and ignore
> +whether the transaction succeeded or failed.
> +
> +The fact that they ignore whether the transaction succeeded means
> +they should not be used in new code.

It depends---not all processors have a way of reporting failed transactions.

> +``cpu_physical_memory_*``
> +~~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +These are convenience functions which are identical to
> +``address_space_*`` but operate specifically on the system address space,
> +always pass a ``MEMTXATTRS_UNSPECIFIED`` set of memory attributes and
> +ignore whether the memory transaction succeeded or failed.
> +For new code they are better avoided:
> +
> +* there is likely to be behaviour you need to model correctly for a
> +  failed read or write operation
> +* a device should usually perform operations on its own AddressSpace
> +  rather than using the system address space

Agreed.  Maybe we should just transform them with Coccinelle.

> +``cpu_physical_memory_write_rom``
> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +This function performs a write by physical address like
> +``address_space_write``, except that if the write is to a ROM then
> +the ROM contents will be modified, even though a write by the guest
> +CPU to the ROM would be ignored.
> +
> +Note that unlike ``cpu_physical_memory_write()`` this function takes
> +an AddressSpace argument, but unlike ``address_space_write()`` this
> +function does not take a ``MemTxAttrs`` or return a ``MemTxResult``.
> +
> +**TODO**: we should probably clean up this inconsistency and
> +turn the function into ``address_space_write_rom`` with an API
> +matching ``address_space_write``.

Agreed.

> +``dma_memory_*``
> +~~~~~~~~~~~~~~~~
> +
> +These behave like ``address_space_*``, except that they perform a DMA
> +barrier operation first.
> +
> +**TODO**: I don't understand when you need to use these, and when
> +you can just use the address_space functions.

I guess it depends on the memory ordering semantics of the bus you're
implementing.  It's probably better/safer to just use these instead of
address_space_*.

Paolo

Reply via email to