mirror of https://github.com/xqemu/xqemu.git
apb: add IOMMU flush register implementation
The IOMMU flush register is a write-only register used to remove entries from the hardware TLB. Allow guest writes to this register as a no-op, and return a value of 0 for reads. This fixes IOMMU DMA operations under NetBSD SPARC64. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
This commit is contained in:
parent
a1cf8be550
commit
b87b0644bc
|
@ -94,6 +94,7 @@ do { printf("IOMMU: " fmt , ## __VA_ARGS__); } while (0)
|
||||||
#define IOMMU_CTRL_TSB_SHIFT 16
|
#define IOMMU_CTRL_TSB_SHIFT 16
|
||||||
|
|
||||||
#define IOMMU_BASE 0x8
|
#define IOMMU_BASE 0x8
|
||||||
|
#define IOMMU_FLUSH 0x10
|
||||||
|
|
||||||
#define IOMMU_TTE_DATA_V (1ULL << 63)
|
#define IOMMU_TTE_DATA_V (1ULL << 63)
|
||||||
#define IOMMU_TTE_DATA_SIZE (1ULL << 61)
|
#define IOMMU_TTE_DATA_SIZE (1ULL << 61)
|
||||||
|
@ -352,6 +353,9 @@ static void iommu_config_write(void *opaque, hwaddr addr,
|
||||||
is->regs[IOMMU_BASE >> 3] &= 0xffffffff00000000ULL;
|
is->regs[IOMMU_BASE >> 3] &= 0xffffffff00000000ULL;
|
||||||
is->regs[IOMMU_BASE >> 3] |= val & 0xffffffffULL;
|
is->regs[IOMMU_BASE >> 3] |= val & 0xffffffffULL;
|
||||||
break;
|
break;
|
||||||
|
case IOMMU_FLUSH:
|
||||||
|
case IOMMU_FLUSH + 0x4:
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
qemu_log_mask(LOG_UNIMP,
|
qemu_log_mask(LOG_UNIMP,
|
||||||
"apb iommu: Unimplemented register write "
|
"apb iommu: Unimplemented register write "
|
||||||
|
@ -387,6 +391,10 @@ static uint64_t iommu_config_read(void *opaque, hwaddr addr, unsigned size)
|
||||||
case IOMMU_BASE + 0x4:
|
case IOMMU_BASE + 0x4:
|
||||||
val = is->regs[IOMMU_BASE >> 3] & 0xffffffffULL;
|
val = is->regs[IOMMU_BASE >> 3] & 0xffffffffULL;
|
||||||
break;
|
break;
|
||||||
|
case IOMMU_FLUSH:
|
||||||
|
case IOMMU_FLUSH + 0x4:
|
||||||
|
val = 0;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
qemu_log_mask(LOG_UNIMP,
|
qemu_log_mask(LOG_UNIMP,
|
||||||
"apb iommu: Unimplemented register read "
|
"apb iommu: Unimplemented register read "
|
||||||
|
@ -415,7 +423,7 @@ static void apb_config_writel (void *opaque, hwaddr addr,
|
||||||
/* XXX: not implemented yet */
|
/* XXX: not implemented yet */
|
||||||
break;
|
break;
|
||||||
case 0x200 ... 0x217: /* IOMMU */
|
case 0x200 ... 0x217: /* IOMMU */
|
||||||
iommu_config_write(is, (addr & 0xf), val, size);
|
iommu_config_write(is, (addr & 0x1f), val, size);
|
||||||
break;
|
break;
|
||||||
case 0xc00 ... 0xc3f: /* PCI interrupt control */
|
case 0xc00 ... 0xc3f: /* PCI interrupt control */
|
||||||
if (addr & 4) {
|
if (addr & 4) {
|
||||||
|
@ -497,7 +505,7 @@ static uint64_t apb_config_readl (void *opaque,
|
||||||
/* XXX: not implemented yet */
|
/* XXX: not implemented yet */
|
||||||
break;
|
break;
|
||||||
case 0x200 ... 0x217: /* IOMMU */
|
case 0x200 ... 0x217: /* IOMMU */
|
||||||
val = iommu_config_read(is, (addr & 0xf), size);
|
val = iommu_config_read(is, (addr & 0x1f), size);
|
||||||
break;
|
break;
|
||||||
case 0xc00 ... 0xc3f: /* PCI interrupt control */
|
case 0xc00 ... 0xc3f: /* PCI interrupt control */
|
||||||
if (addr & 4) {
|
if (addr & 4) {
|
||||||
|
|
Loading…
Reference in New Issue