mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-25 23:06:15 +00:00
iommu: apple: Manage IOVA separately from global LMB mem map
There is no overlap between the IOVA space managed by the iommu (here
the 32-bit address space) and physical RAM on Apple silicon systems. The
RAM starts at 0x10_0000_0000 or 0x100_0000_0000 so it's not possible to
manage the IOVA with the global memory LMB and use 1:1 translation.
In addition each device has its own iommu and does not need to share the
address space with all other devices. This should not be problem for
u-boot's limited use and hardware support.
Restore the private per instance LMB IOVA map.
Fixes: ed17a33fed
("lmb: make LMB memory map persistent and global")
Signed-off-by: Janne Grunau <j@jannau.net>
This commit is contained in:
parent
f6999cb554
commit
f642f34434
1 changed files with 14 additions and 4 deletions
|
@ -73,6 +73,8 @@ struct apple_dart_priv {
|
||||||
u64 *l1, *l2;
|
u64 *l1, *l2;
|
||||||
int bypass, shift;
|
int bypass, shift;
|
||||||
|
|
||||||
|
struct lmb io_lmb;
|
||||||
|
|
||||||
dma_addr_t dvabase;
|
dma_addr_t dvabase;
|
||||||
dma_addr_t dvaend;
|
dma_addr_t dvaend;
|
||||||
|
|
||||||
|
@ -123,7 +125,7 @@ static dma_addr_t apple_dart_map(struct udevice *dev, void *addr, size_t size)
|
||||||
off = (phys_addr_t)addr - paddr;
|
off = (phys_addr_t)addr - paddr;
|
||||||
psize = ALIGN(size + off, DART_PAGE_SIZE);
|
psize = ALIGN(size + off, DART_PAGE_SIZE);
|
||||||
|
|
||||||
dva = lmb_alloc(psize, DART_PAGE_SIZE);
|
dva = io_lmb_alloc(&priv->io_lmb, psize, DART_PAGE_SIZE);
|
||||||
|
|
||||||
idx = dva / DART_PAGE_SIZE;
|
idx = dva / DART_PAGE_SIZE;
|
||||||
for (i = 0; i < psize / DART_PAGE_SIZE; i++) {
|
for (i = 0; i < psize / DART_PAGE_SIZE; i++) {
|
||||||
|
@ -159,7 +161,7 @@ static void apple_dart_unmap(struct udevice *dev, dma_addr_t addr, size_t size)
|
||||||
(unsigned long)&priv->l2[idx + i]);
|
(unsigned long)&priv->l2[idx + i]);
|
||||||
priv->flush_tlb(priv);
|
priv->flush_tlb(priv);
|
||||||
|
|
||||||
lmb_free(dva, psize);
|
io_lmb_free(&priv->io_lmb, dva, psize);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct iommu_ops apple_dart_ops = {
|
static struct iommu_ops apple_dart_ops = {
|
||||||
|
@ -173,7 +175,7 @@ static int apple_dart_probe(struct udevice *dev)
|
||||||
dma_addr_t addr;
|
dma_addr_t addr;
|
||||||
phys_addr_t l2;
|
phys_addr_t l2;
|
||||||
int ntte, nl1, nl2;
|
int ntte, nl1, nl2;
|
||||||
int sid, i;
|
int ret, sid, i;
|
||||||
u32 params2, params4;
|
u32 params2, params4;
|
||||||
|
|
||||||
priv->base = dev_read_addr_ptr(dev);
|
priv->base = dev_read_addr_ptr(dev);
|
||||||
|
@ -212,7 +214,13 @@ static int apple_dart_probe(struct udevice *dev)
|
||||||
priv->dvabase = DART_PAGE_SIZE;
|
priv->dvabase = DART_PAGE_SIZE;
|
||||||
priv->dvaend = SZ_4G - DART_PAGE_SIZE;
|
priv->dvaend = SZ_4G - DART_PAGE_SIZE;
|
||||||
|
|
||||||
lmb_add(priv->dvabase, priv->dvaend - priv->dvabase);
|
ret = io_lmb_setup(&priv->io_lmb);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
ret = io_lmb_add(&priv->io_lmb, priv->dvabase,
|
||||||
|
priv->dvaend - priv->dvabase);
|
||||||
|
if (ret)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
/* Disable translations. */
|
/* Disable translations. */
|
||||||
for (sid = 0; sid < priv->nsid; sid++)
|
for (sid = 0; sid < priv->nsid; sid++)
|
||||||
|
@ -294,6 +302,8 @@ static int apple_dart_remove(struct udevice *dev)
|
||||||
}
|
}
|
||||||
priv->flush_tlb(priv);
|
priv->flush_tlb(priv);
|
||||||
|
|
||||||
|
io_lmb_teardown(&priv->io_lmb);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue