qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Bernhard Beschow <shentey@gmail.com>
To: qemu-devel@nongnu.org, Jiaxun Yang <jiaxun.yang@flygoat.com>
Cc: "Huacai Chen" <chenhuacai@kernel.org>,
	"Philippe Mathieu-Daudé" <philmd@linaro.org>
Subject: Re: [PATCH 3/5] hw/pci-host/bonito: Implement DMA address translation
Date: Mon, 15 Sep 2025 10:30:28 +0000	[thread overview]
Message-ID: <DA22DFAE-CD22-4A99-8FEB-D665F7C6B827@gmail.com> (raw)
In-Reply-To: <20250508-bonito-v1-3-4f9f27733028@flygoat.com>



Am 8. Mai 2025 14:46:08 UTC schrieb Jiaxun Yang <jiaxun.yang@flygoat.com>:
>PCIBase (Host Bridge config space BARs) and PCIBaseCfg registers
>in Bonito controls PCI DMA address translation.
>
>For any incoming DMA requests, it will be matched against PCiBase{0, 1}
>together with PciBaseCfg.MASK{0,1}. If it hits any of both, higher bits
>of address will be replaced by PciBaseCfg.TRANSx.
>
>Emulating this behavior by PCI IOMMU DMA address space with dynamic
>remapping on register writes.
>
>Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
>---
> hw/pci-host/bonito.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 113 insertions(+)
>
>diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c
>index f509f22df90ff7ed31ff5387a0acc239c22fd5f6..1c0d502a1e2dfa3c9803ca219cf505e08bf94a75 100644
>--- a/hw/pci-host/bonito.c
>+++ b/hw/pci-host/bonito.c
>@@ -144,6 +144,17 @@ FIELD(PCIMAP, LO2, 12, 6)
> FIELD(PCIMAP, 2, 18, 1)
> 
> #define BONITO_PCIMEMBASECFG    (0x14 >> 2)      /* 0x114 */
>+REG32(PCIMEMBASECFG, 0x114)
>+FIELD(PCIMEMBASECFG, MASK0, 0, 5)
>+FIELD(PCIMEMBASECFG, TRANS0, 5, 5)
>+FIELD(PCIMEMBASECFG, CACHED0, 10, 1)
>+FIELD(PCIMEMBASECFG, IO0, 11, 1)
>+FIELD(PCIMEMBASECFG, MASK1, 12, 5)
>+FIELD(PCIMEMBASECFG, TRANS1, 17, 5)
>+FIELD(PCIMEMBASECFG, CACHED1, 22, 1)
>+FIELD(PCIMEMBASECFG, IO1, 23, 1)
>+
>+
> #define BONITO_PCIMAP_CFG       (0x18 >> 2)      /* 0x118 */
> 
> /* 5. ICU & GPIO regs */
>@@ -258,9 +269,12 @@ struct BonitoState {
>     PCIHostState parent_obj;
>     qemu_irq *pic;
>     PCIBonitoState *pci_dev;
>+    MemoryRegion dma_mr;
>     MemoryRegion pci_mem;
>+    AddressSpace dma_as;
>     MemoryRegion *pcimem_lo_alias;
>     MemoryRegion *pcimem_hi_alias;
>+    MemoryRegion *dma_alias;

Should be `MemoryRegion dma_alias[2]` for simplicity and to avoid memory leaks.

> };
> 
> #define TYPE_PCI_BONITO "Bonito"
>@@ -314,6 +328,57 @@ static void bonito_update_pcimap(PCIBonitoState *s)
>                                    FIELD_EX32(pcimap, PCIMAP, 2) << 31);
> }
> 
>+static void pcibasecfg_decode(uint32_t mask, uint32_t trans, bool io,
>+                                     uint32_t *base, uint32_t *size)
>+{
>+    uint32_t val;
>+
>+    mask = (mask << 23 | 0xF0000000);
>+    val = ctz32(mask);
>+    *size = 1 << val;
>+    *base = (trans & ~(*size - 1)) | io << 28;
>+}
>+
>+static void bonito_update_pcibase(PCIBonitoState *s)
>+{
>+    uint32_t pcibasecfg = s->regs[BONITO_PCIMEMBASECFG];
>+    uint32_t size, base;
>+    uint32_t pcibase, wmask;
>+
>+    pcibasecfg_decode(FIELD_EX32(pcibasecfg, PCIMEMBASECFG, MASK0),
>+                      FIELD_EX32(pcibasecfg, PCIMEMBASECFG, TRANS0),
>+                      FIELD_EX32(pcibasecfg, PCIMEMBASECFG, IO0),
>+                      &base, &size);
>+
>+    wmask = ~(size - 1);
>+    /* Mask will also influence PCIBase register writable range */
>+    pci_set_long(s->dev.wmask + PCI_BASE_ADDRESS_0, wmask);
>+    /* Clear RO bits in PCIBase */
>+    pcibase = pci_get_long(s->dev.config + PCI_BASE_ADDRESS_0);
>+    pcibase &= wmask;
>+    pci_set_long(s->dev.config + PCI_BASE_ADDRESS_0, pcibase);
>+    /* Adjust DMA spaces */
>+    memory_region_set_size(&s->pcihost->dma_alias[0], size);
>+    memory_region_set_alias_offset(&s->pcihost->dma_alias[0], base);
>+    memory_region_set_address(&s->pcihost->dma_alias[0], pcibase);
>+
>+    /* Ditto for PCIMEMBASECFG1 */
>+    pcibasecfg_decode(FIELD_EX32(pcibasecfg, PCIMEMBASECFG, MASK1),
>+                      FIELD_EX32(pcibasecfg, PCIMEMBASECFG, TRANS1),
>+                      FIELD_EX32(pcibasecfg, PCIMEMBASECFG, IO1),
>+                      &base, &size);
>+
>+    wmask = ~(size - 1);
>+    pci_set_long(s->dev.wmask + PCI_BASE_ADDRESS_1, wmask);
>+    pcibase = pci_get_long(s->dev.config + PCI_BASE_ADDRESS_1);
>+    pcibase &= wmask;
>+    pci_set_long(s->dev.config + PCI_BASE_ADDRESS_1, pcibase);
>+
>+    memory_region_set_size(&s->pcihost->dma_alias[1], size);
>+    memory_region_set_alias_offset(&s->pcihost->dma_alias[1], base);
>+    memory_region_set_address(&s->pcihost->dma_alias[1], pcibase);
>+}
>+
> static void bonito_writel(void *opaque, hwaddr addr,
>                           uint64_t val, unsigned size)
> {
>@@ -624,12 +689,35 @@ static const MemoryRegionOps bonito_spciconf_ops = {
>     .endianness = DEVICE_NATIVE_ENDIAN,
> };
> 
>+static void bonito_pci_write_config(PCIDevice *dev, uint32_t address,
>+                                    uint32_t val, int len)
>+{
>+    pci_default_write_config(dev, address, val, len);
>+
>+    if (ranges_overlap(address, len, PCI_BASE_ADDRESS_0, 12)) {
>+        /* Bonito Host Bridge BARs are defined as DMA windows (pciBase) */
>+        bonito_update_pcibase(PCI_BONITO(dev));
>+    }
>+}
>+
> static int pci_bonito_map_irq(PCIDevice *pci_dev, int irq_num)
> {
>     /* Fuloong 2E PCI INTX are connected to Bonito GPIN[3:0] */
>     return ICU_PIN_GPINx(irq_num);
> }
> 
>+static AddressSpace *bonito_pcihost_set_iommu(PCIBus *bus, void *opaque,

s/set/get/ since it gets assigned to `get_address_space`.

>+                                              int devfn)
>+{
>+    BonitoState *bs = opaque;
>+
>+    return &bs->dma_as;
>+}
>+
>+static const PCIIOMMUOps bonito_iommu_ops = {
>+    .get_address_space = bonito_pcihost_set_iommu,
>+};
>+
> static void bonito_reset_hold(Object *obj, ResetType type)
> {
>     PCIBonitoState *s = PCI_BONITO(obj);
>@@ -653,6 +741,11 @@ static void bonito_reset_hold(Object *obj, ResetType type)
>     s->regs[BONITO_DQCFG] = 0x8;
>     s->regs[BONITO_MEMSIZE] = 0x10000000;
>     s->regs[BONITO_PCIMAP] = 0x6140;
>+    bonito_update_pcimap(s);
>+
>+    pci_set_long(s->dev.config + PCI_BASE_ADDRESS_0, 0x80000000);
>+    pci_set_long(s->dev.config + PCI_BASE_ADDRESS_1, 0x0);
>+    bonito_update_pcibase(s);
> }
> 
> static const VMStateDescription vmstate_bonito = {
>@@ -700,6 +793,7 @@ static void bonito_pci_realize(PCIDevice *dev, Error **errp)
>     PCIHostState *phb = PCI_HOST_BRIDGE(s->pcihost);
>     BonitoState *bs = s->pcihost;
>     MemoryRegion *pcimem_hi_alias = g_new(MemoryRegion, 1);
>+    MemoryRegion *dma_alias = g_new(MemoryRegion, 2);
> 
>     /*
>      * Bonito North Bridge, built on FPGA,
>@@ -764,6 +858,24 @@ static void bonito_pci_realize(PCIDevice *dev, Error **errp)
>                                 (hwaddr)BONITO_PCIHI_BASE + BONITO_PCIHI_SIZE,
>                                 2 * GiB);
> 
>+    /* 32bit DMA */
>+    memory_region_init(&bs->dma_mr, OBJECT(s), "dma.pciBase", 4 * GiB);
>+
>+    /* pciBase0, mapped to system RAM */
>+    memory_region_init_alias(&dma_alias[0], NULL, "pciBase0.mem.alias",
>+                             host_mem, 0x80000000, 256 * MiB);
>+    memory_region_add_subregion_overlap(&bs->dma_mr, 0, &dma_alias[0], 2);
>+
>+    /* pciBase1, mapped to system RAM */
>+    memory_region_init_alias(&dma_alias[1], NULL, "pciBase1.mem.alias",
>+                            host_mem, 0, 256 * MiB);
>+    memory_region_add_subregion_overlap(&bs->dma_mr, 0, &dma_alias[1], 1);
>+
>+    bs->dma_alias = dma_alias;
>+
>+    address_space_init(&bs->dma_as, &bs->dma_mr, "pciBase.dma");
>+    pci_setup_iommu(phb->bus, &bonito_iommu_ops, bs);
>+
>     /* set the default value of north bridge pci config */
>     pci_set_word(dev->config + PCI_COMMAND, 0x0000);
>     pci_set_word(dev->config + PCI_STATUS, 0x0000);
>@@ -806,6 +918,7 @@ static void bonito_pci_class_init(ObjectClass *klass, const void *data)
>     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
>     ResettableClass *rc = RESETTABLE_CLASS(klass);
> 
>+    k->config_write = bonito_pci_write_config;
>     rc->phases.hold = bonito_reset_hold;
>     k->realize = bonito_pci_realize;
>     k->vendor_id = 0xdf53;
>

With the above comments addressed:
Reviewed-by: Bernhard Beschow <shentey@gmail.com>


  reply	other threads:[~2025-09-15 10:31 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-05-08 14:46 [PATCH 0/5] hw/pci-host/bonito: Improve various emulation functions Jiaxun Yang
2025-05-08 14:46 ` [PATCH 1/5] hw/pci-host/bonito: Implement ICU Jiaxun Yang
2025-09-15 10:41   ` Bernhard Beschow
2025-05-08 14:46 ` [PATCH 2/5] hw/pci-host/bonito: Implement PCIMAP register Jiaxun Yang
2025-09-15 10:45   ` Bernhard Beschow
2025-05-08 14:46 ` [PATCH 3/5] hw/pci-host/bonito: Implement DMA address translation Jiaxun Yang
2025-09-15 10:30   ` Bernhard Beschow [this message]
2025-05-08 14:46 ` [PATCH 4/5] hw/pci-host/bonito: Rework PCI config space accessor Jiaxun Yang
2025-09-15 10:48   ` Bernhard Beschow
2025-05-08 14:46 ` [PATCH 5/5] hw/pci-host/bonito: Add comments about documentation Jiaxun Yang
2025-09-09  7:14   ` Bernhard Beschow
2025-09-15 10:50     ` Bernhard Beschow
2025-05-28 10:04 ` [PATCH 0/5] hw/pci-host/bonito: Improve various emulation functions Jiaxun Yang
2025-07-15 19:09 ` Jiaxun Yang
2025-09-03  5:34   ` Jiaxun Yang
2025-09-03 20:28     ` Bernhard Beschow
2025-09-15 10:57 ` Bernhard Beschow

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=DA22DFAE-CD22-4A99-8FEB-D665F7C6B827@gmail.com \
    --to=shentey@gmail.com \
    --cc=chenhuacai@kernel.org \
    --cc=jiaxun.yang@flygoat.com \
    --cc=philmd@linaro.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).