Message ID | 1373901083-18730-6-git-send-email-aliguori@us.ibm.com |
---|---|
State | New |
Headers | show |
On 07/16/2013 01:11 AM, Anthony Liguori wrote: > Model TCE tables as a device that's hooked up as a child object to > the owner. Besides the code cleanup, we get a few nice benefits: > > 1) free actually works now (it was dead code before) > > 2) the TCE information is visible in the device tree > > 3) we can expose table information as properties such that if we > change the window_size, we can use globals to keep migration > working. > > Signed-off-by: David Gibson <david@gibson.dropbear.id.au> > [dwg: pseries: savevm support for PAPR TCE tables] > Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> > --- > hw/ppc/spapr.c | 3 - > hw/ppc/spapr_iommu.c | 145 ++++++++++++++++++++++++++++++++----------------- > hw/ppc/spapr_pci.c | 2 +- > hw/ppc/spapr_vio.c | 2 +- > include/hw/ppc/spapr.h | 23 +++++--- > 5 files changed, 114 insertions(+), 61 deletions(-) > > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c > index 48ae092..e340708 100644 > --- a/hw/ppc/spapr.c > +++ b/hw/ppc/spapr.c > @@ -848,9 +848,6 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args) > /* Set up EPOW events infrastructure */ > spapr_events_init(spapr); > > - /* Set up IOMMU */ > - spapr_iommu_init(); > - > /* Set up VIO bus */ > spapr->vio_bus = spapr_vio_bus_init(); > > diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c > index 89b33a5..709cc34 100644 > --- a/hw/ppc/spapr_iommu.c > +++ b/hw/ppc/spapr_iommu.c > @@ -36,17 +36,6 @@ enum sPAPRTCEAccess { > SPAPR_TCE_RW = 3, > }; > > -struct sPAPRTCETable { > - uint32_t liobn; > - uint32_t window_size; > - sPAPRTCE *table; > - bool bypass; > - int fd; > - MemoryRegion iommu; > - QLIST_ENTRY(sPAPRTCETable) list; > -}; > - > - > QLIST_HEAD(spapr_tce_tables, sPAPRTCETable) spapr_tce_tables; > > static sPAPRTCETable *spapr_tce_find_by_liobn(uint32_t liobn) > @@ -96,7 +85,7 @@ static IOMMUTLBEntry spapr_tce_translate_iommu(MemoryRegion *iommu, hwaddr addr) > return (IOMMUTLBEntry) { .perm = IOMMU_NONE }; > } > > - tce = tcet->table[addr >> SPAPR_TCE_PAGE_SHIFT].tce; > + tce = tcet->table[addr >> SPAPR_TCE_PAGE_SHIFT]; > > #ifdef DEBUG_TCE > fprintf(stderr, " -> *paddr=0x%llx, *len=0x%llx\n", > @@ -112,37 +101,51 @@ static IOMMUTLBEntry spapr_tce_translate_iommu(MemoryRegion *iommu, hwaddr addr) > }; > } > > +static int spapr_tce_table_pre_load(void *opaque) > +{ > + sPAPRTCETable *tcet = SPAPR_TCE_TABLE(opaque); > + > + tcet->nb_table = tcet->window_size >> SPAPR_TCE_PAGE_SHIFT; > + > + return 0; > +} > + > +static const VMStateDescription vmstate_spapr_tce_table = { > + .name = "spapr_iommu", > + .version_id = 1, > + .minimum_version_id = 1, > + .minimum_version_id_old = 1, > + .pre_load = spapr_tce_table_pre_load, > + .fields = (VMStateField []) { > + /* Sanity check */ > + VMSTATE_UINT32_EQUAL(liobn, sPAPRTCETable), > + VMSTATE_UINT32_EQUAL(window_size, sPAPRTCETable), > + > + /* IOMMU state */ > + VMSTATE_BOOL(bypass, sPAPRTCETable), > + VMSTATE_VARRAY_UINT32(table, sPAPRTCETable, nb_table, 0, vmstate_info_uint64, uint64_t), > + > + VMSTATE_END_OF_LIST() > + }, > +}; > + > static MemoryRegionIOMMUOps spapr_iommu_ops = { > .translate = spapr_tce_translate_iommu, > }; > > -sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn, size_t window_size) > +static int spapr_tce_table_realize(DeviceState *dev) > { > - sPAPRTCETable *tcet; > - > - if (spapr_tce_find_by_liobn(liobn)) { > - fprintf(stderr, "Attempted to create TCE table with duplicate" > - " LIOBN 0x%x\n", liobn); > - return NULL; > - } > - > - if (!window_size) { > - return NULL; > - } > - > - tcet = g_malloc0(sizeof(*tcet)); > - tcet->liobn = liobn; > - tcet->window_size = window_size; > + sPAPRTCETable *tcet = SPAPR_TCE_TABLE(dev); > > if (kvm_enabled()) { > - tcet->table = kvmppc_create_spapr_tce(liobn, > - window_size, > + tcet->table = kvmppc_create_spapr_tce(tcet->liobn, > + tcet->window_size, > &tcet->fd); > } > > if (!tcet->table) { > - size_t table_size = (window_size >> SPAPR_TCE_PAGE_SHIFT) > - * sizeof(sPAPRTCE); > + size_t table_size = (tcet->window_size >> SPAPR_TCE_PAGE_SHIFT) > + * sizeof(uint64_t); > tcet->table = g_malloc0(table_size); > } > > @@ -151,16 +154,43 @@ sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn, size_t wi > "table @ %p, fd=%d\n", tcet, liobn, tcet->table, tcet->fd); > #endif > > - memory_region_init_iommu(&tcet->iommu, OBJECT(owner), &spapr_iommu_ops, > + memory_region_init_iommu(&tcet->iommu, OBJECT(dev), &spapr_iommu_ops, > "iommu-spapr", UINT64_MAX); > > QLIST_INSERT_HEAD(&spapr_tce_tables, tcet, list); > > + return 0; > +} > + > +sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn, size_t window_size) > +{ > + sPAPRTCETable *tcet; > + > + if (spapr_tce_find_by_liobn(liobn)) { > + fprintf(stderr, "Attempted to create TCE table with duplicate" > + " LIOBN 0x%x\n", liobn); > + return NULL; > + } > + > + if (!window_size) { > + return NULL; > + } > + > + tcet = SPAPR_TCE_TABLE(object_new(TYPE_SPAPR_TCE_TABLE)); > + tcet->liobn = liobn; > + tcet->window_size = window_size; I am trying to understand the QOM. How do you understand what initialization should go to .realize and what should stay in spapr_tce_new_table? In this particular case having the .realize implementation does not make much sense to me. If you made .liobn and .window_size members of sPAPRTCETable then it would be ok but you did not. What do I miss? Thanks.
Alexey Kardashevskiy <aik@ozlabs.ru> writes: > On 07/16/2013 01:11 AM, Anthony Liguori wrote: >> Model TCE tables as a device that's hooked up as a child object to >> the owner. Besides the code cleanup, we get a few nice benefits: >> >> 1) free actually works now (it was dead code before) >> >> 2) the TCE information is visible in the device tree >> >> 3) we can expose table information as properties such that if we >> change the window_size, we can use globals to keep migration >> working. >> >> Signed-off-by: David Gibson <david@gibson.dropbear.id.au> >> [dwg: pseries: savevm support for PAPR TCE tables] >> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> >> --- >> hw/ppc/spapr.c | 3 - >> hw/ppc/spapr_iommu.c | 145 ++++++++++++++++++++++++++++++++----------------- >> hw/ppc/spapr_pci.c | 2 +- >> hw/ppc/spapr_vio.c | 2 +- >> include/hw/ppc/spapr.h | 23 +++++--- >> 5 files changed, 114 insertions(+), 61 deletions(-) >> >> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c >> index 48ae092..e340708 100644 >> --- a/hw/ppc/spapr.c >> +++ b/hw/ppc/spapr.c >> @@ -848,9 +848,6 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args) >> /* Set up EPOW events infrastructure */ >> spapr_events_init(spapr); >> >> - /* Set up IOMMU */ >> - spapr_iommu_init(); >> - >> /* Set up VIO bus */ >> spapr->vio_bus = spapr_vio_bus_init(); >> >> diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c >> index 89b33a5..709cc34 100644 >> --- a/hw/ppc/spapr_iommu.c >> +++ b/hw/ppc/spapr_iommu.c >> @@ -36,17 +36,6 @@ enum sPAPRTCEAccess { >> SPAPR_TCE_RW = 3, >> }; >> >> -struct sPAPRTCETable { >> - uint32_t liobn; >> - uint32_t window_size; >> - sPAPRTCE *table; >> - bool bypass; >> - int fd; >> - MemoryRegion iommu; >> - QLIST_ENTRY(sPAPRTCETable) list; >> -}; >> - >> - >> QLIST_HEAD(spapr_tce_tables, sPAPRTCETable) spapr_tce_tables; >> >> static sPAPRTCETable *spapr_tce_find_by_liobn(uint32_t liobn) >> @@ -96,7 +85,7 @@ static IOMMUTLBEntry spapr_tce_translate_iommu(MemoryRegion *iommu, hwaddr addr) >> return (IOMMUTLBEntry) { .perm = IOMMU_NONE }; >> } >> >> - tce = tcet->table[addr >> SPAPR_TCE_PAGE_SHIFT].tce; >> + tce = tcet->table[addr >> SPAPR_TCE_PAGE_SHIFT]; >> >> #ifdef DEBUG_TCE >> fprintf(stderr, " -> *paddr=0x%llx, *len=0x%llx\n", >> @@ -112,37 +101,51 @@ static IOMMUTLBEntry spapr_tce_translate_iommu(MemoryRegion *iommu, hwaddr addr) >> }; >> } >> >> +static int spapr_tce_table_pre_load(void *opaque) >> +{ >> + sPAPRTCETable *tcet = SPAPR_TCE_TABLE(opaque); >> + >> + tcet->nb_table = tcet->window_size >> SPAPR_TCE_PAGE_SHIFT; >> + >> + return 0; >> +} >> + >> +static const VMStateDescription vmstate_spapr_tce_table = { >> + .name = "spapr_iommu", >> + .version_id = 1, >> + .minimum_version_id = 1, >> + .minimum_version_id_old = 1, >> + .pre_load = spapr_tce_table_pre_load, >> + .fields = (VMStateField []) { >> + /* Sanity check */ >> + VMSTATE_UINT32_EQUAL(liobn, sPAPRTCETable), >> + VMSTATE_UINT32_EQUAL(window_size, sPAPRTCETable), >> + >> + /* IOMMU state */ >> + VMSTATE_BOOL(bypass, sPAPRTCETable), >> + VMSTATE_VARRAY_UINT32(table, sPAPRTCETable, nb_table, 0, vmstate_info_uint64, uint64_t), >> + >> + VMSTATE_END_OF_LIST() >> + }, >> +}; >> + >> static MemoryRegionIOMMUOps spapr_iommu_ops = { >> .translate = spapr_tce_translate_iommu, >> }; >> >> -sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn, size_t window_size) >> +static int spapr_tce_table_realize(DeviceState *dev) >> { >> - sPAPRTCETable *tcet; >> - >> - if (spapr_tce_find_by_liobn(liobn)) { >> - fprintf(stderr, "Attempted to create TCE table with duplicate" >> - " LIOBN 0x%x\n", liobn); >> - return NULL; >> - } >> - >> - if (!window_size) { >> - return NULL; >> - } >> - >> - tcet = g_malloc0(sizeof(*tcet)); >> - tcet->liobn = liobn; >> - tcet->window_size = window_size; >> + sPAPRTCETable *tcet = SPAPR_TCE_TABLE(dev); >> >> if (kvm_enabled()) { >> - tcet->table = kvmppc_create_spapr_tce(liobn, >> - window_size, >> + tcet->table = kvmppc_create_spapr_tce(tcet->liobn, >> + tcet->window_size, >> &tcet->fd); >> } >> >> if (!tcet->table) { >> - size_t table_size = (window_size >> SPAPR_TCE_PAGE_SHIFT) >> - * sizeof(sPAPRTCE); >> + size_t table_size = (tcet->window_size >> SPAPR_TCE_PAGE_SHIFT) >> + * sizeof(uint64_t); >> tcet->table = g_malloc0(table_size); >> } >> >> @@ -151,16 +154,43 @@ sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn, size_t wi >> "table @ %p, fd=%d\n", tcet, liobn, tcet->table, tcet->fd); >> #endif >> >> - memory_region_init_iommu(&tcet->iommu, OBJECT(owner), &spapr_iommu_ops, >> + memory_region_init_iommu(&tcet->iommu, OBJECT(dev), &spapr_iommu_ops, >> "iommu-spapr", UINT64_MAX); >> >> QLIST_INSERT_HEAD(&spapr_tce_tables, tcet, list); >> >> + return 0; >> +} >> + >> +sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn, size_t window_size) >> +{ >> + sPAPRTCETable *tcet; >> + >> + if (spapr_tce_find_by_liobn(liobn)) { >> + fprintf(stderr, "Attempted to create TCE table with duplicate" >> + " LIOBN 0x%x\n", liobn); >> + return NULL; >> + } >> + >> + if (!window_size) { >> + return NULL; >> + } >> + >> + tcet = SPAPR_TCE_TABLE(object_new(TYPE_SPAPR_TCE_TABLE)); >> + tcet->liobn = liobn; >> + tcet->window_size = window_size; > > > > I am trying to understand the QOM. How do you understand what > initialization should go to .realize and what should stay in > spapr_tce_new_table? Really nothing should be in spapr_tce_new_table(). It should strictly be an helper function to create a device and set properties (via qdev_prop_set..). We really should make liobn and window_size proper properties. Regards, Anthony Liguori > > In this particular case having the .realize implementation does not make > much sense to me. If you made .liobn and .window_size members of > sPAPRTCETable then it would be ok but you did not. What do I miss? > Thanks. > > > > -- > Alexey
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 48ae092..e340708 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -848,9 +848,6 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args) /* Set up EPOW events infrastructure */ spapr_events_init(spapr); - /* Set up IOMMU */ - spapr_iommu_init(); - /* Set up VIO bus */ spapr->vio_bus = spapr_vio_bus_init(); diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c index 89b33a5..709cc34 100644 --- a/hw/ppc/spapr_iommu.c +++ b/hw/ppc/spapr_iommu.c @@ -36,17 +36,6 @@ enum sPAPRTCEAccess { SPAPR_TCE_RW = 3, }; -struct sPAPRTCETable { - uint32_t liobn; - uint32_t window_size; - sPAPRTCE *table; - bool bypass; - int fd; - MemoryRegion iommu; - QLIST_ENTRY(sPAPRTCETable) list; -}; - - QLIST_HEAD(spapr_tce_tables, sPAPRTCETable) spapr_tce_tables; static sPAPRTCETable *spapr_tce_find_by_liobn(uint32_t liobn) @@ -96,7 +85,7 @@ static IOMMUTLBEntry spapr_tce_translate_iommu(MemoryRegion *iommu, hwaddr addr) return (IOMMUTLBEntry) { .perm = IOMMU_NONE }; } - tce = tcet->table[addr >> SPAPR_TCE_PAGE_SHIFT].tce; + tce = tcet->table[addr >> SPAPR_TCE_PAGE_SHIFT]; #ifdef DEBUG_TCE fprintf(stderr, " -> *paddr=0x%llx, *len=0x%llx\n", @@ -112,37 +101,51 @@ static IOMMUTLBEntry spapr_tce_translate_iommu(MemoryRegion *iommu, hwaddr addr) }; } +static int spapr_tce_table_pre_load(void *opaque) +{ + sPAPRTCETable *tcet = SPAPR_TCE_TABLE(opaque); + + tcet->nb_table = tcet->window_size >> SPAPR_TCE_PAGE_SHIFT; + + return 0; +} + +static const VMStateDescription vmstate_spapr_tce_table = { + .name = "spapr_iommu", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .pre_load = spapr_tce_table_pre_load, + .fields = (VMStateField []) { + /* Sanity check */ + VMSTATE_UINT32_EQUAL(liobn, sPAPRTCETable), + VMSTATE_UINT32_EQUAL(window_size, sPAPRTCETable), + + /* IOMMU state */ + VMSTATE_BOOL(bypass, sPAPRTCETable), + VMSTATE_VARRAY_UINT32(table, sPAPRTCETable, nb_table, 0, vmstate_info_uint64, uint64_t), + + VMSTATE_END_OF_LIST() + }, +}; + static MemoryRegionIOMMUOps spapr_iommu_ops = { .translate = spapr_tce_translate_iommu, }; -sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn, size_t window_size) +static int spapr_tce_table_realize(DeviceState *dev) { - sPAPRTCETable *tcet; - - if (spapr_tce_find_by_liobn(liobn)) { - fprintf(stderr, "Attempted to create TCE table with duplicate" - " LIOBN 0x%x\n", liobn); - return NULL; - } - - if (!window_size) { - return NULL; - } - - tcet = g_malloc0(sizeof(*tcet)); - tcet->liobn = liobn; - tcet->window_size = window_size; + sPAPRTCETable *tcet = SPAPR_TCE_TABLE(dev); if (kvm_enabled()) { - tcet->table = kvmppc_create_spapr_tce(liobn, - window_size, + tcet->table = kvmppc_create_spapr_tce(tcet->liobn, + tcet->window_size, &tcet->fd); } if (!tcet->table) { - size_t table_size = (window_size >> SPAPR_TCE_PAGE_SHIFT) - * sizeof(sPAPRTCE); + size_t table_size = (tcet->window_size >> SPAPR_TCE_PAGE_SHIFT) + * sizeof(uint64_t); tcet->table = g_malloc0(table_size); } @@ -151,16 +154,43 @@ sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn, size_t wi "table @ %p, fd=%d\n", tcet, liobn, tcet->table, tcet->fd); #endif - memory_region_init_iommu(&tcet->iommu, OBJECT(owner), &spapr_iommu_ops, + memory_region_init_iommu(&tcet->iommu, OBJECT(dev), &spapr_iommu_ops, "iommu-spapr", UINT64_MAX); QLIST_INSERT_HEAD(&spapr_tce_tables, tcet, list); + return 0; +} + +sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn, size_t window_size) +{ + sPAPRTCETable *tcet; + + if (spapr_tce_find_by_liobn(liobn)) { + fprintf(stderr, "Attempted to create TCE table with duplicate" + " LIOBN 0x%x\n", liobn); + return NULL; + } + + if (!window_size) { + return NULL; + } + + tcet = SPAPR_TCE_TABLE(object_new(TYPE_SPAPR_TCE_TABLE)); + tcet->liobn = liobn; + tcet->window_size = window_size; + + object_property_add_child(OBJECT(owner), "tce-table", OBJECT(tcet), NULL); + + qdev_init_nofail(DEVICE(tcet)); + return tcet; } -void spapr_tce_free(sPAPRTCETable *tcet) +static void spapr_tce_table_finalize(Object *obj) { + sPAPRTCETable *tcet = SPAPR_TCE_TABLE(obj); + QLIST_REMOVE(tcet, list); if (!kvm_enabled() || @@ -168,8 +198,6 @@ void spapr_tce_free(sPAPRTCETable *tcet) tcet->window_size) != 0)) { g_free(tcet->table); } - - g_free(tcet); } MemoryRegion *spapr_tce_get_iommu(sPAPRTCETable *tcet) @@ -182,10 +210,11 @@ void spapr_tce_set_bypass(sPAPRTCETable *tcet, bool bypass) tcet->bypass = bypass; } -void spapr_tce_reset(sPAPRTCETable *tcet) +static void spapr_tce_reset(DeviceState *dev) { + sPAPRTCETable *tcet = SPAPR_TCE_TABLE(dev); size_t table_size = (tcet->window_size >> SPAPR_TCE_PAGE_SHIFT) - * sizeof(sPAPRTCE); + * sizeof(uint64_t); tcet->bypass = false; memset(tcet->table, 0, table_size); @@ -194,7 +223,6 @@ void spapr_tce_reset(sPAPRTCETable *tcet) static target_ulong put_tce_emu(sPAPRTCETable *tcet, target_ulong ioba, target_ulong tce) { - sPAPRTCE *tcep; IOMMUTLBEntry entry; if (ioba >= tcet->window_size) { @@ -203,8 +231,7 @@ static target_ulong put_tce_emu(sPAPRTCETable *tcet, target_ulong ioba, return H_PARAMETER; } - tcep = tcet->table + (ioba >> SPAPR_TCE_PAGE_SHIFT); - tcep->tce = tce; + tcet->table[ioba >> SPAPR_TCE_PAGE_SHIFT] = tce; entry.target_as = &address_space_memory, entry.iova = ioba & ~SPAPR_TCE_PAGE_MASK; @@ -238,14 +265,6 @@ static target_ulong h_put_tce(PowerPCCPU *cpu, sPAPREnvironment *spapr, return H_PARAMETER; } -void spapr_iommu_init(void) -{ - QLIST_INIT(&spapr_tce_tables); - - /* hcall-tce */ - spapr_register_hypercall(H_PUT_TCE, h_put_tce); -} - int spapr_dma_dt(void *fdt, int node_off, const char *propname, uint32_t liobn, uint64_t window, uint32_t size) { @@ -286,3 +305,31 @@ int spapr_tcet_dma_dt(void *fdt, int node_off, const char *propname, return spapr_dma_dt(fdt, node_off, propname, tcet->liobn, 0, tcet->window_size); } + +static void spapr_tce_table_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + dc->vmsd = &vmstate_spapr_tce_table; + dc->init = spapr_tce_table_realize; + dc->reset = spapr_tce_reset; + + QLIST_INIT(&spapr_tce_tables); + + /* hcall-tce */ + spapr_register_hypercall(H_PUT_TCE, h_put_tce); +} + +static TypeInfo spapr_tce_table_info = { + .name = TYPE_SPAPR_TCE_TABLE, + .parent = TYPE_DEVICE, + .instance_size = sizeof(sPAPRTCETable), + .class_init = spapr_tce_table_class_init, + .instance_finalize = spapr_tce_table_finalize, +}; + +static void register_types(void) +{ + type_register_static(&spapr_tce_table_info); +} + +type_init(register_types); diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index 318bc9d..dd9e74e 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -682,7 +682,7 @@ static void spapr_phb_reset(DeviceState *qdev) sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(s); /* Reset the IOMMU state */ - spapr_tce_reset(sphb->tcet); + device_reset(DEVICE(sphb->tcet)); } static Property spapr_phb_properties[] = { diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c index 75ce19f..c3f85bf 100644 --- a/hw/ppc/spapr_vio.c +++ b/hw/ppc/spapr_vio.c @@ -316,7 +316,7 @@ int spapr_vio_send_crq(VIOsPAPRDevice *dev, uint8_t *crq) static void spapr_vio_quiesce_one(VIOsPAPRDevice *dev) { if (dev->tcet) { - spapr_tce_reset(dev->tcet); + device_reset(DEVICE(dev->tcet)); } free_crq(dev); } diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index de95480..82ad7c0 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -334,10 +334,6 @@ int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr, #define SPAPR_TCE_PAGE_SIZE (1ULL << SPAPR_TCE_PAGE_SHIFT) #define SPAPR_TCE_PAGE_MASK (SPAPR_TCE_PAGE_SIZE - 1) -typedef struct sPAPRTCE { - uint64_t tce; -} sPAPRTCE; - #define SPAPR_VIO_BASE_LIOBN 0x00000000 #define SPAPR_PCI_BASE_LIOBN 0x80000000 @@ -345,14 +341,27 @@ typedef struct sPAPRTCE { typedef struct sPAPRTCETable sPAPRTCETable; -void spapr_iommu_init(void); +#define TYPE_SPAPR_TCE_TABLE "spapr-tce-table" +#define SPAPR_TCE_TABLE(obj) \ + OBJECT_CHECK(sPAPRTCETable, (obj), TYPE_SPAPR_TCE_TABLE) + +struct sPAPRTCETable { + DeviceState parent; + uint32_t liobn; + uint32_t window_size; + uint32_t nb_table; + uint64_t *table; + bool bypass; + int fd; + MemoryRegion iommu; + QLIST_ENTRY(sPAPRTCETable) list; +}; + void spapr_events_init(sPAPREnvironment *spapr); void spapr_events_fdt_skel(void *fdt, uint32_t epow_irq); sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn, size_t window_size); MemoryRegion *spapr_tce_get_iommu(sPAPRTCETable *tcet); -void spapr_tce_free(sPAPRTCETable *tcet); -void spapr_tce_reset(sPAPRTCETable *tcet); void spapr_tce_set_bypass(sPAPRTCETable *tcet, bool bypass); int spapr_dma_dt(void *fdt, int node_off, const char *propname, uint32_t liobn, uint64_t window, uint32_t size);