On 16/07/2015 12:51, Ефимов Василий wrote:
> The rest of code looks up destination or source region or child region
> offset in memory sub-tree which root is PCI or RAM region provided on
> PAM creation. We cannon use common address_space_translate because it
> searches from address space root and will return current PAM region.
> To summarize, I suggest to move the code to exec.c. It is generic
> enough. 

All these mechanism are extremely low level.  They are encapsulated
within exec.c, and copying code to pam.c is not a good idea because you
already have all the AddressSpaces and RAM MemoryRegions you need.

>> Could you use an IOMMU memory region instead?  Then a single region can
>> be used to implement all four modes, and you don't hit the "trying to
>> execute code outside RAM or RAM".
> Did you mean MemoryRegion.iommu_ops ? The feature does not allow to
> change destination memory region.

It does.  You're right about this:

> exec.c: address_space_translate_for_iotlb:
>                                     assert(!section->mr->iommu_ops); 

... but an IOMMU region is not needed, and I think you can do everything
without touching exec.c at all.

+    /* Read from RAM and write to PCI */
+    memory_region_init_io(&pam->region[1], OBJECT(dev), &pam_ops, pam,
+            "pam-r-ram-w-pci", size);

This can be done with memory_region_set_readonly on the RAM region.  You
need to set mr->ops in order to point to pam_ops; for a first proof of
concept you can just set the field directly.

Writes to the PCI memory space can use the PCI address space, with
address_space_st*.

+    /* Read from PCI and write to RAM */
+    memory_region_init_io(&pam->region[2], OBJECT(dev), &pam_ops, pam,
+            "pam-r-pci-w-ram", size);

Here you cannot run code from ROM, so it can be a pure MMIO region.
Reads can use address_space_ld*, while writes can use
memory_region_get_ram_ptr.

Paolo

Reply via email to