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>
next prev parent 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).