Re: [PULL 00/22] ppc-for-6.0 queue 20210106
On Wed, 6 Jan 2021, Peter Maydell wrote: On Wed, 6 Jan 2021 at 03:38, David Gibson wrote: The following changes since commit 52d25464605dc20022ad94aa8bc8e8473e600833: Merge remote-tracking branch 'remotes/rth-gitlab/tags/pull-tcg-20210104' into staging (2021-01-05 16:18:20 +) are available in the Git repository at: https://gitlab.com/dgibson/qemu.git tags/ppc-for-6.0-20210106 for you to fetch changes up to 5cbd51a5a58098444ffa246ece2013849be04299: ppc440_pcix: Fix up pci config access (2021-01-06 11:09:59 +1100) ppc patch queue 2021-01-06 First pull request for 2021, which has a bunch of things accumulated over the holidays. Includes: * A number of cleanups to sam460ex and ppc440 code from BALATON Zoltan * Several fixes for builds with --without-default-devices from Greg Kurz * Fixes for some DRC reset problems from Greg Kurz * QOM conversion of the PPC 4xx UIC devices from Peter Maydell * Some other assorted fixes and cleanups BALATON Zoltan via (5): ppc4xx: Move common dependency on serial to common option sam460ex: Remove FDT_PPC dependency from KConfig ppc440_pcix: Improve comment for IRQ mapping ppc440_pcix: Fix register write trace event ppc440_pcix: Fix up pci config access Applied, thanks. I'm afraid I missed reading Balaton's email before pushing this to master, so the whole set is in there; sorry about that. Would you mind sending a patchset that makes the necessary changes on top of master (reverts or fixes as appropriate)? Sent a fixup series with the two reverts and the missing patch. Regards, BALATON Zoltan Please update the changelog at https://wiki.qemu.org/ChangeLog/6.0 for any user-visible changes. -- PMM
[PATCH 1/3] Revert "sam460ex: Remove FDT_PPC dependency from KConfig"
This reverts commit 038da2adf that was mistakenly added, this dependency is still needed to get libfdt dependencies even if fdt.o is not needed by sam460ex. Signed-off-by: BALATON Zoltan --- hw/ppc/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig index 7e267d94a1..d2329edbab 100644 --- a/hw/ppc/Kconfig +++ b/hw/ppc/Kconfig @@ -64,6 +64,7 @@ config SAM460EX select SMBUS_EEPROM select USB_EHCI_SYSBUS select USB_OHCI +select FDT_PPC config PREP bool -- 2.21.3
[PATCH 3/3] sam460ex: Use type cast macro instead of simple cast
Use the PCI_BUS type cast macro to convert result of qdev_get_child_bus(). Also remove the check for NULL afterwards which should not be needed because sysbus_create_simple() uses error_abort and PCI_BUS macro also checks its argument by default so this shouldn't fail here. Signed-off-by: BALATON Zoltan --- hw/ppc/sam460ex.c | 7 ++- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c index 14e6583eb0..cc67e9c39b 100644 --- a/hw/ppc/sam460ex.c +++ b/hw/ppc/sam460ex.c @@ -384,11 +384,8 @@ static void sam460ex_init(MachineState *machine) ppc460ex_pcie_init(env); /* All PCI irqs are connected to the same UIC pin (cf. UBoot source) */ dev = sysbus_create_simple("ppc440-pcix-host", 0xc0ec0, uic[1][0]); -pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci.0"); -if (!pci_bus) { -error_report("couldn't create PCI controller!"); -exit(1); -} +pci_bus = PCI_BUS(qdev_get_child_bus(dev, "pci.0")); + memory_region_init_alias(isa, NULL, "isa_mmio", get_system_io(), 0, 0x1); memory_region_add_subregion(get_system_memory(), 0xc0800, isa); -- 2.21.3
[PATCH 2/3] Revert "ppc4xx: Move common dependency on serial to common option"
This reverts commit e6d5106786 which was added mistakenly. While this change works it was suggested during review that keeping dependencies explicit for each board may be better than listing them in a common option so keep the previous version and revert this change. Signed-off-by: BALATON Zoltan --- hw/ppc/Kconfig | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig index d2329edbab..d11dc30509 100644 --- a/hw/ppc/Kconfig +++ b/hw/ppc/Kconfig @@ -36,6 +36,7 @@ config PPC405 select M48T59 select PFLASH_CFI02 select PPC4XX +select SERIAL config PPC440 bool @@ -44,6 +45,7 @@ config PPC440 imply E1000_PCI select PCI_EXPRESS select PPC4XX +select SERIAL select FDT_PPC config PPC4XX @@ -51,7 +53,6 @@ config PPC4XX select BITBANG_I2C select PCI select PPC_UIC -select SERIAL config SAM460EX bool @@ -60,6 +61,7 @@ config SAM460EX select IDE_SII3112 select M41T80 select PPC440 +select SERIAL select SM501 select SMBUS_EEPROM select USB_EHCI_SYSBUS @@ -121,6 +123,7 @@ config VIRTEX bool select PPC4XX select PFLASH_CFI01 +select SERIAL select XILINX select XILINX_ETHLITE select FDT_PPC -- 2.21.3
[PATCH 0/3] Fix up sam460ex fixes
Accidentally the wrong version of this series was committed, this series fixes that up to the last version that was meant to be merged. BALATON Zoltan (3): Revert "sam460ex: Remove FDT_PPC dependency from KConfig" Revert "ppc4xx: Move common dependency on serial to common option" sam460ex: Use type cast macro instead of simple cast hw/ppc/Kconfig| 6 +- hw/ppc/sam460ex.c | 7 ++- 2 files changed, 7 insertions(+), 6 deletions(-) -- 2.21.3
Re: [PULL 00/22] ppc-for-6.0 queue 20210106
On Wed, 6 Jan 2021, David Gibson wrote: The following changes since commit 52d25464605dc20022ad94aa8bc8e8473e600833: Merge remote-tracking branch 'remotes/rth-gitlab/tags/pull-tcg-20210104' into staging (2021-01-05 16:18:20 +) are available in the Git repository at: https://gitlab.com/dgibson/qemu.git tags/ppc-for-6.0-20210106 for you to fetch changes up to 5cbd51a5a58098444ffa246ece2013849be04299: ppc440_pcix: Fix up pci config access (2021-01-06 11:09:59 +1100) ppc patch queue 2021-01-06 First pull request for 2021, which has a bunch of things accumulated over the holidays. Includes: * A number of cleanups to sam460ex and ppc440 code from BALATON Zoltan * Several fixes for builds with --without-default-devices from Greg Kurz * Fixes for some DRC reset problems from Greg Kurz * QOM conversion of the PPC 4xx UIC devices from Peter Maydell * Some other assorted fixes and cleanups BALATON Zoltan via (5): ppc4xx: Move common dependency on serial to common option sam460ex: Remove FDT_PPC dependency from KConfig I've sent a v4 without these pathces ppc440_pcix: Improve comment for IRQ mapping ppc440_pcix: Fix register write trace event ppc440_pcix: Fix up pci config access but including another one missing from here so this pull request does not have the latest set of patches. Of course it's difficult for me to tell you when I can't send mail to your domain. We're trying to figure out why. Regards, BALATON Zoltan Cédric Le Goater (1): spapr/xive: Make spapr_xive_pic_print_info() static Greg Kurz (12): spapr: DRC lookup cannot fail spapr: Fix DR properties of the root node spapr: Allow memory unplug to always succeed spapr: Fix buffer overflow in spapr_numa_associativity_init() spapr: Call spapr_drc_reset() for all DRCs at CAS spapr: Fix reset of transient DR connectors spapr: Introduce spapr_drc_reset_all() spapr: Use spapr_drc_reset_all() at machine reset spapr: Add drc_ prefix to the DRC realize and unrealize functions ppc: Fix build with --without-default-devices ppc: Simplify reverse dependencies of POWERNV and PSERIES on XICS and XIVE pnv: Fix reverse dependency on PCI express root ports Peter Maydell (4): hw/ppc/ppc4xx_devs: Make code style fixes to UIC code ppc: Convert PPC UIC to a QOM device hw/ppc/virtex_ml507: Drop use of ppcuic_init() hw/ppc/ppc440_bamboo: Drop use of ppcuic_init() MAINTAINERS | 2 + hw/intc/Kconfig | 17 +-- hw/intc/meson.build | 13 +- hw/intc/ppc-uic.c | 321 hw/intc/spapr_xive.c| 2 +- hw/pci-host/Kconfig | 5 + hw/pci-host/meson.build | 2 +- hw/ppc/Kconfig | 29 +--- hw/ppc/ppc440_bamboo.c | 38 -- hw/ppc/ppc440_pcix.c| 50 --- hw/ppc/ppc4xx_devs.c| 262 +--- hw/ppc/spapr.c | 44 +++--- hw/ppc/spapr_drc.c | 63 +++-- hw/ppc/spapr_events.c | 3 +- hw/ppc/spapr_hcall.c| 33 + hw/ppc/trace-events | 1 + hw/ppc/virtex_ml507.c | 21 ++- include/hw/intc/ppc-uic.h | 73 ++ include/hw/pci-host/spapr.h | 2 - include/hw/ppc/spapr.h | 6 +- include/hw/ppc/spapr_drc.h | 10 +- include/hw/ppc/spapr_xive.h | 2 - 22 files changed, 616 insertions(+), 383 deletions(-) create mode 100644 hw/intc/ppc-uic.c create mode 100644 include/hw/intc/ppc-uic.h
[PATCH v4 3/4] ppc440_pcix: Fix up pci config access
This fixes a long standing issue with MorphOS booting on sam460ex which turns out to be because of suspicious values written to PCI config address that apparently works on real machine but caused wrong access on this device model. This replaces a previous work around for this with a better fix that makes it work. Signed-off-by: BALATON Zoltan --- hw/ppc/ppc440_pcix.c | 37 ++--- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/hw/ppc/ppc440_pcix.c b/hw/ppc/ppc440_pcix.c index 7829d3e556..91cbcd0504 100644 --- a/hw/ppc/ppc440_pcix.c +++ b/hw/ppc/ppc440_pcix.c @@ -449,28 +449,35 @@ static AddressSpace *ppc440_pcix_set_iommu(PCIBus *b, void *opaque, int devfn) return >bm_as; } -/* The default pci_host_data_{read,write} functions in pci/pci_host.c - * deny access to registers without bit 31 set but our clients want - * this to work so we have to override these here */ -static void pci_host_data_write(void *opaque, hwaddr addr, -uint64_t val, unsigned len) +/* + * Some guests on sam460ex write all kinds of garbage here such as + * missing enable bit and low bits set and still expect this to work + * (apparently it does on real hardware because these boot there) so + * we have to override these ops here and fix it up + */ +static void pci_host_config_write(void *opaque, hwaddr addr, + uint64_t val, unsigned len) { PCIHostState *s = opaque; -pci_data_write(s->bus, s->config_reg | (addr & 3), val, len); + +if (addr != 0 || len != 4) { +return; +} +s->config_reg = (val & 0xfffcULL) | (1UL << 31); } -static uint64_t pci_host_data_read(void *opaque, - hwaddr addr, unsigned len) +static uint64_t pci_host_config_read(void *opaque, hwaddr addr, + unsigned len) { PCIHostState *s = opaque; -uint32_t val; -val = pci_data_read(s->bus, s->config_reg | (addr & 3), len); +uint32_t val = s->config_reg; + return val; } -const MemoryRegionOps ppc440_pcix_host_data_ops = { -.read = pci_host_data_read, -.write = pci_host_data_write, +const MemoryRegionOps ppc440_pcix_host_conf_ops = { +.read = pci_host_config_read, +.write = pci_host_config_write, .endianness = DEVICE_LITTLE_ENDIAN, }; @@ -497,9 +504,9 @@ static void ppc440_pcix_realize(DeviceState *dev, Error **errp) pci_setup_iommu(h->bus, ppc440_pcix_set_iommu, s); memory_region_init(>container, OBJECT(s), "pci-container", PCI_ALL_SIZE); -memory_region_init_io(>conf_mem, OBJECT(s), _host_conf_le_ops, +memory_region_init_io(>conf_mem, OBJECT(s), _pcix_host_conf_ops, h, "pci-conf-idx", 4); -memory_region_init_io(>data_mem, OBJECT(s), _pcix_host_data_ops, +memory_region_init_io(>data_mem, OBJECT(s), _host_data_le_ops, h, "pci-conf-data", 4); memory_region_init_io(>iomem, OBJECT(s), _reg_ops, s, "pci.reg", PPC440_REG_SIZE); -- 2.21.3
[PATCH v4 4/4] sam460ex: Use type cast macro instead of simple cast
Use the PCI_BUS type cast macro to convert result of qdev_get_child_bus(). Also remove the check for NULL afterwards which should not be needed because sysbus_create_simple() uses error_abort and PCI_BUS macro also checks its argument by default so this shouldn't fail here. Signed-off-by: BALATON Zoltan --- hw/ppc/sam460ex.c | 7 ++- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c index 14e6583eb0..cc67e9c39b 100644 --- a/hw/ppc/sam460ex.c +++ b/hw/ppc/sam460ex.c @@ -384,11 +384,8 @@ static void sam460ex_init(MachineState *machine) ppc460ex_pcie_init(env); /* All PCI irqs are connected to the same UIC pin (cf. UBoot source) */ dev = sysbus_create_simple("ppc440-pcix-host", 0xc0ec0, uic[1][0]); -pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci.0"); -if (!pci_bus) { -error_report("couldn't create PCI controller!"); -exit(1); -} +pci_bus = PCI_BUS(qdev_get_child_bus(dev, "pci.0")); + memory_region_init_alias(isa, NULL, "isa_mmio", get_system_io(), 0, 0x1); memory_region_add_subregion(get_system_memory(), 0xc0800, isa); -- 2.21.3
[PATCH v4 2/4] ppc440_pcix: Fix register write trace event
The trace event for pci_host_config_write() was also using the trace event for read. Add corresponding trace and correct this. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé --- hw/ppc/ppc440_pcix.c | 2 +- hw/ppc/trace-events | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/hw/ppc/ppc440_pcix.c b/hw/ppc/ppc440_pcix.c index eb1290ffc8..7829d3e556 100644 --- a/hw/ppc/ppc440_pcix.c +++ b/hw/ppc/ppc440_pcix.c @@ -169,7 +169,7 @@ static void ppc440_pcix_reg_write4(void *opaque, hwaddr addr, { struct PPC440PCIXState *s = opaque; -trace_ppc440_pcix_reg_read(addr, val); +trace_ppc440_pcix_reg_write(addr, val, size); switch (addr) { case PCI_VENDOR_ID ... PCI_MAX_LAT: stl_le_p(s->dev->config + addr, val); diff --git a/hw/ppc/trace-events b/hw/ppc/trace-events index ed05f2fc9a..017c48624f 100644 --- a/hw/ppc/trace-events +++ b/hw/ppc/trace-events @@ -117,3 +117,4 @@ ppc440_pcix_set_irq(int irq_num) "PCI irq %d" ppc440_pcix_update_pim(int idx, uint64_t size, uint64_t la) "Added window %d of size=0x%" PRIx64 " to CPU=0x%" PRIx64 ppc440_pcix_update_pom(int idx, uint32_t size, uint64_t la, uint64_t pcia) "Added window %d of size=0x%x from CPU=0x%" PRIx64 " to PCI=0x%" PRIx64 ppc440_pcix_reg_read(uint64_t addr, uint32_t val) "addr 0x%" PRIx64 " = 0x%" PRIx32 +ppc440_pcix_reg_write(uint64_t addr, uint32_t val, uint32_t size) "addr 0x%" PRIx64 " = 0x%" PRIx32 " size 0x%" PRIx32 -- 2.21.3
[PATCH v4 0/4] Misc sam460ex fixes (was: Clean up sam460ex irq mapping)
Changes from v3: - removed first two patches changing Kconfig because the FDT one seems to be needed so we should not remove those from KConfig and there was some question about patch 1 - added a new patch to use type cast macro in sam460ex.c - the other 3 patches should be the same as in v3 Regards, BALATON Zoltan BALATON Zoltan (4): ppc440_pcix: Improve comment for IRQ mapping ppc440_pcix: Fix register write trace event ppc440_pcix: Fix up pci config access sam460ex: Use type cast macro instead of simple cast hw/ppc/ppc440_pcix.c | 50 hw/ppc/sam460ex.c| 7 ++- hw/ppc/trace-events | 1 + 3 files changed, 35 insertions(+), 23 deletions(-) -- 2.21.3
[PATCH v4 1/4] ppc440_pcix: Improve comment for IRQ mapping
The code mapping all PCI interrupts to a single CPU IRQ works but is not trivial so document it in a comment. Signed-off-by: BALATON Zoltan --- hw/ppc/ppc440_pcix.c | 11 +-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/hw/ppc/ppc440_pcix.c b/hw/ppc/ppc440_pcix.c index ee952314c8..eb1290ffc8 100644 --- a/hw/ppc/ppc440_pcix.c +++ b/hw/ppc/ppc440_pcix.c @@ -415,8 +415,15 @@ static void ppc440_pcix_reset(DeviceState *dev) s->sts = 0; } -/* All pins from each slot are tied to a single board IRQ. - * This may need further refactoring for other boards. */ +/* + * All four IRQ[ABCD] pins from all slots are tied to a single board + * IRQ, so our mapping function here maps everything to IRQ 0. + * The code in pci_change_irq_level() tracks the number of times + * the mapped IRQ is asserted and deasserted, so if multiple devices + * assert an IRQ at the same time the behaviour is correct. + * + * This may need further refactoring for boards that use multiple IRQ lines. + */ static int ppc440_pcix_map_irq(PCIDevice *pci_dev, int irq_num) { trace_ppc440_pcix_map_irq(pci_dev->devfn, irq_num, 0); -- 2.21.3
Re: [PATCH v2 2/3] sam460ex: Remove FDT_PPC dependency from KConfig
On Thu, 31 Dec 2020, BALATON Zoltan via wrote: Dependency on FDT_PPC was added in commit b0048f76095 ("hw/ppc/Kconfig: Only select FDT helper for machines using it") but it does not seem to be really necessary so remove it again. Signed-off-by: BALATON Zoltan --- v2: Do not remove PPC405, reworded commit message hw/ppc/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig index 8548f42b0d..f1e1be208e 100644 --- a/hw/ppc/Kconfig +++ b/hw/ppc/Kconfig @@ -64,7 +64,6 @@ config SAM460EX select SMBUS_EEPROM select USB_EHCI_SYSBUS select USB_OHCI -select FDT_PPC config PREP bool Something is still not right with this, I've noticed that a few other boards also have this option selected but they don't need fdt.o that's gated by this option in meson.build. That fdt.o is only needed by PSERIES and POWERNV but removing FDT_PPC from other boards I get: ../hw/ppc/sam460ex.c:43:10: fatal error: libfdt.h: No such file or directory #include so apparently this switch also pulls in the necessary CPPFLAGS or libfdt dependency. Is there a separate switch for that or we can only get it with fdt.o. Not a big deal just not trivial why we need an option that at first sight select a source file which we don't need. I think I'll drop this patch for now when resending the series. Regards, BALATON Zoltan
Re: [PATCH v3 1/5] ppc4xx: Move common dependency on serial to common option
On Sun, 3 Jan 2021, Thomas Huth wrote: On 03/01/2021 02.09, BALATON Zoltan via wrote: All machines that select SERIAL also select PPC4XX so we can just add this common dependency there once. Signed-off-by: BALATON Zoltan --- hw/ppc/Kconfig | 5 + 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig index dd86e664d2..8548f42b0d 100644 --- a/hw/ppc/Kconfig +++ b/hw/ppc/Kconfig @@ -37,7 +37,6 @@ config PPC405 select M48T59 select PFLASH_CFI02 select PPC4XX -select SERIAL config PPC440 bool @@ -46,13 +45,13 @@ config PPC440 imply E1000_PCI select PCI_EXPRESS select PPC4XX -select SERIAL select FDT_PPC config PPC4XX bool select BITBANG_I2C select PCI +select SERIAL Not sure whether this is really the right way to go... serial_hd() and serial_mm_init() are only used in ppc405_uc.c and ppc440_bamboo.c, so IMHO it does make sense to keep the SERIAL setting with PPC405 and PPC440. config SAM460EX bool @@ -61,7 +60,6 @@ config SAM460EX select IDE_SII3112 select M41T80 select PPC440 -select SERIAL But this hunk here should be fine, I think, since PPC440 already includes the SERIAL switch. If it's OK in this case why doesn't the same argument apply in case of PPC440 including PPC4XX which then includes SERIAL. All these boards use serial_mm_init but they also all include PPC4XX either directly or indirectly via an intermeriate option such as PPC440 or PPC405. Regards, BALATON Zoltan Thomas select SM501 select SMBUS_EEPROM select USB_EHCI_SYSBUS @@ -123,7 +121,6 @@ config VIRTEX bool select PPC4XX select PFLASH_CFI01 -select SERIAL select XILINX select XILINX_ETHLITE select FDT_PPC
Re: [PATCH v3 0/5] Misc sam460ex fixes (was: Clean up sam460ex irq mapping)
On Mon, 4 Jan 2021, David Gibson wrote: On Sun, Jan 03, 2021 at 02:09:33AM +0100, BALATON Zoltan via wrote: So this is v3 of a series that started to fix a potential problem with irq mapping in pci440_pcix (used by sam460ex) that got some other fixes along the way as by-products. But it turns out the irq issue this was trying to fix is not really a problem so finally we just update the comment for now documenting why it works and only the by-products remain in this series. Of which there are two more in this v3 finally fixing a long standing problem booting MorphOS on sam460ex (which I've got after debugging similar problem with pegasos2/vt8231 that gave me an idea how to debug this.) Applied to ppc-for-6.0. So.. you're pretty much the only person who's shown any interest in the embedded ppc stuff in qemu for a pretty long time. Any chance I could convince you to be ppc4xx submaintainer? Not if it involves testing or sending pull requests because I don't have time for that. I'm already listed as maintainer for stuff I contributed and try to review and test changes to that (i.e. sam460ex) but I'm afraid that's all I can do. Regards, BALATON Zoltan
Re: [PATCH v2 1/3] ppc4xx: Move common dependency on serial to common option
On Mon, 4 Jan 2021, David Gibson wrote: On Thu, Dec 31, 2020 at 12:11:55PM +0100, BALATON Zoltan via wrote: All machines that select SERIAL also select PPC4XX so we can just add this common dependency there once. Signed-off-by: BALATON Zoltan Applied to ppc-for-6.0. Not yet please, I'll send another version with changes suggested by Thomas. and also noticed another patch in this series needs update so I'll wait until tomorrow to see if anybody else has anything to say then will send and updated series. Regards, BALATON Zoltan. --- hw/ppc/Kconfig | 5 + 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig index dd86e664d2..8548f42b0d 100644 --- a/hw/ppc/Kconfig +++ b/hw/ppc/Kconfig @@ -37,7 +37,6 @@ config PPC405 select M48T59 select PFLASH_CFI02 select PPC4XX -select SERIAL config PPC440 bool @@ -46,13 +45,13 @@ config PPC440 imply E1000_PCI select PCI_EXPRESS select PPC4XX -select SERIAL select FDT_PPC config PPC4XX bool select BITBANG_I2C select PCI +select SERIAL config SAM460EX bool @@ -61,7 +60,6 @@ config SAM460EX select IDE_SII3112 select M41T80 select PPC440 -select SERIAL select SM501 select SMBUS_EEPROM select USB_EHCI_SYSBUS @@ -123,7 +121,6 @@ config VIRTEX bool select PPC4XX select PFLASH_CFI01 -select SERIAL select XILINX select XILINX_ETHLITE select FDT_PPC
Re: [RFC PATCH 2/5] via-ide: Fix fuloong2e support
On Sun, 3 Jan 2021, Mark Cave-Ayland wrote: On 01/01/2021 23:12, Philippe Mathieu-Daudé wrote: From: Guenter Roeck The IDE legacy mode emulation has been removed in commit 4ea98d317eb ("ide/via: Implement and use native PCI IDE mode") but some Linux kernels (probably including def_config) require legacy mode on the Fuloong2e so only emulating native mode did not turn out feasible. Add property to via-ide model to make the mode configurable, and set legacy mode for Fuloong2e. [balaton: Use bit in flags for property, add comment for missing BAR4] Signed-off-by: Guenter Roeck Signed-off-by: BALATON Zoltan Tested-by: Guenter Roeck Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Jiaxun Yang Message-Id: <17a50e58e6baa26440c7dac83f07fdbba1595439.1609191252.git.bala...@eik.bme.hu> Signed-off-by: Philippe Mathieu-Daudé --- hw/ide/via.c| 19 +-- hw/mips/fuloong2e.c | 4 +++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/hw/ide/via.c b/hw/ide/via.c index be09912b334..2d935b910f8 100644 --- a/hw/ide/via.c +++ b/hw/ide/via.c @@ -26,6 +26,7 @@ #include "qemu/osdep.h" #include "hw/pci/pci.h" +#include "hw/qdev-properties.h" #include "migration/vmstate.h" #include "qemu/module.h" #include "sysemu/dma.h" @@ -185,12 +186,19 @@ static void via_ide_realize(PCIDevice *dev, Error **errp) >bus[1], "via-ide1-cmd", 4); pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, >cmd_bar[1]); -bmdma_setup_bar(d); -pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, >bmdma_bar); +if (!(d->flags & BIT(PCI_IDE_LEGACY_MODE))) { +/* Missing BAR4 will make Linux driver fall back to legacy PIO mode */ +bmdma_setup_bar(d); +pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, >bmdma_bar); +} qdev_init_gpio_in(ds, via_ide_set_irq, 2); for (i = 0; i < 2; i++) { ide_bus_new(>bus[i], sizeof(d->bus[i]), ds, i, 2); +if (d->flags & BIT(PCI_IDE_LEGACY_MODE)) { +ide_init_ioport(>bus[i], NULL, i ? 0x170 : 0x1f0, +i ? 0x376 : 0x3f6); +} ide_init2(>bus[i], qdev_get_gpio_in(ds, i)); The if() here needs to be removed because the VIA IDE device starts up in legacy mode. If you look at the PCI bus master specification [1] the table at the top of page 3 is the breakdown of the PCI_CLASS_PROG byte: the configured value of 0x8a clearly indicates both channels are in legacy mode, which means that the PCI BARs are disabled and the controller is fixed to use the legacy IDE ioports with the option to switch up to native mode. This if says that these ports are enabled when the legacy-mode flag is set, i.e. we only emulate legacy-mode. It is disabled when we only emulate half-native mode for pegasos2. If we leave it there unconditionally as you suggest then we'll emulate (half-)native mode with the PCI BARs containing these regs as well as having legacy ioports enabled at the same time. I can't see how that's cleaner or more like what real hardware does. This is the main reason that the fuloong2e kernel panics on startup because its reads PCI_CLASS_PROG, discovers the controller is in legacy mode and then tries to access the legacy IDE ioports. Since the ioports are no longer mapped then the kernel crashes. (Fun fact: you can change PCI_CLASS_PROG to 0x8f and watch Linux configure the VIA IDE controller in native mode: it gets quite far before it decides to eventually panic) The fix here is simple: always enable the legacy IDE ioports. Zoltan mentioned he was concerned about having multiple IDE ports available, but this is not an issue for 2 reasons: 1) Before any of Zoltan's patches were applied, the VIA IDE driver set PCI_CLASS_PROG to 0x8a with the legacy IDE ports always enabled, and there were no issues It did not run with pegasos2 back then, only with fuloong2e Linux and even that wasn't tested very much, that's why my patches were needed in the first place so of course there were no issues as it did not work at all once something tried to use native mode like pegasos2 guests. 2) PCI bus enumeration always leaves the low end of IO space free so that there are no clashes with legacy ISA devices which can't be freely relocated in IO space I don't know if that's a valid assumption to expect to be generally true but I've tested pegasos2 with MorphOS after removing the if around ide_init_ioport() above as you say and only leaving it around BAR4 and it still boots, we end up with this memory map: memory-region: pci1-io - (prio 0, i/o): pci1-io -0007 (prio 0, i/o): dma-chan 0008-000f (prio 0, i/o): dma-cont 0020-0021 (prio 0, i/o): pic 0040-0043 (prio 0, i/o): pit 0060-0060 (prio 0, i/o): i8042-data
Re: [PATCH 00/24] vt82c686b clean ups and vt8231 emulation - all in one
On Sun, 3 Jan 2021, Philippe Mathieu-Daudé wrote: On 1/3/21 3:27 PM, BALATON Zoltan via wrote: On Sun, 3 Jan 2021, Philippe Mathieu-Daudé wrote: On 1/2/21 11:43 AM, BALATON Zoltan via wrote: Hello, This is an all in one series containing all the patches from my previous part I and part II vt82c686b clean up series plus the end of it to finally add vt8231 emulation that will be used by subsequent ppc/pegasos2 emulation. I consider this finished for now and good enough to get in also cleaning up and improving fuloong2e emulation a bit but previous disclaimer is still valid: It does not aim to fix all existing bugs or make the model perfectly emulate the real chip just reach the level where we can have working emulation to boot guests which can then be improved later. (E.g. I think state saving was broken before and it remains broken after because I don't know all the details how to add vmstate for all kinds of data structures and this could be addressed separately when fixing the already broken state saving if someone wants to test and fix it.) With this it boots at least MorphOS on pegasos2 and works with the pmon_2e.bin for fuloong2e which needs more fixes for Linux that are currently under review. More testing is welcome. It still needs the Bonito BONITO_PCICONF_REG_MASK fix for fuloong2e because it no longer maps SMBus but due to the Bonito bug guest cannot write register 0xd2 to map it. With that fix pmon_2e.bin from here: http://www.anheng.com.cn/loongson/pmon/ works for me with this command: qemu-system-mips64el -M fuloong2e -net none -bios pmon_2e.bin After rolling this for two years now I hope it can finally be merged and eventually also get pegasos2 emulation that will need this. Regards, BALATON Zoltan BALATON Zoltan (24): vt82c686: Rename AC97/MC97 parts from VT82C686B to VIA vt82c686: Remove unnecessary _DEVICE suffix from type macros vt82c686b: Rename VT82C686B to VT82C686B_ISA vt82c686: Remove vt82c686b_[am]c97_init() functions vt82c686: Split off via-[am]c97 into separate file in hw/audio audio/via-ac97: Simplify code and set user_creatable to false vt82c686: Remove legacy vt82c686b_isa_init() function vt82c686: Remove legacy vt82c686b_pm_init() function vt82c686: Convert debug printf to trace points vt82c686: Remove unneeded includes and defines vt82c686: Use shorter name for local variable holding object state vt82c686: Rename superio config related parts As the first half of this series is reviewed, I'm queuing it (patches 1-12) via mips-next. Thanks, You may want to fix the single vt82c686b: in the above commit title that was a typo, just for consistency. Fixed (along with your git author email, instead of the list). Thanks, sorry for the email address, that's something that seems to have changed last August without me doing anthing differently and I still don't know if it's something with the list or my mail provider. I've asked them both but I guess it's still holidays so haven't got an answer yet. Will this pull include the Bonito BONITO_PCICONF_REG_MASK fix or some replacement for that? That would be needed to get the rest of this series starting with 15/24 working. Up to that it's just clean up which should be OK. I checked the Bonito(32) ASIC and Bonito64 (FPGA) manuals, and for (vendor_id = 0xdf53, device_id = 0x00d5) our implementation is correct. I am waiting for further news from Jiaxun who asked someone at Loongson for a manual of their Bonito variant. I expect a different PCI device_id, so we can add it with your change. It's not my change, Jiaxun suggested it but fixes the problem with accessing register at 0xd2 that's needed on fuloong2e to get SMBus mapped after my series (patch 15 to be exact). I can repost the remaining patches rebased once it's merged in master or if you tell me which branch should I use. IMHO no need (at least not worthwhile until mips/next is merged). OK, I'll wait for that then before posting the remaining patches again. If you can have a look at them anyway I can make any necessary changes by then. Regards, BALATON Zoltan
Re: [RFC PATCH 0/5] hw/mips: Fix Fuloong2E to boot Linux guest again
On Sun, 3 Jan 2021, Mark Cave-Ayland wrote: On 01/01/2021 23:56, BALATON Zoltan via wrote: But Mark still considered that a horrible hack but after looking more closely he also found the difficulty of implementing a more faithful emulation so he would accept the flag at the end but still wanted registers to be set more consistently matching what the data sheet and whatever ideals would dictate. However I've spent a lot of time before finding these values that work with all clients and found some of these clients have assumptions instead of working in an ideal world following what data sheets say and I don't want to make any changes to this now before we also have pegasos2 upstreamed so any change can be more throughly tested and I don't have to retest everything for every small change just to find something broke, I'll reply briefly to this: I'm also trying to keep on technical terms, will write a separate letter off-list about the rest. from the latest analysis the part that's missing from QEMU is the ability to disable/enable PCI BARs. But this is only something that has come to light during the past week from Guenter's bug It did come to light (at least to me) in first iteration of these via-ide patches in March and I did tell you about it because I though it may help finding a problem with CMD646 that is used on a Sparc machine that to my knowledge you're interested in. See this thread: https://lists.nongnu.org/archive/html/qemu-devel/2020-03/msg00776.html (Probably that's how you got involved with the via-ide stuff in the first place, as otherwise I've only cc-d you for CMD646 related changes.) reports, as it is now clear the Gentoo image you were using for a test case (which you also provided to me) was not sufficient to test the VIA IDE functionality. That's true. It wasn't easy to find an image for fuloong2e as this was only ever popular in China and has been long discontinued it seems so the manufacturer's site that everything linked to was down. Therefore I could only find this gentoo image that said it should work on real hardware. Later Jiaxun and Huacai came back with other Linux images that we did not have in March and Guenter updated his QEMU version now to find this problem so now we have new, better test cases which showed we can't keep the approach of only emulating (half-)native mode but also need legacy mode for fuloong2e because while the beta gentoo kernel worked with native mode other Linux kernels seem to want legacy mode on fuloong2e. (Pegasos2 guests still want half-native mode so we need both and can't keep the original version that only emulated legacy mode.) I've already said that we can make use of a temporary hack for now, but the patch in its current form is still not right. I'll send a follow-up again to this thread so it is in one place for Phil's reference. Thanks, I appreciate if this solution of having the legacy-mode flag can get in now, even if you think it's not perfect. But it would allow to get pegasos2 working while getting fuloong2e back the way it was and not making it any worse than it was already (in fact I think it does improve it a little even if not going the whole way). This can always be improved later but I'd appreciate if you could also test your proposed solutions with pegasos2 which will be easier once that's upstream otherwise I'll have to do all the testing again and get pushed back from being able to finally upstream this board that I've stared working on 2 years ago. That's why I get upset if you demand more clean ups than absolutely necessary to reach the minimum acceptable level. If you can't wait until pegasos2 lands maybe you could experiment with CMD646 which I think may be somewhat similar and used by boards you maintain so it may be easier to experiment with without getting in the way of each other. That one I think only emulates native mode that may be enough for guests but also has a legacy mode that may be needed by some boot loaders or different boards so you could try to find a way to implement it cleanly in CMD646 then similar approach could be used for via-ide. As for the way to solve legacy/native mode switching I think going from the ISA side is probably better than from the PCI side, i.e. instead of disabling PCI BARs that you mention above it would be better to fix the ISA emulation to allow deregistering previously added devices and allow changing their parameters. I think so for the following reasons: - PCI BAR regions are already disabled until something programs their BARs and all of these IDE controllers start in legacy mode and guests change it to native mode and unlikely to change back to legacy so we don't really need to disable BARs once they are set up but we need to be able to turn off legacy ISA IDE emulation when switching to native mode. - Other parts of the via south bridge have similar problems that are ISA devices that can
Re: [PATCH 00/24] vt82c686b clean ups and vt8231 emulation - all in one
On Sun, 3 Jan 2021, Philippe Mathieu-Daudé wrote: On 1/2/21 11:43 AM, BALATON Zoltan via wrote: Hello, This is an all in one series containing all the patches from my previous part I and part II vt82c686b clean up series plus the end of it to finally add vt8231 emulation that will be used by subsequent ppc/pegasos2 emulation. I consider this finished for now and good enough to get in also cleaning up and improving fuloong2e emulation a bit but previous disclaimer is still valid: It does not aim to fix all existing bugs or make the model perfectly emulate the real chip just reach the level where we can have working emulation to boot guests which can then be improved later. (E.g. I think state saving was broken before and it remains broken after because I don't know all the details how to add vmstate for all kinds of data structures and this could be addressed separately when fixing the already broken state saving if someone wants to test and fix it.) With this it boots at least MorphOS on pegasos2 and works with the pmon_2e.bin for fuloong2e which needs more fixes for Linux that are currently under review. More testing is welcome. It still needs the Bonito BONITO_PCICONF_REG_MASK fix for fuloong2e because it no longer maps SMBus but due to the Bonito bug guest cannot write register 0xd2 to map it. With that fix pmon_2e.bin from here: http://www.anheng.com.cn/loongson/pmon/ works for me with this command: qemu-system-mips64el -M fuloong2e -net none -bios pmon_2e.bin After rolling this for two years now I hope it can finally be merged and eventually also get pegasos2 emulation that will need this. Regards, BALATON Zoltan BALATON Zoltan (24): vt82c686: Rename AC97/MC97 parts from VT82C686B to VIA vt82c686: Remove unnecessary _DEVICE suffix from type macros vt82c686b: Rename VT82C686B to VT82C686B_ISA vt82c686: Remove vt82c686b_[am]c97_init() functions vt82c686: Split off via-[am]c97 into separate file in hw/audio audio/via-ac97: Simplify code and set user_creatable to false vt82c686: Remove legacy vt82c686b_isa_init() function vt82c686: Remove legacy vt82c686b_pm_init() function vt82c686: Convert debug printf to trace points vt82c686: Remove unneeded includes and defines vt82c686: Use shorter name for local variable holding object state vt82c686: Rename superio config related parts As the first half of this series is reviewed, I'm queuing it (patches 1-12) via mips-next. Thanks, You may want to fix the single vt82c686b: in the above commit title that was a typo, just for consistency. Will this pull include the Bonito BONITO_PCICONF_REG_MASK fix or some replacement for that? That would be needed to get the rest of this series starting with 15/24 working. Up to that it's just clean up which should be OK. I can repost the remaining patches rebased once it's merged in master or if you tell me which branch should I use. Regards, BALATON Zoltan
Re: [PATCH v2 3/3] sam460ex: Clean up irq mapping
On Fri, 1 Jan 2021, Peter Maydell wrote: On Thu, 31 Dec 2020 at 20:55, BALATON Zoltan wrote: The SoC is called 460EX (despite having a PPC 440 core not 460 one) but I think you've looked at the right data sheet and it's just a typo. I also don't know how the board is wired so I think in this case I prefer dropping this patch and keeping the current code just for simplicity but to avoid going through this again maybe we should add a comment saying why it's working. Can you please suggest a text for such comment pointing to the relevant part of pci_change_irq_level() you refer to above? I don't think I understand it enough to document it. How about: /* * All four IRQ[ABCD] pins from all slots are tied to a single board * IRQ, so our mapping function here maps everything to IRQ 0. * The code in pci_change_irq_level() tracks the number of times * the mapped IRQ is asserted and deasserted, so if multiple devices * assert an IRQ at the same time the behaviour is correct. */ Very good, thank you. Leaving it as it is now also avoids needing to rebase your UIC series so that should still apply. I've sent a series with the above comment now, please add your Suggested-by, Reviewed-by as you see fit. Regards, BALATON Zoltan
[PATCH v3 4/5] ppc440_pcix: Fix register write trace event
The trace event for pci_host_config_write() was also using the trace event for read. Add corresponding trace and correct this. Signed-off-by: BALATON Zoltan --- hw/ppc/ppc440_pcix.c | 2 +- hw/ppc/trace-events | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/hw/ppc/ppc440_pcix.c b/hw/ppc/ppc440_pcix.c index eb1290ffc8..7829d3e556 100644 --- a/hw/ppc/ppc440_pcix.c +++ b/hw/ppc/ppc440_pcix.c @@ -169,7 +169,7 @@ static void ppc440_pcix_reg_write4(void *opaque, hwaddr addr, { struct PPC440PCIXState *s = opaque; -trace_ppc440_pcix_reg_read(addr, val); +trace_ppc440_pcix_reg_write(addr, val, size); switch (addr) { case PCI_VENDOR_ID ... PCI_MAX_LAT: stl_le_p(s->dev->config + addr, val); diff --git a/hw/ppc/trace-events b/hw/ppc/trace-events index ed05f2fc9a..017c48624f 100644 --- a/hw/ppc/trace-events +++ b/hw/ppc/trace-events @@ -117,3 +117,4 @@ ppc440_pcix_set_irq(int irq_num) "PCI irq %d" ppc440_pcix_update_pim(int idx, uint64_t size, uint64_t la) "Added window %d of size=0x%" PRIx64 " to CPU=0x%" PRIx64 ppc440_pcix_update_pom(int idx, uint32_t size, uint64_t la, uint64_t pcia) "Added window %d of size=0x%x from CPU=0x%" PRIx64 " to PCI=0x%" PRIx64 ppc440_pcix_reg_read(uint64_t addr, uint32_t val) "addr 0x%" PRIx64 " = 0x%" PRIx32 +ppc440_pcix_reg_write(uint64_t addr, uint32_t val, uint32_t size) "addr 0x%" PRIx64 " = 0x%" PRIx32 " size 0x%" PRIx32 -- 2.21.3
[PATCH v3 2/5] sam460ex: Remove FDT_PPC dependency from KConfig
Dependency on FDT_PPC was added in commit b0048f76095 ("hw/ppc/Kconfig: Only select FDT helper for machines using it") but it does not seem to be really necessary so remove it again. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé --- hw/ppc/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig index 8548f42b0d..f1e1be208e 100644 --- a/hw/ppc/Kconfig +++ b/hw/ppc/Kconfig @@ -64,7 +64,6 @@ config SAM460EX select SMBUS_EEPROM select USB_EHCI_SYSBUS select USB_OHCI -select FDT_PPC config PREP bool -- 2.21.3
[PATCH v3 3/5] ppc440_pcix: Improve comment for IRQ mapping
The code mapping all PCI interrupts to a single CPU IRQ works but is not trivial so document it in a comment. Signed-off-by: BALATON Zoltan --- hw/ppc/ppc440_pcix.c | 11 +-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/hw/ppc/ppc440_pcix.c b/hw/ppc/ppc440_pcix.c index ee952314c8..eb1290ffc8 100644 --- a/hw/ppc/ppc440_pcix.c +++ b/hw/ppc/ppc440_pcix.c @@ -415,8 +415,15 @@ static void ppc440_pcix_reset(DeviceState *dev) s->sts = 0; } -/* All pins from each slot are tied to a single board IRQ. - * This may need further refactoring for other boards. */ +/* + * All four IRQ[ABCD] pins from all slots are tied to a single board + * IRQ, so our mapping function here maps everything to IRQ 0. + * The code in pci_change_irq_level() tracks the number of times + * the mapped IRQ is asserted and deasserted, so if multiple devices + * assert an IRQ at the same time the behaviour is correct. + * + * This may need further refactoring for boards that use multiple IRQ lines. + */ static int ppc440_pcix_map_irq(PCIDevice *pci_dev, int irq_num) { trace_ppc440_pcix_map_irq(pci_dev->devfn, irq_num, 0); -- 2.21.3
[PATCH v3 5/5] ppc440_pcix: Fix up pci config access
This fixes a long standing issue with MorphOS booting on sam460ex which turns out to be because of suspicious values written to PCI config address that apparently works on real machine but caused wrong access on this device model. This replaces a previous work around for this with a better fix that makes it work. Signed-off-by: BALATON Zoltan --- hw/ppc/ppc440_pcix.c | 37 ++--- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/hw/ppc/ppc440_pcix.c b/hw/ppc/ppc440_pcix.c index 7829d3e556..91cbcd0504 100644 --- a/hw/ppc/ppc440_pcix.c +++ b/hw/ppc/ppc440_pcix.c @@ -449,28 +449,35 @@ static AddressSpace *ppc440_pcix_set_iommu(PCIBus *b, void *opaque, int devfn) return >bm_as; } -/* The default pci_host_data_{read,write} functions in pci/pci_host.c - * deny access to registers without bit 31 set but our clients want - * this to work so we have to override these here */ -static void pci_host_data_write(void *opaque, hwaddr addr, -uint64_t val, unsigned len) +/* + * Some guests on sam460ex write all kinds of garbage here such as + * missing enable bit and low bits set and still expect this to work + * (apparently it does on real hardware because these boot there) so + * we have to override these ops here and fix it up + */ +static void pci_host_config_write(void *opaque, hwaddr addr, + uint64_t val, unsigned len) { PCIHostState *s = opaque; -pci_data_write(s->bus, s->config_reg | (addr & 3), val, len); + +if (addr != 0 || len != 4) { +return; +} +s->config_reg = (val & 0xfffcULL) | (1UL << 31); } -static uint64_t pci_host_data_read(void *opaque, - hwaddr addr, unsigned len) +static uint64_t pci_host_config_read(void *opaque, hwaddr addr, + unsigned len) { PCIHostState *s = opaque; -uint32_t val; -val = pci_data_read(s->bus, s->config_reg | (addr & 3), len); +uint32_t val = s->config_reg; + return val; } -const MemoryRegionOps ppc440_pcix_host_data_ops = { -.read = pci_host_data_read, -.write = pci_host_data_write, +const MemoryRegionOps ppc440_pcix_host_conf_ops = { +.read = pci_host_config_read, +.write = pci_host_config_write, .endianness = DEVICE_LITTLE_ENDIAN, }; @@ -497,9 +504,9 @@ static void ppc440_pcix_realize(DeviceState *dev, Error **errp) pci_setup_iommu(h->bus, ppc440_pcix_set_iommu, s); memory_region_init(>container, OBJECT(s), "pci-container", PCI_ALL_SIZE); -memory_region_init_io(>conf_mem, OBJECT(s), _host_conf_le_ops, +memory_region_init_io(>conf_mem, OBJECT(s), _pcix_host_conf_ops, h, "pci-conf-idx", 4); -memory_region_init_io(>data_mem, OBJECT(s), _pcix_host_data_ops, +memory_region_init_io(>data_mem, OBJECT(s), _host_data_le_ops, h, "pci-conf-data", 4); memory_region_init_io(>iomem, OBJECT(s), _reg_ops, s, "pci.reg", PPC440_REG_SIZE); -- 2.21.3
[PATCH v3 1/5] ppc4xx: Move common dependency on serial to common option
All machines that select SERIAL also select PPC4XX so we can just add this common dependency there once. Signed-off-by: BALATON Zoltan --- hw/ppc/Kconfig | 5 + 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig index dd86e664d2..8548f42b0d 100644 --- a/hw/ppc/Kconfig +++ b/hw/ppc/Kconfig @@ -37,7 +37,6 @@ config PPC405 select M48T59 select PFLASH_CFI02 select PPC4XX -select SERIAL config PPC440 bool @@ -46,13 +45,13 @@ config PPC440 imply E1000_PCI select PCI_EXPRESS select PPC4XX -select SERIAL select FDT_PPC config PPC4XX bool select BITBANG_I2C select PCI +select SERIAL config SAM460EX bool @@ -61,7 +60,6 @@ config SAM460EX select IDE_SII3112 select M41T80 select PPC440 -select SERIAL select SM501 select SMBUS_EEPROM select USB_EHCI_SYSBUS @@ -123,7 +121,6 @@ config VIRTEX bool select PPC4XX select PFLASH_CFI01 -select SERIAL select XILINX select XILINX_ETHLITE select FDT_PPC -- 2.21.3
[PATCH v3 0/5] Misc sam460ex fixes (was: Clean up sam460ex irq mapping)
So this is v3 of a series that started to fix a potential problem with irq mapping in pci440_pcix (used by sam460ex) that got some other fixes along the way as by-products. But it turns out the irq issue this was trying to fix is not really a problem so finally we just update the comment for now documenting why it works and only the by-products remain in this series. Of which there are two more in this v3 finally fixing a long standing problem booting MorphOS on sam460ex (which I've got after debugging similar problem with pegasos2/vt8231 that gave me an idea how to debug this.) Regards, BALATON Zoltan BALATON Zoltan (5): ppc4xx: Move common dependency on serial to common option sam460ex: Remove FDT_PPC dependency from KConfig ppc440_pcix: Improve comment for IRQ mapping ppc440_pcix: Fix register write trace event ppc440_pcix: Fix up pci config access hw/ppc/Kconfig | 6 +- hw/ppc/ppc440_pcix.c | 50 hw/ppc/trace-events | 1 + 3 files changed, 34 insertions(+), 23 deletions(-) -- 2.21.3
Re: [RFC PATCH 3/5] hw/pci-host/bonito: Remap PCI "lo" regions when PCIMAP reg is modified
On Sat, 2 Jan 2021, Peter Maydell wrote: On Sat, 2 Jan 2021 at 11:22, BALATON Zoltan wrote: I have similar code in the series I've just posted where I'm mapping regions of serial devices. I did consider using set_enabled and set_address but ended up with removing and adding regions because I'm not sure what happens if guest tries to move one region over another like having one region at a default location while guest tries to map the other one there (the pegasos2 maps serial at 0x2f8 which is normally COM2 on a PC). This should not happen in theory but when removing disabled regions it cannot happen so that looks safer therefore I chose to do that. Not sure if this could be a problem here just shared my thughts about this. I'm not sure what you have in mind -- could you explain further? There should be no difference as far as the MemoryRegion handling code is concerned between "this memory region is marked disabled" and "the memory region was deleted and will be created from fresh and added back later" -- an MR that's in the hierarchy but not enabled is entirely ignored, as if it wasn't there at all, when creating the flat-view. The device I was implementing has two registers one to set base address of io region and another with bits to enable/disable the regions so I could do set_address for base regs and set_enabled for control reg bits but I've seen guests first flipping the enable bits on then setting the base address so I thought it might cause problems with regions added to their parent but thinking about it more it's probably the same if we remove regions and add them instead of just set_enabled because they should be readded when control reg bits are set so they'll end up at the same default address. That said, doing memory_region_del_subregion()/memory_region_add_subregion() I think is also OK -- what's definitely not required is actually deleting and recreating the MRs the way this code is doing. Anyway that's what I ended up doing and did not notice that this patch was also deleting and recreating the memory regions which I did not do just removing from parent when they are disabled but using set_address if they are enabled and new base is set. Removing inactive regions maybe better for debugging because they show up in info mtree so one can see which one is enabled/disabled not sure how disabled regions show up though. All in all I probably have nothing to add to this so just disregard my comment. Regards, BALATON Zoltan
[PATCH 24/24] vt82c686: Add emulation of VT8231 south bridge
Add emulation of VT8231 south bridge ISA part based on the similar VT82C686B but implemented in a separate subclass that holds the differences while reusing parts that can be shared. Signed-off-by: BALATON Zoltan --- hw/isa/vt82c686.c | 152 ++ include/hw/isa/vt82c686.h | 1 + 2 files changed, 123 insertions(+), 30 deletions(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index 0390782d1d..604ab4a55e 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -8,6 +8,9 @@ * * Contributions after 2012-01-13 are licensed under the terms of the * GNU GPL, version 2 or (at your option) any later version. + * + * VT8231 south bridge support and general clean up to allow it + * Copyright (c) 2018-2020 BALATON Zoltan */ #include "qemu/osdep.h" @@ -609,24 +612,48 @@ static const TypeInfo vt8231_superio_info = { }; -OBJECT_DECLARE_SIMPLE_TYPE(VT82C686BISAState, VT82C686B_ISA) +#define TYPE_VIA_ISA "via-isa" +OBJECT_DECLARE_SIMPLE_TYPE(ViaISAState, VIA_ISA) -struct VT82C686BISAState { +struct ViaISAState { PCIDevice dev; qemu_irq cpu_intr; ViaSuperIOState *via_sio; }; +static const VMStateDescription vmstate_via = { +.name = "via-isa", +.version_id = 1, +.minimum_version_id = 1, +.fields = (VMStateField[]) { +VMSTATE_PCI_DEVICE(dev, ViaISAState), +VMSTATE_END_OF_LIST() +} +}; + +static const TypeInfo via_isa_info = { +.name = TYPE_VIA_ISA, +.parent= TYPE_PCI_DEVICE, +.instance_size = sizeof(ViaISAState), +.abstract = true, +.interfaces= (InterfaceInfo[]) { +{ INTERFACE_CONVENTIONAL_PCI_DEVICE }, +{ }, +}, +}; + static void via_isa_request_i8259_irq(void *opaque, int irq, int level) { -VT82C686BISAState *s = opaque; +ViaISAState *s = opaque; qemu_set_irq(s->cpu_intr, level); } +/* TYPE_VT82C686B_ISA */ + static void vt82c686b_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int len) { -VT82C686BISAState *s = VT82C686B_ISA(d); +ViaISAState *s = VIA_ISA(d); trace_via_isa_write(addr, val, len); pci_default_write_config(d, addr, val, len); @@ -636,19 +663,9 @@ static void vt82c686b_write_config(PCIDevice *d, uint32_t addr, } } -static const VMStateDescription vmstate_via = { -.name = "vt82c686b", -.version_id = 1, -.minimum_version_id = 1, -.fields = (VMStateField[]) { -VMSTATE_PCI_DEVICE(dev, VT82C686BISAState), -VMSTATE_END_OF_LIST() -} -}; - static void vt82c686b_isa_reset(DeviceState *dev) { -VT82C686BISAState *s = VT82C686B_ISA(dev); +ViaISAState *s = VIA_ISA(dev); uint8_t *pci_conf = s->dev.config; pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x00c0); @@ -668,7 +685,7 @@ static void vt82c686b_isa_reset(DeviceState *dev) static void vt82c686b_realize(PCIDevice *d, Error **errp) { -VT82C686BISAState *s = VT82C686B_ISA(d); +ViaISAState *s = VIA_ISA(d); DeviceState *dev = DEVICE(d); ISABus *isa_bus; qemu_irq *isa_irq; @@ -692,7 +709,7 @@ static void vt82c686b_realize(PCIDevice *d, Error **errp) } } -static void via_class_init(ObjectClass *klass, void *data) +static void vt82c686b_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -706,22 +723,95 @@ static void via_class_init(ObjectClass *klass, void *data) dc->reset = vt82c686b_isa_reset; dc->desc = "ISA bridge"; dc->vmsd = _via; -/* - * Reason: part of VIA VT82C686 southbridge, needs to be wired up, - * e.g. by mips_fuloong2e_init() - */ +/* Reason: part of VIA VT82C686 southbridge, needs to be wired up */ dc->user_creatable = false; } -static const TypeInfo via_info = { +static const TypeInfo vt82c686b_isa_info = { .name = TYPE_VT82C686B_ISA, -.parent= TYPE_PCI_DEVICE, -.instance_size = sizeof(VT82C686BISAState), -.class_init= via_class_init, -.interfaces = (InterfaceInfo[]) { -{ INTERFACE_CONVENTIONAL_PCI_DEVICE }, -{ }, -}, +.parent= TYPE_VIA_ISA, +.instance_size = sizeof(ViaISAState), +.class_init= vt82c686b_class_init, +}; + +/* TYPE_VT8231_ISA */ + +static void vt8231_write_config(PCIDevice *d, uint32_t addr, +uint32_t val, int len) +{ +ViaISAState *s = VIA_ISA(d); + +trace_via_isa_write(addr, val, len); +pci_default_write_config(d, addr, val, len); +if (addr == 0x50) { +/* BIT(2): enable or disable superio config io ports */ +via_superio_io_enable(s->via_sio, val & BIT(2)); +} +} + +static void vt8231_isa_reset(DeviceState *dev) +{ +ViaISAState *s = VIA_ISA(dev); +uint8_t *pci_conf = s->dev.config; + +pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x00c0); +pci_set_word(pci_conf +
[PATCH 14/24] vt82c686: Reorganise code
Move lines around so that object definitions become consecutive and not scattered around. This brings functions belonging to an object together so it's clearer what is defined and what parts belong to which object. Signed-off-by: BALATON Zoltan --- hw/isa/vt82c686.c | 279 +++--- 1 file changed, 140 insertions(+), 139 deletions(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index 30fe02f4c6..fe8961b057 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -26,112 +26,7 @@ #include "exec/address-spaces.h" #include "trace.h" -typedef struct SuperIOConfig { -uint8_t regs[0x100]; -uint8_t index; -MemoryRegion io; -} SuperIOConfig; - -struct VT82C686BISAState { -PCIDevice dev; -SuperIOConfig superio_cfg; -}; - -OBJECT_DECLARE_SIMPLE_TYPE(VT82C686BISAState, VT82C686B_ISA) - -static void superio_cfg_write(void *opaque, hwaddr addr, uint64_t data, - unsigned size) -{ -SuperIOConfig *sc = opaque; - -if (addr == 0x3f0) { /* config index register */ -sc->index = data & 0xff; -} else { -bool can_write = true; -/* 0x3f1, config data register */ -trace_via_superio_write(sc->index, data & 0xff); -switch (sc->index) { -case 0x00 ... 0xdf: -case 0xe4: -case 0xe5: -case 0xe9 ... 0xed: -case 0xf3: -case 0xf5: -case 0xf7: -case 0xf9 ... 0xfb: -case 0xfd ... 0xff: -can_write = false; -break; -/* case 0xe6 ... 0xe8: Should set base port of parallel and serial */ -default: -break; - -} -if (can_write) { -sc->regs[sc->index] = data & 0xff; -} -} -} - -static uint64_t superio_cfg_read(void *opaque, hwaddr addr, unsigned size) -{ -SuperIOConfig *sc = opaque; -uint8_t val = sc->regs[sc->index]; - -trace_via_superio_read(sc->index, val); -return val; -} - -static const MemoryRegionOps superio_cfg_ops = { -.read = superio_cfg_read, -.write = superio_cfg_write, -.endianness = DEVICE_NATIVE_ENDIAN, -.impl = { -.min_access_size = 1, -.max_access_size = 1, -}, -}; - -static void vt82c686b_isa_reset(DeviceState *dev) -{ -VT82C686BISAState *s = VT82C686B_ISA(dev); -uint8_t *pci_conf = s->dev.config; - -pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x00c0); -pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY | - PCI_COMMAND_MASTER | PCI_COMMAND_SPECIAL); -pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM); - -pci_conf[0x48] = 0x01; /* Miscellaneous Control 3 */ -pci_conf[0x4a] = 0x04; /* IDE interrupt Routing */ -pci_conf[0x4f] = 0x03; /* DMA/Master Mem Access Control 3 */ -pci_conf[0x50] = 0x2d; /* PnP DMA Request Control */ -pci_conf[0x59] = 0x04; -pci_conf[0x5a] = 0x04; /* KBC/RTC Control*/ -pci_conf[0x5f] = 0x04; -pci_conf[0x77] = 0x10; /* GPIO Control 1/2/3/4 */ - -s->superio_cfg.regs[0xe0] = 0x3c; /* Device ID */ -s->superio_cfg.regs[0xe2] = 0x03; /* Function select */ -s->superio_cfg.regs[0xe3] = 0xfc; /* Floppy ctrl base addr */ -s->superio_cfg.regs[0xe6] = 0xde; /* Parallel port base addr */ -s->superio_cfg.regs[0xe7] = 0xfe; /* Serial port 1 base addr */ -s->superio_cfg.regs[0xe8] = 0xbe; /* Serial port 2 base addr */ -} - -/* write config pci function0 registers. PCI-ISA bridge */ -static void vt82c686b_write_config(PCIDevice *d, uint32_t addr, - uint32_t val, int len) -{ -VT82C686BISAState *s = VT82C686B_ISA(d); - -trace_via_isa_write(addr, val, len); -pci_default_write_config(d, addr, val, len); -if (addr == 0x85) { -/* BIT(1): enable or disable superio config io ports */ -memory_region_set_enabled(>superio_cfg.io, val & BIT(1)); -} -} +OBJECT_DECLARE_SIMPLE_TYPE(VT686PMState, VT82C686B_PM) struct VT686PMState { PCIDevice dev; @@ -142,30 +37,6 @@ struct VT686PMState { uint32_t smb_io_base; }; -OBJECT_DECLARE_SIMPLE_TYPE(VT686PMState, VT82C686B_PM) - -static void pm_update_sci(VT686PMState *s) -{ -int sci_level, pmsts; - -pmsts = acpi_pm1_evt_get_sts(>ar); -sci_level = (((pmsts & s->ar.pm1.evt.en) & - (ACPI_BITMASK_RT_CLOCK_ENABLE | - ACPI_BITMASK_POWER_BUTTON_ENABLE | - ACPI_BITMASK_GLOBAL_LOCK_ENABLE | - ACPI_BITMASK_TIMER_ENABLE)) != 0); -pci_set_irq(>dev, sci_level); -/* schedule a timer interruption if needed */ -acpi_pm_tmr_update(>ar, (s->ar.pm1.evt.en & ACPI_BITMASK_TIMER_ENABLE) && - !(pmsts & ACPI_BITMASK_TIMER_STATUS)); -} - -static void pm_tmr_timer(ACPIREGS *ar) -{ -VT686PMState *s = container_of(ar, VT686PMState, ar); -pm_update_sci(s); -} - static void pm_io_space_update(VT686PMState *s) { uint32_t
[PATCH 22/24] vt82c686: QOM-ify superio related functionality
Collect superio functionality and its controlling config registers handling in an abstract VIA_SUPERIO class that is a subclass of ISA_SUPERIO and put vt82c686b specific parts in a subclass of this abstract class. Signed-off-by: BALATON Zoltan --- hw/isa/vt82c686.c | 240 -- include/hw/isa/vt82c686.h | 1 - 2 files changed, 150 insertions(+), 91 deletions(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index 26db1a18e2..a755896b8e 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -249,12 +249,21 @@ static const TypeInfo vt8231_pm_info = { }; -typedef struct SuperIOConfig { +#define TYPE_VIA_SUPERIO "via-superio" +OBJECT_DECLARE_SIMPLE_TYPE(ViaSuperIOState, VIA_SUPERIO) + +struct ViaSuperIOState { +ISASuperIODevice superio; uint8_t regs[0x100]; +const MemoryRegionOps *io_ops; MemoryRegion io; -ISASuperIODevice *superio; MemoryRegion *serial_io[SUPERIO_MAX_SERIAL_PORTS]; -} SuperIOConfig; +}; + +static inline void via_superio_io_enable(ViaSuperIOState *s, bool enable) +{ +memory_region_set_enabled(>io, enable); +} static MemoryRegion *find_subregion(ISADevice *d, MemoryRegion *parent, int offs) @@ -270,10 +279,76 @@ static MemoryRegion *find_subregion(ISADevice *d, MemoryRegion *parent, return mr; } -static void superio_cfg_write(void *opaque, hwaddr addr, uint64_t data, - unsigned size) +static void via_superio_realize(DeviceState *d, Error **errp) +{ +ViaSuperIOState *s = VIA_SUPERIO(d); +ISASuperIOClass *ic = ISA_SUPERIO_GET_CLASS(s); +int i; + +assert(s->io_ops); +ic->parent_realize(d, errp); +if (*errp) { +return; +} +/* Grab io regions of serial devices so we can control them */ +for (i = 0; i < ic->serial.count; i++) { +ISADevice *sd = s->superio.serial[i]; +MemoryRegion *io = isa_address_space_io(sd); +MemoryRegion *mr = find_subregion(sd, io, sd->ioport_id); +if (!mr) { +error_setg(errp, "Could not get io region for serial %d", i); +return; +} +s->serial_io[i] = mr; +} + +memory_region_init_io(>io, OBJECT(d), s->io_ops, s, "via-superio", 2); +memory_region_set_enabled(>io, false); +/* The floppy also uses 0x3f0 and 0x3f1 but this seems to work anyway */ +memory_region_add_subregion(isa_address_space_io(ISA_DEVICE(s)), 0x3f0, +>io); +} + +static uint64_t via_superio_cfg_read(void *opaque, hwaddr addr, unsigned size) +{ +ViaSuperIOState *sc = opaque; +uint8_t idx = sc->regs[0]; +uint8_t val = sc->regs[idx]; + +if (addr == 0) { +return idx; +} +if (addr == 1 && idx == 0) { +val = 0; /* reading reg 0 where we store index value */ +} +trace_via_superio_read(idx, val); +return val; +} + +static void via_superio_class_init(ObjectClass *klass, void *data) +{ +DeviceClass *dc = DEVICE_CLASS(klass); +ISASuperIOClass *sc = ISA_SUPERIO_CLASS(klass); + +sc->parent_realize = dc->realize; +dc->realize = via_superio_realize; +} + +static const TypeInfo via_superio_info = { +.name = TYPE_VIA_SUPERIO, +.parent= TYPE_ISA_SUPERIO, +.instance_size = sizeof(ViaSuperIOState), +.class_size= sizeof(ISASuperIOClass), +.class_init= via_superio_class_init, +.abstract = true, +}; + +#define TYPE_VT82C686B_SUPERIO "vt82c686b-superio" + +static void vt82c686b_superio_cfg_write(void *opaque, hwaddr addr, +uint64_t data, unsigned size) { -SuperIOConfig *sc = opaque; +ViaSuperIOState *sc = opaque; uint8_t idx = sc->regs[0]; if (addr == 0) { /* config index register */ @@ -295,29 +370,29 @@ static void superio_cfg_write(void *opaque, hwaddr addr, uint64_t data, case 0xfd ... 0xff: /* ignore write to read only registers */ return; -case 0xe2: +case 0xe2: /* Function select */ { data &= 0x1f; if (data & BIT(2)) { /* Serial port 1 enable */ -ISADevice *dev = sc->superio->serial[0]; +ISADevice *dev = sc->superio.serial[0]; if (!memory_region_is_mapped(sc->serial_io[0])) { memory_region_add_subregion(isa_address_space_io(dev), dev->ioport_id, sc->serial_io[0]); } } else { -MemoryRegion *io = isa_address_space_io(sc->superio->serial[0]); +MemoryRegion *io = isa_address_space_io(sc->superio.serial[0]); if (memory_region_is_mapped(sc->serial_io[0])) { memory_region_del_subregion(io, sc->serial_io[0]); } } if (data & BIT(3)) { /* Serial port 2 enable */ -ISADevice *dev = sc->superio->serial[1]; +ISADevice *dev = sc->superio.serial[1];
[PATCH 16/24] vt82c686: Fix up power management io base and config
Similar to the SMBus io registers there is a power management io range that is set via similar base address reg and enable bit. Some handling of this was already there but with several problems: using the wrong registers and bits, wrong size range, not acually updating mapping and handling reset correctly, nor emulating any of the actual io registers. Some of these errors are fixed up here. After this patch we use the correct base address register, enable bit and region size and allow guests to map/unmap this region and correctly reset all registers to default values on reset but we still don't emulate any of the registers in this range. Previously just an empty RAM region was mapped on realize, now we add an empty io range logging access instead. I think the pm timer should be hooked up here but not sure guests need it. PMON on fuloong2e sets a base address but does not seem to enable region; the pegasos2 firmware pokes some regs but continues anyway so don't know if anything would make use of these facilities. Therefore this is just a clean up of previous state for now and not intending to fully implement missing functionality which could be done later if some guests need it. Signed-off-by: BALATON Zoltan --- hw/isa/trace-events | 2 ++ hw/isa/vt82c686.c | 56 - 2 files changed, 42 insertions(+), 16 deletions(-) diff --git a/hw/isa/trace-events b/hw/isa/trace-events index d267d3e652..641d69eedf 100644 --- a/hw/isa/trace-events +++ b/hw/isa/trace-events @@ -17,5 +17,7 @@ apm_io_write(uint8_t addr, uint8_t val) "write addr=0x%x val=0x%02x" # vt82c686.c via_isa_write(uint32_t addr, uint32_t val, int len) "addr 0x%x val 0x%x len 0x%x" via_pm_write(uint32_t addr, uint32_t val, int len) "addr 0x%x val 0x%x len 0x%x" +via_pm_io_read(uint32_t addr, uint32_t val, int len) "addr 0x%x val 0x%x len 0x%x" +via_pm_io_write(uint32_t addr, uint32_t val, int len) "addr 0x%x val 0x%x len 0x%x" via_superio_read(uint8_t addr, uint8_t val) "addr 0x%x val 0x%x" via_superio_write(uint8_t addr, uint32_t val) "addr 0x%x val 0x%x" diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index 9c4d153022..fc2a1f4430 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -39,14 +39,11 @@ struct VT686PMState { static void pm_io_space_update(VT686PMState *s) { -uint32_t pm_io_base; - -pm_io_base = pci_get_long(s->dev.config + 0x40); -pm_io_base &= 0xffc0; +uint32_t pmbase = pci_get_long(s->dev.config + 0x48) & 0xff80UL; memory_region_transaction_begin(); -memory_region_set_enabled(>io, s->dev.config[0x80] & 1); -memory_region_set_address(>io, pm_io_base); +memory_region_set_address(>io, pmbase); +memory_region_set_enabled(>io, s->dev.config[0x41] & BIT(7)); memory_region_transaction_commit(); } @@ -92,6 +89,13 @@ static void pm_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int len) trace_via_pm_write(addr, val, len); pci_default_write_config(d, addr, val, len); +if (ranges_overlap(addr, len, 0x48, 4)) { +uint32_t v = pci_get_long(s->dev.config + 0x48); +pci_set_long(s->dev.config + 0x48, (v & 0xff80UL) | 1); +} +if (range_covers_byte(addr, len, 0x41)) { +pm_io_space_update(s); +} if (ranges_overlap(addr, len, 0x90, 4)) { uint32_t v = pci_get_long(s->dev.config + 0x90); pci_set_long(s->dev.config + 0x90, (v & 0xfff0UL) | 1); @@ -102,6 +106,27 @@ static void pm_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int len) } } +static void pm_io_write(void *op, hwaddr addr, uint64_t data, unsigned size) +{ +trace_via_pm_io_write(addr, data, size); +} + +static uint64_t pm_io_read(void *op, hwaddr addr, unsigned size) +{ +trace_via_pm_io_read(addr, 0, size); +return 0; +} + +static const MemoryRegionOps pm_io_ops = { +.read = pm_io_read, +.write = pm_io_write, +.endianness = DEVICE_NATIVE_ENDIAN, +.impl = { +.min_access_size = 1, +.max_access_size = 1, +}, +}; + static void pm_update_sci(VT686PMState *s) { int sci_level, pmsts; @@ -128,35 +153,34 @@ static void vt82c686b_pm_reset(DeviceState *d) { VT686PMState *s = VT82C686B_PM(d); +memset(s->dev.config + PCI_CONFIG_HEADER_SIZE, 0, + PCI_CONFIG_SPACE_SIZE - PCI_CONFIG_HEADER_SIZE); +/* Power Management IO base */ +pci_set_long(s->dev.config + 0x48, 1); /* SMBus IO base */ pci_set_long(s->dev.config + 0x90, 1); -s->dev.config[0xd2] = 0; +pm_io_space_update(s); smb_io_space_update(s); } static void vt82c686b_pm_realize(PCIDevice *dev, Error **errp) { VT686PMState *s = VT82C686B_PM(dev); -uint8_t *pci_conf; -pci_conf = s->dev.config; -pci_set_word(pci_conf + PCI_COMMAND, 0); -pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_FAST_BACK | +pci_set_word(dev->config + PCI_STATUS, PCI_STATUS_FAST_BACK | PCI_STATUS_DEVSEL_MEDIUM); -
[PATCH 18/24] vt82c686: Simplify vt82c686b_realize()
Remove unneeded variables and setting value to 0 on zero initialised data and replace check for error with error_fatal. Rationalise loop that sets PCI config header fields read only. Signed-off-by: BALATON Zoltan --- hw/isa/vt82c686.c | 20 ++-- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index a989e29fe5..ead60310fe 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -363,24 +363,16 @@ static void vt82c686b_isa_reset(DeviceState *dev) static void vt82c686b_realize(PCIDevice *d, Error **errp) { VT82C686BISAState *s = VT82C686B_ISA(d); -uint8_t *pci_conf; +DeviceState *dev = DEVICE(d); ISABus *isa_bus; -uint8_t *wmask; int i; -isa_bus = isa_bus_new(DEVICE(d), get_system_memory(), - pci_address_space_io(d), errp); -if (!isa_bus) { -return; -} - -pci_conf = d->config; -pci_config_set_prog_interface(pci_conf, 0x0); +isa_bus = isa_bus_new(dev, get_system_memory(), pci_address_space_io(d), + _fatal); -wmask = d->wmask; -for (i = 0x00; i < 0xff; i++) { -if (i <= 0x03 || (i >= 0x08 && i <= 0x3f)) { -wmask[i] = 0x00; +for (i = 0; i < PCI_CONFIG_HEADER_SIZE; i++) { +if (i < PCI_COMMAND || i >= PCI_REVISION_ID) { +d->wmask[i] = 0; } } -- 2.21.3
[PATCH 19/24] vt82c686: Move creation of ISA devices to the ISA bridge
Currently the ISA devices that are part of the VIA south bridge, superio chip are wired up by board code. Move creation of these ISA devices to the VIA ISA bridge model so that board code does not need to access ISA bus. This also allows vt82c686b-superio to be made internal to vt82c686 which allows implementing its configuration via registers in subseqent commits. Signed-off-by: BALATON Zoltan --- hw/isa/vt82c686.c | 20 hw/mips/fuloong2e.c | 29 + 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index ead60310fe..3a45056226 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -16,6 +16,11 @@ #include "hw/qdev-properties.h" #include "hw/isa/isa.h" #include "hw/isa/superio.h" +#include "hw/intc/i8259.h" +#include "hw/irq.h" +#include "hw/dma/i8257.h" +#include "hw/timer/i8254.h" +#include "hw/rtc/mc146818rtc.h" #include "migration/vmstate.h" #include "hw/isa/apm.h" #include "hw/acpi/acpi.h" @@ -307,9 +312,16 @@ OBJECT_DECLARE_SIMPLE_TYPE(VT82C686BISAState, VT82C686B_ISA) struct VT82C686BISAState { PCIDevice dev; +qemu_irq cpu_intr; SuperIOConfig superio_cfg; }; +static void via_isa_request_i8259_irq(void *opaque, int irq, int level) +{ +VT82C686BISAState *s = opaque; +qemu_set_irq(s->cpu_intr, level); +} + static void vt82c686b_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int len) { @@ -365,10 +377,18 @@ static void vt82c686b_realize(PCIDevice *d, Error **errp) VT82C686BISAState *s = VT82C686B_ISA(d); DeviceState *dev = DEVICE(d); ISABus *isa_bus; +qemu_irq *isa_irq; int i; +qdev_init_gpio_out(dev, >cpu_intr, 1); +isa_irq = qemu_allocate_irqs(via_isa_request_i8259_irq, s, 1); isa_bus = isa_bus_new(dev, get_system_memory(), pci_address_space_io(d), _fatal); +isa_bus_irqs(isa_bus, i8259_init(isa_bus, *isa_irq)); +i8254_pit_init(isa_bus, 0x40, 0, NULL); +i8257_dma_init(isa_bus, 0); +isa_create_simple(isa_bus, TYPE_VT82C686B_SUPERIO); +mc146818_rtc_init(isa_bus, 2000, NULL); for (i = 0; i < PCI_CONFIG_HEADER_SIZE; i++) { if (i < PCI_COMMAND || i >= PCI_REVISION_ID) { diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c index bf19b4603e..59b96b3aae 100644 --- a/hw/mips/fuloong2e.c +++ b/hw/mips/fuloong2e.c @@ -25,9 +25,6 @@ #include "qapi/error.h" #include "cpu.h" #include "hw/clock.h" -#include "hw/intc/i8259.h" -#include "hw/dma/i8257.h" -#include "hw/isa/superio.h" #include "net/net.h" #include "hw/boards.h" #include "hw/i2c/smbus_eeprom.h" @@ -38,13 +35,13 @@ #include "qemu/log.h" #include "hw/loader.h" #include "hw/ide/pci.h" +#include "hw/qdev-properties.h" #include "elf.h" #include "hw/isa/vt82c686.h" -#include "hw/rtc/mc146818rtc.h" -#include "hw/timer/i8254.h" #include "exec/address-spaces.h" #include "sysemu/qtest.h" #include "sysemu/reset.h" +#include "sysemu/sysemu.h" #include "qemu/error-report.h" #define DEBUG_FULOONG2E_INIT @@ -234,26 +231,13 @@ static void main_cpu_reset(void *opaque) } static void vt82c686b_southbridge_init(PCIBus *pci_bus, int slot, qemu_irq intc, - I2CBus **i2c_bus, ISABus **p_isa_bus) + I2CBus **i2c_bus) { -qemu_irq *i8259; -ISABus *isa_bus; PCIDevice *dev; dev = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(slot, 0), true, TYPE_VT82C686B_ISA); -isa_bus = ISA_BUS(qdev_get_child_bus(DEVICE(dev), "isa.0")); -assert(isa_bus); -*p_isa_bus = isa_bus; -/* Interrupt controller */ -/* The 8259 -> IP5 */ -i8259 = i8259_init(isa_bus, intc); -isa_bus_irqs(isa_bus, i8259); -/* init other devices */ -i8254_pit_init(isa_bus, 0x40, 0, NULL); -i8257_dma_init(isa_bus, 0); -/* Super I/O */ -isa_create_simple(isa_bus, TYPE_VT82C686B_SUPERIO); +qdev_connect_gpio_out(DEVICE(dev), 0, intc); dev = pci_new(PCI_DEVFN(slot, 1), "via-ide"); qdev_prop_set_bit(>qdev, "legacy-mode", true); @@ -302,7 +286,6 @@ static void mips_fuloong2e_init(MachineState *machine) int64_t kernel_entry; PCIDevice *pci_dev; PCIBus *pci_bus; -ISABus *isa_bus; I2CBus *smbus; Clock *cpuclk; MIPSCPU *cpu; @@ -369,7 +352,7 @@ static void mips_fuloong2e_init(MachineState *machine) /* South bridge -> IP5 */ vt82c686b_southbridge_init(pci_bus, FULOONG2E_VIA_SLOT, env->irq[5], - , _bus); + ); /* GPU */ if (vga_interface_type != VGA_NONE) { @@ -384,8 +367,6 @@ static void mips_fuloong2e_init(MachineState *machine) spd_data = spd_data_generate(DDR, machine->ram_size); smbus_eeprom_init_one(smbus, 0x50, spd_data); -mc146818_rtc_init(isa_bus, 2000, NULL); - /* Network card:
[PATCH 10/24] vt82c686: Remove unneeded includes and defines
These are not used or not needed. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé --- hw/isa/vt82c686.c | 5 - 1 file changed, 5 deletions(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index d7ce15bf9f..02d6759c00 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -16,9 +16,7 @@ #include "hw/qdev-properties.h" #include "hw/isa/isa.h" #include "hw/isa/superio.h" -#include "hw/sysbus.h" #include "migration/vmstate.h" -#include "hw/mips/mips.h" #include "hw/isa/apm.h" #include "hw/acpi/acpi.h" #include "hw/i2c/pm_smbus.h" @@ -26,7 +24,6 @@ #include "qemu/module.h" #include "qemu/timer.h" #include "exec/address-spaces.h" -#include "qom/object.h" #include "trace.h" typedef struct SuperIOConfig { @@ -136,8 +133,6 @@ static void vt82c686b_write_config(PCIDevice *d, uint32_t addr, } } -#define ACPI_DBG_IO_ADDR 0xb044 - struct VT686PMState { PCIDevice dev; MemoryRegion io; -- 2.21.3
Re: [RFC PATCH 3/5] hw/pci-host/bonito: Remap PCI "lo" regions when PCIMAP reg is modified
On Sat, 2 Jan 2021, Philippe Mathieu-Daudé wrote: On 1/2/21 12:19 AM, Peter Maydell wrote: On Fri, 1 Jan 2021 at 23:12, Philippe Mathieu-Daudé wrote: Per the datasheet (Chapter 5.7.1. "PCI address regions"), the PCIMAP register: Map the 64Mbyte regions marked "PCI_Lo" in the CPU's memory map, each of which can be assigned to any 64 Mbyte-aligned region of PCI memory. The address appearing on the PCI bus consists of the low 26 bits of the CPU physical address, with the high 6 bits coming from the appropriate base6 field. Each of the three regions is an independent window onto PCI memory, and can be positioned on any 64Mbyte boundary in PCI space. Remap the 3 regions on reset and when PCIMAP is updated. Signed-off-by: Philippe Mathieu-Daudé --- hw/pci-host/bonito.c | 49 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c index a99eced0657..c58eeaf504c 100644 --- a/hw/pci-host/bonito.c +++ b/hw/pci-host/bonito.c @@ -137,6 +137,10 @@ FIELD(BONGENCFG, PCIQUEUE, 12, 1) /* 4. PCI address map control */ #define BONITO_PCIMAP (0x10 >> 2) /* 0x110 */ +FIELD(PCIMAP, LO0, 0, 6) +FIELD(PCIMAP, LO1, 6, 6) +FIELD(PCIMAP, LO2, 12, 6) +FIELD(PCIMAP, 2G, 18, 1) #define BONITO_PCIMEMBASECFG(0x14 >> 2) /* 0x114 */ #define BONITO_PCIMAP_CFG (0x18 >> 2) /* 0x118 */ @@ -237,6 +241,7 @@ struct BonitoState { qemu_irq *pic; PCIBonitoState *pci_dev; MemoryRegion pci_mem; +MemoryRegion pcimem_lo_alias[3]; }; #define TYPE_BONITO_PCI_HOST_BRIDGE "Bonito-pcihost" @@ -245,6 +250,31 @@ OBJECT_DECLARE_SIMPLE_TYPE(BonitoState, BONITO_PCI_HOST_BRIDGE) #define TYPE_PCI_BONITO "Bonito" OBJECT_DECLARE_SIMPLE_TYPE(PCIBonitoState, PCI_BONITO) +static void bonito_remap(PCIBonitoState *s) +{ +static const char *const region_name[3] = { +"pci.lomem0", "pci.lomem1", "pci.lomem2" +}; +BonitoState *bs = BONITO_PCI_HOST_BRIDGE(s->pcihost); + +for (size_t i = 0; i < 3; i++) { +uint32_t offset = extract32(s->regs[BONITO_PCIMAP], 6 * i, 6) << 26; + +if (memory_region_is_mapped(>pcimem_lo_alias[i])) { +memory_region_del_subregion(get_system_memory(), +>pcimem_lo_alias[i]); +object_unparent(OBJECT(>pcimem_lo_alias[i])); +} + +memory_region_init_alias(>pcimem_lo_alias[i], OBJECT(s), + region_name[i], >pci_mem, + offset, 64 * MiB); +memory_region_add_subregion(get_system_memory(), +BONITO_PCILO_BASE + i * 64 * MiB, +>pcimem_lo_alias[i]); +} Rather than delete-and-reinit-and-add, it's probably better to just create the subregions once at device startup, and then use memory_region_set_enabled() and memory_region_set_address() to manipulate whether the subregion is visible and what address in the system memory it is mapped at. Great! Thanks Peter :) TIL these functions. From what I understand from memory_region_readd_subregion (called from memory_region_set_address) using memory_region_set_enabled() directly is enough. I have similar code in the series I've just posted where I'm mapping regions of serial devices. I did consider using set_enabled and set_address but ended up with removing and adding regions because I'm not sure what happens if guest tries to move one region over another like having one region at a default location while guest tries to map the other one there (the pegasos2 maps serial at 0x2f8 which is normally COM2 on a PC). This should not happen in theory but when removing disabled regions it cannot happen so that looks safer therefore I chose to do that. Not sure if this could be a problem here just shared my thughts about this. Regards, BALATON Zoltan
[PATCH 20/24] vt82c686: Fix superio_cfg_{read,write}() functions
These functions are memory region callbacks so we have to check against relative address not the mapped address. Also reduce indentation by returning early and log unimplemented accesses. Additionally we remove separate index value from SuperIOConfig and store the index at reg 0 which is reserved and returns 0 on read. This simpilifies object state. Signed-off-by: BALATON Zoltan --- hw/isa/vt82c686.c | 63 ++- 1 file changed, 35 insertions(+), 28 deletions(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index 3a45056226..1a876a1fbf 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -26,6 +26,7 @@ #include "hw/acpi/acpi.h" #include "hw/i2c/pm_smbus.h" #include "qapi/error.h" +#include "qemu/log.h" #include "qemu/module.h" #include "qemu/range.h" #include "qemu/timer.h" @@ -250,7 +251,6 @@ static const TypeInfo vt8231_pm_info = { typedef struct SuperIOConfig { uint8_t regs[0x100]; -uint8_t index; MemoryRegion io; } SuperIOConfig; @@ -258,42 +258,49 @@ static void superio_cfg_write(void *opaque, hwaddr addr, uint64_t data, unsigned size) { SuperIOConfig *sc = opaque; +uint8_t idx = sc->regs[0]; -if (addr == 0x3f0) { /* config index register */ -sc->index = data & 0xff; -} else { -bool can_write = true; -/* 0x3f1, config data register */ -trace_via_superio_write(sc->index, data & 0xff); -switch (sc->index) { -case 0x00 ... 0xdf: -case 0xe4: -case 0xe5: -case 0xe9 ... 0xed: -case 0xf3: -case 0xf5: -case 0xf7: -case 0xf9 ... 0xfb: -case 0xfd ... 0xff: -can_write = false; -break; -/* case 0xe6 ... 0xe8: Should set base port of parallel and serial */ -default: -break; +if (addr == 0) { /* config index register */ +sc->regs[0] = data; +return; +} -} -if (can_write) { -sc->regs[sc->index] = data & 0xff; -} +/* config data register */ +trace_via_superio_write(idx, data); +switch (idx) { +case 0x00 ... 0xdf: +case 0xe4: +case 0xe5: +case 0xe9 ... 0xed: +case 0xf3: +case 0xf5: +case 0xf7: +case 0xf9 ... 0xfb: +case 0xfd ... 0xff: +/* ignore write to read only registers */ +return; +/* case 0xe6 ... 0xe8: Should set base port of parallel and serial */ +default: +qemu_log_mask(LOG_UNIMP, + "via_superio_cfg: unimplemented register 0x%x\n", idx); +break; } +sc->regs[idx] = data; } static uint64_t superio_cfg_read(void *opaque, hwaddr addr, unsigned size) { SuperIOConfig *sc = opaque; -uint8_t val = sc->regs[sc->index]; +uint8_t idx = sc->regs[0]; +uint8_t val = sc->regs[idx]; -trace_via_superio_read(sc->index, val); +if (addr == 0) { +return idx; +} +if (addr == 1 && idx == 0) { +val = 0; /* reading reg 0 where we store index value */ +} +trace_via_superio_read(idx, val); return val; } -- 2.21.3
[PATCH 23/24] vt82c686: Add VT8231_SUPERIO based on VIA_SUPERIO
The VT8231 south bridge is very similar to VT82C686B but there are some differences in register addresses and functionality, e.g. the VT8231 only has one serial port. This commit adds VT8231_SUPERIO subclass based on the abstract VIA_SUPERIO class to emulate the superio part of VT8231. Signed-off-by: BALATON Zoltan --- hw/isa/vt82c686.c | 121 ++ 1 file changed, 121 insertions(+) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index a755896b8e..0390782d1d 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -489,6 +489,126 @@ static const TypeInfo vt82c686b_superio_info = { }; +#define TYPE_VT8231_SUPERIO "vt8231-superio" + +static void vt8231_superio_cfg_write(void *opaque, hwaddr addr, + uint64_t data, unsigned size) +{ +ViaSuperIOState *sc = opaque; +uint8_t idx = sc->regs[0]; + +if (addr == 0) { /* config index register */ +sc->regs[0] = data; +return; +} + +/* config data register */ +trace_via_superio_write(idx, data); +switch (idx) { +case 0x00 ... 0xdf: +case 0xe7 ... 0xef: +case 0xf0 ... 0xf1: +case 0xf5: +case 0xf8: +case 0xfd: +/* ignore write to read only registers */ +return; +case 0xf2: /* Function select */ +{ +data &= 0x17; +if (data & BIT(2)) { /* Serial port enable */ +ISADevice *dev = sc->superio.serial[0]; +if (!memory_region_is_mapped(sc->serial_io[0])) { +memory_region_add_subregion(isa_address_space_io(dev), +dev->ioport_id, sc->serial_io[0]); +} +} else { +MemoryRegion *io = isa_address_space_io(sc->superio.serial[0]); +if (memory_region_is_mapped(sc->serial_io[0])) { +memory_region_del_subregion(io, sc->serial_io[0]); +} +} +break; +} +case 0xf4: /* Serial port io base address */ +{ +data &= 0xfe; +sc->superio.serial[0]->ioport_id = data << 2; +if (memory_region_is_mapped(sc->serial_io[0])) { +memory_region_set_address(sc->serial_io[0], data << 2); +} +break; +} +default: +qemu_log_mask(LOG_UNIMP, + "via_superio_cfg: unimplemented register 0x%x\n", idx); +break; +} +sc->regs[idx] = data; +} + +static const MemoryRegionOps vt8231_superio_cfg_ops = { +.read = via_superio_cfg_read, +.write = vt8231_superio_cfg_write, +.endianness = DEVICE_NATIVE_ENDIAN, +.impl = { +.min_access_size = 1, +.max_access_size = 1, +}, +}; + +static void vt8231_superio_reset(DeviceState *dev) +{ +ViaSuperIOState *s = VIA_SUPERIO(dev); + +memset(s->regs, 0, sizeof(s->regs)); +/* Device ID */ +s->regs[0xf0] = 0x3c; +/* Device revision */ +s->regs[0xf1] = 0x01; +/* Function select - all disabled */ +vt8231_superio_cfg_write(s, 0, 0xf2, 1); +vt8231_superio_cfg_write(s, 1, 0x03, 1); +/* Serial port base addr */ +vt8231_superio_cfg_write(s, 0, 0xf4, 1); +vt8231_superio_cfg_write(s, 1, 0xfe, 1); +/* Parallel port base addr */ +vt8231_superio_cfg_write(s, 0, 0xf6, 1); +vt8231_superio_cfg_write(s, 1, 0xde, 1); +/* Floppy ctrl base addr */ +vt8231_superio_cfg_write(s, 0, 0xf7, 1); +vt8231_superio_cfg_write(s, 1, 0xfc, 1); + +vt8231_superio_cfg_write(s, 0, 0, 1); +} + +static void vt8231_superio_init(Object *obj) +{ +VIA_SUPERIO(obj)->io_ops = _superio_cfg_ops; +} + +static void vt8231_superio_class_init(ObjectClass *klass, void *data) +{ +DeviceClass *dc = DEVICE_CLASS(klass); +ISASuperIOClass *sc = ISA_SUPERIO_CLASS(klass); + +dc->reset = vt8231_superio_reset; +sc->serial.count = 1; +sc->parallel.count = 1; +sc->ide.count = 0; /* emulated by via-ide */ +sc->floppy.count = 1; +} + +static const TypeInfo vt8231_superio_info = { +.name = TYPE_VT8231_SUPERIO, +.parent= TYPE_VIA_SUPERIO, +.instance_size = sizeof(ViaSuperIOState), +.instance_init = vt8231_superio_init, +.class_size= sizeof(ISASuperIOClass), +.class_init= vt8231_superio_class_init, +}; + + OBJECT_DECLARE_SIMPLE_TYPE(VT82C686BISAState, VT82C686B_ISA) struct VT82C686BISAState { @@ -612,6 +732,7 @@ static void vt82c686b_register_types(void) type_register_static(_pm_info); type_register_static(_superio_info); type_register_static(_superio_info); +type_register_static(_superio_info); type_register_static(_info); } -- 2.21.3
[PATCH 15/24] vt82c686: Fix SMBus IO base and configuration registers
The base address of the SMBus io ports and its enabled status is set by registers in the PCI config space but this was not correctly emulated. Instead the SMBus registers were mapped on realize to the base address set by a property to the address expected by fuloong2e firmware. Fix the base and config register handling to more closely model hardware which allows to remove the property and allows the guest to control this mapping. Do all this in reset instead of realize so it's correctly updated on reset. Signed-off-by: BALATON Zoltan --- hw/isa/vt82c686.c | 49 + hw/mips/fuloong2e.c | 4 +--- 2 files changed, 37 insertions(+), 16 deletions(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index fe8961b057..9c4d153022 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -22,6 +22,7 @@ #include "hw/i2c/pm_smbus.h" #include "qapi/error.h" #include "qemu/module.h" +#include "qemu/range.h" #include "qemu/timer.h" #include "exec/address-spaces.h" #include "trace.h" @@ -34,7 +35,6 @@ struct VT686PMState { ACPIREGS ar; APMState apm; PMSMBus smb; -uint32_t smb_io_base; }; static void pm_io_space_update(VT686PMState *s) @@ -50,11 +50,22 @@ static void pm_io_space_update(VT686PMState *s) memory_region_transaction_commit(); } +static void smb_io_space_update(VT686PMState *s) +{ +uint32_t smbase = pci_get_long(s->dev.config + 0x90) & 0xfff0UL; + +memory_region_transaction_begin(); +memory_region_set_address(>smb.io, smbase); +memory_region_set_enabled(>smb.io, s->dev.config[0xd2] & BIT(0)); +memory_region_transaction_commit(); +} + static int vmstate_acpi_post_load(void *opaque, int version_id) { VT686PMState *s = opaque; pm_io_space_update(s); +smb_io_space_update(s); return 0; } @@ -77,8 +88,18 @@ static const VMStateDescription vmstate_acpi = { static void pm_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int len) { +VT686PMState *s = VT82C686B_PM(d); + trace_via_pm_write(addr, val, len); pci_default_write_config(d, addr, val, len); +if (ranges_overlap(addr, len, 0x90, 4)) { +uint32_t v = pci_get_long(s->dev.config + 0x90); +pci_set_long(s->dev.config + 0x90, (v & 0xfff0UL) | 1); +} +if (range_covers_byte(addr, len, 0xd2)) { +s->dev.config[0xd2] &= 0xf; +smb_io_space_update(s); +} } static void pm_update_sci(VT686PMState *s) @@ -103,6 +124,17 @@ static void pm_tmr_timer(ACPIREGS *ar) pm_update_sci(s); } +static void vt82c686b_pm_reset(DeviceState *d) +{ +VT686PMState *s = VT82C686B_PM(d); + +/* SMBus IO base */ +pci_set_long(s->dev.config + 0x90, 1); +s->dev.config[0xd2] = 0; + +smb_io_space_update(s); +} + static void vt82c686b_pm_realize(PCIDevice *dev, Error **errp) { VT686PMState *s = VT82C686B_PM(dev); @@ -116,13 +148,9 @@ static void vt82c686b_pm_realize(PCIDevice *dev, Error **errp) /* 0x48-0x4B is Power Management I/O Base */ pci_set_long(pci_conf + 0x48, 0x0001); -/* SMB ports:0xeee0~0xeeef */ -s->smb_io_base = ((s->smb_io_base & 0xfff0) + 0x0); -pci_conf[0x90] = s->smb_io_base | 1; -pci_conf[0x91] = s->smb_io_base >> 8; -pci_conf[0xd2] = 0x90; pm_smbus_init(DEVICE(s), >smb, false); -memory_region_add_subregion(get_system_io(), s->smb_io_base, >smb.io); +memory_region_add_subregion(pci_address_space_io(dev), 0, >smb.io); +memory_region_set_enabled(>smb.io, false); apm_init(dev, >apm, NULL, s); @@ -135,11 +163,6 @@ static void vt82c686b_pm_realize(PCIDevice *dev, Error **errp) acpi_pm1_cnt_init(>ar, >io, false, false, 2); } -static Property via_pm_properties[] = { -DEFINE_PROP_UINT32("smb_io_base", VT686PMState, smb_io_base, 0), -DEFINE_PROP_END_OF_LIST(), -}; - static void via_pm_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -151,10 +174,10 @@ static void via_pm_class_init(ObjectClass *klass, void *data) k->device_id = PCI_DEVICE_ID_VIA_ACPI; k->class_id = PCI_CLASS_BRIDGE_OTHER; k->revision = 0x40; +dc->reset = vt82c686b_pm_reset; dc->desc = "PM"; dc->vmsd = _acpi; set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); -device_class_set_props(dc, via_pm_properties); } static const TypeInfo via_pm_info = { diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c index f393509633..bf19b4603e 100644 --- a/hw/mips/fuloong2e.c +++ b/hw/mips/fuloong2e.c @@ -263,9 +263,7 @@ static void vt82c686b_southbridge_init(PCIBus *pci_bus, int slot, qemu_irq intc, pci_create_simple(pci_bus, PCI_DEVFN(slot, 2), "vt82c686b-usb-uhci"); pci_create_simple(pci_bus, PCI_DEVFN(slot, 3), "vt82c686b-usb-uhci"); -dev = pci_new(PCI_DEVFN(slot, 4), TYPE_VT82C686B_PM); -qdev_prop_set_uint32(DEVICE(dev), "smb_io_base", 0xeee1); -pci_realize_and_unref(dev, pci_bus, _fatal); +dev =
[PATCH 09/24] vt82c686: Convert debug printf to trace points
Drop DPRINTF and use trace functions instead. Two debug messages about unimplemented registers could be converted to qemu_log_mask() but in reality all registers are currently unimplemented (we just store and return values of writable regs but do nothing with them). As we already trace register access there's no need for additional debug messages so these are just removed and a comment is added as a reminder. Signed-off-by: BALATON Zoltan --- hw/isa/trace-events | 6 ++ hw/isa/vt82c686.c | 51 + 2 files changed, 21 insertions(+), 36 deletions(-) diff --git a/hw/isa/trace-events b/hw/isa/trace-events index 3544c6213c..d267d3e652 100644 --- a/hw/isa/trace-events +++ b/hw/isa/trace-events @@ -13,3 +13,9 @@ pc87312_io_write(uint32_t addr, uint32_t val) "write addr=0x%x val=0x%x" # apm.c apm_io_read(uint8_t addr, uint8_t val) "read addr=0x%x val=0x%02x" apm_io_write(uint8_t addr, uint8_t val) "write addr=0x%x val=0x%02x" + +# vt82c686.c +via_isa_write(uint32_t addr, uint32_t val, int len) "addr 0x%x val 0x%x len 0x%x" +via_pm_write(uint32_t addr, uint32_t val, int len) "addr 0x%x val 0x%x len 0x%x" +via_superio_read(uint8_t addr, uint8_t val) "addr 0x%x val 0x%x" +via_superio_write(uint8_t addr, uint32_t val) "addr 0x%x val 0x%x" diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index cd87ec0103..d7ce15bf9f 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -27,14 +27,7 @@ #include "qemu/timer.h" #include "exec/address-spaces.h" #include "qom/object.h" - -/* #define DEBUG_VT82C686B */ - -#ifdef DEBUG_VT82C686B -#define DPRINTF(fmt, ...) fprintf(stderr, "%s: " fmt, __func__, ##__VA_ARGS__) -#else -#define DPRINTF(fmt, ...) -#endif +#include "trace.h" typedef struct SuperIOConfig { uint8_t config[0x100]; @@ -55,12 +48,12 @@ static void superio_ioport_writeb(void *opaque, hwaddr addr, uint64_t data, { SuperIOConfig *superio_conf = opaque; -DPRINTF("superio_ioport_writeb address 0x%x val 0x%x\n", addr, data); -if (addr == 0x3f0) { +if (addr == 0x3f0) { /* config index register */ superio_conf->index = data & 0xff; } else { bool can_write = true; -/* 0x3f1 */ +/* 0x3f1, config data register */ +trace_via_superio_write(superio_conf->index, data & 0xff); switch (superio_conf->index) { case 0x00 ... 0xdf: case 0xe4: @@ -73,18 +66,7 @@ static void superio_ioport_writeb(void *opaque, hwaddr addr, uint64_t data, case 0xfd ... 0xff: can_write = false; break; -case 0xe7: -if ((data & 0xff) != 0xfe) { -DPRINTF("change uart 1 base. unsupported yet\n"); -can_write = false; -} -break; -case 0xe8: -if ((data & 0xff) != 0xbe) { -DPRINTF("change uart 2 base. unsupported yet\n"); -can_write = false; -} -break; +/* case 0xe6 ... 0xe8: Should set base port of parallel and serial */ default: break; @@ -98,9 +80,10 @@ static void superio_ioport_writeb(void *opaque, hwaddr addr, uint64_t data, static uint64_t superio_ioport_readb(void *opaque, hwaddr addr, unsigned size) { SuperIOConfig *superio_conf = opaque; +uint8_t val = superio_conf->config[superio_conf->index]; -DPRINTF("superio_ioport_readb address 0x%x\n", addr); -return superio_conf->config[superio_conf->index]; +trace_via_superio_read(superio_conf->index, val); +return val; } static const MemoryRegionOps superio_ops = { @@ -141,16 +124,14 @@ static void vt82c686b_isa_reset(DeviceState *dev) } /* write config pci function0 registers. PCI-ISA bridge */ -static void vt82c686b_write_config(PCIDevice *d, uint32_t address, +static void vt82c686b_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int len) { VT82C686BISAState *vt686 = VT82C686B_ISA(d); -DPRINTF("vt82c686b_write_config address 0x%x val 0x%x len 0x%x\n", - address, val, len); - -pci_default_write_config(d, address, val, len); -if (address == 0x85) { /* enable or disable super IO configure */ +trace_via_isa_write(addr, val, len); +pci_default_write_config(d, addr, val, len); +if (addr == 0x85) { /* enable or disable super IO configure */ memory_region_set_enabled(>superio, val & 0x2); } } @@ -203,12 +184,10 @@ static void pm_io_space_update(VT686PMState *s) memory_region_transaction_commit(); } -static void pm_write_config(PCIDevice *d, -uint32_t address, uint32_t val, int len) +static void pm_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int len) { -DPRINTF("pm_write_config address 0x%x val 0x%x len 0x%x\n", - address, val, len); -pci_default_write_config(d, address, val, len); +trace_via_pm_write(addr, val, len); +
[PATCH 21/24] vt82c686: Implement control of serial port io ranges via config regs
In VIA super south bridge the io ranges of superio components (parallel and serial ports and FDC) can be controlled by superio config registers to set their base address and enable/disable them. This is not easy to implement in QEMU because ISA emulation is only designed to set io base address once on creating the device and io ranges are registered at creation and cannot easily be disabled or moved later. In this patch we hack around that but only for serial ports because those have a single io range at port base that's relatively easy to handle and it's what guests actually use and set address different than the default. We do not attempt to handle controlling the parallel and FDC regions because those have multiple io ranges so handling them would be messy and guests either don't change their deafult or don't care. We could even get away with disabling and not emulating them, but since they are already there, this patch leaves them mapped at their default address just in case this could be useful for a guest in the future. Signed-off-by: BALATON Zoltan --- hw/isa/vt82c686.c | 84 +-- 1 file changed, 82 insertions(+), 2 deletions(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index 1a876a1fbf..26db1a18e2 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -252,8 +252,24 @@ static const TypeInfo vt8231_pm_info = { typedef struct SuperIOConfig { uint8_t regs[0x100]; MemoryRegion io; +ISASuperIODevice *superio; +MemoryRegion *serial_io[SUPERIO_MAX_SERIAL_PORTS]; } SuperIOConfig; +static MemoryRegion *find_subregion(ISADevice *d, MemoryRegion *parent, +int offs) +{ +MemoryRegion *subregion, *mr = NULL; + +QTAILQ_FOREACH(subregion, >subregions, subregions_link) { +if (subregion->addr == offs) { +mr = subregion; +break; +} +} +return mr; +} + static void superio_cfg_write(void *opaque, hwaddr addr, uint64_t data, unsigned size) { @@ -279,7 +295,53 @@ static void superio_cfg_write(void *opaque, hwaddr addr, uint64_t data, case 0xfd ... 0xff: /* ignore write to read only registers */ return; -/* case 0xe6 ... 0xe8: Should set base port of parallel and serial */ +case 0xe2: +{ +data &= 0x1f; +if (data & BIT(2)) { /* Serial port 1 enable */ +ISADevice *dev = sc->superio->serial[0]; +if (!memory_region_is_mapped(sc->serial_io[0])) { +memory_region_add_subregion(isa_address_space_io(dev), +dev->ioport_id, sc->serial_io[0]); +} +} else { +MemoryRegion *io = isa_address_space_io(sc->superio->serial[0]); +if (memory_region_is_mapped(sc->serial_io[0])) { +memory_region_del_subregion(io, sc->serial_io[0]); +} +} +if (data & BIT(3)) { /* Serial port 2 enable */ +ISADevice *dev = sc->superio->serial[1]; +if (!memory_region_is_mapped(sc->serial_io[1])) { +memory_region_add_subregion(isa_address_space_io(dev), +dev->ioport_id, sc->serial_io[1]); +} +} else { +MemoryRegion *io = isa_address_space_io(sc->superio->serial[1]); +if (memory_region_is_mapped(sc->serial_io[1])) { +memory_region_del_subregion(io, sc->serial_io[1]); +} +} +break; +} +case 0xe7: /* Serial port 1 io base address */ +{ +data &= 0xfe; +sc->superio->serial[0]->ioport_id = data << 2; +if (memory_region_is_mapped(sc->serial_io[0])) { +memory_region_set_address(sc->serial_io[0], data << 2); +} +break; +} +case 0xe8: /* Serial port 2 io base address */ +{ +data &= 0xfe; +sc->superio->serial[1]->ioport_id = data << 2; +if (memory_region_is_mapped(sc->serial_io[1])) { +memory_region_set_address(sc->serial_io[1], data << 2); +} +break; +} default: qemu_log_mask(LOG_UNIMP, "via_superio_cfg: unimplemented register 0x%x\n", idx); @@ -385,6 +447,7 @@ static void vt82c686b_realize(PCIDevice *d, Error **errp) DeviceState *dev = DEVICE(d); ISABus *isa_bus; qemu_irq *isa_irq; +ISASuperIOClass *ic; int i; qdev_init_gpio_out(dev, >cpu_intr, 1); @@ -394,7 +457,9 @@ static void vt82c686b_realize(PCIDevice *d, Error **errp) isa_bus_irqs(isa_bus, i8259_init(isa_bus, *isa_irq)); i8254_pit_init(isa_bus, 0x40, 0, NULL); i8257_dma_init(isa_bus, 0); -isa_create_simple(isa_bus, TYPE_VT82C686B_SUPERIO); +s->superio_cfg.superio = ISA_SUPERIO(isa_create_simple(isa_bus, + TYPE_VT82C686B_SUPERIO)); +ic =
[PATCH 00/24] vt82c686b clean ups and vt8231 emulation - all in one
Hello, This is an all in one series containing all the patches from my previous part I and part II vt82c686b clean up series plus the end of it to finally add vt8231 emulation that will be used by subsequent ppc/pegasos2 emulation. I consider this finished for now and good enough to get in also cleaning up and improving fuloong2e emulation a bit but previous disclaimer is still valid: It does not aim to fix all existing bugs or make the model perfectly emulate the real chip just reach the level where we can have working emulation to boot guests which can then be improved later. (E.g. I think state saving was broken before and it remains broken after because I don't know all the details how to add vmstate for all kinds of data structures and this could be addressed separately when fixing the already broken state saving if someone wants to test and fix it.) With this it boots at least MorphOS on pegasos2 and works with the pmon_2e.bin for fuloong2e which needs more fixes for Linux that are currently under review. More testing is welcome. It still needs the Bonito BONITO_PCICONF_REG_MASK fix for fuloong2e because it no longer maps SMBus but due to the Bonito bug guest cannot write register 0xd2 to map it. With that fix pmon_2e.bin from here: http://www.anheng.com.cn/loongson/pmon/ works for me with this command: qemu-system-mips64el -M fuloong2e -net none -bios pmon_2e.bin After rolling this for two years now I hope it can finally be merged and eventually also get pegasos2 emulation that will need this. Regards, BALATON Zoltan BALATON Zoltan (24): vt82c686: Rename AC97/MC97 parts from VT82C686B to VIA vt82c686: Remove unnecessary _DEVICE suffix from type macros vt82c686b: Rename VT82C686B to VT82C686B_ISA vt82c686: Remove vt82c686b_[am]c97_init() functions vt82c686: Split off via-[am]c97 into separate file in hw/audio audio/via-ac97: Simplify code and set user_creatable to false vt82c686: Remove legacy vt82c686b_isa_init() function vt82c686: Remove legacy vt82c686b_pm_init() function vt82c686: Convert debug printf to trace points vt82c686: Remove unneeded includes and defines vt82c686: Use shorter name for local variable holding object state vt82c686: Rename superio config related parts vt82c686: Move superio memory region to SuperIOConfig struct vt82c686: Reorganise code vt82c686: Fix SMBus IO base and configuration registers vt82c686: Fix up power management io base and config vt82c686: Make vt82c686b-pm an abstract base class and add vt8231-pm based on it vt82c686: Simplify vt82c686b_realize() vt82c686: Move creation of ISA devices to the ISA bridge vt82c686: Fix superio_cfg_{read,write}() functions vt82c686: Implement control of serial port io ranges via config regs vt82c686: QOM-ify superio related functionality vt82c686: Add VT8231_SUPERIO based on VIA_SUPERIO vt82c686: Add emulation of VT8231 south bridge hw/audio/meson.build |1 + hw/audio/via-ac97.c | 93 hw/isa/trace-events |8 + hw/isa/vt82c686.c | 1000 - hw/mips/fuloong2e.c | 38 +- include/hw/isa/vt82c686.h | 15 +- 6 files changed, 761 insertions(+), 394 deletions(-) create mode 100644 hw/audio/via-ac97.c -- 2.21.3
[PATCH 17/24] vt82c686: Make vt82c686b-pm an abstract base class and add vt8231-pm based on it
The vt82c686b-pm model can be shared between VT82C686B and VT8231. The only difference between the two is the device id in what we emulate so make an abstract via-pm model by renaming appropriately and add types for vt82c686b-pm and vt8231-pm based on it. Signed-off-by: BALATON Zoltan --- hw/isa/vt82c686.c | 87 ++- include/hw/isa/vt82c686.h | 1 + 2 files changed, 59 insertions(+), 29 deletions(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index fc2a1f4430..a989e29fe5 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -27,9 +27,10 @@ #include "exec/address-spaces.h" #include "trace.h" -OBJECT_DECLARE_SIMPLE_TYPE(VT686PMState, VT82C686B_PM) +#define TYPE_VIA_PM "via-pm" +OBJECT_DECLARE_SIMPLE_TYPE(ViaPMState, VIA_PM) -struct VT686PMState { +struct ViaPMState { PCIDevice dev; MemoryRegion io; ACPIREGS ar; @@ -37,7 +38,7 @@ struct VT686PMState { PMSMBus smb; }; -static void pm_io_space_update(VT686PMState *s) +static void pm_io_space_update(ViaPMState *s) { uint32_t pmbase = pci_get_long(s->dev.config + 0x48) & 0xff80UL; @@ -47,7 +48,7 @@ static void pm_io_space_update(VT686PMState *s) memory_region_transaction_commit(); } -static void smb_io_space_update(VT686PMState *s) +static void smb_io_space_update(ViaPMState *s) { uint32_t smbase = pci_get_long(s->dev.config + 0x90) & 0xfff0UL; @@ -59,7 +60,7 @@ static void smb_io_space_update(VT686PMState *s) static int vmstate_acpi_post_load(void *opaque, int version_id) { -VT686PMState *s = opaque; +ViaPMState *s = opaque; pm_io_space_update(s); smb_io_space_update(s); @@ -72,20 +73,20 @@ static const VMStateDescription vmstate_acpi = { .minimum_version_id = 1, .post_load = vmstate_acpi_post_load, .fields = (VMStateField[]) { -VMSTATE_PCI_DEVICE(dev, VT686PMState), -VMSTATE_UINT16(ar.pm1.evt.sts, VT686PMState), -VMSTATE_UINT16(ar.pm1.evt.en, VT686PMState), -VMSTATE_UINT16(ar.pm1.cnt.cnt, VT686PMState), -VMSTATE_STRUCT(apm, VT686PMState, 0, vmstate_apm, APMState), -VMSTATE_TIMER_PTR(ar.tmr.timer, VT686PMState), -VMSTATE_INT64(ar.tmr.overflow_time, VT686PMState), +VMSTATE_PCI_DEVICE(dev, ViaPMState), +VMSTATE_UINT16(ar.pm1.evt.sts, ViaPMState), +VMSTATE_UINT16(ar.pm1.evt.en, ViaPMState), +VMSTATE_UINT16(ar.pm1.cnt.cnt, ViaPMState), +VMSTATE_STRUCT(apm, ViaPMState, 0, vmstate_apm, APMState), +VMSTATE_TIMER_PTR(ar.tmr.timer, ViaPMState), +VMSTATE_INT64(ar.tmr.overflow_time, ViaPMState), VMSTATE_END_OF_LIST() } }; static void pm_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int len) { -VT686PMState *s = VT82C686B_PM(d); +ViaPMState *s = VIA_PM(d); trace_via_pm_write(addr, val, len); pci_default_write_config(d, addr, val, len); @@ -127,7 +128,7 @@ static const MemoryRegionOps pm_io_ops = { }, }; -static void pm_update_sci(VT686PMState *s) +static void pm_update_sci(ViaPMState *s) { int sci_level, pmsts; @@ -145,13 +146,13 @@ static void pm_update_sci(VT686PMState *s) static void pm_tmr_timer(ACPIREGS *ar) { -VT686PMState *s = container_of(ar, VT686PMState, ar); +ViaPMState *s = container_of(ar, ViaPMState, ar); pm_update_sci(s); } -static void vt82c686b_pm_reset(DeviceState *d) +static void via_pm_reset(DeviceState *d) { -VT686PMState *s = VT82C686B_PM(d); +ViaPMState *s = VIA_PM(d); memset(s->dev.config + PCI_CONFIG_HEADER_SIZE, 0, PCI_CONFIG_SPACE_SIZE - PCI_CONFIG_HEADER_SIZE); @@ -164,9 +165,9 @@ static void vt82c686b_pm_reset(DeviceState *d) smb_io_space_update(s); } -static void vt82c686b_pm_realize(PCIDevice *dev, Error **errp) +static void via_pm_realize(PCIDevice *dev, Error **errp) { -VT686PMState *s = VT82C686B_PM(dev); +ViaPMState *s = VIA_PM(dev); pci_set_word(dev->config + PCI_STATUS, PCI_STATUS_FAST_BACK | PCI_STATUS_DEVSEL_MEDIUM); @@ -177,8 +178,7 @@ static void vt82c686b_pm_realize(PCIDevice *dev, Error **errp) apm_init(dev, >apm, NULL, s); -memory_region_init_io(>io, OBJECT(dev), _io_ops, s, - "vt82c686-pm", 0x100); +memory_region_init_io(>io, OBJECT(dev), _io_ops, s, "via-pm", 0x100); memory_region_add_subregion(pci_address_space_io(dev), 0, >io); memory_region_set_enabled(>io, false); @@ -187,34 +187,61 @@ static void vt82c686b_pm_realize(PCIDevice *dev, Error **errp) acpi_pm1_cnt_init(>ar, >io, false, false, 2); } +typedef struct via_pm_init_info { +uint16_t device_id; +} ViaPMInitInfo; + static void via_pm_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); +ViaPMInitInfo *info = data; -k->realize = vt82c686b_pm_realize; +k->realize = via_pm_realize;
[PATCH 11/24] vt82c686: Use shorter name for local variable holding object state
Rename local variable holding object state for readability and consistency. Signed-off-by: BALATON Zoltan --- hw/isa/vt82c686.c | 30 +++--- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index 02d6759c00..2633cfe7dc 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -95,8 +95,8 @@ static const MemoryRegionOps superio_ops = { static void vt82c686b_isa_reset(DeviceState *dev) { -VT82C686BISAState *vt82c = VT82C686B_ISA(dev); -uint8_t *pci_conf = vt82c->dev.config; +VT82C686BISAState *s = VT82C686B_ISA(dev); +uint8_t *pci_conf = s->dev.config; pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x00c0); pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY | @@ -112,24 +112,24 @@ static void vt82c686b_isa_reset(DeviceState *dev) pci_conf[0x5f] = 0x04; pci_conf[0x77] = 0x10; /* GPIO Control 1/2/3/4 */ -vt82c->superio_conf.config[0xe0] = 0x3c; -vt82c->superio_conf.config[0xe2] = 0x03; -vt82c->superio_conf.config[0xe3] = 0xfc; -vt82c->superio_conf.config[0xe6] = 0xde; -vt82c->superio_conf.config[0xe7] = 0xfe; -vt82c->superio_conf.config[0xe8] = 0xbe; +s->superio_conf.config[0xe0] = 0x3c; +s->superio_conf.config[0xe2] = 0x03; +s->superio_conf.config[0xe3] = 0xfc; +s->superio_conf.config[0xe6] = 0xde; +s->superio_conf.config[0xe7] = 0xfe; +s->superio_conf.config[0xe8] = 0xbe; } /* write config pci function0 registers. PCI-ISA bridge */ static void vt82c686b_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int len) { -VT82C686BISAState *vt686 = VT82C686B_ISA(d); +VT82C686BISAState *s = VT82C686B_ISA(d); trace_via_isa_write(addr, val, len); pci_default_write_config(d, addr, val, len); if (addr == 0x85) { /* enable or disable super IO configure */ -memory_region_set_enabled(>superio, val & 0x2); +memory_region_set_enabled(>superio, val & 0x2); } } @@ -289,7 +289,7 @@ static const VMStateDescription vmstate_via = { /* init the PCI-to-ISA bridge */ static void vt82c686b_realize(PCIDevice *d, Error **errp) { -VT82C686BISAState *vt82c = VT82C686B_ISA(d); +VT82C686BISAState *s = VT82C686B_ISA(d); uint8_t *pci_conf; ISABus *isa_bus; uint8_t *wmask; @@ -311,15 +311,15 @@ static void vt82c686b_realize(PCIDevice *d, Error **errp) } } -memory_region_init_io(>superio, OBJECT(d), _ops, - >superio_conf, "superio", 2); -memory_region_set_enabled(>superio, false); +memory_region_init_io(>superio, OBJECT(d), _ops, + >superio_conf, "superio", 2); +memory_region_set_enabled(>superio, false); /* * The floppy also uses 0x3f0 and 0x3f1. * But we do not emulate a floppy, so just set it here. */ memory_region_add_subregion(isa_bus->address_space_io, 0x3f0, ->superio); +>superio); } static void via_class_init(ObjectClass *klass, void *data) -- 2.21.3
[PATCH 02/24] vt82c686: Remove unnecessary _DEVICE suffix from type macros
There's no reason to suffix everything with _DEVICE when the names are already unique without it and shorter names are more readable. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé --- hw/isa/vt82c686.c | 48 +++ 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index 2a0f85dea9..1be1169f83 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -49,8 +49,8 @@ struct VT82C686BState { SuperIOConfig superio_conf; }; -#define TYPE_VT82C686B_DEVICE "VT82C686B" -OBJECT_DECLARE_SIMPLE_TYPE(VT82C686BState, VT82C686B_DEVICE) +#define TYPE_VT82C686B "VT82C686B" +OBJECT_DECLARE_SIMPLE_TYPE(VT82C686BState, VT82C686B) static void superio_ioport_writeb(void *opaque, hwaddr addr, uint64_t data, unsigned size) @@ -117,7 +117,7 @@ static const MemoryRegionOps superio_ops = { static void vt82c686b_isa_reset(DeviceState *dev) { -VT82C686BState *vt82c = VT82C686B_DEVICE(dev); +VT82C686BState *vt82c = VT82C686B(dev); uint8_t *pci_conf = vt82c->dev.config; pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x00c0); @@ -146,7 +146,7 @@ static void vt82c686b_isa_reset(DeviceState *dev) static void vt82c686b_write_config(PCIDevice *d, uint32_t address, uint32_t val, int len) { -VT82C686BState *vt686 = VT82C686B_DEVICE(d); +VT82C686BState *vt686 = VT82C686B(d); DPRINTF("vt82c686b_write_config address 0x%x val 0x%x len 0x%x\n", address, val, len); @@ -176,14 +176,14 @@ struct VIAMC97State { PCIDevice dev; }; -#define TYPE_VT82C686B_PM_DEVICE "VT82C686B_PM" -OBJECT_DECLARE_SIMPLE_TYPE(VT686PMState, VT82C686B_PM_DEVICE) +#define TYPE_VT82C686B_PM "VT82C686B_PM" +OBJECT_DECLARE_SIMPLE_TYPE(VT686PMState, VT82C686B_PM) -#define TYPE_VIA_MC97_DEVICE "VIA_MC97" -OBJECT_DECLARE_SIMPLE_TYPE(VIAMC97State, VIA_MC97_DEVICE) +#define TYPE_VIA_MC97 "VIA_MC97" +OBJECT_DECLARE_SIMPLE_TYPE(VIAMC97State, VIA_MC97) -#define TYPE_VIA_AC97_DEVICE "VIA_AC97" -OBJECT_DECLARE_SIMPLE_TYPE(VIAAC97State, VIA_AC97_DEVICE) +#define TYPE_VIA_AC97 "VIA_AC97" +OBJECT_DECLARE_SIMPLE_TYPE(VIAAC97State, VIA_AC97) static void pm_update_sci(VT686PMState *s) { @@ -260,7 +260,7 @@ static const VMStateDescription vmstate_acpi = { static void vt82c686b_ac97_realize(PCIDevice *dev, Error **errp) { -VIAAC97State *s = VIA_AC97_DEVICE(dev); +VIAAC97State *s = VIA_AC97(dev); uint8_t *pci_conf = s->dev.config; pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_INVALIDATE | @@ -274,7 +274,7 @@ void vt82c686b_ac97_init(PCIBus *bus, int devfn) { PCIDevice *dev; -dev = pci_new(devfn, TYPE_VIA_AC97_DEVICE); +dev = pci_new(devfn, TYPE_VIA_AC97); pci_realize_and_unref(dev, bus, _fatal); } @@ -293,7 +293,7 @@ static void via_ac97_class_init(ObjectClass *klass, void *data) } static const TypeInfo via_ac97_info = { -.name = TYPE_VIA_AC97_DEVICE, +.name = TYPE_VIA_AC97, .parent= TYPE_PCI_DEVICE, .instance_size = sizeof(VIAAC97State), .class_init= via_ac97_class_init, @@ -305,7 +305,7 @@ static const TypeInfo via_ac97_info = { static void vt82c686b_mc97_realize(PCIDevice *dev, Error **errp) { -VIAMC97State *s = VIA_MC97_DEVICE(dev); +VIAMC97State *s = VIA_MC97(dev); uint8_t *pci_conf = s->dev.config; pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_INVALIDATE | @@ -318,7 +318,7 @@ void vt82c686b_mc97_init(PCIBus *bus, int devfn) { PCIDevice *dev; -dev = pci_new(devfn, TYPE_VIA_MC97_DEVICE); +dev = pci_new(devfn, TYPE_VIA_MC97); pci_realize_and_unref(dev, bus, _fatal); } @@ -337,7 +337,7 @@ static void via_mc97_class_init(ObjectClass *klass, void *data) } static const TypeInfo via_mc97_info = { -.name = TYPE_VIA_MC97_DEVICE, +.name = TYPE_VIA_MC97, .parent= TYPE_PCI_DEVICE, .instance_size = sizeof(VIAMC97State), .class_init= via_mc97_class_init, @@ -350,7 +350,7 @@ static const TypeInfo via_mc97_info = { /* vt82c686 pm init */ static void vt82c686b_pm_realize(PCIDevice *dev, Error **errp) { -VT686PMState *s = VT82C686B_PM_DEVICE(dev); +VT686PMState *s = VT82C686B_PM(dev); uint8_t *pci_conf; pci_conf = s->dev.config; @@ -386,10 +386,10 @@ I2CBus *vt82c686b_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, PCIDevice *dev; VT686PMState *s; -dev = pci_new(devfn, TYPE_VT82C686B_PM_DEVICE); +dev = pci_new(devfn, TYPE_VT82C686B_PM); qdev_prop_set_uint32(>qdev, "smb_io_base", smb_io_base); -s = VT82C686B_PM_DEVICE(dev); +s = VT82C686B_PM(dev); pci_realize_and_unref(dev, bus, _fatal); @@ -419,7 +419,7 @@ static void via_pm_class_init(ObjectClass *klass, void *data) } static const TypeInfo via_pm_info = { -.name =
[PATCH 12/24] vt82c686: Rename superio config related parts
Use less confusing naming for superio config register handling related parts that makes it clearer what belongs to this part. Signed-off-by: BALATON Zoltan --- hw/isa/vt82c686.c | 48 +++ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index 2633cfe7dc..a6f5a0843d 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -27,7 +27,7 @@ #include "trace.h" typedef struct SuperIOConfig { -uint8_t config[0x100]; +uint8_t regs[0x100]; uint8_t index; uint8_t data; } SuperIOConfig; @@ -35,23 +35,23 @@ typedef struct SuperIOConfig { struct VT82C686BISAState { PCIDevice dev; MemoryRegion superio; -SuperIOConfig superio_conf; +SuperIOConfig superio_cfg; }; OBJECT_DECLARE_SIMPLE_TYPE(VT82C686BISAState, VT82C686B_ISA) -static void superio_ioport_writeb(void *opaque, hwaddr addr, uint64_t data, - unsigned size) +static void superio_cfg_write(void *opaque, hwaddr addr, uint64_t data, + unsigned size) { -SuperIOConfig *superio_conf = opaque; +SuperIOConfig *sc = opaque; if (addr == 0x3f0) { /* config index register */ -superio_conf->index = data & 0xff; +sc->index = data & 0xff; } else { bool can_write = true; /* 0x3f1, config data register */ -trace_via_superio_write(superio_conf->index, data & 0xff); -switch (superio_conf->index) { +trace_via_superio_write(sc->index, data & 0xff); +switch (sc->index) { case 0x00 ... 0xdf: case 0xe4: case 0xe5: @@ -69,23 +69,23 @@ static void superio_ioport_writeb(void *opaque, hwaddr addr, uint64_t data, } if (can_write) { -superio_conf->config[superio_conf->index] = data & 0xff; +sc->regs[sc->index] = data & 0xff; } } } -static uint64_t superio_ioport_readb(void *opaque, hwaddr addr, unsigned size) +static uint64_t superio_cfg_read(void *opaque, hwaddr addr, unsigned size) { -SuperIOConfig *superio_conf = opaque; -uint8_t val = superio_conf->config[superio_conf->index]; +SuperIOConfig *sc = opaque; +uint8_t val = sc->regs[sc->index]; -trace_via_superio_read(superio_conf->index, val); +trace_via_superio_read(sc->index, val); return val; } -static const MemoryRegionOps superio_ops = { -.read = superio_ioport_readb, -.write = superio_ioport_writeb, +static const MemoryRegionOps superio_cfg_ops = { +.read = superio_cfg_read, +.write = superio_cfg_write, .endianness = DEVICE_NATIVE_ENDIAN, .impl = { .min_access_size = 1, @@ -112,12 +112,12 @@ static void vt82c686b_isa_reset(DeviceState *dev) pci_conf[0x5f] = 0x04; pci_conf[0x77] = 0x10; /* GPIO Control 1/2/3/4 */ -s->superio_conf.config[0xe0] = 0x3c; -s->superio_conf.config[0xe2] = 0x03; -s->superio_conf.config[0xe3] = 0xfc; -s->superio_conf.config[0xe6] = 0xde; -s->superio_conf.config[0xe7] = 0xfe; -s->superio_conf.config[0xe8] = 0xbe; +s->superio_cfg.regs[0xe0] = 0x3c; /* Device ID */ +s->superio_cfg.regs[0xe2] = 0x03; /* Function select */ +s->superio_cfg.regs[0xe3] = 0xfc; /* Floppy ctrl base addr */ +s->superio_cfg.regs[0xe6] = 0xde; /* Parallel port base addr */ +s->superio_cfg.regs[0xe7] = 0xfe; /* Serial port 1 base addr */ +s->superio_cfg.regs[0xe8] = 0xbe; /* Serial port 2 base addr */ } /* write config pci function0 registers. PCI-ISA bridge */ @@ -311,8 +311,8 @@ static void vt82c686b_realize(PCIDevice *d, Error **errp) } } -memory_region_init_io(>superio, OBJECT(d), _ops, - >superio_conf, "superio", 2); +memory_region_init_io(>superio, OBJECT(d), _cfg_ops, + >superio_cfg, "superio", 2); memory_region_set_enabled(>superio, false); /* * The floppy also uses 0x3f0 and 0x3f1. -- 2.21.3
[PATCH 08/24] vt82c686: Remove legacy vt82c686b_pm_init() function
Remove legacy vt82c686b_pm_init() function and also rename VT82C686B_PM type name to match other device names. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé --- hw/isa/vt82c686.c | 18 -- hw/mips/fuloong2e.c | 5 - include/hw/isa/vt82c686.h | 5 + 3 files changed, 5 insertions(+), 23 deletions(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index 2912c253dc..cd87ec0103 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -12,7 +12,6 @@ #include "qemu/osdep.h" #include "hw/isa/vt82c686.h" -#include "hw/i2c/i2c.h" #include "hw/pci/pci.h" #include "hw/qdev-properties.h" #include "hw/isa/isa.h" @@ -167,7 +166,6 @@ struct VT686PMState { uint32_t smb_io_base; }; -#define TYPE_VT82C686B_PM "VT82C686B_PM" OBJECT_DECLARE_SIMPLE_TYPE(VT686PMState, VT82C686B_PM) static void pm_update_sci(VT686PMState *s) @@ -271,22 +269,6 @@ static void vt82c686b_pm_realize(PCIDevice *dev, Error **errp) acpi_pm1_cnt_init(>ar, >io, false, false, 2); } -I2CBus *vt82c686b_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, - qemu_irq sci_irq) -{ -PCIDevice *dev; -VT686PMState *s; - -dev = pci_new(devfn, TYPE_VT82C686B_PM); -qdev_prop_set_uint32(>qdev, "smb_io_base", smb_io_base); - -s = VT82C686B_PM(dev); - -pci_realize_and_unref(dev, bus, _fatal); - -return s->smb.smbus; -} - static Property via_pm_properties[] = { DEFINE_PROP_UINT32("smb_io_base", VT686PMState, smb_io_base, 0), DEFINE_PROP_END_OF_LIST(), diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c index fe191e8a9c..f393509633 100644 --- a/hw/mips/fuloong2e.c +++ b/hw/mips/fuloong2e.c @@ -263,7 +263,10 @@ static void vt82c686b_southbridge_init(PCIBus *pci_bus, int slot, qemu_irq intc, pci_create_simple(pci_bus, PCI_DEVFN(slot, 2), "vt82c686b-usb-uhci"); pci_create_simple(pci_bus, PCI_DEVFN(slot, 3), "vt82c686b-usb-uhci"); -*i2c_bus = vt82c686b_pm_init(pci_bus, PCI_DEVFN(slot, 4), 0xeee1, NULL); +dev = pci_new(PCI_DEVFN(slot, 4), TYPE_VT82C686B_PM); +qdev_prop_set_uint32(DEVICE(dev), "smb_io_base", 0xeee1); +pci_realize_and_unref(dev, pci_bus, _fatal); +*i2c_bus = I2C_BUS(qdev_get_child_bus(DEVICE(dev), "i2c")); /* Audio support */ pci_create_simple(pci_bus, PCI_DEVFN(slot, 5), TYPE_VIA_AC97); diff --git a/include/hw/isa/vt82c686.h b/include/hw/isa/vt82c686.h index 8d2d276fe1..5b0a1ffe72 100644 --- a/include/hw/isa/vt82c686.h +++ b/include/hw/isa/vt82c686.h @@ -3,11 +3,8 @@ #define TYPE_VT82C686B_ISA "vt82c686b-isa" #define TYPE_VT82C686B_SUPERIO "vt82c686b-superio" +#define TYPE_VT82C686B_PM "vt82c686b-pm" #define TYPE_VIA_AC97 "via-ac97" #define TYPE_VIA_MC97 "via-mc97" -/* vt82c686.c */ -I2CBus *vt82c686b_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, - qemu_irq sci_irq); - #endif -- 2.21.3
[PATCH 06/24] audio/via-ac97: Simplify code and set user_creatable to false
Remove some unneded, empty code and set user_creatable to false (besides being not implemented yet, so does nothing anyway) it's also normally part of VIA south bridge chips so no need to confuse users showing them these devices. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé --- hw/audio/via-ac97.c | 51 + 1 file changed, 19 insertions(+), 32 deletions(-) diff --git a/hw/audio/via-ac97.c b/hw/audio/via-ac97.c index e617416ff7..6d556f74fc 100644 --- a/hw/audio/via-ac97.c +++ b/hw/audio/via-ac97.c @@ -13,27 +13,13 @@ #include "hw/isa/vt82c686.h" #include "hw/pci/pci.h" -struct VIAAC97State { -PCIDevice dev; -}; - -struct VIAMC97State { -PCIDevice dev; -}; - -OBJECT_DECLARE_SIMPLE_TYPE(VIAAC97State, VIA_AC97) -OBJECT_DECLARE_SIMPLE_TYPE(VIAMC97State, VIA_MC97) - -static void via_ac97_realize(PCIDevice *dev, Error **errp) +static void via_ac97_realize(PCIDevice *pci_dev, Error **errp) { -VIAAC97State *s = VIA_AC97(dev); -uint8_t *pci_conf = s->dev.config; - -pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_INVALIDATE | - PCI_COMMAND_PARITY); -pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_CAP_LIST | - PCI_STATUS_DEVSEL_MEDIUM); -pci_set_long(pci_conf + PCI_INTERRUPT_PIN, 0x03); +pci_set_word(pci_dev->config + PCI_COMMAND, + PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY); +pci_set_word(pci_dev->config + PCI_STATUS, + PCI_STATUS_CAP_LIST | PCI_STATUS_DEVSEL_MEDIUM); +pci_set_long(pci_dev->config + PCI_INTERRUPT_PIN, 0x03); } static void via_ac97_class_init(ObjectClass *klass, void *data) @@ -47,13 +33,15 @@ static void via_ac97_class_init(ObjectClass *klass, void *data) k->revision = 0x50; k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO; set_bit(DEVICE_CATEGORY_SOUND, dc->categories); -dc->desc = "AC97"; +dc->desc = "VIA AC97"; +/* Reason: Part of a south bridge chip */ +dc->user_creatable = false; } static const TypeInfo via_ac97_info = { .name = TYPE_VIA_AC97, .parent= TYPE_PCI_DEVICE, -.instance_size = sizeof(VIAAC97State), +.instance_size = sizeof(PCIDevice), .class_init= via_ac97_class_init, .interfaces = (InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, @@ -61,15 +49,12 @@ static const TypeInfo via_ac97_info = { }, }; -static void via_mc97_realize(PCIDevice *dev, Error **errp) +static void via_mc97_realize(PCIDevice *pci_dev, Error **errp) { -VIAMC97State *s = VIA_MC97(dev); -uint8_t *pci_conf = s->dev.config; - -pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_INVALIDATE | - PCI_COMMAND_VGA_PALETTE); -pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM); -pci_set_long(pci_conf + PCI_INTERRUPT_PIN, 0x03); +pci_set_word(pci_dev->config + PCI_COMMAND, + PCI_COMMAND_INVALIDATE | PCI_COMMAND_VGA_PALETTE); +pci_set_word(pci_dev->config + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM); +pci_set_long(pci_dev->config + PCI_INTERRUPT_PIN, 0x03); } static void via_mc97_class_init(ObjectClass *klass, void *data) @@ -83,13 +68,15 @@ static void via_mc97_class_init(ObjectClass *klass, void *data) k->class_id = PCI_CLASS_COMMUNICATION_OTHER; k->revision = 0x30; set_bit(DEVICE_CATEGORY_NETWORK, dc->categories); -dc->desc = "MC97"; +dc->desc = "VIA MC97"; +/* Reason: Part of a south bridge chip */ +dc->user_creatable = false; } static const TypeInfo via_mc97_info = { .name = TYPE_VIA_MC97, .parent= TYPE_PCI_DEVICE, -.instance_size = sizeof(VIAMC97State), +.instance_size = sizeof(PCIDevice), .class_init= via_mc97_class_init, .interfaces = (InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, -- 2.21.3
[PATCH 05/24] vt82c686: Split off via-[am]c97 into separate file in hw/audio
The via-[am]c97 code is supposed to implement the audio part of VIA south bridge chips so it is better placed under hw/audio/. Split it off into a separate file. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé --- hw/audio/meson.build | 1 + hw/audio/via-ac97.c | 106 +++ hw/isa/vt82c686.c| 91 - 3 files changed, 107 insertions(+), 91 deletions(-) create mode 100644 hw/audio/via-ac97.c diff --git a/hw/audio/meson.build b/hw/audio/meson.build index 549e9a0396..32c42bdebe 100644 --- a/hw/audio/meson.build +++ b/hw/audio/meson.build @@ -11,4 +11,5 @@ softmmu_ss.add(when: 'CONFIG_MILKYMIST', if_true: files('milkymist-ac97.c')) softmmu_ss.add(when: 'CONFIG_PCSPK', if_true: files('pcspk.c')) softmmu_ss.add(when: 'CONFIG_PL041', if_true: files('pl041.c', 'lm4549.c')) softmmu_ss.add(when: 'CONFIG_SB16', if_true: files('sb16.c')) +softmmu_ss.add(when: 'CONFIG_VT82C686', if_true: files('via-ac97.c')) softmmu_ss.add(when: 'CONFIG_WM8750', if_true: files('wm8750.c')) diff --git a/hw/audio/via-ac97.c b/hw/audio/via-ac97.c new file mode 100644 index 00..e617416ff7 --- /dev/null +++ b/hw/audio/via-ac97.c @@ -0,0 +1,106 @@ +/* + * VIA south bridges sound support + * + * This work is licensed under the GNU GPL license version 2 or later. + */ + +/* + * TODO: This is entirely boiler plate just registering empty PCI devices + * with the right ID guests expect, functionality should be added here. + */ + +#include "qemu/osdep.h" +#include "hw/isa/vt82c686.h" +#include "hw/pci/pci.h" + +struct VIAAC97State { +PCIDevice dev; +}; + +struct VIAMC97State { +PCIDevice dev; +}; + +OBJECT_DECLARE_SIMPLE_TYPE(VIAAC97State, VIA_AC97) +OBJECT_DECLARE_SIMPLE_TYPE(VIAMC97State, VIA_MC97) + +static void via_ac97_realize(PCIDevice *dev, Error **errp) +{ +VIAAC97State *s = VIA_AC97(dev); +uint8_t *pci_conf = s->dev.config; + +pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_INVALIDATE | + PCI_COMMAND_PARITY); +pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_CAP_LIST | + PCI_STATUS_DEVSEL_MEDIUM); +pci_set_long(pci_conf + PCI_INTERRUPT_PIN, 0x03); +} + +static void via_ac97_class_init(ObjectClass *klass, void *data) +{ +DeviceClass *dc = DEVICE_CLASS(klass); +PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + +k->realize = via_ac97_realize; +k->vendor_id = PCI_VENDOR_ID_VIA; +k->device_id = PCI_DEVICE_ID_VIA_AC97; +k->revision = 0x50; +k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO; +set_bit(DEVICE_CATEGORY_SOUND, dc->categories); +dc->desc = "AC97"; +} + +static const TypeInfo via_ac97_info = { +.name = TYPE_VIA_AC97, +.parent= TYPE_PCI_DEVICE, +.instance_size = sizeof(VIAAC97State), +.class_init= via_ac97_class_init, +.interfaces = (InterfaceInfo[]) { +{ INTERFACE_CONVENTIONAL_PCI_DEVICE }, +{ }, +}, +}; + +static void via_mc97_realize(PCIDevice *dev, Error **errp) +{ +VIAMC97State *s = VIA_MC97(dev); +uint8_t *pci_conf = s->dev.config; + +pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_INVALIDATE | + PCI_COMMAND_VGA_PALETTE); +pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM); +pci_set_long(pci_conf + PCI_INTERRUPT_PIN, 0x03); +} + +static void via_mc97_class_init(ObjectClass *klass, void *data) +{ +DeviceClass *dc = DEVICE_CLASS(klass); +PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + +k->realize = via_mc97_realize; +k->vendor_id = PCI_VENDOR_ID_VIA; +k->device_id = PCI_DEVICE_ID_VIA_MC97; +k->class_id = PCI_CLASS_COMMUNICATION_OTHER; +k->revision = 0x30; +set_bit(DEVICE_CATEGORY_NETWORK, dc->categories); +dc->desc = "MC97"; +} + +static const TypeInfo via_mc97_info = { +.name = TYPE_VIA_MC97, +.parent= TYPE_PCI_DEVICE, +.instance_size = sizeof(VIAMC97State), +.class_init= via_mc97_class_init, +.interfaces = (InterfaceInfo[]) { +{ INTERFACE_CONVENTIONAL_PCI_DEVICE }, +{ }, +}, +}; + +static void via_ac97_register_types(void) +{ +type_register_static(_ac97_info); +type_register_static(_mc97_info); +} + +type_init(via_ac97_register_types) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index 8677a2d212..9567326d8e 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -168,14 +168,6 @@ struct VT686PMState { uint32_t smb_io_base; }; -struct VIAAC97State { -PCIDevice dev; -}; - -struct VIAMC97State { -PCIDevice dev; -}; - #define TYPE_VT82C686B_PM "VT82C686B_PM" OBJECT_DECLARE_SIMPLE_TYPE(VT686PMState, VT82C686B_PM) @@ -247,87 +239,6 @@ static const VMStateDescription vmstate_acpi = { } }; -/* - * TODO: VIA_AC97 and VIA_MC97 - * just register a PCI device now, functionalities will be implemented later. - */ - -OBJECT_DECLARE_SIMPLE_TYPE(VIAMC97State, VIA_MC97)
[PATCH 13/24] vt82c686: Move superio memory region to SuperIOConfig struct
The superio memory region holds the io space index/data registers used to access the superio config registers that are implemented in struct SuperIOConfig. To keep these related things together move the memory region to SuperIOConfig and rename it accordingly. Also remove the unused "data" member of SuperIOConfig which is not needed as we store actual data values in the regs array. Signed-off-by: BALATON Zoltan --- hw/isa/vt82c686.c | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index a6f5a0843d..30fe02f4c6 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -29,12 +29,11 @@ typedef struct SuperIOConfig { uint8_t regs[0x100]; uint8_t index; -uint8_t data; +MemoryRegion io; } SuperIOConfig; struct VT82C686BISAState { PCIDevice dev; -MemoryRegion superio; SuperIOConfig superio_cfg; }; @@ -128,8 +127,9 @@ static void vt82c686b_write_config(PCIDevice *d, uint32_t addr, trace_via_isa_write(addr, val, len); pci_default_write_config(d, addr, val, len); -if (addr == 0x85) { /* enable or disable super IO configure */ -memory_region_set_enabled(>superio, val & 0x2); +if (addr == 0x85) { +/* BIT(1): enable or disable superio config io ports */ +memory_region_set_enabled(>superio_cfg.io, val & BIT(1)); } } @@ -311,15 +311,15 @@ static void vt82c686b_realize(PCIDevice *d, Error **errp) } } -memory_region_init_io(>superio, OBJECT(d), _cfg_ops, - >superio_cfg, "superio", 2); -memory_region_set_enabled(>superio, false); +memory_region_init_io(>superio_cfg.io, OBJECT(d), _cfg_ops, + >superio_cfg, "superio_cfg", 2); +memory_region_set_enabled(>superio_cfg.io, false); /* * The floppy also uses 0x3f0 and 0x3f1. * But we do not emulate a floppy, so just set it here. */ memory_region_add_subregion(isa_bus->address_space_io, 0x3f0, ->superio); +>superio_cfg.io); } static void via_class_init(ObjectClass *klass, void *data) -- 2.21.3
[PATCH 03/24] vt82c686b: Rename VT82C686B to VT82C686B_ISA
This is really the ISA bridge part so name the type accordingly. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé --- hw/isa/vt82c686.c | 20 ++-- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index 1be1169f83..d40599c7da 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -43,14 +43,14 @@ typedef struct SuperIOConfig { uint8_t data; } SuperIOConfig; -struct VT82C686BState { +struct VT82C686BISAState { PCIDevice dev; MemoryRegion superio; SuperIOConfig superio_conf; }; -#define TYPE_VT82C686B "VT82C686B" -OBJECT_DECLARE_SIMPLE_TYPE(VT82C686BState, VT82C686B) +#define TYPE_VT82C686B_ISA "vt82c686b-isa" +OBJECT_DECLARE_SIMPLE_TYPE(VT82C686BISAState, VT82C686B_ISA) static void superio_ioport_writeb(void *opaque, hwaddr addr, uint64_t data, unsigned size) @@ -117,7 +117,7 @@ static const MemoryRegionOps superio_ops = { static void vt82c686b_isa_reset(DeviceState *dev) { -VT82C686BState *vt82c = VT82C686B(dev); +VT82C686BISAState *vt82c = VT82C686B_ISA(dev); uint8_t *pci_conf = vt82c->dev.config; pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x00c0); @@ -146,7 +146,7 @@ static void vt82c686b_isa_reset(DeviceState *dev) static void vt82c686b_write_config(PCIDevice *d, uint32_t address, uint32_t val, int len) { -VT82C686BState *vt686 = VT82C686B(d); +VT82C686BISAState *vt686 = VT82C686B_ISA(d); DPRINTF("vt82c686b_write_config address 0x%x val 0x%x len 0x%x\n", address, val, len); @@ -434,7 +434,7 @@ static const VMStateDescription vmstate_via = { .version_id = 1, .minimum_version_id = 1, .fields = (VMStateField[]) { -VMSTATE_PCI_DEVICE(dev, VT82C686BState), +VMSTATE_PCI_DEVICE(dev, VT82C686BISAState), VMSTATE_END_OF_LIST() } }; @@ -442,7 +442,7 @@ static const VMStateDescription vmstate_via = { /* init the PCI-to-ISA bridge */ static void vt82c686b_realize(PCIDevice *d, Error **errp) { -VT82C686BState *vt82c = VT82C686B(d); +VT82C686BISAState *vt82c = VT82C686B_ISA(d); uint8_t *pci_conf; ISABus *isa_bus; uint8_t *wmask; @@ -479,7 +479,7 @@ ISABus *vt82c686b_isa_init(PCIBus *bus, int devfn) { PCIDevice *d; -d = pci_create_simple_multifunction(bus, devfn, true, TYPE_VT82C686B); +d = pci_create_simple_multifunction(bus, devfn, true, TYPE_VT82C686B_ISA); return ISA_BUS(qdev_get_child_bus(DEVICE(d), "isa.0")); } @@ -505,9 +505,9 @@ static void via_class_init(ObjectClass *klass, void *data) } static const TypeInfo via_info = { -.name = TYPE_VT82C686B, +.name = TYPE_VT82C686B_ISA, .parent= TYPE_PCI_DEVICE, -.instance_size = sizeof(VT82C686BState), +.instance_size = sizeof(VT82C686BISAState), .class_init= via_class_init, .interfaces = (InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, -- 2.21.3
[PATCH 04/24] vt82c686: Remove vt82c686b_[am]c97_init() functions
These are legacy init functions that are just equivalent to directly calling pci_create_simple so do that instead. Also rename objects to lower case via-ac97 and via-mc97 matching naming of other devices. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé --- hw/isa/vt82c686.c | 27 --- hw/mips/fuloong2e.c | 4 ++-- include/hw/isa/vt82c686.h | 4 ++-- 3 files changed, 8 insertions(+), 27 deletions(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index d40599c7da..8677a2d212 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -179,12 +179,6 @@ struct VIAMC97State { #define TYPE_VT82C686B_PM "VT82C686B_PM" OBJECT_DECLARE_SIMPLE_TYPE(VT686PMState, VT82C686B_PM) -#define TYPE_VIA_MC97 "VIA_MC97" -OBJECT_DECLARE_SIMPLE_TYPE(VIAMC97State, VIA_MC97) - -#define TYPE_VIA_AC97 "VIA_AC97" -OBJECT_DECLARE_SIMPLE_TYPE(VIAAC97State, VIA_AC97) - static void pm_update_sci(VT686PMState *s) { int sci_level, pmsts; @@ -254,10 +248,13 @@ static const VMStateDescription vmstate_acpi = { }; /* - * TODO: vt82c686b_ac97_init() and vt82c686b_mc97_init() + * TODO: VIA_AC97 and VIA_MC97 * just register a PCI device now, functionalities will be implemented later. */ +OBJECT_DECLARE_SIMPLE_TYPE(VIAMC97State, VIA_MC97) +OBJECT_DECLARE_SIMPLE_TYPE(VIAAC97State, VIA_AC97) + static void vt82c686b_ac97_realize(PCIDevice *dev, Error **errp) { VIAAC97State *s = VIA_AC97(dev); @@ -270,14 +267,6 @@ static void vt82c686b_ac97_realize(PCIDevice *dev, Error **errp) pci_set_long(pci_conf + PCI_INTERRUPT_PIN, 0x03); } -void vt82c686b_ac97_init(PCIBus *bus, int devfn) -{ -PCIDevice *dev; - -dev = pci_new(devfn, TYPE_VIA_AC97); -pci_realize_and_unref(dev, bus, _fatal); -} - static void via_ac97_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -314,14 +303,6 @@ static void vt82c686b_mc97_realize(PCIDevice *dev, Error **errp) pci_set_long(pci_conf + PCI_INTERRUPT_PIN, 0x03); } -void vt82c686b_mc97_init(PCIBus *bus, int devfn) -{ -PCIDevice *dev; - -dev = pci_new(devfn, TYPE_VIA_MC97); -pci_realize_and_unref(dev, bus, _fatal); -} - static void via_mc97_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c index d334fde389..941d6642c3 100644 --- a/hw/mips/fuloong2e.c +++ b/hw/mips/fuloong2e.c @@ -264,8 +264,8 @@ static void vt82c686b_southbridge_init(PCIBus *pci_bus, int slot, qemu_irq intc, *i2c_bus = vt82c686b_pm_init(pci_bus, PCI_DEVFN(slot, 4), 0xeee1, NULL); /* Audio support */ -vt82c686b_ac97_init(pci_bus, PCI_DEVFN(slot, 5)); -vt82c686b_mc97_init(pci_bus, PCI_DEVFN(slot, 6)); +pci_create_simple(pci_bus, PCI_DEVFN(slot, 5), TYPE_VIA_AC97); +pci_create_simple(pci_bus, PCI_DEVFN(slot, 6), TYPE_VIA_MC97); } /* Network support */ diff --git a/include/hw/isa/vt82c686.h b/include/hw/isa/vt82c686.h index f23f45dfb1..ff80a926dc 100644 --- a/include/hw/isa/vt82c686.h +++ b/include/hw/isa/vt82c686.h @@ -3,11 +3,11 @@ #define TYPE_VT82C686B_SUPERIO "vt82c686b-superio" +#define TYPE_VIA_AC97 "via-ac97" +#define TYPE_VIA_MC97 "via-mc97" /* vt82c686.c */ ISABus *vt82c686b_isa_init(PCIBus * bus, int devfn); -void vt82c686b_ac97_init(PCIBus *bus, int devfn); -void vt82c686b_mc97_init(PCIBus *bus, int devfn); I2CBus *vt82c686b_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, qemu_irq sci_irq); -- 2.21.3
[PATCH 07/24] vt82c686: Remove legacy vt82c686b_isa_init() function
Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé --- hw/isa/vt82c686.c | 9 - hw/mips/fuloong2e.c | 4 +++- include/hw/isa/vt82c686.h | 3 +-- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index 9567326d8e..2912c253dc 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -49,7 +49,6 @@ struct VT82C686BISAState { SuperIOConfig superio_conf; }; -#define TYPE_VT82C686B_ISA "vt82c686b-isa" OBJECT_DECLARE_SIMPLE_TYPE(VT82C686BISAState, VT82C686B_ISA) static void superio_ioport_writeb(void *opaque, hwaddr addr, uint64_t data, @@ -367,14 +366,6 @@ static void vt82c686b_realize(PCIDevice *d, Error **errp) >superio); } -ISABus *vt82c686b_isa_init(PCIBus *bus, int devfn) -{ -PCIDevice *d; - -d = pci_create_simple_multifunction(bus, devfn, true, TYPE_VT82C686B_ISA); -return ISA_BUS(qdev_get_child_bus(DEVICE(d), "isa.0")); -} - static void via_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c index 941d6642c3..fe191e8a9c 100644 --- a/hw/mips/fuloong2e.c +++ b/hw/mips/fuloong2e.c @@ -240,7 +240,9 @@ static void vt82c686b_southbridge_init(PCIBus *pci_bus, int slot, qemu_irq intc, ISABus *isa_bus; PCIDevice *dev; -isa_bus = vt82c686b_isa_init(pci_bus, PCI_DEVFN(slot, 0)); +dev = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(slot, 0), true, + TYPE_VT82C686B_ISA); +isa_bus = ISA_BUS(qdev_get_child_bus(DEVICE(dev), "isa.0")); assert(isa_bus); *p_isa_bus = isa_bus; /* Interrupt controller */ diff --git a/include/hw/isa/vt82c686.h b/include/hw/isa/vt82c686.h index ff80a926dc..8d2d276fe1 100644 --- a/include/hw/isa/vt82c686.h +++ b/include/hw/isa/vt82c686.h @@ -1,13 +1,12 @@ #ifndef HW_VT82C686_H #define HW_VT82C686_H - +#define TYPE_VT82C686B_ISA "vt82c686b-isa" #define TYPE_VT82C686B_SUPERIO "vt82c686b-superio" #define TYPE_VIA_AC97 "via-ac97" #define TYPE_VIA_MC97 "via-mc97" /* vt82c686.c */ -ISABus *vt82c686b_isa_init(PCIBus * bus, int devfn); I2CBus *vt82c686b_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, qemu_irq sci_irq); -- 2.21.3
[PATCH 01/24] vt82c686: Rename AC97/MC97 parts from VT82C686B to VIA
These parts are common between VT82C686B and VT8231 so can be shared in the future. Rename them to VIA prefix accordingly. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé --- hw/isa/vt82c686.c | 28 ++-- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index b3170c70c3..2a0f85dea9 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -168,22 +168,22 @@ struct VT686PMState { uint32_t smb_io_base; }; -struct VT686AC97State { +struct VIAAC97State { PCIDevice dev; }; -struct VT686MC97State { +struct VIAMC97State { PCIDevice dev; }; #define TYPE_VT82C686B_PM_DEVICE "VT82C686B_PM" OBJECT_DECLARE_SIMPLE_TYPE(VT686PMState, VT82C686B_PM_DEVICE) -#define TYPE_VT82C686B_MC97_DEVICE "VT82C686B_MC97" -OBJECT_DECLARE_SIMPLE_TYPE(VT686MC97State, VT82C686B_MC97_DEVICE) +#define TYPE_VIA_MC97_DEVICE "VIA_MC97" +OBJECT_DECLARE_SIMPLE_TYPE(VIAMC97State, VIA_MC97_DEVICE) -#define TYPE_VT82C686B_AC97_DEVICE "VT82C686B_AC97" -OBJECT_DECLARE_SIMPLE_TYPE(VT686AC97State, VT82C686B_AC97_DEVICE) +#define TYPE_VIA_AC97_DEVICE "VIA_AC97" +OBJECT_DECLARE_SIMPLE_TYPE(VIAAC97State, VIA_AC97_DEVICE) static void pm_update_sci(VT686PMState *s) { @@ -260,7 +260,7 @@ static const VMStateDescription vmstate_acpi = { static void vt82c686b_ac97_realize(PCIDevice *dev, Error **errp) { -VT686AC97State *s = VT82C686B_AC97_DEVICE(dev); +VIAAC97State *s = VIA_AC97_DEVICE(dev); uint8_t *pci_conf = s->dev.config; pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_INVALIDATE | @@ -274,7 +274,7 @@ void vt82c686b_ac97_init(PCIBus *bus, int devfn) { PCIDevice *dev; -dev = pci_new(devfn, TYPE_VT82C686B_AC97_DEVICE); +dev = pci_new(devfn, TYPE_VIA_AC97_DEVICE); pci_realize_and_unref(dev, bus, _fatal); } @@ -293,9 +293,9 @@ static void via_ac97_class_init(ObjectClass *klass, void *data) } static const TypeInfo via_ac97_info = { -.name = TYPE_VT82C686B_AC97_DEVICE, +.name = TYPE_VIA_AC97_DEVICE, .parent= TYPE_PCI_DEVICE, -.instance_size = sizeof(VT686AC97State), +.instance_size = sizeof(VIAAC97State), .class_init= via_ac97_class_init, .interfaces = (InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, @@ -305,7 +305,7 @@ static const TypeInfo via_ac97_info = { static void vt82c686b_mc97_realize(PCIDevice *dev, Error **errp) { -VT686MC97State *s = VT82C686B_MC97_DEVICE(dev); +VIAMC97State *s = VIA_MC97_DEVICE(dev); uint8_t *pci_conf = s->dev.config; pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_INVALIDATE | @@ -318,7 +318,7 @@ void vt82c686b_mc97_init(PCIBus *bus, int devfn) { PCIDevice *dev; -dev = pci_new(devfn, TYPE_VT82C686B_MC97_DEVICE); +dev = pci_new(devfn, TYPE_VIA_MC97_DEVICE); pci_realize_and_unref(dev, bus, _fatal); } @@ -337,9 +337,9 @@ static void via_mc97_class_init(ObjectClass *klass, void *data) } static const TypeInfo via_mc97_info = { -.name = TYPE_VT82C686B_MC97_DEVICE, +.name = TYPE_VIA_MC97_DEVICE, .parent= TYPE_PCI_DEVICE, -.instance_size = sizeof(VT686MC97State), +.instance_size = sizeof(VIAMC97State), .class_init= via_mc97_class_init, .interfaces = (InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, -- 2.21.3
qemu isa irq gpio question
Hello, While cleaning up my VIA south bridge patches I've found that with the finished version I did not get interrupts. At the end I've found a solution in a similar device (piix4) but I don't understand why that's needed. Could someone please explain? Here's what I had originally in board code (this is from pegasos2 but fuloong2e has the same with vt82c686b instead if vt8231): dev = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(12, 0), true, "vt8231"); isa_bus = ISA_BUS(qdev_get_child_bus(DEVICE(dev), "isa.0")); // "vt8231" just created an empty isa_bus with isa_bus_new() qemu_irq *i8259 = i8259_init(isa_bus, qdev_get_gpio_in_named(DEVICE(mv), "gpp", 31)); isa_bus_irqs(isa_bus, i8259); which worked but after completely moving isa_bus, PIC and other ISA devices into the vt82c686b/vt8231 model I ended up with: dev = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(12, 0), true, "vt8231-isa"); qdev_connect_gpio_out(DEVICE(dev), 0, qdev_get_gpio_in_named(DEVICE(mv), "gpp", 31)); where "vt8231-isa" having this: struct ViaISAState { PCIDevice dev; qemu_irq cpu_intr; }; static void vt8231_realize(PCIDevice *d, Error **errp) { qdev_init_gpio_out(dev, >cpu_intr, 1); isa_bus = isa_bus_new(...); isa_bus_irqs(isa_bus, i8259_init(isa_bus, s->cpu_intr)); } this compiled without warnings but irqs were not getting to the connected end. After looking for similar code I ended up with this from piix4 which works again: static void via_isa_request_i8259_irq(void *opaque, int irq, int level) { ViaISAState *s = opaque; qemu_set_irq(s->cpu_intr, level); } static void vt8231_realize(PCIDevice *d, Error **errp) { qdev_init_gpio_out(dev, >cpu_intr, 1); qemu_irq *isa_irq = qemu_allocate_irqs(via_isa_request_i8259_irq, s, 1); isa_bus_irqs(isa_bus, i8259_init(isa_bus, *isa_irq)); } I'm not sure if this will leak the allocated irq and why is this additional function needed inbetween these in this case but this is what works so I'll go with this one for now but still curious what did I miss. Regards, BALATON Zoltan
Re: [RFC PATCH 0/5] hw/mips: Fix Fuloong2E to boot Linux guest again
On Sat, 2 Jan 2021, Philippe Mathieu-Daudé wrote: We closed 2020 with few discussions about the Fuloong 2E board (see [1] and [2]). This series collect the minimum set of patch to have the machine booting Linux guest again, including integration tests. This is sent as RFC because Mark raised some issues in (see [3] and previous in this thread) and I don't understand PCI enough to intervene. Thanks for collecting these. Let me summarise the discussion because the meaning may have been lost in the seamingly heated debate but I think Mark's main concern was that he does not like having a feature flag and property setting the emulation to partially emulate the device: either only emulating legacy mode or native mode that this patch does but he would prefer to faithfully emulate the device preferably allowing switching between modes. But that's not easily possible without rewritig either the ISA emulation or PCI emulation in QEMU because current code does not allow these to be switched once created. That's way more work and risk of breaking other things using these fundamental parts that I would want to take on. My goal was only to allow using this (otherwise quite unused and deglected) device model in pegasos2 emulation which needs native mode. But turns out fuloong2e Linux wants legacy mode so we need a way to resolve this conflict and the solution was this flag and keeping partial emulation depending on machine. But Mark still considered that a horrible hack but after looking more closely he also found the difficulty of implementing a more faithful emulation so he would accept the flag at the end but still wanted registers to be set more consistently matching what the data sheet and whatever ideals would dictate. However I've spent a lot of time before finding these values that work with all clients and found some of these clients have assumptions instead of working in an ideal world following what data sheets say and I don't want to make any changes to this now before we also have pegasos2 upstreamed so any change can be more throughly tested and I don't have to retest everything for every small change just to find something broke, This was the main reason for disagreement and I think Mark's standards for this device was way higher than necessary in this situation and I may have got upset to have this pushed back again when we've already went through this last March where we also had a long discussion after which Mark managed to get rid of the flag but that now came back in a different form. (Previously it was switching between fully native and non-100% native mode, now it selects legacy or non-100% native mode where legacy is needed for fuloong2e linux and non-100% native mode is needed for pegasos2 guests.) This may not be how the real device work (Mark also has concerns about what exactly is non-100% native mode) and it may be a horrible hack but it's probably the best that can be done with current QEMU facilities and in the time I had and since this is only used on fuloong2e and pegasos2 for a few obscure guests I think it does not need any more complex solution at the moment. It seems this disagreement on what's good enough for a device model to get in QEMU is the source of disagreement between us with Mark but we'll sort that out off list once I finish preparing my pegasos2 patches that will finally show where these changes go and oters can also test any proposed changes. Regards, BALATON Zoltan Peter commented a similar PCI issue with the Sam460ex [4] so might be able to help us here. Anyhow, sharing this PoC on the list with the test, the avoid boring manual testing. Regards, Phil. [1] https://www.mail-archive.com/qemu-devel@nongnu.org/msg769105.html [2] https://www.mail-archive.com/qemu-devel@nongnu.org/msg769557.html [3] https://www.mail-archive.com/qemu-devel@nongnu.org/msg769593.html [4] https://www.mail-archive.com/qemu-devel@nongnu.org/msg769697.html BALATON Zoltan (1): ide: Make room for flags in PCIIDEState and add one for legacy mode Guenter Roeck (1): via-ide: Fix fuloong2e support Jiaxun Yang (1): tests/acceptance: Test boot_linux_console for fuloong2e Philippe Mathieu-Daudé (2): hw/pci-host/bonito: Remap PCI "lo" regions when PCIMAP reg is modified tests/integration: Test Fuloong2E IDE drive, run userspace commands include/hw/ide/pci.h | 7 +++- hw/ide/cmd646.c| 6 ++-- hw/ide/via.c | 19 -- hw/mips/fuloong2e.c| 4 ++- hw/pci-host/bonito.c | 49 +++--- hw/sparc64/sun4u.c | 2 +- tests/acceptance/boot_linux_console.py | 47 7 files changed, 113 insertions(+), 21 deletions(-) -- 2.26.2
Re: [PATCH v2 09/10] vt82c686: Convert debug printf to trace points
On Fri, 1 Jan 2021, Philippe Mathieu-Daudé wrote: On 12/28/20 3:08 AM, BALATON Zoltan via wrote: Drop DPRINTF and use trace functions instead. Two debug messages about unimplemented registers could be converted to qemu_log_mask() but in reality all registers are currently unimplemented (we just store and return values of writable regs but do nothing with them). As we already trace register access there's no need for additional debug messages so these are just removed and a comment is added as a reminder. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé --- v2: Extended commit message hw/isa/trace-events | 6 ++ hw/isa/vt82c686.c | 51 + 2 files changed, 21 insertions(+), 36 deletions(-) diff --git a/hw/isa/trace-events b/hw/isa/trace-events index 3544c6213c..d267d3e652 100644 --- a/hw/isa/trace-events +++ b/hw/isa/trace-events @@ -13,3 +13,9 @@ pc87312_io_write(uint32_t addr, uint32_t val) "write addr=0x%x val=0x%x" # apm.c apm_io_read(uint8_t addr, uint8_t val) "read addr=0x%x val=0x%02x" apm_io_write(uint8_t addr, uint8_t val) "write addr=0x%x val=0x%02x" + +# vt82c686.c +via_isa_write(uint32_t addr, uint32_t val, int len) "addr 0x%x val 0x%x len 0x%x" +via_pm_write(uint32_t addr, uint32_t val, int len) "addr 0x%x val 0x%x len 0x%x" +via_superio_read(uint8_t addr, uint8_t val) "addr 0x%x val 0x%x" +via_superio_write(uint8_t addr, uint32_t val) "addr 0x%x val 0x%x" diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index cd87ec0103..d7ce15bf9f 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -27,14 +27,7 @@ #include "qemu/timer.h" #include "exec/address-spaces.h" #include "qom/object.h" - -/* #define DEBUG_VT82C686B */ - -#ifdef DEBUG_VT82C686B -#define DPRINTF(fmt, ...) fprintf(stderr, "%s: " fmt, __func__, ##__VA_ARGS__) -#else -#define DPRINTF(fmt, ...) -#endif +#include "trace.h" typedef struct SuperIOConfig { uint8_t config[0x100]; @@ -55,12 +48,12 @@ static void superio_ioport_writeb(void *opaque, hwaddr addr, uint64_t data, { SuperIOConfig *superio_conf = opaque; -DPRINTF("superio_ioport_writeb address 0x%x val 0x%x\n", addr, data); -if (addr == 0x3f0) { +if (addr == 0x3f0) { /* config index register */ superio_conf->index = data & 0xff; } else { bool can_write = true; -/* 0x3f1 */ +/* 0x3f1, config data register */ +trace_via_superio_write(superio_conf->index, data & 0xff); switch (superio_conf->index) { case 0x00 ... 0xdf: case 0xe4: @@ -73,18 +66,7 @@ static void superio_ioport_writeb(void *opaque, hwaddr addr, uint64_t data, case 0xfd ... 0xff: can_write = false; break; -case 0xe7: -if ((data & 0xff) != 0xfe) { -DPRINTF("change uart 1 base. unsupported yet\n"); -can_write = false; -} -break; -case 0xe8: -if ((data & 0xff) != 0xbe) { -DPRINTF("change uart 2 base. unsupported yet\n"); -can_write = false; -} -break; +/* case 0xe6 ... 0xe8: Should set base port of parallel and serial */ If you don't mind I'll prepend this patch: -- >8 -- diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index cd87ec01039..23b4deaac93 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -25,6 +25,7 @@ #include "qapi/error.h" #include "qemu/module.h" #include "qemu/timer.h" +#include "qemu/log.h" #include "exec/address-spaces.h" #include "qom/object.h" @@ -73,17 +74,9 @@ static void superio_ioport_writeb(void *opaque, hwaddr addr, uint64_t data, case 0xfd ... 0xff: can_write = false; break; -case 0xe7: -if ((data & 0xff) != 0xfe) { -DPRINTF("change uart 1 base. unsupported yet\n"); -can_write = false; -} -break; -case 0xe8: -if ((data & 0xff) != 0xbe) { -DPRINTF("change uart 2 base. unsupported yet\n"); -can_write = false; -} +case 0xe6 ... 0xe8: /* set base port of parallel and serial */ +qemu_log_mask(LOG_UNIMP, "change base port not implemented\n"); +can_write = false; Actually I won't add this log becuse in later patches I've added logging for all unimplemented regs here and implemented changing base for serial (needed for pegasos2 which puts the single serial port at 0x2f8). Still want this patch spit into too? Regards, BALATON Zoltan
Re: [PATCH v2 09/10] vt82c686: Convert debug printf to trace points
On Fri, 1 Jan 2021, Philippe Mathieu-Daudé wrote: On 12/28/20 3:08 AM, BALATON Zoltan via wrote: Drop DPRINTF and use trace functions instead. Two debug messages about unimplemented registers could be converted to qemu_log_mask() but in reality all registers are currently unimplemented (we just store and return values of writable regs but do nothing with them). As we already trace register access there's no need for additional debug messages so these are just removed and a comment is added as a reminder. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé --- v2: Extended commit message hw/isa/trace-events | 6 ++ hw/isa/vt82c686.c | 51 + 2 files changed, 21 insertions(+), 36 deletions(-) diff --git a/hw/isa/trace-events b/hw/isa/trace-events index 3544c6213c..d267d3e652 100644 --- a/hw/isa/trace-events +++ b/hw/isa/trace-events @@ -13,3 +13,9 @@ pc87312_io_write(uint32_t addr, uint32_t val) "write addr=0x%x val=0x%x" # apm.c apm_io_read(uint8_t addr, uint8_t val) "read addr=0x%x val=0x%02x" apm_io_write(uint8_t addr, uint8_t val) "write addr=0x%x val=0x%02x" + +# vt82c686.c +via_isa_write(uint32_t addr, uint32_t val, int len) "addr 0x%x val 0x%x len 0x%x" +via_pm_write(uint32_t addr, uint32_t val, int len) "addr 0x%x val 0x%x len 0x%x" +via_superio_read(uint8_t addr, uint8_t val) "addr 0x%x val 0x%x" +via_superio_write(uint8_t addr, uint32_t val) "addr 0x%x val 0x%x" diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index cd87ec0103..d7ce15bf9f 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -27,14 +27,7 @@ #include "qemu/timer.h" #include "exec/address-spaces.h" #include "qom/object.h" - -/* #define DEBUG_VT82C686B */ - -#ifdef DEBUG_VT82C686B -#define DPRINTF(fmt, ...) fprintf(stderr, "%s: " fmt, __func__, ##__VA_ARGS__) -#else -#define DPRINTF(fmt, ...) -#endif +#include "trace.h" typedef struct SuperIOConfig { uint8_t config[0x100]; @@ -55,12 +48,12 @@ static void superio_ioport_writeb(void *opaque, hwaddr addr, uint64_t data, { SuperIOConfig *superio_conf = opaque; -DPRINTF("superio_ioport_writeb address 0x%x val 0x%x\n", addr, data); -if (addr == 0x3f0) { +if (addr == 0x3f0) { /* config index register */ superio_conf->index = data & 0xff; } else { bool can_write = true; -/* 0x3f1 */ +/* 0x3f1, config data register */ +trace_via_superio_write(superio_conf->index, data & 0xff); switch (superio_conf->index) { case 0x00 ... 0xdf: case 0xe4: @@ -73,18 +66,7 @@ static void superio_ioport_writeb(void *opaque, hwaddr addr, uint64_t data, case 0xfd ... 0xff: can_write = false; break; -case 0xe7: -if ((data & 0xff) != 0xfe) { -DPRINTF("change uart 1 base. unsupported yet\n"); -can_write = false; -} -break; -case 0xe8: -if ((data & 0xff) != 0xbe) { -DPRINTF("change uart 2 base. unsupported yet\n"); -can_write = false; -} -break; +/* case 0xe6 ... 0xe8: Should set base port of parallel and serial */ If you don't mind I'll prepend this patch: I'll split it. I've finished rewriting vt82c686b to add vt8231 emulation and ended up with a 24 patch series. This'll make it 25. This includes all of part I and part II I've already posted and some more. Fuloong2e still seems to work (with the Bonito fix) at least with PMON and pegasos2 firmware also runs and starts to boot but MorphOS does not fully boot for some reason but I'm not sure if it's because of some other change or a bug somewhere in this series. I need to do more testing but I think I'll submit this series now anyway so it can be reviewed in the meantime and I can make changes in next iteration and don't need too many versions because I'll have less time for it now. Regards and happy new year, BALATON Zoltan -- >8 -- diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index cd87ec01039..23b4deaac93 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -25,6 +25,7 @@ #include "qapi/error.h" #include "qemu/module.h" #include "qemu/timer.h" +#include "qemu/log.h" #include "exec/address-spaces.h" #include "qom/object.h" @@ -73,17 +74,9 @@ static void superio_ioport_writeb(void *opaque, hwaddr addr, uint64_t data, case 0xfd ... 0xff: can_write = false; break; -case 0xe7: -if ((data & 0xff) != 0xfe) { -DPRINTF("change uart 1 base. unsupported yet\n"); -can_write = false; -} -bre
Re: [PATCH v2 3/3] sam460ex: Clean up irq mapping
On Thu, 31 Dec 2020, BALATON Zoltan via wrote: On Thu, 31 Dec 2020, Peter Maydell wrote: On Thu, 31 Dec 2020 at 15:11, Peter Maydell wrote: On Thu, 31 Dec 2020 at 11:20, BALATON Zoltan wrote: Avoid mapping multiple interrupts to the same irq. Instead map them to the 4 PCI interrupts and use an or-gate in the board to connect them to the interrupt controller. This does not fix any known problem but does not seem to cause a new problem either and may be cleaner at least. Signed-off-by: BALATON Zoltan Tested-by: Guenter Roeck So, this patch is a behavioural change, but I think it's probably a change to the right behaviour. The difference is relatively slight, but you would see it if there are two different PCI cards and they both assert a different PCI interrupt, and then one of them lowers the interrupt before the other: This turns out to be wrong -- I hadn't looked at the QEMU PCI code, but it has an internal implementation of logic that gives the same behaviour as an explicit OR gate. Basically pci_change_irq_level() tracks how many assert/deasserts of the (mapped) IRQ lines have happened, so it only calls the controller's set_irq function when the count of asserted inputs goes down to 0. So both the current code and this patch's change are functionally correct. I've remembered we had this discussion before and arrived to the same conclusion that current code was equivalently working but could not recall the reason. I'm not sure which would be nominally closer to the "real hardware": the 440ex CPU/SoC datasheet lists a single PCI0INT signal, but it says it is an output, not an input, so I'm pretty sure there's something I don't understand about PCI here. (Also, unlike the 440EP it provides PCI Express as well as PCI.) The SoC is called 460EX (despite having a PPC 440 core not 460 one) but I think you've looked at the right data sheet and it's just a typo. I also don't know how the board is wired so I think in this case I prefer dropping this patch and keeping the current code just for simplicity but to avoid going through this again maybe we should add a comment saying why it's working. Can you please suggest a test for such comment pointing to the I mean "text" not "test" above. relevant part of pci_change_irq_level() you refer to above? I don't think I understand it enough to document it. Thank you, BALATON Zoltan
Re: [PATCH v2 3/3] sam460ex: Clean up irq mapping
On Thu, 31 Dec 2020, Peter Maydell wrote: On Thu, 31 Dec 2020 at 15:11, Peter Maydell wrote: On Thu, 31 Dec 2020 at 11:20, BALATON Zoltan wrote: Avoid mapping multiple interrupts to the same irq. Instead map them to the 4 PCI interrupts and use an or-gate in the board to connect them to the interrupt controller. This does not fix any known problem but does not seem to cause a new problem either and may be cleaner at least. Signed-off-by: BALATON Zoltan Tested-by: Guenter Roeck So, this patch is a behavioural change, but I think it's probably a change to the right behaviour. The difference is relatively slight, but you would see it if there are two different PCI cards and they both assert a different PCI interrupt, and then one of them lowers the interrupt before the other: This turns out to be wrong -- I hadn't looked at the QEMU PCI code, but it has an internal implementation of logic that gives the same behaviour as an explicit OR gate. Basically pci_change_irq_level() tracks how many assert/deasserts of the (mapped) IRQ lines have happened, so it only calls the controller's set_irq function when the count of asserted inputs goes down to 0. So both the current code and this patch's change are functionally correct. I've remembered we had this discussion before and arrived to the same conclusion that current code was equivalently working but could not recall the reason. I'm not sure which would be nominally closer to the "real hardware": the 440ex CPU/SoC datasheet lists a single PCI0INT signal, but it says it is an output, not an input, so I'm pretty sure there's something I don't understand about PCI here. (Also, unlike the 440EP it provides PCI Express as well as PCI.) The SoC is called 460EX (despite having a PPC 440 core not 460 one) but I think you've looked at the right data sheet and it's just a typo. I also don't know how the board is wired so I think in this case I prefer dropping this patch and keeping the current code just for simplicity but to avoid going through this again maybe we should add a comment saying why it's working. Can you please suggest a test for such comment pointing to the relevant part of pci_change_irq_level() you refer to above? I don't think I understand it enough to document it. Thank you, BALATON Zoltan
Re: [PATCH v2 3/3] trace: recommend "log" backend for getting started with tracing
On Thu, 31 Dec 2020, Peter Maydell wrote: On Wed, 16 Dec 2020 at 16:09, Stefan Hajnoczi wrote: The "simple" backend is actually more complicated to use than the "log" backend. Update the quickstart documentation to feature the "log" backend instead of the "simple" backend. Suggested-by: Peter Maydell Signed-off-by: Stefan Hajnoczi --- docs/devel/tracing.rst | 35 ++- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/docs/devel/tracing.rst b/docs/devel/tracing.rst index 76cc1b24fa..e60058bf55 100644 --- a/docs/devel/tracing.rst +++ b/docs/devel/tracing.rst @@ -11,22 +11,22 @@ for debugging, profiling, and observing execution. Quickstart == -1. Build with the 'simple' trace backend:: +Enable tracing of ``memory_region_ops_read`` and ``memory_region_ops_write`` +events:: -./configure --enable-trace-backends=simple -make +$ qemu --trace "memory_region_ops_*" ... +... +719585@1608130130.441188:memory_region_ops_read cpu 0 mr 0x562fdfbb3820 addr 0x3cc value 0x67 size 1 +719585@1608130130.441190:memory_region_ops_write cpu 0 mr 0x562fdfbd2f00 addr 0x3d4 value 0x70e size 2 -2. Create a file with the events you want to trace:: +This output comes from the "log" trace backend that is enabled by default when +``./configure --enable-trace-backends=BACKENDS`` was not explicitly specified. -echo memory_region_ops_read >/tmp/events +More than one trace event pattern can be specified by providing a file +instead:: Does --trace really not let you specify more than one pattern without resorting to putting them into a file? That sounds like a deficiency compared to -d (which allows -d trace:PATTERN,trace:PATTERN...) that we could look at fixing... Ir's possible to give more patterns in multiple options, I'm using that, such as: -trace enable="pci*" -trace enable="ide*" For a lot of patterns using a file may be clearer though. This reminds me to the plainlog backend I've submitted. What happened to that? See: https://lists.nongnu.org/archive/html/qemu-devel/2020-06/msg07296.html I'd like a solution that can be set at compile time and does not need another command line option to turn off time stamps. (Timestamps are annoyong when comparing logs that's often necessary to check changes.) I'm still using my plainlog patch but I have to disable that when bisecting. Regards, BALATON Zoltan Anyway, Reviewed-by: Peter Maydell thanks -- PMM
David Gibson, please read
Hello, I've just sent this but my messages to you are bouncing with: : Host or domain name not found. Name service error for name=gibson.dropbear.id.au type=MX: Host not found, try again after trying for a week so you may have missed it even though I've cc'd you. I've also noticed that my patches don't show up in patchwork and my From address gets modified by the list that don't seem to be the case for other messages so I wonder if it may be something with my email. I've sent this to the list too so you have a chance to see it, please reply off list. Regards, BALATON Zoltan On Thu, 31 Dec 2020, BALATON Zoltan via wrote: v2 of https://patchew.org/QEMU/cover.1608937677.git.bala...@eik.bme.hu/ with added Tested-by from Guenter and revised patch 2 as suggested by Philippe. Regards, BALATON Zoltan BALATON Zoltan (3): ppc4xx: Move common dependency on serial to common option sam460ex: Remove FDT_PPC dependency from KConfig sam460ex: Clean up irq mapping hw/ppc/Kconfig | 7 ++- hw/ppc/ppc440_pcix.c | 28 ++-- hw/ppc/sam460ex.c| 16 +--- 3 files changed, 29 insertions(+), 22 deletions(-)
[PATCH v2 2/3] sam460ex: Remove FDT_PPC dependency from KConfig
Dependency on FDT_PPC was added in commit b0048f76095 ("hw/ppc/Kconfig: Only select FDT helper for machines using it") but it does not seem to be really necessary so remove it again. Signed-off-by: BALATON Zoltan --- v2: Do not remove PPC405, reworded commit message hw/ppc/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig index 8548f42b0d..f1e1be208e 100644 --- a/hw/ppc/Kconfig +++ b/hw/ppc/Kconfig @@ -64,7 +64,6 @@ config SAM460EX select SMBUS_EEPROM select USB_EHCI_SYSBUS select USB_OHCI -select FDT_PPC config PREP bool -- 2.21.3
[PATCH v2 3/3] sam460ex: Clean up irq mapping
Avoid mapping multiple interrupts to the same irq. Instead map them to the 4 PCI interrupts and use an or-gate in the board to connect them to the interrupt controller. This does not fix any known problem but does not seem to cause a new problem either and may be cleaner at least. Signed-off-by: BALATON Zoltan Tested-by: Guenter Roeck --- hw/ppc/Kconfig | 1 + hw/ppc/ppc440_pcix.c | 28 ++-- hw/ppc/sam460ex.c| 16 +--- 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig index f1e1be208e..ebb70803c4 100644 --- a/hw/ppc/Kconfig +++ b/hw/ppc/Kconfig @@ -59,6 +59,7 @@ config SAM460EX select PFLASH_CFI01 select IDE_SII3112 select M41T80 +select OR_IRQ select PPC440 select SM501 select SMBUS_EEPROM diff --git a/hw/ppc/ppc440_pcix.c b/hw/ppc/ppc440_pcix.c index ee952314c8..504decbbc2 100644 --- a/hw/ppc/ppc440_pcix.c +++ b/hw/ppc/ppc440_pcix.c @@ -57,8 +57,8 @@ struct PPC440PCIXState { PCIDevice *dev; struct PLBOutMap pom[PPC440_PCIX_NR_POMS]; struct PLBInMap pim[PPC440_PCIX_NR_PIMS]; +qemu_irq irq[PCI_NUM_PINS]; uint32_t sts; -qemu_irq irq; AddressSpace bm_as; MemoryRegion bm; @@ -415,24 +415,20 @@ static void ppc440_pcix_reset(DeviceState *dev) s->sts = 0; } -/* All pins from each slot are tied to a single board IRQ. - * This may need further refactoring for other boards. */ static int ppc440_pcix_map_irq(PCIDevice *pci_dev, int irq_num) { -trace_ppc440_pcix_map_irq(pci_dev->devfn, irq_num, 0); -return 0; +int n = (irq_num + PCI_SLOT(pci_dev->devfn)) % PCI_NUM_PINS; + +trace_ppc440_pcix_map_irq(pci_dev->devfn, irq_num, n); +return n; } static void ppc440_pcix_set_irq(void *opaque, int irq_num, int level) { -qemu_irq *pci_irq = opaque; +qemu_irq *pci_irqs = opaque; trace_ppc440_pcix_set_irq(irq_num); -if (irq_num < 0) { -error_report("%s: PCI irq %d", __func__, irq_num); -return; -} -qemu_set_irq(*pci_irq, level); +qemu_set_irq(pci_irqs[irq_num], level); } static AddressSpace *ppc440_pcix_set_iommu(PCIBus *b, void *opaque, int devfn) @@ -472,15 +468,19 @@ static void ppc440_pcix_realize(DeviceState *dev, Error **errp) SysBusDevice *sbd = SYS_BUS_DEVICE(dev); PPC440PCIXState *s; PCIHostState *h; +int i; h = PCI_HOST_BRIDGE(dev); s = PPC440_PCIX_HOST_BRIDGE(dev); -sysbus_init_irq(sbd, >irq); +for (i = 0; i < ARRAY_SIZE(s->irq); i++) { +sysbus_init_irq(sbd, >irq[i]); +} memory_region_init(>busmem, OBJECT(dev), "pci bus memory", UINT64_MAX); h->bus = pci_register_root_bus(dev, NULL, ppc440_pcix_set_irq, - ppc440_pcix_map_irq, >irq, >busmem, - get_system_io(), PCI_DEVFN(0, 0), 1, TYPE_PCI_BUS); + ppc440_pcix_map_irq, s->irq, >busmem, + get_system_io(), PCI_DEVFN(0, 0), ARRAY_SIZE(s->irq), + TYPE_PCI_BUS); s->dev = pci_create_simple(h->bus, PCI_DEVFN(0, 0), "ppc4xx-host-bridge"); diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c index 14e6583eb0..59b19fbca1 100644 --- a/hw/ppc/sam460ex.c +++ b/hw/ppc/sam460ex.c @@ -33,6 +33,7 @@ #include "sysemu/qtest.h" #include "sysemu/reset.h" #include "hw/sysbus.h" +#include "hw/or-irq.h" #include "hw/char/serial.h" #include "hw/i2c/ppc4xx_i2c.h" #include "hw/i2c/smbus_eeprom.h" @@ -292,7 +293,7 @@ static void sam460ex_init(MachineState *machine) SysBusDevice *sbdev; struct boot_info *boot_info; uint8_t *spd_data; -int success; +int i, success; cpu = POWERPC_CPU(cpu_create(machine->cpu_type)); env = >env; @@ -382,13 +383,22 @@ static void sam460ex_init(MachineState *machine) /* PCI bus */ ppc460ex_pcie_init(env); -/* All PCI irqs are connected to the same UIC pin (cf. UBoot source) */ -dev = sysbus_create_simple("ppc440-pcix-host", 0xc0ec0, uic[1][0]); +dev = sysbus_create_simple("ppc440-pcix-host", 0xc0ec0, NULL); pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci.0"); if (!pci_bus) { error_report("couldn't create PCI controller!"); exit(1); } +/* All PCI irqs are connected to the same UIC pin (cf. UBoot source) */ +sbdev = SYS_BUS_DEVICE(dev); +dev = qdev_new(TYPE_OR_IRQ); +object_property_set_int(OBJECT(dev), "num-lines", PCI_NUM_PINS, +_fatal); +qdev_realize_and_unref(dev, NULL, _fatal); +for (i = 0; i < PCI_NUM_PINS; i++) { +sysbus_connect_irq(sbdev, i, qdev_get_gpio_in(dev, i)); +} +qdev_connect_gpio_out(dev, 0, uic[1][0]); memory_region_init_alias(isa, NULL, "isa_mmio", get_system_io(), 0, 0x1); memory_region_add_subregion(get_system_memory(), 0xc0800, isa); -- 2.21.3
[PATCH v2 1/3] ppc4xx: Move common dependency on serial to common option
All machines that select SERIAL also select PPC4XX so we can just add this common dependency there once. Signed-off-by: BALATON Zoltan --- hw/ppc/Kconfig | 5 + 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig index dd86e664d2..8548f42b0d 100644 --- a/hw/ppc/Kconfig +++ b/hw/ppc/Kconfig @@ -37,7 +37,6 @@ config PPC405 select M48T59 select PFLASH_CFI02 select PPC4XX -select SERIAL config PPC440 bool @@ -46,13 +45,13 @@ config PPC440 imply E1000_PCI select PCI_EXPRESS select PPC4XX -select SERIAL select FDT_PPC config PPC4XX bool select BITBANG_I2C select PCI +select SERIAL config SAM460EX bool @@ -61,7 +60,6 @@ config SAM460EX select IDE_SII3112 select M41T80 select PPC440 -select SERIAL select SM501 select SMBUS_EEPROM select USB_EHCI_SYSBUS @@ -123,7 +121,6 @@ config VIRTEX bool select PPC4XX select PFLASH_CFI01 -select SERIAL select XILINX select XILINX_ETHLITE select FDT_PPC -- 2.21.3
[PATCH v2 0/3] Clean up sam460ex irq mapping
v2 of https://patchew.org/QEMU/cover.1608937677.git.bala...@eik.bme.hu/ with added Tested-by from Guenter and revised patch 2 as suggested by Philippe. Regards, BALATON Zoltan BALATON Zoltan (3): ppc4xx: Move common dependency on serial to common option sam460ex: Remove FDT_PPC dependency from KConfig sam460ex: Clean up irq mapping hw/ppc/Kconfig | 7 ++- hw/ppc/ppc440_pcix.c | 28 ++-- hw/ppc/sam460ex.c| 16 +--- 3 files changed, 29 insertions(+), 22 deletions(-) -- 2.21.3
[PATCH 6/7] vt82c686: Fix up power management io base and config
Similar to the SMBus io registers there is a power management io range that's set via similar base address reg and enable bit. Some handling of this was already there but with several problems: using the wrong registers and bits, wrong size range, not acually updating mapping and handling reset correctly or emulating any of the acrual io registers. Some of these are fixed up here. After this patch we use the correct base address register, enable bit and region size and allow guests to map/unmap this region and correctly reset all registers to default values on reset but we still don't emulate any of the registers in this range. Previously just an empty RAM region was mapped on realize, now I've added empty io range logging access. I think the pm timer should be hooked up here but not sure guests need it. PMON on fuloong2e sets base address but does not seem to enable region; the pegasos2 firmware pokes some regs but continues anyway so don't know if anything would make use of these facilities. Therefore this is just a clean up of previous state for now and not intending to fully implement missing functionality which could be done later if some guests need it. Signed-off-by: BALATON Zoltan --- hw/isa/trace-events | 2 ++ hw/isa/vt82c686.c | 56 - 2 files changed, 42 insertions(+), 16 deletions(-) diff --git a/hw/isa/trace-events b/hw/isa/trace-events index d267d3e652..641d69eedf 100644 --- a/hw/isa/trace-events +++ b/hw/isa/trace-events @@ -17,5 +17,7 @@ apm_io_write(uint8_t addr, uint8_t val) "write addr=0x%x val=0x%02x" # vt82c686.c via_isa_write(uint32_t addr, uint32_t val, int len) "addr 0x%x val 0x%x len 0x%x" via_pm_write(uint32_t addr, uint32_t val, int len) "addr 0x%x val 0x%x len 0x%x" +via_pm_io_read(uint32_t addr, uint32_t val, int len) "addr 0x%x val 0x%x len 0x%x" +via_pm_io_write(uint32_t addr, uint32_t val, int len) "addr 0x%x val 0x%x len 0x%x" via_superio_read(uint8_t addr, uint8_t val) "addr 0x%x val 0x%x" via_superio_write(uint8_t addr, uint32_t val) "addr 0x%x val 0x%x" diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index 9c4d153022..fc2a1f4430 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -39,14 +39,11 @@ struct VT686PMState { static void pm_io_space_update(VT686PMState *s) { -uint32_t pm_io_base; - -pm_io_base = pci_get_long(s->dev.config + 0x40); -pm_io_base &= 0xffc0; +uint32_t pmbase = pci_get_long(s->dev.config + 0x48) & 0xff80UL; memory_region_transaction_begin(); -memory_region_set_enabled(>io, s->dev.config[0x80] & 1); -memory_region_set_address(>io, pm_io_base); +memory_region_set_address(>io, pmbase); +memory_region_set_enabled(>io, s->dev.config[0x41] & BIT(7)); memory_region_transaction_commit(); } @@ -92,6 +89,13 @@ static void pm_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int len) trace_via_pm_write(addr, val, len); pci_default_write_config(d, addr, val, len); +if (ranges_overlap(addr, len, 0x48, 4)) { +uint32_t v = pci_get_long(s->dev.config + 0x48); +pci_set_long(s->dev.config + 0x48, (v & 0xff80UL) | 1); +} +if (range_covers_byte(addr, len, 0x41)) { +pm_io_space_update(s); +} if (ranges_overlap(addr, len, 0x90, 4)) { uint32_t v = pci_get_long(s->dev.config + 0x90); pci_set_long(s->dev.config + 0x90, (v & 0xfff0UL) | 1); @@ -102,6 +106,27 @@ static void pm_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int len) } } +static void pm_io_write(void *op, hwaddr addr, uint64_t data, unsigned size) +{ +trace_via_pm_io_write(addr, data, size); +} + +static uint64_t pm_io_read(void *op, hwaddr addr, unsigned size) +{ +trace_via_pm_io_read(addr, 0, size); +return 0; +} + +static const MemoryRegionOps pm_io_ops = { +.read = pm_io_read, +.write = pm_io_write, +.endianness = DEVICE_NATIVE_ENDIAN, +.impl = { +.min_access_size = 1, +.max_access_size = 1, +}, +}; + static void pm_update_sci(VT686PMState *s) { int sci_level, pmsts; @@ -128,35 +153,34 @@ static void vt82c686b_pm_reset(DeviceState *d) { VT686PMState *s = VT82C686B_PM(d); +memset(s->dev.config + PCI_CONFIG_HEADER_SIZE, 0, + PCI_CONFIG_SPACE_SIZE - PCI_CONFIG_HEADER_SIZE); +/* Power Management IO base */ +pci_set_long(s->dev.config + 0x48, 1); /* SMBus IO base */ pci_set_long(s->dev.config + 0x90, 1); -s->dev.config[0xd2] = 0; +pm_io_space_update(s); smb_io_space_update(s); } static void vt82c686b_pm_realize(PCIDevice *dev, Error **errp) { VT686PMState *s = VT82C686B_PM(dev); -uint8_t *pci_conf; -pci_conf = s->dev.config; -pci_set_word(pci_conf + PCI_COMMAND, 0); -pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_FAST_BACK | +pci_set_word(dev->config + PCI_STATUS, PCI_STATUS_FAST_BACK | PCI_STATUS_DEVSEL_MEDIUM); -/* 0x48-0x4B is
[PATCH 7/7] vt82c686: Make vt82c686b-pm an abstract base class and add vt8231-pm based on it
The vt82c686b-pm model can be shared between VT82C686B and VT8231. The only difference between the two is the device id in what we model so make an abstract via-pm model by renaming appropriately and add types for vt82c686b-pm and vt8231-pm based on it. Signed-off-by: BALATON Zoltan --- hw/isa/vt82c686.c | 87 ++- include/hw/isa/vt82c686.h | 1 + 2 files changed, 59 insertions(+), 29 deletions(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index fc2a1f4430..2e269a2c0f 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -27,9 +27,10 @@ #include "exec/address-spaces.h" #include "trace.h" -OBJECT_DECLARE_SIMPLE_TYPE(VT686PMState, VT82C686B_PM) +#define TYPE_VIA_PM "via-pm" +OBJECT_DECLARE_SIMPLE_TYPE(ViaPMState, VIA_PM) -struct VT686PMState { +struct ViaPMState { PCIDevice dev; MemoryRegion io; ACPIREGS ar; @@ -37,7 +38,7 @@ struct VT686PMState { PMSMBus smb; }; -static void pm_io_space_update(VT686PMState *s) +static void pm_io_space_update(ViaPMState *s) { uint32_t pmbase = pci_get_long(s->dev.config + 0x48) & 0xff80UL; @@ -47,7 +48,7 @@ static void pm_io_space_update(VT686PMState *s) memory_region_transaction_commit(); } -static void smb_io_space_update(VT686PMState *s) +static void smb_io_space_update(ViaPMState *s) { uint32_t smbase = pci_get_long(s->dev.config + 0x90) & 0xfff0UL; @@ -59,7 +60,7 @@ static void smb_io_space_update(VT686PMState *s) static int vmstate_acpi_post_load(void *opaque, int version_id) { -VT686PMState *s = opaque; +ViaPMState *s = opaque; pm_io_space_update(s); smb_io_space_update(s); @@ -72,20 +73,20 @@ static const VMStateDescription vmstate_acpi = { .minimum_version_id = 1, .post_load = vmstate_acpi_post_load, .fields = (VMStateField[]) { -VMSTATE_PCI_DEVICE(dev, VT686PMState), -VMSTATE_UINT16(ar.pm1.evt.sts, VT686PMState), -VMSTATE_UINT16(ar.pm1.evt.en, VT686PMState), -VMSTATE_UINT16(ar.pm1.cnt.cnt, VT686PMState), -VMSTATE_STRUCT(apm, VT686PMState, 0, vmstate_apm, APMState), -VMSTATE_TIMER_PTR(ar.tmr.timer, VT686PMState), -VMSTATE_INT64(ar.tmr.overflow_time, VT686PMState), +VMSTATE_PCI_DEVICE(dev, ViaPMState), +VMSTATE_UINT16(ar.pm1.evt.sts, ViaPMState), +VMSTATE_UINT16(ar.pm1.evt.en, ViaPMState), +VMSTATE_UINT16(ar.pm1.cnt.cnt, ViaPMState), +VMSTATE_STRUCT(apm, ViaPMState, 0, vmstate_apm, APMState), +VMSTATE_TIMER_PTR(ar.tmr.timer, ViaPMState), +VMSTATE_INT64(ar.tmr.overflow_time, ViaPMState), VMSTATE_END_OF_LIST() } }; static void pm_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int len) { -VT686PMState *s = VT82C686B_PM(d); +ViaPMState *s = VIA_PM(d); trace_via_pm_write(addr, val, len); pci_default_write_config(d, addr, val, len); @@ -127,7 +128,7 @@ static const MemoryRegionOps pm_io_ops = { }, }; -static void pm_update_sci(VT686PMState *s) +static void pm_update_sci(ViaPMState *s) { int sci_level, pmsts; @@ -145,13 +146,13 @@ static void pm_update_sci(VT686PMState *s) static void pm_tmr_timer(ACPIREGS *ar) { -VT686PMState *s = container_of(ar, VT686PMState, ar); +ViaPMState *s = container_of(ar, ViaPMState, ar); pm_update_sci(s); } -static void vt82c686b_pm_reset(DeviceState *d) +static void via_pm_reset(DeviceState *d) { -VT686PMState *s = VT82C686B_PM(d); +ViaPMState *s = VIA_PM(d); memset(s->dev.config + PCI_CONFIG_HEADER_SIZE, 0, PCI_CONFIG_SPACE_SIZE - PCI_CONFIG_HEADER_SIZE); @@ -164,9 +165,9 @@ static void vt82c686b_pm_reset(DeviceState *d) smb_io_space_update(s); } -static void vt82c686b_pm_realize(PCIDevice *dev, Error **errp) +static void via_pm_realize(PCIDevice *dev, Error **errp) { -VT686PMState *s = VT82C686B_PM(dev); +ViaPMState *s = VIA_PM(dev); pci_set_word(dev->config + PCI_STATUS, PCI_STATUS_FAST_BACK | PCI_STATUS_DEVSEL_MEDIUM); @@ -177,8 +178,7 @@ static void vt82c686b_pm_realize(PCIDevice *dev, Error **errp) apm_init(dev, >apm, NULL, s); -memory_region_init_io(>io, OBJECT(dev), _io_ops, s, - "vt82c686-pm", 0x100); +memory_region_init_io(>io, OBJECT(dev), _io_ops, s, "via-pm", 0x100); memory_region_add_subregion(pci_address_space_io(dev), 0, >io); memory_region_set_enabled(>io, false); @@ -187,34 +187,61 @@ static void vt82c686b_pm_realize(PCIDevice *dev, Error **errp) acpi_pm1_cnt_init(>ar, >io, false, false, 2); } +typedef struct via_pm_init_info { +uint16_t device_id; +} ViaPMInitInfo; + static void via_pm_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); +ViaPMInitInfo *info = data; -k->realize = vt82c686b_pm_realize; +k->realize = via_pm_realize;
[PATCH 1/7] vt82c686: Use shorter name for local variable holding object state
Rename local variable holding object state for readability and consistency. Signed-off-by: BALATON Zoltan --- hw/isa/vt82c686.c | 30 +++--- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index 02d6759c00..2633cfe7dc 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -95,8 +95,8 @@ static const MemoryRegionOps superio_ops = { static void vt82c686b_isa_reset(DeviceState *dev) { -VT82C686BISAState *vt82c = VT82C686B_ISA(dev); -uint8_t *pci_conf = vt82c->dev.config; +VT82C686BISAState *s = VT82C686B_ISA(dev); +uint8_t *pci_conf = s->dev.config; pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x00c0); pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY | @@ -112,24 +112,24 @@ static void vt82c686b_isa_reset(DeviceState *dev) pci_conf[0x5f] = 0x04; pci_conf[0x77] = 0x10; /* GPIO Control 1/2/3/4 */ -vt82c->superio_conf.config[0xe0] = 0x3c; -vt82c->superio_conf.config[0xe2] = 0x03; -vt82c->superio_conf.config[0xe3] = 0xfc; -vt82c->superio_conf.config[0xe6] = 0xde; -vt82c->superio_conf.config[0xe7] = 0xfe; -vt82c->superio_conf.config[0xe8] = 0xbe; +s->superio_conf.config[0xe0] = 0x3c; +s->superio_conf.config[0xe2] = 0x03; +s->superio_conf.config[0xe3] = 0xfc; +s->superio_conf.config[0xe6] = 0xde; +s->superio_conf.config[0xe7] = 0xfe; +s->superio_conf.config[0xe8] = 0xbe; } /* write config pci function0 registers. PCI-ISA bridge */ static void vt82c686b_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int len) { -VT82C686BISAState *vt686 = VT82C686B_ISA(d); +VT82C686BISAState *s = VT82C686B_ISA(d); trace_via_isa_write(addr, val, len); pci_default_write_config(d, addr, val, len); if (addr == 0x85) { /* enable or disable super IO configure */ -memory_region_set_enabled(>superio, val & 0x2); +memory_region_set_enabled(>superio, val & 0x2); } } @@ -289,7 +289,7 @@ static const VMStateDescription vmstate_via = { /* init the PCI-to-ISA bridge */ static void vt82c686b_realize(PCIDevice *d, Error **errp) { -VT82C686BISAState *vt82c = VT82C686B_ISA(d); +VT82C686BISAState *s = VT82C686B_ISA(d); uint8_t *pci_conf; ISABus *isa_bus; uint8_t *wmask; @@ -311,15 +311,15 @@ static void vt82c686b_realize(PCIDevice *d, Error **errp) } } -memory_region_init_io(>superio, OBJECT(d), _ops, - >superio_conf, "superio", 2); -memory_region_set_enabled(>superio, false); +memory_region_init_io(>superio, OBJECT(d), _ops, + >superio_conf, "superio", 2); +memory_region_set_enabled(>superio, false); /* * The floppy also uses 0x3f0 and 0x3f1. * But we do not emulate a floppy, so just set it here. */ memory_region_add_subregion(isa_bus->address_space_io, 0x3f0, ->superio); +>superio); } static void via_class_init(ObjectClass *klass, void *data) -- 2.21.3
[PATCH 3/7] vt82c686: Move superio memory region to SuperIOConfig struct
The superio memory region holds the io space index/data registers used to access the superio config registers that are implemented in struct SuperIOConfig. To keep these related things together move the memory region to SuperIOConfig and rename it accordingly. Also remove the unused data member of SuperIOConfig which is not needed as we store actual data values in the regs array. Signed-off-by: BALATON Zoltan --- hw/isa/vt82c686.c | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index a6f5a0843d..30fe02f4c6 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -29,12 +29,11 @@ typedef struct SuperIOConfig { uint8_t regs[0x100]; uint8_t index; -uint8_t data; +MemoryRegion io; } SuperIOConfig; struct VT82C686BISAState { PCIDevice dev; -MemoryRegion superio; SuperIOConfig superio_cfg; }; @@ -128,8 +127,9 @@ static void vt82c686b_write_config(PCIDevice *d, uint32_t addr, trace_via_isa_write(addr, val, len); pci_default_write_config(d, addr, val, len); -if (addr == 0x85) { /* enable or disable super IO configure */ -memory_region_set_enabled(>superio, val & 0x2); +if (addr == 0x85) { +/* BIT(1): enable or disable superio config io ports */ +memory_region_set_enabled(>superio_cfg.io, val & BIT(1)); } } @@ -311,15 +311,15 @@ static void vt82c686b_realize(PCIDevice *d, Error **errp) } } -memory_region_init_io(>superio, OBJECT(d), _cfg_ops, - >superio_cfg, "superio", 2); -memory_region_set_enabled(>superio, false); +memory_region_init_io(>superio_cfg.io, OBJECT(d), _cfg_ops, + >superio_cfg, "superio_cfg", 2); +memory_region_set_enabled(>superio_cfg.io, false); /* * The floppy also uses 0x3f0 and 0x3f1. * But we do not emulate a floppy, so just set it here. */ memory_region_add_subregion(isa_bus->address_space_io, 0x3f0, ->superio); +>superio_cfg.io); } static void via_class_init(ObjectClass *klass, void *data) -- 2.21.3
[PATCH 4/7] vt82c686: Reorganise code
Move lines around so that object definitions become consecutive and not scattered around. This brings functions belonging to an object together so it's clearer what's defined and what parts belong to which object. Signed-off-by: BALATON Zoltan --- hw/isa/vt82c686.c | 279 +++--- 1 file changed, 140 insertions(+), 139 deletions(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index 30fe02f4c6..fe8961b057 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -26,112 +26,7 @@ #include "exec/address-spaces.h" #include "trace.h" -typedef struct SuperIOConfig { -uint8_t regs[0x100]; -uint8_t index; -MemoryRegion io; -} SuperIOConfig; - -struct VT82C686BISAState { -PCIDevice dev; -SuperIOConfig superio_cfg; -}; - -OBJECT_DECLARE_SIMPLE_TYPE(VT82C686BISAState, VT82C686B_ISA) - -static void superio_cfg_write(void *opaque, hwaddr addr, uint64_t data, - unsigned size) -{ -SuperIOConfig *sc = opaque; - -if (addr == 0x3f0) { /* config index register */ -sc->index = data & 0xff; -} else { -bool can_write = true; -/* 0x3f1, config data register */ -trace_via_superio_write(sc->index, data & 0xff); -switch (sc->index) { -case 0x00 ... 0xdf: -case 0xe4: -case 0xe5: -case 0xe9 ... 0xed: -case 0xf3: -case 0xf5: -case 0xf7: -case 0xf9 ... 0xfb: -case 0xfd ... 0xff: -can_write = false; -break; -/* case 0xe6 ... 0xe8: Should set base port of parallel and serial */ -default: -break; - -} -if (can_write) { -sc->regs[sc->index] = data & 0xff; -} -} -} - -static uint64_t superio_cfg_read(void *opaque, hwaddr addr, unsigned size) -{ -SuperIOConfig *sc = opaque; -uint8_t val = sc->regs[sc->index]; - -trace_via_superio_read(sc->index, val); -return val; -} - -static const MemoryRegionOps superio_cfg_ops = { -.read = superio_cfg_read, -.write = superio_cfg_write, -.endianness = DEVICE_NATIVE_ENDIAN, -.impl = { -.min_access_size = 1, -.max_access_size = 1, -}, -}; - -static void vt82c686b_isa_reset(DeviceState *dev) -{ -VT82C686BISAState *s = VT82C686B_ISA(dev); -uint8_t *pci_conf = s->dev.config; - -pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x00c0); -pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY | - PCI_COMMAND_MASTER | PCI_COMMAND_SPECIAL); -pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM); - -pci_conf[0x48] = 0x01; /* Miscellaneous Control 3 */ -pci_conf[0x4a] = 0x04; /* IDE interrupt Routing */ -pci_conf[0x4f] = 0x03; /* DMA/Master Mem Access Control 3 */ -pci_conf[0x50] = 0x2d; /* PnP DMA Request Control */ -pci_conf[0x59] = 0x04; -pci_conf[0x5a] = 0x04; /* KBC/RTC Control*/ -pci_conf[0x5f] = 0x04; -pci_conf[0x77] = 0x10; /* GPIO Control 1/2/3/4 */ - -s->superio_cfg.regs[0xe0] = 0x3c; /* Device ID */ -s->superio_cfg.regs[0xe2] = 0x03; /* Function select */ -s->superio_cfg.regs[0xe3] = 0xfc; /* Floppy ctrl base addr */ -s->superio_cfg.regs[0xe6] = 0xde; /* Parallel port base addr */ -s->superio_cfg.regs[0xe7] = 0xfe; /* Serial port 1 base addr */ -s->superio_cfg.regs[0xe8] = 0xbe; /* Serial port 2 base addr */ -} - -/* write config pci function0 registers. PCI-ISA bridge */ -static void vt82c686b_write_config(PCIDevice *d, uint32_t addr, - uint32_t val, int len) -{ -VT82C686BISAState *s = VT82C686B_ISA(d); - -trace_via_isa_write(addr, val, len); -pci_default_write_config(d, addr, val, len); -if (addr == 0x85) { -/* BIT(1): enable or disable superio config io ports */ -memory_region_set_enabled(>superio_cfg.io, val & BIT(1)); -} -} +OBJECT_DECLARE_SIMPLE_TYPE(VT686PMState, VT82C686B_PM) struct VT686PMState { PCIDevice dev; @@ -142,30 +37,6 @@ struct VT686PMState { uint32_t smb_io_base; }; -OBJECT_DECLARE_SIMPLE_TYPE(VT686PMState, VT82C686B_PM) - -static void pm_update_sci(VT686PMState *s) -{ -int sci_level, pmsts; - -pmsts = acpi_pm1_evt_get_sts(>ar); -sci_level = (((pmsts & s->ar.pm1.evt.en) & - (ACPI_BITMASK_RT_CLOCK_ENABLE | - ACPI_BITMASK_POWER_BUTTON_ENABLE | - ACPI_BITMASK_GLOBAL_LOCK_ENABLE | - ACPI_BITMASK_TIMER_ENABLE)) != 0); -pci_set_irq(>dev, sci_level); -/* schedule a timer interruption if needed */ -acpi_pm_tmr_update(>ar, (s->ar.pm1.evt.en & ACPI_BITMASK_TIMER_ENABLE) && - !(pmsts & ACPI_BITMASK_TIMER_STATUS)); -} - -static void pm_tmr_timer(ACPIREGS *ar) -{ -VT686PMState *s = container_of(ar, VT686PMState, ar); -pm_update_sci(s); -} - static void pm_io_space_update(VT686PMState *s) { uint32_t
[PATCH 2/7] vt82c686: Rename superio config related parts
Use less confusing naming for superio config register handling related parts that makes it clearer what belongs to this part. Signed-off-by: BALATON Zoltan --- hw/isa/vt82c686.c | 48 +++ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index 2633cfe7dc..a6f5a0843d 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -27,7 +27,7 @@ #include "trace.h" typedef struct SuperIOConfig { -uint8_t config[0x100]; +uint8_t regs[0x100]; uint8_t index; uint8_t data; } SuperIOConfig; @@ -35,23 +35,23 @@ typedef struct SuperIOConfig { struct VT82C686BISAState { PCIDevice dev; MemoryRegion superio; -SuperIOConfig superio_conf; +SuperIOConfig superio_cfg; }; OBJECT_DECLARE_SIMPLE_TYPE(VT82C686BISAState, VT82C686B_ISA) -static void superio_ioport_writeb(void *opaque, hwaddr addr, uint64_t data, - unsigned size) +static void superio_cfg_write(void *opaque, hwaddr addr, uint64_t data, + unsigned size) { -SuperIOConfig *superio_conf = opaque; +SuperIOConfig *sc = opaque; if (addr == 0x3f0) { /* config index register */ -superio_conf->index = data & 0xff; +sc->index = data & 0xff; } else { bool can_write = true; /* 0x3f1, config data register */ -trace_via_superio_write(superio_conf->index, data & 0xff); -switch (superio_conf->index) { +trace_via_superio_write(sc->index, data & 0xff); +switch (sc->index) { case 0x00 ... 0xdf: case 0xe4: case 0xe5: @@ -69,23 +69,23 @@ static void superio_ioport_writeb(void *opaque, hwaddr addr, uint64_t data, } if (can_write) { -superio_conf->config[superio_conf->index] = data & 0xff; +sc->regs[sc->index] = data & 0xff; } } } -static uint64_t superio_ioport_readb(void *opaque, hwaddr addr, unsigned size) +static uint64_t superio_cfg_read(void *opaque, hwaddr addr, unsigned size) { -SuperIOConfig *superio_conf = opaque; -uint8_t val = superio_conf->config[superio_conf->index]; +SuperIOConfig *sc = opaque; +uint8_t val = sc->regs[sc->index]; -trace_via_superio_read(superio_conf->index, val); +trace_via_superio_read(sc->index, val); return val; } -static const MemoryRegionOps superio_ops = { -.read = superio_ioport_readb, -.write = superio_ioport_writeb, +static const MemoryRegionOps superio_cfg_ops = { +.read = superio_cfg_read, +.write = superio_cfg_write, .endianness = DEVICE_NATIVE_ENDIAN, .impl = { .min_access_size = 1, @@ -112,12 +112,12 @@ static void vt82c686b_isa_reset(DeviceState *dev) pci_conf[0x5f] = 0x04; pci_conf[0x77] = 0x10; /* GPIO Control 1/2/3/4 */ -s->superio_conf.config[0xe0] = 0x3c; -s->superio_conf.config[0xe2] = 0x03; -s->superio_conf.config[0xe3] = 0xfc; -s->superio_conf.config[0xe6] = 0xde; -s->superio_conf.config[0xe7] = 0xfe; -s->superio_conf.config[0xe8] = 0xbe; +s->superio_cfg.regs[0xe0] = 0x3c; /* Device ID */ +s->superio_cfg.regs[0xe2] = 0x03; /* Function select */ +s->superio_cfg.regs[0xe3] = 0xfc; /* Floppy ctrl base addr */ +s->superio_cfg.regs[0xe6] = 0xde; /* Parallel port base addr */ +s->superio_cfg.regs[0xe7] = 0xfe; /* Serial port 1 base addr */ +s->superio_cfg.regs[0xe8] = 0xbe; /* Serial port 2 base addr */ } /* write config pci function0 registers. PCI-ISA bridge */ @@ -311,8 +311,8 @@ static void vt82c686b_realize(PCIDevice *d, Error **errp) } } -memory_region_init_io(>superio, OBJECT(d), _ops, - >superio_conf, "superio", 2); +memory_region_init_io(>superio, OBJECT(d), _cfg_ops, + >superio_cfg, "superio", 2); memory_region_set_enabled(>superio, false); /* * The floppy also uses 0x3f0 and 0x3f1. -- 2.21.3
[PATCH 5/7] vt82c686: Fix SMBus IO base and configuration registers
The base address of the SMBus io ports and its enabled status is set by registers in the PCI config space but this was not correctly emulated. Instead the SMBus registers were mapped on realize to the base address set by a property to the address expected by fuloong2e firmware. Fix the base and config register handling to more closely model hardware which allows to remove the property and allows the guest to control this mapping. Do all this in reset instead of realize so it's correctly updated on reset. Signed-off-by: BALATON Zoltan --- hw/isa/vt82c686.c | 49 + hw/mips/fuloong2e.c | 4 +--- 2 files changed, 37 insertions(+), 16 deletions(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index fe8961b057..9c4d153022 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -22,6 +22,7 @@ #include "hw/i2c/pm_smbus.h" #include "qapi/error.h" #include "qemu/module.h" +#include "qemu/range.h" #include "qemu/timer.h" #include "exec/address-spaces.h" #include "trace.h" @@ -34,7 +35,6 @@ struct VT686PMState { ACPIREGS ar; APMState apm; PMSMBus smb; -uint32_t smb_io_base; }; static void pm_io_space_update(VT686PMState *s) @@ -50,11 +50,22 @@ static void pm_io_space_update(VT686PMState *s) memory_region_transaction_commit(); } +static void smb_io_space_update(VT686PMState *s) +{ +uint32_t smbase = pci_get_long(s->dev.config + 0x90) & 0xfff0UL; + +memory_region_transaction_begin(); +memory_region_set_address(>smb.io, smbase); +memory_region_set_enabled(>smb.io, s->dev.config[0xd2] & BIT(0)); +memory_region_transaction_commit(); +} + static int vmstate_acpi_post_load(void *opaque, int version_id) { VT686PMState *s = opaque; pm_io_space_update(s); +smb_io_space_update(s); return 0; } @@ -77,8 +88,18 @@ static const VMStateDescription vmstate_acpi = { static void pm_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int len) { +VT686PMState *s = VT82C686B_PM(d); + trace_via_pm_write(addr, val, len); pci_default_write_config(d, addr, val, len); +if (ranges_overlap(addr, len, 0x90, 4)) { +uint32_t v = pci_get_long(s->dev.config + 0x90); +pci_set_long(s->dev.config + 0x90, (v & 0xfff0UL) | 1); +} +if (range_covers_byte(addr, len, 0xd2)) { +s->dev.config[0xd2] &= 0xf; +smb_io_space_update(s); +} } static void pm_update_sci(VT686PMState *s) @@ -103,6 +124,17 @@ static void pm_tmr_timer(ACPIREGS *ar) pm_update_sci(s); } +static void vt82c686b_pm_reset(DeviceState *d) +{ +VT686PMState *s = VT82C686B_PM(d); + +/* SMBus IO base */ +pci_set_long(s->dev.config + 0x90, 1); +s->dev.config[0xd2] = 0; + +smb_io_space_update(s); +} + static void vt82c686b_pm_realize(PCIDevice *dev, Error **errp) { VT686PMState *s = VT82C686B_PM(dev); @@ -116,13 +148,9 @@ static void vt82c686b_pm_realize(PCIDevice *dev, Error **errp) /* 0x48-0x4B is Power Management I/O Base */ pci_set_long(pci_conf + 0x48, 0x0001); -/* SMB ports:0xeee0~0xeeef */ -s->smb_io_base = ((s->smb_io_base & 0xfff0) + 0x0); -pci_conf[0x90] = s->smb_io_base | 1; -pci_conf[0x91] = s->smb_io_base >> 8; -pci_conf[0xd2] = 0x90; pm_smbus_init(DEVICE(s), >smb, false); -memory_region_add_subregion(get_system_io(), s->smb_io_base, >smb.io); +memory_region_add_subregion(pci_address_space_io(dev), 0, >smb.io); +memory_region_set_enabled(>smb.io, false); apm_init(dev, >apm, NULL, s); @@ -135,11 +163,6 @@ static void vt82c686b_pm_realize(PCIDevice *dev, Error **errp) acpi_pm1_cnt_init(>ar, >io, false, false, 2); } -static Property via_pm_properties[] = { -DEFINE_PROP_UINT32("smb_io_base", VT686PMState, smb_io_base, 0), -DEFINE_PROP_END_OF_LIST(), -}; - static void via_pm_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -151,10 +174,10 @@ static void via_pm_class_init(ObjectClass *klass, void *data) k->device_id = PCI_DEVICE_ID_VIA_ACPI; k->class_id = PCI_CLASS_BRIDGE_OTHER; k->revision = 0x40; +dc->reset = vt82c686b_pm_reset; dc->desc = "PM"; dc->vmsd = _acpi; set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); -device_class_set_props(dc, via_pm_properties); } static const TypeInfo via_pm_info = { diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c index f393509633..bf19b4603e 100644 --- a/hw/mips/fuloong2e.c +++ b/hw/mips/fuloong2e.c @@ -263,9 +263,7 @@ static void vt82c686b_southbridge_init(PCIBus *pci_bus, int slot, qemu_irq intc, pci_create_simple(pci_bus, PCI_DEVFN(slot, 2), "vt82c686b-usb-uhci"); pci_create_simple(pci_bus, PCI_DEVFN(slot, 3), "vt82c686b-usb-uhci"); -dev = pci_new(PCI_DEVFN(slot, 4), TYPE_VT82C686B_PM); -qdev_prop_set_uint32(DEVICE(dev), "smb_io_base", 0xeee1); -pci_realize_and_unref(dev, pci_bus, _fatal); +dev =
[PATCH 0/7] vt82c686b clean ups - part II
This is continuing cleaning up the vt82c686b model with the aim to add vt8231 emulation without too much duplication, reusing or fixing the existing model where possible. (DISCALIMER: It does not aim to fix all existing bugs or make the model perfectly emulate the real chip.) This series continues general clean up and finishes the power management part. It is based on previous series and also needs Bonito fix (currently tested with Jiaxun's proposal). Still to go are superio and isa bridge parts that will be addressed in some later series but this and previous series could be merged so far independently of those future series so I'd appreciate if this could be reviewed and merged to keep outstanding patches managable. I can submit this and previous series together as one series if that helps. Regards, BALATON Zoltan BALATON Zoltan (7): vt82c686: Use shorter name for local variable holding object state vt82c686: Rename superio config related parts vt82c686: Move superio memory region to SuperIOConfig struct vt82c686: Reorganise code vt82c686: Fix SMBus IO base and configuration registers vt82c686: Fix up power management io base and config vt82c686: Make vt82c686b-pm an abstract base class and add vt8231-pm based on it hw/isa/trace-events | 2 + hw/isa/vt82c686.c | 417 ++ hw/mips/fuloong2e.c | 4 +- include/hw/isa/vt82c686.h | 1 + 4 files changed, 251 insertions(+), 173 deletions(-) -- 2.21.3
Re: [PATCH v2 2/2] via-ide: Fix fuloong2e support
On Tue, 29 Dec 2020, Mark Cave-Ayland wrote: On 29/12/2020 12:01, BALATON Zoltan via wrote: Fortunately with PCI_CLASS_PROG at 0x8a Linux will keep the VIA IDE in compatible mode and not attempt to switch to native mode: therefore if you keep this as-is and add the legacy IDE ioports back, that just leaves the problem with BAR4 (BMDMA). In effect your patch isn't setting compatible mode anymore, it is just disabling BMDMA. It's actually Guenter's patch so you're now bashing him not me... This is a deliberately misleading comment, and not a good introduction for It's not deliberately misleading just stating a fact that you deliberately misinterpret. Guenter has contributed before (he also fixed up my sam460ex emulation) and his contributions are certainly appreciated. I'm sorry that he got unintentinally invoved in this disagreement between us two but I think he can ignore all this without a problem. I did not mean to drag him into it, just pointed out what you're doing and I think he got that. someone external becoming involved with the project. Guenter's patch was a PoC demonstrating how to fix the fuloong2e machine, which is really appreciated since it clearly locates the problems to allow a fix to be applied upstream. (But I also think your time could be better spent than getting rid of this hack when there are much more hacks or missing functionalities to get rid of in the part you maintain.) And comments like this are not appropriate for a technical mailing list either. I've done my best to review your patch in good faith (including Don't misunderstand this again, I did not mean to say that you made mistakes (although everyone does so that's not a problem) but what I meant is that there are a lot of things even in your areas that could be improved and that's time much better spent than discussing this patch endlessly on phylosophical basis when it's unlikely to get better. reading related specifications and testing your pegasos2 model) and explain why it isn't reporting the correct information to the guest. Yes I agree this should be brought to off list and clear up this between us I just don't have time for it now but I'll write to you later. As for your comments, we've been through all this in March and I get the impression that whatever I submit is criticised by you all the time so I really wonder if it's against me personally or you just getting old and grumpy :-) Don't take this as personal, no insult is meant just want to know if I did something that made you change your mind about my contributions or you do this to everything submitted to QEMU, because that's slowly becomes a burden discouriging me to contribute anything. I already gave up contributing to OpenBIOS but won't give up with QEMU, but I'm a bit tired having to fight for every little change to get past you (even in areas you're not maintaining like this one). You can answer in private to this, I think others will be greateful to be left out of the discussion. Phil - I hope you find that found my review comments useful and that they explain why the patchset is wrong by always claiming legacy IDE ioports exist but not providing them unless the new option is set (and indeed indicating some of the shortcomings of QEMU related to PCI BARs in this area that can be improved in future). As I feel comments in this thread have become directed at me personally, I am going to take a step back from this. I'm sorry if you feel my replies got personal but I also feel your comments getting at me and you seemed to critique something that was addmittedly not perfect but working and demanded perfection where it's not feasible (without way more work that you can expect from unpayed contributors) and calling my patches wrong for that reason. I don't mind if you add comments, warnnings or change the commit message to say "this patch is all wrong but fixes Linux on fuloong2e and makes guests work with pegasos2 within the constraints of QEMU" as long as it gets in until a better fix may be available sometimes in the future. But: - this patch is not mine now - I did change what you asked in the first review but then you came back with this - all this has been discussed to death and everyone but you seemed to accept it I'll try to refrain from answering any more about this and let's continue off list if you want. I'd really want to avoid further confrontation but I happen to contribute to parts you also have an interest in so it's hard to avid each other so it would be better to get to some acceptable terms that allow me to contribute without upsetting you too much. Regards, BALATON Zoltan
Re: [PATCH v2 2/2] via-ide: Fix fuloong2e support
On Tue, 29 Dec 2020, Mark Cave-Ayland wrote: On 28/12/2020 20:50, BALATON Zoltan via wrote: I think leaving the legacy ports enabled is a bad idea for at least two reasons: 1) It may clash with other io ports on other machines, e.g. I'm not sure on PPC where firmware or OS does not expect to see legacy ISA ports won't map some io BAR of a PCI card there. 2) If this is left enabled there would be two ports poking the same registers so if that does not cause a problem by itself, writing to one accidentally (like when something is mapped over it) could cause corruption of IDE state so I think it's much better to protect this than later trying to debug such problems. Legacy ioports originate in the x86 world, however all the PCI bus enumeration code I've seen reserves the lower part of the IO address space to prevent such problems with e.g. a BIOS starting up in legacy mode. I don't remember the details and won't test it again but PPC has neither BIOS nor legacy io ports (or io ports for that matter, all that is memory mapped). If you want go back to the email thread in March where I've described in detail how I ended up with these and what are the assumptions of guests I've tested and tried to satisfy with this. Stop trying to compare it with hardware and look at it in a way that we want to make a device model that works with the guests we want to run. In that frame this works and probably the simplest way. Unless you fully want to implement all the quirks of the chip and take up all the clean up in QEMU needed for that (possibly risking breaking a lot of other boards along the way) this won't match hardware 100%. Regards, BALATON Zoltan
Re: [PATCH v2 2/2] via-ide: Fix fuloong2e support
On Tue, 29 Dec 2020, Mark Cave-Ayland wrote: On 28/12/2020 20:50, BALATON Zoltan via wrote: diff --git a/hw/ide/via.c b/hw/ide/via.c index be09912b33..7d54d7e829 100644 --- a/hw/ide/via.c +++ b/hw/ide/via.c @@ -26,6 +26,7 @@ #include "qemu/osdep.h" #include "hw/pci/pci.h" +#include "hw/qdev-properties.h" #include "migration/vmstate.h" #include "qemu/module.h" #include "sysemu/dma.h" @@ -185,12 +186,19 @@ static void via_ide_realize(PCIDevice *dev, Error **errp) >bus[1], "via-ide1-cmd", 4); pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, >cmd_bar[1]); - bmdma_setup_bar(d); - pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, >bmdma_bar); + if (!(d->flags & BIT(PCI_IDE_LEGACY_MODE))) { + /* Missing BAR4 will make Linux driver fall back to legacy PIO mode */ + bmdma_setup_bar(d); + pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, >bmdma_bar); + } Since the default value of the legacy mode parameter is false, then this means the device assumes native mode by default. Therefore PCI_CLASS_PROG should be set to 0x8f unless legacy mode is being used, in which case it should be 0x8a. I think this casued problems before because if it's not set to 0x8a (legacy) at start then guests may assume it's already switched to native mode by firmware and won't program the BARs and it will not work. This way, even if it looks odd all guests I've tested work so I don't want to touch this, because I don't want to test all guests again. Keep in mind we're not fully emulating this device so not every combination that may work on real hardware work in this model. We really either only emulate "half-native" mode (i.e. native mode with ISA IRQs) that's needed for pegasos2 guests or now again only emulate legacy mode if property is set for Linux on fuloong2e. (My original patch emulated half-native and native mode instead of legacy thinking that Linux on fuloong2e would adapt.) All other combinations, including switching between these two is expected to not work which is due to QEMU limitations as you've also discovered now. I think this is still an improvement over only emulating legacy mode before even if it does not yet fully model the chip and I've also cleaned up PCI IDE emulation during implementing this so that code can be shared between via-ide, sii3112 and CMD646 without much duplication. qdev_init_gpio_in(ds, via_ide_set_irq, 2); for (i = 0; i < 2; i++) { ide_bus_new(>bus[i], sizeof(d->bus[i]), ds, i, 2); + if (d->flags & BIT(PCI_IDE_LEGACY_MODE)) { + ide_init_ioport(>bus[i], NULL, i ? 0x170 : 0x1f0, + i ? 0x376 : 0x3f6); + } You could actually remove the if() here: PCI configuration always leaves a gap at the lower end of IO address space to avoid clashes with legacy ports. Therefore if a guest decides to switch to native mode and configure the BAR, it will never clash with the default legacy IDE ports. This has the advantage of minimising the parts protected by PCI_IDE_LEGACY_MODE whilst also providing the legacy ports if someone can devise a method to dynamically switch between compatible and native modes later. I think leaving the legacy ports enabled is a bad idea for at least two reasons: 1) It may clash with other io ports on other machines, e.g. I'm not sure on PPC where firmware or OS does not expect to see legacy ISA ports won't map some io BAR of a PCI card there. 2) If this is left enabled there would be two ports poking the same registers so if that does not cause a problem by itself, writing to one accidentally (like when something is mapped over it) could cause corruption of IDE state so I think it's much better to protect this than later trying to debug such problems. (You can't get rid of the flag without implementing mode switching that needs rewrite of ISA and PCI emulation in QEMU so just get over it.) Okay I'm getting confused now: I thought the original aim of this patchset was to allow a guest OS to switch VIA IDE to compatible mode by default? Then No, switching is still not supported and as you also discovered it's not easy to implement in QEMU so aim is to have property to set if we want to emulate legacy mode only or (half) native mode only. again whichever way you look at this, regardless of whether PCI_CLASS_PROG is set to 0x8a or 0x8f then QEMU's VIA IDE device is still advertising unsupported configurations to the guest OS. Yes, we're not fully emulating this device (see above) but advertise configurations that work WITH THE GUESTS! Pegasos2 guests will read PCI_CLASS_PROG and then switch to native mode (but still expecting interrupts on IRQ 14/15) so nothing will actually try to use legacy mode there but if it's not in that mode at the start
Re: [PATCH v2 2/2] via-ide: Fix fuloong2e support
On Tue, 29 Dec 2020, Philippe Mathieu-Daudé wrote: I think this casued problems before because if it's not set to 0x8a (legacy) at start then guests may assume it's already switched to native mode by firmware and won't program the BARs and it will not work. This way, even if it looks odd all guests I've tested work so I don't want to touch this, because I don't want to test all guests again. If you can describe on the list how you do your testing (mostly command line used, where image/demo can be downloaded), we might help writing an integration test to automate the testing. Don't worry if it involves using close-source binaries, we'll try to figure out a way. It's documented here: https://osdn.net/projects/qmiga/wiki/SubprojectPegasos2#h2-Current.20status.20and.20outstanding.20issues but pegasos2 is not in QEMU master yet, I'm just trying to clean it up and submit it so testing likely comes after I have a set of patches to send to add pegasos2. The version in qmiga repo is not the latest but one that works in itself, my current vt82c686c work is to upstream the vt8231 part. After that the rest should be simple: add mv64361 model and pegasos2 board code. The only problem I see with those is if it's OK to have board needing ROM image or if Mark torpedoes it for some reason :-). For the ROM I have plans to use vof (virtual open firmware emulation within QEMU, unmerged on qemu-ppc list currently for a while) but I couldn't get to that yet. Maybe Linux can be used via -kernel but I think it also needs Open Firmware client interface on pegasos2 so it won't work without some kind of firmware. (All this is also documented on above page if you scroll up.) (By the way I've created the qmiga.osdn.net project with the intent to share work with interested people on these but so far nobody seemed to be interested enough to join and help. There were about 2 or 3 people interested in ati-vga but got scared away when saw how much work is needed yet. Contributions are still welcome otherwise it will take another few years to finish.) Regards, BALATON Zoltan
Re: Bug in Bonito? (mips/fuloong2e)
On Tue, 29 Dec 2020, Philippe Mathieu-Daudé wrote: On 12/29/20 6:26 AM, Jiaxun Yang wrote: 在 2020/12/29 上午11:26, BALATON Zoltan 写道: Hello, While continuing with part two of my vt82c686b clean ups I've tried to implement SMBus IO base configuration in the vt82c686b-pm part that I've already done for vt8231 for pegasos2 and it should be the same for 686B. (In short, writing address to pm config 0x90 sets base address of smbus regs and bit 0 of 0xd2 enables/disables it.) This is what the firmware does first and it would allow removing hard coded 0xeee1 value and the property to set it and then I could reuse the same PM part in VT8231. [...] Any idea what this is trying to do and how to fix it? It's trying to translate Bonito style PCI config space r/w to standard PCI config space R/W. A quick galance told me change BONITO_PCICONF_REG_MASK to 0xff may help. With Jiaxun's change it works better: bonito_spciconf_write: bonito_spciconf_write 0490 size 4 val eee1 bonito_sbridge_pciaddr: cfgaddr 10490 pciaddr 2c90 busno 0 devno 5 funno 4 regno 144 pci_cfg_write vt82c686b-pm 05:4 @0x90 <- 0xeee1 via_pm_write addr 0x90 val 0xeee1 len 0x4 bonito_writel: bonito_writel 0018 val 1 saddr 6 bonito_readl: bonito_readl 0018 bonito_spciconf_write: bonito_spciconf_write 04d2 size 2 val 1 bonito_sbridge_pciaddr: cfgaddr 104d2 pciaddr 2cd2 busno 0 devno 5 funno 4 regno 210 pci_cfg_write vt82c686b-pm 05:4 @0xd2 <- 0x1 via_pm_write addr 0xd2 val 0x1 len 0x2 *** Should update smbus io base to eee1, enable (last line is my debug message). Not sure if this breaks anyhing else but PMON still seems to work (tested with pmon_2e.bin). Per the datasheet section "5.7.5. Accessing PCI configuration space" 0xfc is the correct value, but the register number starts at the 2nd bit. So this is not a write access to register 0xd2 but 0x34? If you can test, this is the snippet I plan to send later: -- >8 -- diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c index a99eced0657..65953766dd0 100644 --- a/hw/pci-host/bonito.c +++ b/hw/pci-host/bonito.c @@ -189,3 +189,3 @@ FIELD(BONGENCFG, PCIQUEUE, 12, 1) #define BONITO_PCICONF_REG_MASK0xFC -#define BONITO_PCICONF_REG_OFFSET 0 +#define BONITO_PCICONF_REG_OFFSET 2 --- This does not seem to work, I get all mixed up regs: bonito_spciconf_write: bonito_spciconf_write 0490 size 4 val eee1 bonito_sbridge_pciaddr: cfgaddr 10490 pciaddr 2c24 busno 0 devno 5 funno 4 regno 36 pci_cfg_write vt82c686b-pm 05:4 @0x24 <- 0xeee1 via_pm_write addr 0x24 val 0xeee1 len 0x4 bonito_writel: bonito_writel 0018 val 1 saddr 6 bonito_readl: bonito_readl 0018 bonito_spciconf_write: bonito_spciconf_write 04d2 size 2 val 1 bonito_sbridge_pciaddr: cfgaddr 104d2 pciaddr 2c34 busno 0 devno 5 funno 4 regno 52 pci_cfg_write vt82c686b-pm 05:4 @0x34 <- 0x1 via_pm_write addr 0x34 val 0x1 len 0x2 So I'll use the first one for now, that allows me to continue with vt82c686b. Regards, BALATON Zoltan
Bug in Bonito? (mips/fuloong2e)
Hello, While continuing with part two of my vt82c686b clean ups I've tried to implement SMBus IO base configuration in the vt82c686b-pm part that I've already done for vt8231 for pegasos2 and it should be the same for 686B. (In short, writing address to pm config 0x90 sets base address of smbus regs and bit 0 of 0xd2 enables/disables it.) This is what the firmware does first and it would allow removing hard coded 0xeee1 value and the property to set it and then I could reuse the same PM part in VT8231. I have code to implement this and it works with pegasos2 but fails with fuloong2e and pmon. I've debugged it that write to 0xd2 comes out as 0xd0 after some mapping in bonito: bonito_spciconf_write: bonito_spciconf_write 0490 size 4 val eee1 bonito_sbridge_pciaddr: cfgaddr 10490 pciaddr 2c90 busno 0 devno 5 funno 4 regno 144 pci_cfg_write vt82c686b-pm 05:4 @0x90 <- 0xeee1 via_pm_write addr 0x90 val 0xeee1 len 0x4 bonito_spciconf_write: bonito_spciconf_write 04d2 size 2 val 1 bonito_sbridge_pciaddr: cfgaddr 104d2 pciaddr 2cd0 busno 0 devno 5 funno 4 regno 208 pci_cfg_write vt82c686b-pm 05:4 @0xd0 <- 0x1 via_pm_write addr 0xd0 val 0x1 len 0x2 Note the first write to 0x90 is correct but the second ends up at 0xd0 instead of 0xd2 after bonito_sbridge_pciaddr(). This is somewhere here: https://git.qemu.org/?p=qemu.git;a=blob;f=hw/pci-host/bonito.c;h=a99eced06574f999f3f1b999576ae09d5f4b06ca;hb=HEAD#l446 Any idea what this is trying to do and how to fix it? Regards, BALATON Zoltan
[PATCH v3 1/2] ide: Make room for flags in PCIIDEState and add one for legacy mode
We'll need a flag for implementing some device specific behaviour in via-ide but we already have a currently CMD646 specific field that can be repurposed for this and leave room for further flags if needed in the future. This patch changes the "secondary" field to "flags" and change CMD646 and its users accordingly and define a new flag for forcing legacy mode that will be used by via-ide for now. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Guenter Roeck Tested-by: Guenter Roeck --- v3: Convert // comment in context v2: Fixed typo in commit message hw/ide/cmd646.c | 6 +++--- hw/sparc64/sun4u.c | 2 +- include/hw/ide/pci.h | 7 ++- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c index c254631485..cfea7fca06 100644 --- a/hw/ide/cmd646.c +++ b/hw/ide/cmd646.c @@ -255,8 +255,8 @@ static void pci_cmd646_ide_realize(PCIDevice *dev, Error **errp) pci_conf[PCI_CLASS_PROG] = 0x8f; -pci_conf[CNTRL] = CNTRL_EN_CH0; // enable IDE0 -if (d->secondary) { +pci_conf[CNTRL] = CNTRL_EN_CH0; /* enable IDE0 */ +if (d->flags & BIT(PCI_IDE_SECONDARY)) { /* XXX: if not enabled, really disable the seconday IDE controller */ pci_conf[CNTRL] |= CNTRL_EN_CH1; /* enable IDE1 */ } @@ -314,7 +314,7 @@ static void pci_cmd646_ide_exitfn(PCIDevice *dev) } static Property cmd646_ide_properties[] = { -DEFINE_PROP_UINT32("secondary", PCIIDEState, secondary, 0), +DEFINE_PROP_BIT("secondary", PCIIDEState, flags, PCI_IDE_SECONDARY, false), DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c index 0fa13a7330..c46baa9f48 100644 --- a/hw/sparc64/sun4u.c +++ b/hw/sparc64/sun4u.c @@ -674,7 +674,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem, } pci_dev = pci_new(PCI_DEVFN(3, 0), "cmd646-ide"); -qdev_prop_set_uint32(_dev->qdev, "secondary", 1); +qdev_prop_set_bit(_dev->qdev, "secondary", true); pci_realize_and_unref(pci_dev, pci_busA, _fatal); pci_ide_create_devs(pci_dev); diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h index d8384e1c42..75d1a32f6d 100644 --- a/include/hw/ide/pci.h +++ b/include/hw/ide/pci.h @@ -42,6 +42,11 @@ typedef struct BMDMAState { #define TYPE_PCI_IDE "pci-ide" OBJECT_DECLARE_SIMPLE_TYPE(PCIIDEState, PCI_IDE) +enum { +PCI_IDE_SECONDARY, /* used only for cmd646 */ +PCI_IDE_LEGACY_MODE +}; + struct PCIIDEState { /*< private >*/ PCIDevice parent_obj; @@ -49,7 +54,7 @@ struct PCIIDEState { IDEBus bus[2]; BMDMAState bmdma[2]; -uint32_t secondary; /* used only for cmd646 */ +uint32_t flags; MemoryRegion bmdma_bar; MemoryRegion cmd_bar[2]; MemoryRegion data_bar[2]; -- 2.21.3
[PATCH v3 2/2] via-ide: Fix fuloong2e support
From: Guenter Roeck The IDE legacy mode emulation has been removed in commit 4ea98d317eb ("ide/via: Implement and use native PCI IDE mode") but some Linux kernels (probably including def_config) require legacy mode on the Fuloong2e so only emulating native mode did not turn out feasible. Add property to via-ide model to make the mode configurable, and set legacy mode for Fuloong2e. Signed-off-by: Guenter Roeck [balaton: Use bit in flags for property, add comment for missing BAR4] Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé Tested-by: Guenter Roeck Reviewed-by: Jiaxun Yang --- v3: Use dash in property name v2: Reworded commit message hw/ide/via.c| 19 +-- hw/mips/fuloong2e.c | 4 +++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/hw/ide/via.c b/hw/ide/via.c index be09912b33..2d935b910f 100644 --- a/hw/ide/via.c +++ b/hw/ide/via.c @@ -26,6 +26,7 @@ #include "qemu/osdep.h" #include "hw/pci/pci.h" +#include "hw/qdev-properties.h" #include "migration/vmstate.h" #include "qemu/module.h" #include "sysemu/dma.h" @@ -185,12 +186,19 @@ static void via_ide_realize(PCIDevice *dev, Error **errp) >bus[1], "via-ide1-cmd", 4); pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, >cmd_bar[1]); -bmdma_setup_bar(d); -pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, >bmdma_bar); +if (!(d->flags & BIT(PCI_IDE_LEGACY_MODE))) { +/* Missing BAR4 will make Linux driver fall back to legacy PIO mode */ +bmdma_setup_bar(d); +pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, >bmdma_bar); +} qdev_init_gpio_in(ds, via_ide_set_irq, 2); for (i = 0; i < 2; i++) { ide_bus_new(>bus[i], sizeof(d->bus[i]), ds, i, 2); +if (d->flags & BIT(PCI_IDE_LEGACY_MODE)) { +ide_init_ioport(>bus[i], NULL, i ? 0x170 : 0x1f0, +i ? 0x376 : 0x3f6); +} ide_init2(>bus[i], qdev_get_gpio_in(ds, i)); bmdma_init(>bus[i], >bmdma[i], d); @@ -210,6 +218,12 @@ static void via_ide_exitfn(PCIDevice *dev) } } +static Property via_ide_properties[] = { +DEFINE_PROP_BIT("legacy-mode", PCIIDEState, flags, PCI_IDE_LEGACY_MODE, +false), +DEFINE_PROP_END_OF_LIST(), +}; + static void via_ide_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -223,6 +237,7 @@ static void via_ide_class_init(ObjectClass *klass, void *data) k->device_id = PCI_DEVICE_ID_VIA_IDE; k->revision = 0x06; k->class_id = PCI_CLASS_STORAGE_IDE; +device_class_set_props(dc, via_ide_properties); set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); } diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c index 45c596f4fe..d334fde389 100644 --- a/hw/mips/fuloong2e.c +++ b/hw/mips/fuloong2e.c @@ -253,7 +253,9 @@ static void vt82c686b_southbridge_init(PCIBus *pci_bus, int slot, qemu_irq intc, /* Super I/O */ isa_create_simple(isa_bus, TYPE_VT82C686B_SUPERIO); -dev = pci_create_simple(pci_bus, PCI_DEVFN(slot, 1), "via-ide"); +dev = pci_new(PCI_DEVFN(slot, 1), "via-ide"); +qdev_prop_set_bit(>qdev, "legacy-mode", true); +pci_realize_and_unref(dev, pci_bus, _fatal); pci_ide_create_devs(dev); pci_create_simple(pci_bus, PCI_DEVFN(slot, 2), "vt82c686b-usb-uhci"); -- 2.21.3
[PATCH v3 0/2] Fix via-ide for fuloong2e
v3 with review comments from Mark addressed BALATON Zoltan (1): ide: Make room for flags in PCIIDEState and add one for legacy mode Guenter Roeck (1): via-ide: Fix fuloong2e support hw/ide/cmd646.c | 6 +++--- hw/ide/via.c | 19 +-- hw/mips/fuloong2e.c | 4 +++- hw/sparc64/sun4u.c | 2 +- include/hw/ide/pci.h | 7 ++- 5 files changed, 30 insertions(+), 8 deletions(-) -- 2.21.3
Re: Problems with irq mapping in qemu v5.2
On Mon, 28 Dec 2020, Mark Cave-Ayland wrote: On 24/12/2020 08:11, BALATON Zoltan via wrote: On Wed, 23 Dec 2020, Guenter Roeck wrote: On Thu, Dec 24, 2020 at 02:34:07AM +0100, BALATON Zoltan wrote: [ ... ] If we need legacy mode then we may be able to emulate that by setting BARs to legacy ports ignoring what values are written to them if legacy mode config is set (which may be what the real chip does) and we already have IRQs hard wired to legacy values so that would give us legacy and half-native mode which is enough for both fuloong2e and pegasos2 but I'm not sure how can we fix BARs in QEMU because that's also handled by generic PCI code which I also don't want to break. The code below works for booting Linux while at the same time not affecting any other emulation. I don't claim it to be a perfect fix, and overloading the existing property is a bit hackish, but it does work. Yes, maybe combining it with my original patch 1 to change secondary to flags to make it a bit cleaner would work for me. Then we would either only emulate legacy or half-native mode which is sufficient for these two machines we have. If Mark or others do not object it this time, I can update my patch and resubmit with this one to fix this issue, otherwise let's wait what idea do they have because I hate to spend time with something only to be discarded again. I think we don't need more complete emulation of this chip than this for now but if somebody wants to attempt that I don't mind as long as it does not break pegasos2. I had a play with your patches this afternoon, and spent some time performing some experiments and also reading various PCI bus master specifications and datasheets: this helped me understand a lot more about the theory of IRQ routing and compatible vs. legacy mode. From reading all the documentation (including the VIA and other datasheets) I cannot find any reference to a half-native mode which makes me think The half-native mode is my simpler term for Linux's "non 100% native mode". This may not exist in hardware but exists as a concept in some Linux (and maybe other) drivers so emulating it just means we do what these drivers expect to work correctly. How this maps to hardware and what interactions are there with firmware may be interesting but I'm not interested to find out as long as all guests we care about work because adding more complexity just for the sake of correctly modeling hardware seems like a waste of time in this case. Thanks for taking the time to find and document these though, it may be useful if someone wants to clean this up further. I'm satisfied with getting it in good enough shape for fuloong2e and pegasos2 to boot the guests we want, because I'd rather spend time on other, more interesting stuff such as writing replacement firmware for pegasos2 to avoid needing an undistributable ROM, implementing missing sound support, improving ati-vga or getting the Mac ROM work with g3beige, and also FPU emulation on PPC (and these are just the QEMU related stuff, I can think of others too). All of those seem time better spent than beating this via-ide model further now just for the sake of perfection without any gain, because guests will not work better even after spending more time with this. That's why I call it a waste of time. I know you prefer perfect patches but as they say "Perfect is the enemy of good." (I could think of better use of your time too such as finishing your screamer patches or improving OpenBIOS or your original sparc interest but that's for you to decide what you do.) I also try to improve these models and add missing stuff as needed but my goal is not perfection because I don't have that much time, just reaching good enough. It can always be improved later (or corrected if it turns out to be needed as in this case) but if we always hold back until getting it perfect we wont get anywhere. If your level of perfection was a requirement in QEMU a lot of devices would not be there as they could not get in in the first place which means other people cannot improve it as there's nothing there to start with. So I think something that is good enough is at least a good start towards perfection. We can argue what level is good enough. I think if it makes guests work which seems to be the general approach in QEMU as a lot of devices don't actually model real hardware correctly but just so that guests run with it. Of course we should make it clean and follow hardware where possible but a lot of models don't do that (maybe actually very few are anywhere near perfect). something else is wrong here. At the simplest level it could simply be that the VIA doesn't tri-state its legacy IRQ lines whilst the device is in native mode (the SI controller has an option for this), or it could indicate there is a PCI IRQ routing problem somewhere else that hasn't been picked up yet. All of th
Re: [PATCH v2 2/2] via-ide: Fix fuloong2e support
On Mon, 28 Dec 2020, Mark Cave-Ayland wrote: On 27/12/2020 22:13, BALATON Zoltan via wrote: From: Guenter Roeck The IDE legacy mode emulation has been removed in commit 4ea98d317eb ("ide/via: Implement and use native PCI IDE mode") but some Linux kernels (probably including def_config) require legacy mode on the Fuloong2e so only emulating native mode did not turn out feasible. Add property to via-ide model to make the mode configurable, and set legacy mode for Fuloong2e. Signed-off-by: Guenter Roeck [balaton: Use bit in flags for property, add comment for missing BAR4] Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé Tested-by: Guenter Roeck --- v2: Reworded commit message hw/ide/via.c| 19 +-- hw/mips/fuloong2e.c | 4 +++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/hw/ide/via.c b/hw/ide/via.c index be09912b33..7d54d7e829 100644 --- a/hw/ide/via.c +++ b/hw/ide/via.c @@ -26,6 +26,7 @@ #include "qemu/osdep.h" #include "hw/pci/pci.h" +#include "hw/qdev-properties.h" #include "migration/vmstate.h" #include "qemu/module.h" #include "sysemu/dma.h" @@ -185,12 +186,19 @@ static void via_ide_realize(PCIDevice *dev, Error **errp) >bus[1], "via-ide1-cmd", 4); pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, >cmd_bar[1]); -bmdma_setup_bar(d); -pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, >bmdma_bar); +if (!(d->flags & BIT(PCI_IDE_LEGACY_MODE))) { +/* Missing BAR4 will make Linux driver fall back to legacy PIO mode */ +bmdma_setup_bar(d); +pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, >bmdma_bar); +} Since the default value of the legacy mode parameter is false, then this means the device assumes native mode by default. Therefore PCI_CLASS_PROG should be set to 0x8f unless legacy mode is being used, in which case it should be 0x8a. I think this casued problems before because if it's not set to 0x8a (legacy) at start then guests may assume it's already switched to native mode by firmware and won't program the BARs and it will not work. This way, even if it looks odd all guests I've tested work so I don't want to touch this, because I don't want to test all guests again. Keep in mind we're not fully emulating this device so not every combination that may work on real hardware work in this model. We really either only emulate "half-native" mode (i.e. native mode with ISA IRQs) that's needed for pegasos2 guests or now again only emulate legacy mode if property is set for Linux on fuloong2e. (My original patch emulated half-native and native mode instead of legacy thinking that Linux on fuloong2e would adapt.) All other combinations, including switching between these two is expected to not work which is due to QEMU limitations as you've also discovered now. I think this is still an improvement over only emulating legacy mode before even if it does not yet fully model the chip and I've also cleaned up PCI IDE emulation during implementing this so that code can be shared between via-ide, sii3112 and CMD646 without much duplication. qdev_init_gpio_in(ds, via_ide_set_irq, 2); for (i = 0; i < 2; i++) { ide_bus_new(>bus[i], sizeof(d->bus[i]), ds, i, 2); +if (d->flags & BIT(PCI_IDE_LEGACY_MODE)) { +ide_init_ioport(>bus[i], NULL, i ? 0x170 : 0x1f0, +i ? 0x376 : 0x3f6); +} You could actually remove the if() here: PCI configuration always leaves a gap at the lower end of IO address space to avoid clashes with legacy ports. Therefore if a guest decides to switch to native mode and configure the BAR, it will never clash with the default legacy IDE ports. This has the advantage of minimising the parts protected by PCI_IDE_LEGACY_MODE whilst also providing the legacy ports if someone can devise a method to dynamically switch between compatible and native modes later. I think leaving the legacy ports enabled is a bad idea for at least two reasons: 1) It may clash with other io ports on other machines, e.g. I'm not sure on PPC where firmware or OS does not expect to see legacy ISA ports won't map some io BAR of a PCI card there. 2) If this is left enabled there would be two ports poking the same registers so if that does not cause a problem by itself, writing to one accidentally (like when something is mapped over it) could cause corruption of IDE state so I think it's much better to protect this than later trying to debug such problems. (You can't get rid of the flag without implementing mode switching that needs rewrite of ISA and PCI emulation in QEMU so just get over it.) ide_init2(>bus[i], qdev_get_gpio_in(ds, i)); bmdma_init(>bus[i], >bmdma[i], d); @@
Re: [PATCH v2 1/2] ide: Make room for flags in PCIIDEState and add one for legacy mode
On Mon, 28 Dec 2020, Mark Cave-Ayland wrote: On 27/12/2020 22:13, BALATON Zoltan wrote: We'll need a flag for implementing some device specific behaviour in via-ide but we already have a currently CMD646 specific field that can be repurposed for this and leave room for further flags if needed in the future. This patch changes the "secondary" field to "flags" and change CMD646 and its users accordingly and define a new flag for forcing legacy mode that will be used by via-ide for now. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Guenter Roeck Tested-by: Guenter Roeck --- v2: Fixed typo in commit message hw/ide/cmd646.c | 4 ++-- hw/sparc64/sun4u.c | 2 +- include/hw/ide/pci.h | 7 ++- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c index c254631485..7a96016116 100644 --- a/hw/ide/cmd646.c +++ b/hw/ide/cmd646.c @@ -256,7 +256,7 @@ static void pci_cmd646_ide_realize(PCIDevice *dev, Error **errp) pci_conf[PCI_CLASS_PROG] = 0x8f; pci_conf[CNTRL] = CNTRL_EN_CH0; // enable IDE0 Doesn't the existing comment above cause checkpatch to fail? It didn't (nether when I ran it nor in patchew) but I can fix it if I send a new version. Regards, BALATON Zoltan -if (d->secondary) { +if (d->flags & BIT(PCI_IDE_SECONDARY)) { /* XXX: if not enabled, really disable the seconday IDE controller */ pci_conf[CNTRL] |= CNTRL_EN_CH1; /* enable IDE1 */ } @@ -314,7 +314,7 @@ static void pci_cmd646_ide_exitfn(PCIDevice *dev) } static Property cmd646_ide_properties[] = { -DEFINE_PROP_UINT32("secondary", PCIIDEState, secondary, 0), +DEFINE_PROP_BIT("secondary", PCIIDEState, flags, PCI_IDE_SECONDARY, false), DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c index 0fa13a7330..c46baa9f48 100644 --- a/hw/sparc64/sun4u.c +++ b/hw/sparc64/sun4u.c @@ -674,7 +674,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem, } pci_dev = pci_new(PCI_DEVFN(3, 0), "cmd646-ide"); -qdev_prop_set_uint32(_dev->qdev, "secondary", 1); +qdev_prop_set_bit(_dev->qdev, "secondary", true); pci_realize_and_unref(pci_dev, pci_busA, _fatal); pci_ide_create_devs(pci_dev); diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h index d8384e1c42..75d1a32f6d 100644 --- a/include/hw/ide/pci.h +++ b/include/hw/ide/pci.h @@ -42,6 +42,11 @@ typedef struct BMDMAState { #define TYPE_PCI_IDE "pci-ide" OBJECT_DECLARE_SIMPLE_TYPE(PCIIDEState, PCI_IDE) +enum { +PCI_IDE_SECONDARY, /* used only for cmd646 */ +PCI_IDE_LEGACY_MODE +}; + struct PCIIDEState { /*< private >*/ PCIDevice parent_obj; @@ -49,7 +54,7 @@ struct PCIIDEState { IDEBus bus[2]; BMDMAState bmdma[2]; -uint32_t secondary; /* used only for cmd646 */ +uint32_t flags; MemoryRegion bmdma_bar; MemoryRegion cmd_bar[2]; MemoryRegion data_bar[2]; Other than that I think this looks okay. ATB, Mark.
[PATCH v2 09/10] vt82c686: Convert debug printf to trace points
Drop DPRINTF and use trace functions instead. Two debug messages about unimplemented registers could be converted to qemu_log_mask() but in reality all registers are currently unimplemented (we just store and return values of writable regs but do nothing with them). As we already trace register access there's no need for additional debug messages so these are just removed and a comment is added as a reminder. Signed-off-by: BALATON Zoltan --- v2: Extended commit message hw/isa/trace-events | 6 ++ hw/isa/vt82c686.c | 51 + 2 files changed, 21 insertions(+), 36 deletions(-) diff --git a/hw/isa/trace-events b/hw/isa/trace-events index 3544c6213c..d267d3e652 100644 --- a/hw/isa/trace-events +++ b/hw/isa/trace-events @@ -13,3 +13,9 @@ pc87312_io_write(uint32_t addr, uint32_t val) "write addr=0x%x val=0x%x" # apm.c apm_io_read(uint8_t addr, uint8_t val) "read addr=0x%x val=0x%02x" apm_io_write(uint8_t addr, uint8_t val) "write addr=0x%x val=0x%02x" + +# vt82c686.c +via_isa_write(uint32_t addr, uint32_t val, int len) "addr 0x%x val 0x%x len 0x%x" +via_pm_write(uint32_t addr, uint32_t val, int len) "addr 0x%x val 0x%x len 0x%x" +via_superio_read(uint8_t addr, uint8_t val) "addr 0x%x val 0x%x" +via_superio_write(uint8_t addr, uint32_t val) "addr 0x%x val 0x%x" diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index cd87ec0103..d7ce15bf9f 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -27,14 +27,7 @@ #include "qemu/timer.h" #include "exec/address-spaces.h" #include "qom/object.h" - -/* #define DEBUG_VT82C686B */ - -#ifdef DEBUG_VT82C686B -#define DPRINTF(fmt, ...) fprintf(stderr, "%s: " fmt, __func__, ##__VA_ARGS__) -#else -#define DPRINTF(fmt, ...) -#endif +#include "trace.h" typedef struct SuperIOConfig { uint8_t config[0x100]; @@ -55,12 +48,12 @@ static void superio_ioport_writeb(void *opaque, hwaddr addr, uint64_t data, { SuperIOConfig *superio_conf = opaque; -DPRINTF("superio_ioport_writeb address 0x%x val 0x%x\n", addr, data); -if (addr == 0x3f0) { +if (addr == 0x3f0) { /* config index register */ superio_conf->index = data & 0xff; } else { bool can_write = true; -/* 0x3f1 */ +/* 0x3f1, config data register */ +trace_via_superio_write(superio_conf->index, data & 0xff); switch (superio_conf->index) { case 0x00 ... 0xdf: case 0xe4: @@ -73,18 +66,7 @@ static void superio_ioport_writeb(void *opaque, hwaddr addr, uint64_t data, case 0xfd ... 0xff: can_write = false; break; -case 0xe7: -if ((data & 0xff) != 0xfe) { -DPRINTF("change uart 1 base. unsupported yet\n"); -can_write = false; -} -break; -case 0xe8: -if ((data & 0xff) != 0xbe) { -DPRINTF("change uart 2 base. unsupported yet\n"); -can_write = false; -} -break; +/* case 0xe6 ... 0xe8: Should set base port of parallel and serial */ default: break; @@ -98,9 +80,10 @@ static void superio_ioport_writeb(void *opaque, hwaddr addr, uint64_t data, static uint64_t superio_ioport_readb(void *opaque, hwaddr addr, unsigned size) { SuperIOConfig *superio_conf = opaque; +uint8_t val = superio_conf->config[superio_conf->index]; -DPRINTF("superio_ioport_readb address 0x%x\n", addr); -return superio_conf->config[superio_conf->index]; +trace_via_superio_read(superio_conf->index, val); +return val; } static const MemoryRegionOps superio_ops = { @@ -141,16 +124,14 @@ static void vt82c686b_isa_reset(DeviceState *dev) } /* write config pci function0 registers. PCI-ISA bridge */ -static void vt82c686b_write_config(PCIDevice *d, uint32_t address, +static void vt82c686b_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int len) { VT82C686BISAState *vt686 = VT82C686B_ISA(d); -DPRINTF("vt82c686b_write_config address 0x%x val 0x%x len 0x%x\n", - address, val, len); - -pci_default_write_config(d, address, val, len); -if (address == 0x85) { /* enable or disable super IO configure */ +trace_via_isa_write(addr, val, len); +pci_default_write_config(d, addr, val, len); +if (addr == 0x85) { /* enable or disable super IO configure */ memory_region_set_enabled(>superio, val & 0x2); } } @@ -203,12 +184,10 @@ static void pm_io_space_update(VT686PMState *s) memory_region_transaction_commit(); } -static void pm_write_config(PCIDevice *d, -uint32_t address, uint32_t val, int len) +static void pm_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int len) { -DPRINTF("pm_write_config address 0x%x val 0x%x len 0x%x\n", - address, val, len); -pci_default_write_config(d, address, val, len); +
[PATCH v2 08/10] vt82c686: Remove legacy vt82c686b_pm_init() function
Remove legacy vt82c686b_pm_init() function and also rename VT82C686B_PM type name to match other device names. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé --- v2: Reworded commit message, delete i2c include here hw/isa/vt82c686.c | 18 -- hw/mips/fuloong2e.c | 5 - include/hw/isa/vt82c686.h | 5 + 3 files changed, 5 insertions(+), 23 deletions(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index 2912c253dc..cd87ec0103 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -12,7 +12,6 @@ #include "qemu/osdep.h" #include "hw/isa/vt82c686.h" -#include "hw/i2c/i2c.h" #include "hw/pci/pci.h" #include "hw/qdev-properties.h" #include "hw/isa/isa.h" @@ -167,7 +166,6 @@ struct VT686PMState { uint32_t smb_io_base; }; -#define TYPE_VT82C686B_PM "VT82C686B_PM" OBJECT_DECLARE_SIMPLE_TYPE(VT686PMState, VT82C686B_PM) static void pm_update_sci(VT686PMState *s) @@ -271,22 +269,6 @@ static void vt82c686b_pm_realize(PCIDevice *dev, Error **errp) acpi_pm1_cnt_init(>ar, >io, false, false, 2); } -I2CBus *vt82c686b_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, - qemu_irq sci_irq) -{ -PCIDevice *dev; -VT686PMState *s; - -dev = pci_new(devfn, TYPE_VT82C686B_PM); -qdev_prop_set_uint32(>qdev, "smb_io_base", smb_io_base); - -s = VT82C686B_PM(dev); - -pci_realize_and_unref(dev, bus, _fatal); - -return s->smb.smbus; -} - static Property via_pm_properties[] = { DEFINE_PROP_UINT32("smb_io_base", VT686PMState, smb_io_base, 0), DEFINE_PROP_END_OF_LIST(), diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c index d123e34d9e..a2b69a3a7a 100644 --- a/hw/mips/fuloong2e.c +++ b/hw/mips/fuloong2e.c @@ -263,7 +263,10 @@ static void vt82c686b_southbridge_init(PCIBus *pci_bus, int slot, qemu_irq intc, pci_create_simple(pci_bus, PCI_DEVFN(slot, 2), "vt82c686b-usb-uhci"); pci_create_simple(pci_bus, PCI_DEVFN(slot, 3), "vt82c686b-usb-uhci"); -*i2c_bus = vt82c686b_pm_init(pci_bus, PCI_DEVFN(slot, 4), 0xeee1, NULL); +dev = pci_new(PCI_DEVFN(slot, 4), TYPE_VT82C686B_PM); +qdev_prop_set_uint32(DEVICE(dev), "smb_io_base", 0xeee1); +pci_realize_and_unref(dev, pci_bus, _fatal); +*i2c_bus = I2C_BUS(qdev_get_child_bus(DEVICE(dev), "i2c")); /* Audio support */ pci_create_simple(pci_bus, PCI_DEVFN(slot, 5), TYPE_VIA_AC97); diff --git a/include/hw/isa/vt82c686.h b/include/hw/isa/vt82c686.h index 8d2d276fe1..5b0a1ffe72 100644 --- a/include/hw/isa/vt82c686.h +++ b/include/hw/isa/vt82c686.h @@ -3,11 +3,8 @@ #define TYPE_VT82C686B_ISA "vt82c686b-isa" #define TYPE_VT82C686B_SUPERIO "vt82c686b-superio" +#define TYPE_VT82C686B_PM "vt82c686b-pm" #define TYPE_VIA_AC97 "via-ac97" #define TYPE_VIA_MC97 "via-mc97" -/* vt82c686.c */ -I2CBus *vt82c686b_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, - qemu_irq sci_irq); - #endif -- 2.21.3
[PATCH v2 06/10] audio/via-ac97: Simplify code and set user_creatable to false
Remove some unneded, empty code and set user_creatable to false (besides being not implemented yet, so does nothing anyway) it's also normally part of VIA south bridge chips so no need to confuse users showing them these devices. Signed-off-by: BALATON Zoltan --- hw/audio/via-ac97.c | 51 + 1 file changed, 19 insertions(+), 32 deletions(-) diff --git a/hw/audio/via-ac97.c b/hw/audio/via-ac97.c index e617416ff7..6d556f74fc 100644 --- a/hw/audio/via-ac97.c +++ b/hw/audio/via-ac97.c @@ -13,27 +13,13 @@ #include "hw/isa/vt82c686.h" #include "hw/pci/pci.h" -struct VIAAC97State { -PCIDevice dev; -}; - -struct VIAMC97State { -PCIDevice dev; -}; - -OBJECT_DECLARE_SIMPLE_TYPE(VIAAC97State, VIA_AC97) -OBJECT_DECLARE_SIMPLE_TYPE(VIAMC97State, VIA_MC97) - -static void via_ac97_realize(PCIDevice *dev, Error **errp) +static void via_ac97_realize(PCIDevice *pci_dev, Error **errp) { -VIAAC97State *s = VIA_AC97(dev); -uint8_t *pci_conf = s->dev.config; - -pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_INVALIDATE | - PCI_COMMAND_PARITY); -pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_CAP_LIST | - PCI_STATUS_DEVSEL_MEDIUM); -pci_set_long(pci_conf + PCI_INTERRUPT_PIN, 0x03); +pci_set_word(pci_dev->config + PCI_COMMAND, + PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY); +pci_set_word(pci_dev->config + PCI_STATUS, + PCI_STATUS_CAP_LIST | PCI_STATUS_DEVSEL_MEDIUM); +pci_set_long(pci_dev->config + PCI_INTERRUPT_PIN, 0x03); } static void via_ac97_class_init(ObjectClass *klass, void *data) @@ -47,13 +33,15 @@ static void via_ac97_class_init(ObjectClass *klass, void *data) k->revision = 0x50; k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO; set_bit(DEVICE_CATEGORY_SOUND, dc->categories); -dc->desc = "AC97"; +dc->desc = "VIA AC97"; +/* Reason: Part of a south bridge chip */ +dc->user_creatable = false; } static const TypeInfo via_ac97_info = { .name = TYPE_VIA_AC97, .parent= TYPE_PCI_DEVICE, -.instance_size = sizeof(VIAAC97State), +.instance_size = sizeof(PCIDevice), .class_init= via_ac97_class_init, .interfaces = (InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, @@ -61,15 +49,12 @@ static const TypeInfo via_ac97_info = { }, }; -static void via_mc97_realize(PCIDevice *dev, Error **errp) +static void via_mc97_realize(PCIDevice *pci_dev, Error **errp) { -VIAMC97State *s = VIA_MC97(dev); -uint8_t *pci_conf = s->dev.config; - -pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_INVALIDATE | - PCI_COMMAND_VGA_PALETTE); -pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM); -pci_set_long(pci_conf + PCI_INTERRUPT_PIN, 0x03); +pci_set_word(pci_dev->config + PCI_COMMAND, + PCI_COMMAND_INVALIDATE | PCI_COMMAND_VGA_PALETTE); +pci_set_word(pci_dev->config + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM); +pci_set_long(pci_dev->config + PCI_INTERRUPT_PIN, 0x03); } static void via_mc97_class_init(ObjectClass *klass, void *data) @@ -83,13 +68,15 @@ static void via_mc97_class_init(ObjectClass *klass, void *data) k->class_id = PCI_CLASS_COMMUNICATION_OTHER; k->revision = 0x30; set_bit(DEVICE_CATEGORY_NETWORK, dc->categories); -dc->desc = "MC97"; +dc->desc = "VIA MC97"; +/* Reason: Part of a south bridge chip */ +dc->user_creatable = false; } static const TypeInfo via_mc97_info = { .name = TYPE_VIA_MC97, .parent= TYPE_PCI_DEVICE, -.instance_size = sizeof(VIAMC97State), +.instance_size = sizeof(PCIDevice), .class_init= via_mc97_class_init, .interfaces = (InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, -- 2.21.3
[PATCH v2 07/10] vt82c686: Remove legacy vt82c686b_isa_init() function
Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé --- v2: Reworded commit message hw/isa/vt82c686.c | 9 - hw/mips/fuloong2e.c | 4 +++- include/hw/isa/vt82c686.h | 3 +-- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index 9567326d8e..2912c253dc 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -49,7 +49,6 @@ struct VT82C686BISAState { SuperIOConfig superio_conf; }; -#define TYPE_VT82C686B_ISA "vt82c686b-isa" OBJECT_DECLARE_SIMPLE_TYPE(VT82C686BISAState, VT82C686B_ISA) static void superio_ioport_writeb(void *opaque, hwaddr addr, uint64_t data, @@ -367,14 +366,6 @@ static void vt82c686b_realize(PCIDevice *d, Error **errp) >superio); } -ISABus *vt82c686b_isa_init(PCIBus *bus, int devfn) -{ -PCIDevice *d; - -d = pci_create_simple_multifunction(bus, devfn, true, TYPE_VT82C686B_ISA); -return ISA_BUS(qdev_get_child_bus(DEVICE(d), "isa.0")); -} - static void via_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c index 3b0489f781..d123e34d9e 100644 --- a/hw/mips/fuloong2e.c +++ b/hw/mips/fuloong2e.c @@ -240,7 +240,9 @@ static void vt82c686b_southbridge_init(PCIBus *pci_bus, int slot, qemu_irq intc, ISABus *isa_bus; PCIDevice *dev; -isa_bus = vt82c686b_isa_init(pci_bus, PCI_DEVFN(slot, 0)); +dev = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(slot, 0), true, + TYPE_VT82C686B_ISA); +isa_bus = ISA_BUS(qdev_get_child_bus(DEVICE(dev), "isa.0")); assert(isa_bus); *p_isa_bus = isa_bus; /* Interrupt controller */ diff --git a/include/hw/isa/vt82c686.h b/include/hw/isa/vt82c686.h index ff80a926dc..8d2d276fe1 100644 --- a/include/hw/isa/vt82c686.h +++ b/include/hw/isa/vt82c686.h @@ -1,13 +1,12 @@ #ifndef HW_VT82C686_H #define HW_VT82C686_H - +#define TYPE_VT82C686B_ISA "vt82c686b-isa" #define TYPE_VT82C686B_SUPERIO "vt82c686b-superio" #define TYPE_VIA_AC97 "via-ac97" #define TYPE_VIA_MC97 "via-mc97" /* vt82c686.c */ -ISABus *vt82c686b_isa_init(PCIBus * bus, int devfn); I2CBus *vt82c686b_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, qemu_irq sci_irq); -- 2.21.3
[PATCH v2 10/10] vt82c686: Remove unneeded includes and defines
These are not used or not needed. Signed-off-by: BALATON Zoltan --- v2: Added back a few that we get indirectly but keep it explicit hw/isa/vt82c686.c | 5 - 1 file changed, 5 deletions(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index d7ce15bf9f..02d6759c00 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -16,9 +16,7 @@ #include "hw/qdev-properties.h" #include "hw/isa/isa.h" #include "hw/isa/superio.h" -#include "hw/sysbus.h" #include "migration/vmstate.h" -#include "hw/mips/mips.h" #include "hw/isa/apm.h" #include "hw/acpi/acpi.h" #include "hw/i2c/pm_smbus.h" @@ -26,7 +24,6 @@ #include "qemu/module.h" #include "qemu/timer.h" #include "exec/address-spaces.h" -#include "qom/object.h" #include "trace.h" typedef struct SuperIOConfig { @@ -136,8 +133,6 @@ static void vt82c686b_write_config(PCIDevice *d, uint32_t addr, } } -#define ACPI_DBG_IO_ADDR 0xb044 - struct VT686PMState { PCIDevice dev; MemoryRegion io; -- 2.21.3
[PATCH v2 05/10] vt82c686: Split off via-[am]c97 into separate file in hw/audio
The via-[am]c97 code is supposed to implement the audio part of VIA south bridge chips so it is better placed under hw/audio/. Split it off into a separate file. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé --- v2: Reworded commit message hw/audio/meson.build | 1 + hw/audio/via-ac97.c | 106 +++ hw/isa/vt82c686.c| 91 - 3 files changed, 107 insertions(+), 91 deletions(-) create mode 100644 hw/audio/via-ac97.c diff --git a/hw/audio/meson.build b/hw/audio/meson.build index 549e9a0396..32c42bdebe 100644 --- a/hw/audio/meson.build +++ b/hw/audio/meson.build @@ -11,4 +11,5 @@ softmmu_ss.add(when: 'CONFIG_MILKYMIST', if_true: files('milkymist-ac97.c')) softmmu_ss.add(when: 'CONFIG_PCSPK', if_true: files('pcspk.c')) softmmu_ss.add(when: 'CONFIG_PL041', if_true: files('pl041.c', 'lm4549.c')) softmmu_ss.add(when: 'CONFIG_SB16', if_true: files('sb16.c')) +softmmu_ss.add(when: 'CONFIG_VT82C686', if_true: files('via-ac97.c')) softmmu_ss.add(when: 'CONFIG_WM8750', if_true: files('wm8750.c')) diff --git a/hw/audio/via-ac97.c b/hw/audio/via-ac97.c new file mode 100644 index 00..e617416ff7 --- /dev/null +++ b/hw/audio/via-ac97.c @@ -0,0 +1,106 @@ +/* + * VIA south bridges sound support + * + * This work is licensed under the GNU GPL license version 2 or later. + */ + +/* + * TODO: This is entirely boiler plate just registering empty PCI devices + * with the right ID guests expect, functionality should be added here. + */ + +#include "qemu/osdep.h" +#include "hw/isa/vt82c686.h" +#include "hw/pci/pci.h" + +struct VIAAC97State { +PCIDevice dev; +}; + +struct VIAMC97State { +PCIDevice dev; +}; + +OBJECT_DECLARE_SIMPLE_TYPE(VIAAC97State, VIA_AC97) +OBJECT_DECLARE_SIMPLE_TYPE(VIAMC97State, VIA_MC97) + +static void via_ac97_realize(PCIDevice *dev, Error **errp) +{ +VIAAC97State *s = VIA_AC97(dev); +uint8_t *pci_conf = s->dev.config; + +pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_INVALIDATE | + PCI_COMMAND_PARITY); +pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_CAP_LIST | + PCI_STATUS_DEVSEL_MEDIUM); +pci_set_long(pci_conf + PCI_INTERRUPT_PIN, 0x03); +} + +static void via_ac97_class_init(ObjectClass *klass, void *data) +{ +DeviceClass *dc = DEVICE_CLASS(klass); +PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + +k->realize = via_ac97_realize; +k->vendor_id = PCI_VENDOR_ID_VIA; +k->device_id = PCI_DEVICE_ID_VIA_AC97; +k->revision = 0x50; +k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO; +set_bit(DEVICE_CATEGORY_SOUND, dc->categories); +dc->desc = "AC97"; +} + +static const TypeInfo via_ac97_info = { +.name = TYPE_VIA_AC97, +.parent= TYPE_PCI_DEVICE, +.instance_size = sizeof(VIAAC97State), +.class_init= via_ac97_class_init, +.interfaces = (InterfaceInfo[]) { +{ INTERFACE_CONVENTIONAL_PCI_DEVICE }, +{ }, +}, +}; + +static void via_mc97_realize(PCIDevice *dev, Error **errp) +{ +VIAMC97State *s = VIA_MC97(dev); +uint8_t *pci_conf = s->dev.config; + +pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_INVALIDATE | + PCI_COMMAND_VGA_PALETTE); +pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM); +pci_set_long(pci_conf + PCI_INTERRUPT_PIN, 0x03); +} + +static void via_mc97_class_init(ObjectClass *klass, void *data) +{ +DeviceClass *dc = DEVICE_CLASS(klass); +PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + +k->realize = via_mc97_realize; +k->vendor_id = PCI_VENDOR_ID_VIA; +k->device_id = PCI_DEVICE_ID_VIA_MC97; +k->class_id = PCI_CLASS_COMMUNICATION_OTHER; +k->revision = 0x30; +set_bit(DEVICE_CATEGORY_NETWORK, dc->categories); +dc->desc = "MC97"; +} + +static const TypeInfo via_mc97_info = { +.name = TYPE_VIA_MC97, +.parent= TYPE_PCI_DEVICE, +.instance_size = sizeof(VIAMC97State), +.class_init= via_mc97_class_init, +.interfaces = (InterfaceInfo[]) { +{ INTERFACE_CONVENTIONAL_PCI_DEVICE }, +{ }, +}, +}; + +static void via_ac97_register_types(void) +{ +type_register_static(_ac97_info); +type_register_static(_mc97_info); +} + +type_init(via_ac97_register_types) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index 8677a2d212..9567326d8e 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -168,14 +168,6 @@ struct VT686PMState { uint32_t smb_io_base; }; -struct VIAAC97State { -PCIDevice dev; -}; - -struct VIAMC97State { -PCIDevice dev; -}; - #define TYPE_VT82C686B_PM "VT82C686B_PM" OBJECT_DECLARE_SIMPLE_TYPE(VT686PMState, VT82C686B_PM) @@ -247,87 +239,6 @@ static const VMStateDescription vmstate_acpi = { } }; -/* - * TODO: VIA_AC97 and VIA_MC97 - * just register a PCI device now, functionalities will be implemented later. - */ - -OBJECT_DECLARE_SIMPLE_TYPE(VIAMC97State, VIA_MC97)
[PATCH v2 02/10] vt82c686: Remove unnecessary _DEVICE suffix from type macros
There's no reason to suffix everything with _DEVICE when the names are already unique without it and shorter names are more readable. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé --- hw/isa/vt82c686.c | 48 +++ 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index 2a0f85dea9..1be1169f83 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -49,8 +49,8 @@ struct VT82C686BState { SuperIOConfig superio_conf; }; -#define TYPE_VT82C686B_DEVICE "VT82C686B" -OBJECT_DECLARE_SIMPLE_TYPE(VT82C686BState, VT82C686B_DEVICE) +#define TYPE_VT82C686B "VT82C686B" +OBJECT_DECLARE_SIMPLE_TYPE(VT82C686BState, VT82C686B) static void superio_ioport_writeb(void *opaque, hwaddr addr, uint64_t data, unsigned size) @@ -117,7 +117,7 @@ static const MemoryRegionOps superio_ops = { static void vt82c686b_isa_reset(DeviceState *dev) { -VT82C686BState *vt82c = VT82C686B_DEVICE(dev); +VT82C686BState *vt82c = VT82C686B(dev); uint8_t *pci_conf = vt82c->dev.config; pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x00c0); @@ -146,7 +146,7 @@ static void vt82c686b_isa_reset(DeviceState *dev) static void vt82c686b_write_config(PCIDevice *d, uint32_t address, uint32_t val, int len) { -VT82C686BState *vt686 = VT82C686B_DEVICE(d); +VT82C686BState *vt686 = VT82C686B(d); DPRINTF("vt82c686b_write_config address 0x%x val 0x%x len 0x%x\n", address, val, len); @@ -176,14 +176,14 @@ struct VIAMC97State { PCIDevice dev; }; -#define TYPE_VT82C686B_PM_DEVICE "VT82C686B_PM" -OBJECT_DECLARE_SIMPLE_TYPE(VT686PMState, VT82C686B_PM_DEVICE) +#define TYPE_VT82C686B_PM "VT82C686B_PM" +OBJECT_DECLARE_SIMPLE_TYPE(VT686PMState, VT82C686B_PM) -#define TYPE_VIA_MC97_DEVICE "VIA_MC97" -OBJECT_DECLARE_SIMPLE_TYPE(VIAMC97State, VIA_MC97_DEVICE) +#define TYPE_VIA_MC97 "VIA_MC97" +OBJECT_DECLARE_SIMPLE_TYPE(VIAMC97State, VIA_MC97) -#define TYPE_VIA_AC97_DEVICE "VIA_AC97" -OBJECT_DECLARE_SIMPLE_TYPE(VIAAC97State, VIA_AC97_DEVICE) +#define TYPE_VIA_AC97 "VIA_AC97" +OBJECT_DECLARE_SIMPLE_TYPE(VIAAC97State, VIA_AC97) static void pm_update_sci(VT686PMState *s) { @@ -260,7 +260,7 @@ static const VMStateDescription vmstate_acpi = { static void vt82c686b_ac97_realize(PCIDevice *dev, Error **errp) { -VIAAC97State *s = VIA_AC97_DEVICE(dev); +VIAAC97State *s = VIA_AC97(dev); uint8_t *pci_conf = s->dev.config; pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_INVALIDATE | @@ -274,7 +274,7 @@ void vt82c686b_ac97_init(PCIBus *bus, int devfn) { PCIDevice *dev; -dev = pci_new(devfn, TYPE_VIA_AC97_DEVICE); +dev = pci_new(devfn, TYPE_VIA_AC97); pci_realize_and_unref(dev, bus, _fatal); } @@ -293,7 +293,7 @@ static void via_ac97_class_init(ObjectClass *klass, void *data) } static const TypeInfo via_ac97_info = { -.name = TYPE_VIA_AC97_DEVICE, +.name = TYPE_VIA_AC97, .parent= TYPE_PCI_DEVICE, .instance_size = sizeof(VIAAC97State), .class_init= via_ac97_class_init, @@ -305,7 +305,7 @@ static const TypeInfo via_ac97_info = { static void vt82c686b_mc97_realize(PCIDevice *dev, Error **errp) { -VIAMC97State *s = VIA_MC97_DEVICE(dev); +VIAMC97State *s = VIA_MC97(dev); uint8_t *pci_conf = s->dev.config; pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_INVALIDATE | @@ -318,7 +318,7 @@ void vt82c686b_mc97_init(PCIBus *bus, int devfn) { PCIDevice *dev; -dev = pci_new(devfn, TYPE_VIA_MC97_DEVICE); +dev = pci_new(devfn, TYPE_VIA_MC97); pci_realize_and_unref(dev, bus, _fatal); } @@ -337,7 +337,7 @@ static void via_mc97_class_init(ObjectClass *klass, void *data) } static const TypeInfo via_mc97_info = { -.name = TYPE_VIA_MC97_DEVICE, +.name = TYPE_VIA_MC97, .parent= TYPE_PCI_DEVICE, .instance_size = sizeof(VIAMC97State), .class_init= via_mc97_class_init, @@ -350,7 +350,7 @@ static const TypeInfo via_mc97_info = { /* vt82c686 pm init */ static void vt82c686b_pm_realize(PCIDevice *dev, Error **errp) { -VT686PMState *s = VT82C686B_PM_DEVICE(dev); +VT686PMState *s = VT82C686B_PM(dev); uint8_t *pci_conf; pci_conf = s->dev.config; @@ -386,10 +386,10 @@ I2CBus *vt82c686b_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, PCIDevice *dev; VT686PMState *s; -dev = pci_new(devfn, TYPE_VT82C686B_PM_DEVICE); +dev = pci_new(devfn, TYPE_VT82C686B_PM); qdev_prop_set_uint32(>qdev, "smb_io_base", smb_io_base); -s = VT82C686B_PM_DEVICE(dev); +s = VT82C686B_PM(dev); pci_realize_and_unref(dev, bus, _fatal); @@ -419,7 +419,7 @@ static void via_pm_class_init(ObjectClass *klass, void *data) } static const TypeInfo via_pm_info = { -.name =
[PATCH v2 01/10] vt82c686: Rename AC97/MC97 parts from VT82C686B to VIA
These parts are common between VT82C686B and VT8231 so can be shared in the future. Rename them to VIA prefix accordingly. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé --- hw/isa/vt82c686.c | 28 ++-- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index b3170c70c3..2a0f85dea9 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -168,22 +168,22 @@ struct VT686PMState { uint32_t smb_io_base; }; -struct VT686AC97State { +struct VIAAC97State { PCIDevice dev; }; -struct VT686MC97State { +struct VIAMC97State { PCIDevice dev; }; #define TYPE_VT82C686B_PM_DEVICE "VT82C686B_PM" OBJECT_DECLARE_SIMPLE_TYPE(VT686PMState, VT82C686B_PM_DEVICE) -#define TYPE_VT82C686B_MC97_DEVICE "VT82C686B_MC97" -OBJECT_DECLARE_SIMPLE_TYPE(VT686MC97State, VT82C686B_MC97_DEVICE) +#define TYPE_VIA_MC97_DEVICE "VIA_MC97" +OBJECT_DECLARE_SIMPLE_TYPE(VIAMC97State, VIA_MC97_DEVICE) -#define TYPE_VT82C686B_AC97_DEVICE "VT82C686B_AC97" -OBJECT_DECLARE_SIMPLE_TYPE(VT686AC97State, VT82C686B_AC97_DEVICE) +#define TYPE_VIA_AC97_DEVICE "VIA_AC97" +OBJECT_DECLARE_SIMPLE_TYPE(VIAAC97State, VIA_AC97_DEVICE) static void pm_update_sci(VT686PMState *s) { @@ -260,7 +260,7 @@ static const VMStateDescription vmstate_acpi = { static void vt82c686b_ac97_realize(PCIDevice *dev, Error **errp) { -VT686AC97State *s = VT82C686B_AC97_DEVICE(dev); +VIAAC97State *s = VIA_AC97_DEVICE(dev); uint8_t *pci_conf = s->dev.config; pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_INVALIDATE | @@ -274,7 +274,7 @@ void vt82c686b_ac97_init(PCIBus *bus, int devfn) { PCIDevice *dev; -dev = pci_new(devfn, TYPE_VT82C686B_AC97_DEVICE); +dev = pci_new(devfn, TYPE_VIA_AC97_DEVICE); pci_realize_and_unref(dev, bus, _fatal); } @@ -293,9 +293,9 @@ static void via_ac97_class_init(ObjectClass *klass, void *data) } static const TypeInfo via_ac97_info = { -.name = TYPE_VT82C686B_AC97_DEVICE, +.name = TYPE_VIA_AC97_DEVICE, .parent= TYPE_PCI_DEVICE, -.instance_size = sizeof(VT686AC97State), +.instance_size = sizeof(VIAAC97State), .class_init= via_ac97_class_init, .interfaces = (InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, @@ -305,7 +305,7 @@ static const TypeInfo via_ac97_info = { static void vt82c686b_mc97_realize(PCIDevice *dev, Error **errp) { -VT686MC97State *s = VT82C686B_MC97_DEVICE(dev); +VIAMC97State *s = VIA_MC97_DEVICE(dev); uint8_t *pci_conf = s->dev.config; pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_INVALIDATE | @@ -318,7 +318,7 @@ void vt82c686b_mc97_init(PCIBus *bus, int devfn) { PCIDevice *dev; -dev = pci_new(devfn, TYPE_VT82C686B_MC97_DEVICE); +dev = pci_new(devfn, TYPE_VIA_MC97_DEVICE); pci_realize_and_unref(dev, bus, _fatal); } @@ -337,9 +337,9 @@ static void via_mc97_class_init(ObjectClass *klass, void *data) } static const TypeInfo via_mc97_info = { -.name = TYPE_VT82C686B_MC97_DEVICE, +.name = TYPE_VIA_MC97_DEVICE, .parent= TYPE_PCI_DEVICE, -.instance_size = sizeof(VT686MC97State), +.instance_size = sizeof(VIAMC97State), .class_init= via_mc97_class_init, .interfaces = (InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, -- 2.21.3
[PATCH v2 04/10] vt82c686: Remove vt82c686b_[am]c97_init() functions
These are legacy init functions that are just equivalent to directly calling pci_create_simple so do that instead. Also rename objects to lower case via-ac97 and via-mc97 matching naming of other devices. Signed-off-by: BALATON Zoltan --- hw/isa/vt82c686.c | 27 --- hw/mips/fuloong2e.c | 4 ++-- include/hw/isa/vt82c686.h | 4 ++-- 3 files changed, 8 insertions(+), 27 deletions(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index d40599c7da..8677a2d212 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -179,12 +179,6 @@ struct VIAMC97State { #define TYPE_VT82C686B_PM "VT82C686B_PM" OBJECT_DECLARE_SIMPLE_TYPE(VT686PMState, VT82C686B_PM) -#define TYPE_VIA_MC97 "VIA_MC97" -OBJECT_DECLARE_SIMPLE_TYPE(VIAMC97State, VIA_MC97) - -#define TYPE_VIA_AC97 "VIA_AC97" -OBJECT_DECLARE_SIMPLE_TYPE(VIAAC97State, VIA_AC97) - static void pm_update_sci(VT686PMState *s) { int sci_level, pmsts; @@ -254,10 +248,13 @@ static const VMStateDescription vmstate_acpi = { }; /* - * TODO: vt82c686b_ac97_init() and vt82c686b_mc97_init() + * TODO: VIA_AC97 and VIA_MC97 * just register a PCI device now, functionalities will be implemented later. */ +OBJECT_DECLARE_SIMPLE_TYPE(VIAMC97State, VIA_MC97) +OBJECT_DECLARE_SIMPLE_TYPE(VIAAC97State, VIA_AC97) + static void vt82c686b_ac97_realize(PCIDevice *dev, Error **errp) { VIAAC97State *s = VIA_AC97(dev); @@ -270,14 +267,6 @@ static void vt82c686b_ac97_realize(PCIDevice *dev, Error **errp) pci_set_long(pci_conf + PCI_INTERRUPT_PIN, 0x03); } -void vt82c686b_ac97_init(PCIBus *bus, int devfn) -{ -PCIDevice *dev; - -dev = pci_new(devfn, TYPE_VIA_AC97); -pci_realize_and_unref(dev, bus, _fatal); -} - static void via_ac97_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -314,14 +303,6 @@ static void vt82c686b_mc97_realize(PCIDevice *dev, Error **errp) pci_set_long(pci_conf + PCI_INTERRUPT_PIN, 0x03); } -void vt82c686b_mc97_init(PCIBus *bus, int devfn) -{ -PCIDevice *dev; - -dev = pci_new(devfn, TYPE_VIA_MC97); -pci_realize_and_unref(dev, bus, _fatal); -} - static void via_mc97_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c index f0733e87b7..3b0489f781 100644 --- a/hw/mips/fuloong2e.c +++ b/hw/mips/fuloong2e.c @@ -264,8 +264,8 @@ static void vt82c686b_southbridge_init(PCIBus *pci_bus, int slot, qemu_irq intc, *i2c_bus = vt82c686b_pm_init(pci_bus, PCI_DEVFN(slot, 4), 0xeee1, NULL); /* Audio support */ -vt82c686b_ac97_init(pci_bus, PCI_DEVFN(slot, 5)); -vt82c686b_mc97_init(pci_bus, PCI_DEVFN(slot, 6)); +pci_create_simple(pci_bus, PCI_DEVFN(slot, 5), TYPE_VIA_AC97); +pci_create_simple(pci_bus, PCI_DEVFN(slot, 6), TYPE_VIA_MC97); } /* Network support */ diff --git a/include/hw/isa/vt82c686.h b/include/hw/isa/vt82c686.h index f23f45dfb1..ff80a926dc 100644 --- a/include/hw/isa/vt82c686.h +++ b/include/hw/isa/vt82c686.h @@ -3,11 +3,11 @@ #define TYPE_VT82C686B_SUPERIO "vt82c686b-superio" +#define TYPE_VIA_AC97 "via-ac97" +#define TYPE_VIA_MC97 "via-mc97" /* vt82c686.c */ ISABus *vt82c686b_isa_init(PCIBus * bus, int devfn); -void vt82c686b_ac97_init(PCIBus *bus, int devfn); -void vt82c686b_mc97_init(PCIBus *bus, int devfn); I2CBus *vt82c686b_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, qemu_irq sci_irq); -- 2.21.3
[PATCH v2 03/10] vt82c686b: Rename VT82C686B to VT82C686B_ISA
This is really the ISA bridge part so name the type accordingly. Signed-off-by: BALATON Zoltan --- hw/isa/vt82c686.c | 20 ++-- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index 1be1169f83..d40599c7da 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -43,14 +43,14 @@ typedef struct SuperIOConfig { uint8_t data; } SuperIOConfig; -struct VT82C686BState { +struct VT82C686BISAState { PCIDevice dev; MemoryRegion superio; SuperIOConfig superio_conf; }; -#define TYPE_VT82C686B "VT82C686B" -OBJECT_DECLARE_SIMPLE_TYPE(VT82C686BState, VT82C686B) +#define TYPE_VT82C686B_ISA "vt82c686b-isa" +OBJECT_DECLARE_SIMPLE_TYPE(VT82C686BISAState, VT82C686B_ISA) static void superio_ioport_writeb(void *opaque, hwaddr addr, uint64_t data, unsigned size) @@ -117,7 +117,7 @@ static const MemoryRegionOps superio_ops = { static void vt82c686b_isa_reset(DeviceState *dev) { -VT82C686BState *vt82c = VT82C686B(dev); +VT82C686BISAState *vt82c = VT82C686B_ISA(dev); uint8_t *pci_conf = vt82c->dev.config; pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x00c0); @@ -146,7 +146,7 @@ static void vt82c686b_isa_reset(DeviceState *dev) static void vt82c686b_write_config(PCIDevice *d, uint32_t address, uint32_t val, int len) { -VT82C686BState *vt686 = VT82C686B(d); +VT82C686BISAState *vt686 = VT82C686B_ISA(d); DPRINTF("vt82c686b_write_config address 0x%x val 0x%x len 0x%x\n", address, val, len); @@ -434,7 +434,7 @@ static const VMStateDescription vmstate_via = { .version_id = 1, .minimum_version_id = 1, .fields = (VMStateField[]) { -VMSTATE_PCI_DEVICE(dev, VT82C686BState), +VMSTATE_PCI_DEVICE(dev, VT82C686BISAState), VMSTATE_END_OF_LIST() } }; @@ -442,7 +442,7 @@ static const VMStateDescription vmstate_via = { /* init the PCI-to-ISA bridge */ static void vt82c686b_realize(PCIDevice *d, Error **errp) { -VT82C686BState *vt82c = VT82C686B(d); +VT82C686BISAState *vt82c = VT82C686B_ISA(d); uint8_t *pci_conf; ISABus *isa_bus; uint8_t *wmask; @@ -479,7 +479,7 @@ ISABus *vt82c686b_isa_init(PCIBus *bus, int devfn) { PCIDevice *d; -d = pci_create_simple_multifunction(bus, devfn, true, TYPE_VT82C686B); +d = pci_create_simple_multifunction(bus, devfn, true, TYPE_VT82C686B_ISA); return ISA_BUS(qdev_get_child_bus(DEVICE(d), "isa.0")); } @@ -505,9 +505,9 @@ static void via_class_init(ObjectClass *klass, void *data) } static const TypeInfo via_info = { -.name = TYPE_VT82C686B, +.name = TYPE_VT82C686B_ISA, .parent= TYPE_PCI_DEVICE, -.instance_size = sizeof(VT82C686BState), +.instance_size = sizeof(VT82C686BISAState), .class_init= via_class_init, .interfaces = (InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, -- 2.21.3
[PATCH v2 00/10] Misc vt82c686b clean ups
I'm sending this v2 with tags added and small edits after Philippe's review for now, maybe these are already good to go. I've taken out a few patches that may need some more work but I've run out of free time for now so will have to come back to them later. I still could not cleanly add the VT8231 model which may need some more reorganising and found a few issues with the existin 868B that may need to be fixed first so those left out patches may change anyway so will be included in a future series. Regards, BALATON Zoltan BALATON Zoltan (10): vt82c686: Rename AC97/MC97 parts from VT82C686B to VIA vt82c686: Remove unnecessary _DEVICE suffix from type macros vt82c686b: Rename VT82C686B to VT82C686B_ISA vt82c686: Remove vt82c686b_[am]c97_init() functions vt82c686: Split off via-[am]c97 into separate file in hw/audio audio/via-ac97: Simplify code and set user_creatable to false vt82c686: Remove legacy vt82c686b_isa_init() function vt82c686: Remove legacy vt82c686b_pm_init() function vt82c686: Convert debug printf to trace points vt82c686: Remove unneeded includes and defines hw/audio/meson.build | 1 + hw/audio/via-ac97.c | 93 hw/isa/trace-events | 6 ++ hw/isa/vt82c686.c | 217 +- hw/mips/fuloong2e.c | 13 ++- include/hw/isa/vt82c686.h | 12 +-- 6 files changed, 139 insertions(+), 203 deletions(-) create mode 100644 hw/audio/via-ac97.c -- 2.21.3
Re: [PATCH 01/12] vt82c686: Add APM and ACPI dependencies for VT82C686
Hello, On Mon, 28 Dec 2020, Huacai Chen wrote: Hi, BALATON On Sun, Dec 27, 2020 at 9:21 AM BALATON Zoltan wrote: Compiling vt82c686.c fails without APM and ACPI_PM functions. Add dependency on these in Kconfig to fix this. Signed-off-by: BALATON Zoltan --- hw/isa/Kconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/isa/Kconfig b/hw/isa/Kconfig index c7f07854f7..2ca2593ee6 100644 --- a/hw/isa/Kconfig +++ b/hw/isa/Kconfig @@ -47,6 +47,8 @@ config VT82C686 select ACPI_SMBUS select SERIAL_ISA select FDC +select APM +select ACPI_X86 I feel a bit uncomfortable with ACPI_X86 in the MIPS code, can we just select ACPI? And if that is not enough, can we select more options? This patch is not new, I've tried submitting it before but got rejeceted for similar reason: https://lists.nongnu.org/archive/html/qemu-devel/2019-03/msg03428.html Then Philippe said he had a better alternative but it's still not fixed in master so this patch is needed and you likely already depend on X86 without knowing as something is pulling these in for MIPS. This can be reproduced e,g, by adding this device to PPC as: diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig index d235a096c6..90b53d40c2 100644 --- a/hw/ppc/Kconfig +++ b/hw/ppc/Kconfig @@ -64,6 +64,7 @@ config SAM460EX select SMBUS_EEPROM select USB_EHCI_SYSBUS select USB_OHCI +select VT82C686 config PREP bool then compiling --target-list=ppc-softmmu Even after: diff --git a/hw/isa/Kconfig b/hw/isa/Kconfig index c7f07854f7..75986671b9 100644 --- a/hw/isa/Kconfig +++ b/hw/isa/Kconfig @@ -47,6 +47,8 @@ config VT82C686 select ACPI_SMBUS select SERIAL_ISA select FDC +select APM +select ACPI config SMC37C669 bool I get: [] Linking target qemu-system-ppc FAILED: qemu-system-ppc ld: libcommon.fa.p/hw_isa_vt82c686.c.o: in function `vt82c686b_pm_realize': hw/isa/vt82c686.c:378: undefined reference to `acpi_pm_tmr_init' ld: hw/isa/vt82c686.c:379: undefined reference to `acpi_pm1_evt_init' ld: libcommon.fa.p/hw_isa_vt82c686.c.o: in function `pm_update_sci': hw/isa/vt82c686.c:192: undefined reference to `acpi_pm1_evt_get_sts' ld: libcommon.fa.p/hw_isa_vt82c686.c.o: in function `vt82c686b_pm_realize': hw/isa/vt82c686.c:380: undefined reference to `acpi_pm1_cnt_init' ld: libcommon.fa.p/hw_isa_vt82c686.c.o: in function `pm_update_sci': hw/isa/vt82c686.c:200: undefined reference to `acpi_pm_tmr_update' collect2: error: ld returned 1 exit status So my patch just makes existing dependencies explicit and allows this to build but I'm OK with any other fix you propose that fixes the above case as that's how I'll try to use this in the future. (I did look at this when first found it and concluded that I could not make a better fix than depending on ACPI_X86 here. I forgot the details but it was way more work than I want to take up for this so please propose a better fix if you can't accept this patch.) Maybe Philippe remembers some more. Regards, BALATON Zoltan
Re: [PATCH 2/2] via-ide: Fix fuloong2e support
On Sun, 27 Dec 2020, Philippe Mathieu-Daudé wrote: On 12/27/20 5:40 PM, BALATON Zoltan via wrote: On Sun, 27 Dec 2020, Philippe Mathieu-Daudé wrote: On 12/25/20 12:23 AM, BALATON Zoltan wrote: From: Guenter Roeck Fuloong2e needs to use legacy mode for IDE support to work with Linux. Add property to via-ide driver to make the mode configurable, and set legacy mode for Fuloong2e. Fixes: 4ea98d317eb ("ide/via: Implement and use native PCI IDE mode")? Not really. That patch did what it said (only emulating (half) native mode instead of only emulating legacy mode) so it wasn't broken per se but it turned out that approach wasn't good enough for all use cases so this now takes a different turn (emulating either legacy or half-native mode based on option property). Therefore. I don't think Fixes: applies in this case. It fixes an issue with a guest but replaces previous patch with different approach. (Even though it reuses most of it.) Well, if Linux guest got broken by this commit, why not name it a "fix"? We do call it a fix in the patch title. I just thought Fixes: tag was more for either security fixes or cases when original commit had a bug that's fixed up by this patch which is not exactly the case here. Anyway I don't mind how it is called. I find important to refer to the commit hash to help navigating between commits while reviewing history. What about: ''' The legacy mode for IDE support has been removed in commit 4ea98d317eb ("ide/via: Implement and use native PCI IDE mode"). When using a Linux guest, the Fuloong2e machine requires the legacy mode. Add property to via-ide driver to make the mode configurable, and set legacy mode for Fuloong2e. ''' Guenter, is that OK with you? (I can update when applying this series via the MIPS tree). I've submitted v2 with this commit message (slightly edited) mentioning the original commit for tracking. Regards, BALATON Zoltan
[PATCH v2 2/2] via-ide: Fix fuloong2e support
From: Guenter Roeck The IDE legacy mode emulation has been removed in commit 4ea98d317eb ("ide/via: Implement and use native PCI IDE mode") but some Linux kernels (probably including def_config) require legacy mode on the Fuloong2e so only emulating native mode did not turn out feasible. Add property to via-ide model to make the mode configurable, and set legacy mode for Fuloong2e. Signed-off-by: Guenter Roeck [balaton: Use bit in flags for property, add comment for missing BAR4] Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé Tested-by: Guenter Roeck --- v2: Reworded commit message hw/ide/via.c| 19 +-- hw/mips/fuloong2e.c | 4 +++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/hw/ide/via.c b/hw/ide/via.c index be09912b33..7d54d7e829 100644 --- a/hw/ide/via.c +++ b/hw/ide/via.c @@ -26,6 +26,7 @@ #include "qemu/osdep.h" #include "hw/pci/pci.h" +#include "hw/qdev-properties.h" #include "migration/vmstate.h" #include "qemu/module.h" #include "sysemu/dma.h" @@ -185,12 +186,19 @@ static void via_ide_realize(PCIDevice *dev, Error **errp) >bus[1], "via-ide1-cmd", 4); pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, >cmd_bar[1]); -bmdma_setup_bar(d); -pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, >bmdma_bar); +if (!(d->flags & BIT(PCI_IDE_LEGACY_MODE))) { +/* Missing BAR4 will make Linux driver fall back to legacy PIO mode */ +bmdma_setup_bar(d); +pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, >bmdma_bar); +} qdev_init_gpio_in(ds, via_ide_set_irq, 2); for (i = 0; i < 2; i++) { ide_bus_new(>bus[i], sizeof(d->bus[i]), ds, i, 2); +if (d->flags & BIT(PCI_IDE_LEGACY_MODE)) { +ide_init_ioport(>bus[i], NULL, i ? 0x170 : 0x1f0, +i ? 0x376 : 0x3f6); +} ide_init2(>bus[i], qdev_get_gpio_in(ds, i)); bmdma_init(>bus[i], >bmdma[i], d); @@ -210,6 +218,12 @@ static void via_ide_exitfn(PCIDevice *dev) } } +static Property via_ide_properties[] = { +DEFINE_PROP_BIT("legacy_mode", PCIIDEState, flags, PCI_IDE_LEGACY_MODE, +false), +DEFINE_PROP_END_OF_LIST(), +}; + static void via_ide_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -223,6 +237,7 @@ static void via_ide_class_init(ObjectClass *klass, void *data) k->device_id = PCI_DEVICE_ID_VIA_IDE; k->revision = 0x06; k->class_id = PCI_CLASS_STORAGE_IDE; +device_class_set_props(dc, via_ide_properties); set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); } diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c index 45c596f4fe..f0733e87b7 100644 --- a/hw/mips/fuloong2e.c +++ b/hw/mips/fuloong2e.c @@ -253,7 +253,9 @@ static void vt82c686b_southbridge_init(PCIBus *pci_bus, int slot, qemu_irq intc, /* Super I/O */ isa_create_simple(isa_bus, TYPE_VT82C686B_SUPERIO); -dev = pci_create_simple(pci_bus, PCI_DEVFN(slot, 1), "via-ide"); +dev = pci_new(PCI_DEVFN(slot, 1), "via-ide"); +qdev_prop_set_bit(>qdev, "legacy_mode", true); +pci_realize_and_unref(dev, pci_bus, _fatal); pci_ide_create_devs(dev); pci_create_simple(pci_bus, PCI_DEVFN(slot, 2), "vt82c686b-usb-uhci"); -- 2.21.3
[PATCH v2 1/2] ide: Make room for flags in PCIIDEState and add one for legacy mode
We'll need a flag for implementing some device specific behaviour in via-ide but we already have a currently CMD646 specific field that can be repurposed for this and leave room for further flags if needed in the future. This patch changes the "secondary" field to "flags" and change CMD646 and its users accordingly and define a new flag for forcing legacy mode that will be used by via-ide for now. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Guenter Roeck Tested-by: Guenter Roeck --- v2: Fixed typo in commit message hw/ide/cmd646.c | 4 ++-- hw/sparc64/sun4u.c | 2 +- include/hw/ide/pci.h | 7 ++- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c index c254631485..7a96016116 100644 --- a/hw/ide/cmd646.c +++ b/hw/ide/cmd646.c @@ -256,7 +256,7 @@ static void pci_cmd646_ide_realize(PCIDevice *dev, Error **errp) pci_conf[PCI_CLASS_PROG] = 0x8f; pci_conf[CNTRL] = CNTRL_EN_CH0; // enable IDE0 -if (d->secondary) { +if (d->flags & BIT(PCI_IDE_SECONDARY)) { /* XXX: if not enabled, really disable the seconday IDE controller */ pci_conf[CNTRL] |= CNTRL_EN_CH1; /* enable IDE1 */ } @@ -314,7 +314,7 @@ static void pci_cmd646_ide_exitfn(PCIDevice *dev) } static Property cmd646_ide_properties[] = { -DEFINE_PROP_UINT32("secondary", PCIIDEState, secondary, 0), +DEFINE_PROP_BIT("secondary", PCIIDEState, flags, PCI_IDE_SECONDARY, false), DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c index 0fa13a7330..c46baa9f48 100644 --- a/hw/sparc64/sun4u.c +++ b/hw/sparc64/sun4u.c @@ -674,7 +674,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem, } pci_dev = pci_new(PCI_DEVFN(3, 0), "cmd646-ide"); -qdev_prop_set_uint32(_dev->qdev, "secondary", 1); +qdev_prop_set_bit(_dev->qdev, "secondary", true); pci_realize_and_unref(pci_dev, pci_busA, _fatal); pci_ide_create_devs(pci_dev); diff --git a/include/hw/ide/pci.h b/include/hw/ide/pci.h index d8384e1c42..75d1a32f6d 100644 --- a/include/hw/ide/pci.h +++ b/include/hw/ide/pci.h @@ -42,6 +42,11 @@ typedef struct BMDMAState { #define TYPE_PCI_IDE "pci-ide" OBJECT_DECLARE_SIMPLE_TYPE(PCIIDEState, PCI_IDE) +enum { +PCI_IDE_SECONDARY, /* used only for cmd646 */ +PCI_IDE_LEGACY_MODE +}; + struct PCIIDEState { /*< private >*/ PCIDevice parent_obj; @@ -49,7 +54,7 @@ struct PCIIDEState { IDEBus bus[2]; BMDMAState bmdma[2]; -uint32_t secondary; /* used only for cmd646 */ +uint32_t flags; MemoryRegion bmdma_bar; MemoryRegion cmd_bar[2]; MemoryRegion data_bar[2]; -- 2.21.3