hw/pci-host/astro: Fix boot for C3700 machine
Apply the "32-bit PCI addressing on 40-bit Runway" as the default iommu transformation. This allows PCI devices to dma PDC memory. Signed-off-by: Helge Deller <deller@gmx.de> Acked-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
fa71b4f84f
commit
8066102df1
@ -32,6 +32,7 @@
|
||||
#include "hw/pci-host/astro.h"
|
||||
#include "hw/hppa/hppa_hardware.h"
|
||||
#include "migration/vmstate.h"
|
||||
#include "target/hppa/cpu.h"
|
||||
#include "trace.h"
|
||||
#include "qom/object.h"
|
||||
|
||||
@ -268,22 +269,6 @@ static const MemoryRegionOps elroy_config_addr_ops = {
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* A subroutine of astro_translate_iommu that builds an IOMMUTLBEntry using the
|
||||
* given translated address and mask.
|
||||
*/
|
||||
static bool make_iommu_tlbe(hwaddr addr, hwaddr taddr, hwaddr mask,
|
||||
IOMMUTLBEntry *ret)
|
||||
{
|
||||
hwaddr tce_mask = ~((1ull << 12) - 1);
|
||||
ret->target_as = &address_space_memory;
|
||||
ret->iova = addr & tce_mask;
|
||||
ret->translated_addr = taddr & tce_mask;
|
||||
ret->addr_mask = ~tce_mask;
|
||||
ret->perm = IOMMU_RW;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Handle PCI-to-system address translation. */
|
||||
static IOMMUTLBEntry astro_translate_iommu(IOMMUMemoryRegion *iommu,
|
||||
hwaddr addr,
|
||||
@ -291,53 +276,59 @@ static IOMMUTLBEntry astro_translate_iommu(IOMMUMemoryRegion *iommu,
|
||||
int iommu_idx)
|
||||
{
|
||||
AstroState *s = container_of(iommu, AstroState, iommu);
|
||||
IOMMUTLBEntry ret = {
|
||||
.target_as = &address_space_memory,
|
||||
.iova = addr,
|
||||
.translated_addr = 0,
|
||||
.addr_mask = ~(hwaddr)0,
|
||||
.perm = IOMMU_NONE,
|
||||
};
|
||||
hwaddr pdir_ptr, index, a, ibase;
|
||||
hwaddr pdir_ptr, index, ibase;
|
||||
hwaddr addr_mask = 0xfff; /* 4k translation */
|
||||
uint64_t entry;
|
||||
|
||||
#define IOVP_SHIFT 12 /* equals PAGE_SHIFT */
|
||||
#define PDIR_INDEX(iovp) ((iovp) >> IOVP_SHIFT)
|
||||
#define IOVP_MASK PAGE_MASK
|
||||
#define SBA_PDIR_VALID_BIT 0x8000000000000000ULL
|
||||
|
||||
addr &= ~addr_mask;
|
||||
|
||||
/*
|
||||
* Default translation: "32-bit PCI Addressing on 40-bit Runway".
|
||||
* For addresses in the 32-bit memory address range ... and then
|
||||
* language which not-coincidentally matches the PSW.W=0 mapping.
|
||||
*/
|
||||
if (addr <= UINT32_MAX) {
|
||||
entry = hppa_abs_to_phys_pa2_w0(addr);
|
||||
} else {
|
||||
entry = addr;
|
||||
}
|
||||
|
||||
/* "range enable" flag cleared? */
|
||||
if ((s->tlb_ibase & 1) == 0) {
|
||||
make_iommu_tlbe(addr, addr, addr_mask, &ret);
|
||||
return ret;
|
||||
goto skip;
|
||||
}
|
||||
|
||||
a = addr;
|
||||
ibase = s->tlb_ibase & ~1ULL;
|
||||
if ((a & s->tlb_imask) != ibase) {
|
||||
if ((addr & s->tlb_imask) != ibase) {
|
||||
/* do not translate this one! */
|
||||
make_iommu_tlbe(addr, addr, addr_mask, &ret);
|
||||
return ret;
|
||||
goto skip;
|
||||
}
|
||||
index = PDIR_INDEX(a);
|
||||
|
||||
index = PDIR_INDEX(addr);
|
||||
pdir_ptr = s->tlb_pdir_base + index * sizeof(entry);
|
||||
entry = ldq_le_phys(&address_space_memory, pdir_ptr);
|
||||
|
||||
if (!(entry & SBA_PDIR_VALID_BIT)) { /* I/O PDIR entry valid ? */
|
||||
g_assert_not_reached();
|
||||
goto failure;
|
||||
/* failure */
|
||||
return (IOMMUTLBEntry) { .perm = IOMMU_NONE };
|
||||
}
|
||||
|
||||
entry &= ~SBA_PDIR_VALID_BIT;
|
||||
entry >>= IOVP_SHIFT;
|
||||
entry <<= 12;
|
||||
entry |= addr & 0xfff;
|
||||
make_iommu_tlbe(addr, entry, addr_mask, &ret);
|
||||
goto success;
|
||||
|
||||
failure:
|
||||
ret = (IOMMUTLBEntry) { .perm = IOMMU_NONE };
|
||||
success:
|
||||
return ret;
|
||||
skip:
|
||||
return (IOMMUTLBEntry) {
|
||||
.target_as = &address_space_memory,
|
||||
.iova = addr,
|
||||
.translated_addr = entry,
|
||||
.addr_mask = addr_mask,
|
||||
.perm = IOMMU_RW,
|
||||
};
|
||||
}
|
||||
|
||||
static AddressSpace *elroy_pcihost_set_iommu(PCIBus *bus, void *opaque,
|
||||
|
@ -29,7 +29,7 @@ pci_ss.add(when: 'CONFIG_MV64361', if_true: files('mv64361.c'))
|
||||
pci_ss.add(when: 'CONFIG_VERSATILE_PCI', if_true: files('versatile.c'))
|
||||
|
||||
# HPPA devices
|
||||
pci_ss.add(when: 'CONFIG_ASTRO', if_true: files('astro.c'))
|
||||
specific_ss.add(when: 'CONFIG_ASTRO', if_true: files('astro.c'))
|
||||
pci_ss.add(when: 'CONFIG_DINO', if_true: files('dino.c'))
|
||||
|
||||
system_ss.add_all(when: 'CONFIG_PCI', if_true: pci_ss)
|
||||
|
Loading…
Reference in New Issue
Block a user