Re: [PATCH 07/23] hw/ppc/e500: Extract ppce500_ccsr.c

2024-10-01 Thread Bernhard Beschow



Am 24. September 2024 20:02:31 UTC schrieb Bernhard Beschow :
>
>
>Am 23. September 2024 10:38:46 UTC schrieb BALATON Zoltan :
>>On Mon, 23 Sep 2024, Bernhard Beschow wrote:
>>> The device model already has a header file. Also extract its implementation 
>>> into
>>> an accompanying source file like other e500 devices.
>>> 
>>> This commit is also a preparation for the next commit.
>>> 
>>> Signed-off-by: Bernhard Beschow 
>>> ---
>>> MAINTAINERS   |  2 +-
>>> hw/ppc/e500-ccsr.h|  2 ++
>>> hw/ppc/e500.c | 17 -
>>> hw/ppc/ppce500_ccsr.c | 38 ++
>>
>>Maybe you could call it e500_ccsr.c and also rename the header to e500_ccsr.h 
>>(underscore instead of dash) to match them. Or if you want to match 
>>ppce500_spin.c then maybe move contents of e500-ccsr.h to e500.h?
>
>Yeah, naming is hard. I'd actually prefer something like fsl_immr.* (taking 
>inspiration from device tree here) to not confuse the whole SoC with the CPU. 
>With the ppce500 prefix I was sticking to the convention of the PCIE device. 
>Though there is also mpc-i2c and fsl_etsec...

I'll name the header like the struct it defines, i.e. ppce500_ccsr.h.

>
>>(More below...)
>>
>>> hw/ppc/meson.build|  1 +
>>> 5 files changed, 42 insertions(+), 18 deletions(-)
>>> create mode 100644 hw/ppc/ppce500_ccsr.c
>>> 
>>> diff --git a/MAINTAINERS b/MAINTAINERS
>>> index ffacd60f40..b7c8b7ae72 100644
>>> --- a/MAINTAINERS
>>> +++ b/MAINTAINERS
>>> @@ -1433,7 +1433,7 @@ e500
>>> L: qemu-...@nongnu.org
>>> S: Orphan
>>> F: hw/ppc/e500*
>>> -F: hw/ppc/ppce500_spin.c
>>> +F: hw/ppc/ppce500_*.c
>>> F: hw/gpio/mpc8xxx.c
>>> F: hw/i2c/mpc_i2c.c
>>> F: hw/net/fsl_etsec/
>>> diff --git a/hw/ppc/e500-ccsr.h b/hw/ppc/e500-ccsr.h
>>> index 249c17be3b..3ab7e72568 100644
>>> --- a/hw/ppc/e500-ccsr.h
>>> +++ b/hw/ppc/e500-ccsr.h
>>> @@ -4,6 +4,8 @@
>>> #include "hw/sysbus.h"
>>> #include "qom/object.h"
>>> 
>>> +#define MPC8544_CCSRBAR_SIZE   0x0010ULL
>>> +
>>> struct PPCE500CCSRState {
>>> /*< private >*/
>>> SysBusDevice parent;
>>> diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
>>> index 2225533e33..4ee4304a8a 100644
>>> --- a/hw/ppc/e500.c
>>> +++ b/hw/ppc/e500.c
>>> @@ -61,7 +61,6 @@
>>> #define RAM_SIZES_ALIGN(64 * MiB)
>>> 
>>> /* TODO: parameterize */
>>> -#define MPC8544_CCSRBAR_SIZE   0x0010ULL
>>> #define MPC8544_MPIC_REGS_OFFSET   0x4ULL
>>> #define MPC8544_MSI_REGS_OFFSET   0x41600ULL
>>> #define MPC8544_SERIAL0_REGS_OFFSET 0x4500ULL
>>> @@ -1264,21 +1263,6 @@ void ppce500_init(MachineState *machine)
>>> pms->boot_info.dt_size = dt_size;
>>> }
>>> 
>>> -static void e500_ccsr_initfn(Object *obj)
>>> -{
>>> -PPCE500CCSRState *ccsr = CCSR(obj);
>>> -memory_region_init(&ccsr->ccsr_space, obj, "e500-ccsr",
>>> -   MPC8544_CCSRBAR_SIZE);
>>> -sysbus_init_mmio(SYS_BUS_DEVICE(ccsr), &ccsr->ccsr_space);
>>> -}
>>> -
>>> -static const TypeInfo e500_ccsr_info = {
>>> -.name  = TYPE_CCSR,
>>> -.parent= TYPE_SYS_BUS_DEVICE,
>>> -.instance_size = sizeof(PPCE500CCSRState),
>>> -.instance_init = e500_ccsr_initfn,
>>> -};
>>> -
>>> static const TypeInfo ppce500_info = {
>>> .name  = TYPE_PPCE500_MACHINE,
>>> .parent= TYPE_MACHINE,
>>> @@ -1289,7 +1273,6 @@ static const TypeInfo ppce500_info = {
>>> 
>>> static void e500_register_types(void)
>>> {
>>> -type_register_static(&e500_ccsr_info);
>>> type_register_static(&ppce500_info);
>>> }
>>> 
>>> diff --git a/hw/ppc/ppce500_ccsr.c b/hw/ppc/ppce500_ccsr.c
>>> new file mode 100644
>>> index 00..191a9ceec3
>>> --- /dev/null
>>> +++ b/hw/ppc/ppce500_ccsr.c
>>> @@ -0,0 +1,38 @@
>>> +/*
>>> + * QEMU PowerPC E500 embedded processors CCSR space emulation
>>> + *
>>> + * Copyright (C) 2009 Freescale Semiconductor, Inc. All rights reserved.
>>> + *
>>> + * Author: Yu Liu, 
>>> + *
>>> + * This file is deri

Re: [PATCH 01/23] hw/ppc/e500: Do not leak struct boot_info

2024-10-01 Thread Bernhard Beschow



Am 26. September 2024 00:14:04 UTC schrieb BALATON Zoltan :
>On Wed, 25 Sep 2024, Cédric Le Goater wrote:
>> On 9/23/24 11:29, Bernhard Beschow wrote:
>>> The struct is allocated once with g_new0() but never free()'d. Fix the 
>>> leakage
>>> by adding an attribute to struct PPCE500MachineState which avoids the
>>> allocation.
>>> 
>>> Signed-off-by: Bernhard Beschow 
>>> ---
>>>   hw/ppc/e500.h |  8 
>>>   hw/ppc/e500.c | 17 -
>>>   2 files changed, 12 insertions(+), 13 deletions(-)
>>> 
>>> diff --git a/hw/ppc/e500.h b/hw/ppc/e500.h
>>> index 8c09ef92e4..557ce6ad93 100644
>>> --- a/hw/ppc/e500.h
>>> +++ b/hw/ppc/e500.h
>>> @@ -5,10 +5,18 @@
>>>   #include "hw/platform-bus.h"
>>>   #include "qom/object.h"
>>>   +typedef struct boot_info {
>>> +uint32_t dt_base;
>>> +uint32_t dt_size;
>>> +uint32_t entry;
>>> +} boot_info;
>> 
>> or simply move the fields under the machine state struct to avoif
>> the struct boot_info which doesn't seem that necessary. Is it ?
>
>It's passed to CPU reset function via env->load_info. It could be possible to 
>pass the whole machine state but it seems that's unneeded so this struct just 
>contains what's needed for this. Other machines also have similar boot_info 
>structs although they seem to be different and not common to all machines. 
>Thus I don't think merging with machine state would be better than keeping is 
>separate as this is more CPU related.

I agree that having a consistent style across machines is prefereable, so I'll 
keep struct boot_info. It also avoids conflicts with your TLB cleanup series.

Best regards,
Bernhard

>
>Regards,
>BALATON Zoltan
>
>> 
>> Thanks,
>> 
>> C.
>> 
>> 
>> 
>>> +
>>>   struct PPCE500MachineState {
>>>   /*< private >*/
>>>   MachineState parent_obj;
>>>   +boot_info boot_info;
>>> +
>>>   /* points to instance of TYPE_PLATFORM_BUS_DEVICE if
>>>* board supports dynamic sysbus devices
>>>*/
>>> diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
>>> index 3bd12b54ab..75b051009f 100644
>>> --- a/hw/ppc/e500.c
>>> +++ b/hw/ppc/e500.c
>>> @@ -80,13 +80,6 @@
>>> #define PLATFORM_CLK_FREQ_HZ   (400 * 1000 * 1000)
>>>   -struct boot_info
>>> -{
>>> -uint32_t dt_base;
>>> -uint32_t dt_size;
>>> -uint32_t entry;
>>> -};
>>> -
>>>   static uint32_t *pci_map_create(void *fdt, uint32_t mpic, int first_slot,
>>>   int nr_slots, int *len)
>>>   {
>>> @@ -919,7 +912,6 @@ void ppce500_init(MachineState *machine)
>>>   bool kernel_as_payload;
>>>   hwaddr bios_entry = 0;
>>>   target_long payload_size;
>>> -struct boot_info *boot_info = NULL;
>>>   int dt_size;
>>>   int i;
>>>   unsigned int smp_cpus = machine->smp.cpus;
>>> @@ -974,9 +966,8 @@ void ppce500_init(MachineState *machine)
>>>   /* Register reset handler */
>>>   if (!i) {
>>>   /* Primary CPU */
>>> -boot_info = g_new0(struct boot_info, 1);
>>>   qemu_register_reset(ppce500_cpu_reset, cpu);
>>> -env->load_info = boot_info;
>>> +env->load_info = &pms->boot_info;
>>>   } else {
>>>   /* Secondary CPUs */
>>>   qemu_register_reset(ppce500_cpu_reset_sec, cpu);
>>> @@ -1274,9 +1265,9 @@ void ppce500_init(MachineState *machine)
>>>   }
>>>   assert(dt_size < DTB_MAX_SIZE);
>>>   -boot_info->entry = bios_entry;
>>> -boot_info->dt_base = dt_base;
>>> -boot_info->dt_size = dt_size;
>>> +pms->boot_info.entry = bios_entry;
>>> +pms->boot_info.dt_base = dt_base;
>>> +pms->boot_info.dt_size = dt_size;
>>>   }
>>> static void e500_ccsr_initfn(Object *obj)
>> 
>> 
>>



Re: [PATCH 06/23] hw/ppc/e500: Use SysBusDevice API to access TYPE_CCSR's internal resources

2024-09-27 Thread Bernhard Beschow



Am 23. September 2024 10:28:35 UTC schrieb BALATON Zoltan :
>On Mon, 23 Sep 2024, Bernhard Beschow wrote:
>> Rather than accessing the attributes of TYPE_CCSR directly, use the 
>> SysBusDevice
>> API which exists exactly for that purpose. Furthermore, registering the 
>> memory
>> region with the SysBusDevice API makes it show up in QMP's `info qom-tree`
>> command.
>> 
>> Signed-off-by: Bernhard Beschow 
>> ---
>> hw/pci-host/ppce500.c | 10 +-
>> hw/ppc/e500.c |  8 
>> 2 files changed, 9 insertions(+), 9 deletions(-)
>> 
>> diff --git a/hw/pci-host/ppce500.c b/hw/pci-host/ppce500.c
>> index 95b983b2b3..97e5d47cec 100644
>> --- a/hw/pci-host/ppce500.c
>> +++ b/hw/pci-host/ppce500.c
>> @@ -16,7 +16,6 @@
>> 
>> #include "qemu/osdep.h"
>> #include "hw/irq.h"
>> -#include "hw/ppc/e500-ccsr.h"
>> #include "hw/qdev-properties.h"
>> #include "migration/vmstate.h"
>> #include "hw/pci/pci_device.h"
>> @@ -419,11 +418,12 @@ static const VMStateDescription vmstate_ppce500_pci = {
>> static void e500_pcihost_bridge_realize(PCIDevice *d, Error **errp)
>> {
>> PPCE500PCIBridgeState *b = PPC_E500_PCI_BRIDGE(d);
>> -PPCE500CCSRState *ccsr = CCSR(container_get(qdev_get_machine(),
>> -  "/e500-ccsr"));
>> +SysBusDevice *ccsr = SYS_BUS_DEVICE(container_get(qdev_get_machine(),
>> +  "/e500-ccsr"));
>> +MemoryRegion *ccsr_space = sysbus_mmio_get_region(ccsr, 0);
>> 
>> -memory_region_init_alias(&b->bar0, OBJECT(ccsr), "e500-pci-bar0", 
>> &ccsr->ccsr_space,
>> - 0, int128_get64(ccsr->ccsr_space.size));
>> +memory_region_init_alias(&b->bar0, OBJECT(ccsr), "e500-pci-bar0",
>> + ccsr_space, 0, int128_get64(ccsr_space->size));
>
>I wonder if this really needs an alias or could the original memory region be 
>registered as the PCI BAR region? Otherwise:

This hits an assertion when running Buildroot's qemu_ppc64_e5500_defconfig. 
Therefore I'll keep the alias.

Best regards,
Bernhard

>
>Reviewed-by: BALATON Zoltan 
>
>Regards,
>BALATON Zoltan
>
>> pci_register_bar(d, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &b->bar0);
>> }
>> 
>> diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
>> index e2a4f265a5..2225533e33 100644
>> --- a/hw/ppc/e500.c
>> +++ b/hw/ppc/e500.c
>> @@ -924,7 +924,6 @@ void ppce500_init(MachineState *machine)
>> DriveInfo *dinfo;
>> MemoryRegion *ccsr_addr_space;
>> SysBusDevice *s;
>> -PPCE500CCSRState *ccsr;
>> I2CBus *i2c;
>> 
>> irqs = g_new0(IrqLines, smp_cpus);
>> @@ -980,10 +979,10 @@ void ppce500_init(MachineState *machine)
>> memory_region_add_subregion(address_space_mem, 0, machine->ram);
>> 
>> dev = qdev_new("e500-ccsr");
>> +s = SYS_BUS_DEVICE(dev);
>> object_property_add_child(OBJECT(machine), "e500-ccsr", OBJECT(dev));
>> -sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
>> -ccsr = CCSR(dev);
>> -ccsr_addr_space = &ccsr->ccsr_space;
>> +sysbus_realize_and_unref(s, &error_fatal);
>> +ccsr_addr_space = sysbus_mmio_get_region(s, 0);
>> memory_region_add_subregion(address_space_mem, pmc->ccsrbar_base,
>> ccsr_addr_space);
>> 
>> @@ -1270,6 +1269,7 @@ static void e500_ccsr_initfn(Object *obj)
>> PPCE500CCSRState *ccsr = CCSR(obj);
>> memory_region_init(&ccsr->ccsr_space, obj, "e500-ccsr",
>>MPC8544_CCSRBAR_SIZE);
>> +sysbus_init_mmio(SYS_BUS_DEVICE(ccsr), &ccsr->ccsr_space);
>> }
>> 
>> static const TypeInfo e500_ccsr_info = {
>> 



Re: [PATCH 00/23] E500 Cleanup

2024-09-26 Thread Bernhard Beschow



Am 24. September 2024 08:33:26 UTC schrieb "Cédric Le Goater" :
>On 9/23/24 23:25, Bernhard Beschow wrote:
>> 
>> 
>> 
>> Am 23. September 2024 20:23:54 UTC schrieb "Cédric Le Goater" 
>> :
>>> Hello Bernhard,
>> 
>> Hi Cédric,
>> 
>>> 
>>> On 9/23/24 11:29, Bernhard Beschow wrote:
>>>> This series is part of a bigger series exploring data-driven machine 
>>>> creation
>>>> using device tree blobs on top of the e500 machines [1]. It contains 
>>>> patches to
>>>> make this exploration easier which are also expected to provide value in
>>>> themselves.
>>>> 
>>>> The cleanup starts with the e500 machine class itself, then proceeds with
>>>> machine-specific device models and concludes with more or less loosely 
>>>> related
>>>> devices. Device cleanup mostly consists of using the DEFINE_TYPES() macro.
>>> 
>>> Since you recently took a look at the machine models, would you
>>> be willing to take over maintenance of the e500 ? It shouldn't
>>> be an enormous amount of work.
>> 
>> Are you referring to the machine and related devices or the CPU? I'm 
>> somewhat familiar with the P102x and could take over but the CPU would be a 
>> different beast.
>
>Please take a look at the MAINTAINERS file. You will see it is not
>that large and the CPU target models are not part of it.

Patch sent: 
https://lore.kernel.org/qemu-devel/20240926075948.2343-1-shen...@gmail.com/

Best regards,
Bernhard

>
>
>Thanks,
>
>C.
>
> 
>
>> 
>> Best regards,
>> Bernhard
>> 
>>> 
>>> Thanks,
>>> 
>>> C.
>>> 
>>> 
>>> 
>>>> [1] https://github.com/shentok/qemu/tree/e500-fdt
>>>> 
>>>> Bernhard Beschow (23):
>>>> hw/ppc/e500: Do not leak struct boot_info
>>>> hw/ppc/e500: Reduce scope of env pointer
>>>> hw/ppc/e500: Prefer QOM cast
>>>> hw/ppc/e500: Remove unused "irqs" parameter
>>>> hw/ppc/e500: Add missing device tree properties to i2c controller node
>>>> hw/ppc/e500: Use SysBusDevice API to access TYPE_CCSR's internal
>>>>   resources
>>>> hw/ppc/e500: Extract ppce500_ccsr.c
>>>> hw/ppc/ppce500_ccsr: Log access to unimplemented registers
>>>> hw/ppc/mpc8544_guts: Populate POR PLL ratio status register
>>>> hw/i2c/mpc_i2c: Convert DPRINTF to trace events for register access
>>>> hw/i2c/mpc_i2c: Prefer DEFINE_TYPES() macro
>>>> hw/pci-host/ppce500: Reuse TYPE_PPC_E500_PCI_BRIDGE define
>>>> hw/pci-host/ppce500: Prefer DEFINE_TYPES() macro
>>>> hw/gpio/mpc8xxx: Prefer DEFINE_TYPES() macro
>>>> hw/ppc/mpc8544_guts: Prefer DEFINE_TYPES() macro
>>>> hw/net/fsl_etsec/etsec: Prefer DEFINE_TYPES() macro
>>>> hw/intc: Guard openpic_kvm.c by dedicated OPENPIC_KVM Kconfig switch
>>>> hw/sd/sdhci: Prefer DEFINE_TYPES() macro
>>>> hw/block/pflash_cfi01: Prefer DEFINE_TYPES() macro
>>>> hw/i2c/smbus_eeprom: Prefer DEFINE_TYPES() macro
>>>> hw/rtc/ds1338: Prefer DEFINE_TYPES() macro
>>>> hw/usb/hcd-ehci-sysbus: Prefer DEFINE_TYPES() macro
>>>> hw/vfio/platform: Let vfio_start_eventfd_injection() take
>>>>   VFIOPlatformDevice pointer
>>>> 
>>>>MAINTAINERS  |   2 +-
>>>>hw/ppc/e500-ccsr.h   |   2 +
>>>>hw/ppc/e500.h|   8 +++
>>>>hw/block/pflash_cfi01.c  |  21 +++
>>>>hw/gpio/mpc8xxx.c|  22 +++-
>>>>hw/i2c/mpc_i2c.c |  29 +-
>>>>hw/i2c/smbus_eeprom.c|  19 +++
>>>>hw/net/fsl_etsec/etsec.c |  22 +++-
>>>>hw/pci-host/ppce500.c|  54 --
>>>>hw/ppc/e500.c|  61 +---
>>>>hw/ppc/mpc8544_guts.c|  32 +++
>>>>hw/ppc/ppce500_ccsr.c|  67 ++
>>>>hw/rtc/ds1338.c  |  20 +++
>>>>hw/sd/sdhci.c|  62 +---
>>>>hw/usb/hcd-ehci-sysbus.c | 118 +--
>>>>hw/vfio/platform.c   |   7 +--
>>>>hw/i2c/trace-events  |   5 ++
>>>>hw/intc/Kconfig  |   4 ++
>>>>hw/intc/meson.build  |   3 +-
>>>>hw/ppc/meson.build   |   1 +
>>>>hw/ppc/trace-events  |   3 +
>>>>21 files changed, 285 insertions(+), 277 deletions(-)
>>>>create mode 100644 hw/ppc/ppce500_ccsr.c
>>>> 
>>> 
>> 
>



Re: [PATCH 01/23] hw/ppc/e500: Do not leak struct boot_info

2024-09-25 Thread Bernhard Beschow



Am 25. September 2024 15:35:15 UTC schrieb "Cédric Le Goater" :
>On 9/23/24 11:29, Bernhard Beschow wrote:
>> The struct is allocated once with g_new0() but never free()'d. Fix the 
>> leakage
>> by adding an attribute to struct PPCE500MachineState which avoids the
>> allocation.
>> 
>> Signed-off-by: Bernhard Beschow 
>> ---
>>   hw/ppc/e500.h |  8 
>>   hw/ppc/e500.c | 17 -
>>   2 files changed, 12 insertions(+), 13 deletions(-)
>> 
>> diff --git a/hw/ppc/e500.h b/hw/ppc/e500.h
>> index 8c09ef92e4..557ce6ad93 100644
>> --- a/hw/ppc/e500.h
>> +++ b/hw/ppc/e500.h
>> @@ -5,10 +5,18 @@
>>   #include "hw/platform-bus.h"
>>   #include "qom/object.h"
>>   +typedef struct boot_info {
>> +uint32_t dt_base;
>> +uint32_t dt_size;
>> +uint32_t entry;
>> +} boot_info;
>
>or simply move the fields under the machine state struct to avoif
>the struct boot_info which doesn't seem that necessary. Is it ?

Yes, this works. Good idea.

Best regards,
Bernhard

>
>
>Thanks,
>
>C.
>
>
>
>> +
>>   struct PPCE500MachineState {
>>   /*< private >*/
>>   MachineState parent_obj;
>>   +boot_info boot_info;
>> +
>>   /* points to instance of TYPE_PLATFORM_BUS_DEVICE if
>>* board supports dynamic sysbus devices
>>*/
>> diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
>> index 3bd12b54ab..75b051009f 100644
>> --- a/hw/ppc/e500.c
>> +++ b/hw/ppc/e500.c
>> @@ -80,13 +80,6 @@
>> #define PLATFORM_CLK_FREQ_HZ   (400 * 1000 * 1000)
>>   -struct boot_info
>> -{
>> -uint32_t dt_base;
>> -uint32_t dt_size;
>> -uint32_t entry;
>> -};
>> -
>>   static uint32_t *pci_map_create(void *fdt, uint32_t mpic, int first_slot,
>>   int nr_slots, int *len)
>>   {
>> @@ -919,7 +912,6 @@ void ppce500_init(MachineState *machine)
>>   bool kernel_as_payload;
>>   hwaddr bios_entry = 0;
>>   target_long payload_size;
>> -struct boot_info *boot_info = NULL;
>>   int dt_size;
>>   int i;
>>   unsigned int smp_cpus = machine->smp.cpus;
>> @@ -974,9 +966,8 @@ void ppce500_init(MachineState *machine)
>>   /* Register reset handler */
>>   if (!i) {
>>   /* Primary CPU */
>> -boot_info = g_new0(struct boot_info, 1);
>>   qemu_register_reset(ppce500_cpu_reset, cpu);
>> -env->load_info = boot_info;
>> +env->load_info = &pms->boot_info;
>>   } else {
>>   /* Secondary CPUs */
>>   qemu_register_reset(ppce500_cpu_reset_sec, cpu);
>> @@ -1274,9 +1265,9 @@ void ppce500_init(MachineState *machine)
>>   }
>>   assert(dt_size < DTB_MAX_SIZE);
>>   -boot_info->entry = bios_entry;
>> -boot_info->dt_base = dt_base;
>> -boot_info->dt_size = dt_size;
>> +pms->boot_info.entry = bios_entry;
>> +pms->boot_info.dt_base = dt_base;
>> +pms->boot_info.dt_size = dt_size;
>>   }
>> static void e500_ccsr_initfn(Object *obj)
>



Re: [PATCH 02/23] hw/ppc/e500: Reduce scope of env pointer

2024-09-25 Thread Bernhard Beschow



Am 25. September 2024 15:37:22 UTC schrieb "Cédric Le Goater" :
>On 9/23/24 11:29, Bernhard Beschow wrote:
>> The env pointer isn't used outside the for loop, so move it inside. After 
>> that,
>> the firstenv pointer is never read, so remove it.
>
>Just wondering, have you considered introducing an PowerPCCPU array
>under the machine state ?
>
>This would be an intermediate step towards the introduction of an SoC
>model (in the long term)

Well, there seem to be many members in the QorIQ family with incompatible 
offsets. So I experimented with dtb-driven machine creation instead to sidestep 
the whole problem. Once this series is merged I plan to submit an RFC for that.

Best regards,
Bernhard

>
>Thanks,
>
>C.
>
>
>
>> Signed-off-by: Bernhard Beschow 
>> ---
>>   hw/ppc/e500.c | 9 +
>>   1 file changed, 1 insertion(+), 8 deletions(-)
>> 
>> diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
>> index 75b051009f..f68779a1ea 100644
>> --- a/hw/ppc/e500.c
>> +++ b/hw/ppc/e500.c
>> @@ -899,7 +899,6 @@ void ppce500_init(MachineState *machine)
>>   const PPCE500MachineClass *pmc = PPCE500_MACHINE_GET_CLASS(machine);
>>   MachineClass *mc = MACHINE_CLASS(pmc);
>>   PCIBus *pci_bus;
>> -CPUPPCState *env = NULL;
>>   uint64_t loadaddr;
>>   hwaddr kernel_base = -1LL;
>>   int kernel_size = 0;
>> @@ -921,7 +920,6 @@ void ppce500_init(MachineState *machine)
>>   IrqLines *irqs;
>>   DeviceState *dev, *mpicdev;
>>   DriveInfo *dinfo;
>> -CPUPPCState *firstenv = NULL;
>>   MemoryRegion *ccsr_addr_space;
>>   SysBusDevice *s;
>>   PPCE500CCSRState *ccsr;
>> @@ -930,6 +928,7 @@ void ppce500_init(MachineState *machine)
>>   irqs = g_new0(IrqLines, smp_cpus);
>>   for (i = 0; i < smp_cpus; i++) {
>>   PowerPCCPU *cpu;
>> +CPUPPCState *env;
>>   CPUState *cs;
>> cpu = POWERPC_CPU(object_new(machine->cpu_type));
>> @@ -950,10 +949,6 @@ void ppce500_init(MachineState *machine)
>>&error_abort);
>>   qdev_realize_and_unref(DEVICE(cs), NULL, &error_fatal);
>>   -if (!firstenv) {
>> -firstenv = env;
>> -}
>> -
>>   irqs[i].irq[OPENPIC_OUTPUT_INT] =
>>   qdev_get_gpio_in(DEVICE(cpu), PPCE500_INPUT_INT);
>>   irqs[i].irq[OPENPIC_OUTPUT_CINT] =
>> @@ -974,8 +969,6 @@ void ppce500_init(MachineState *machine)
>>   }
>>   }
>>   -env = firstenv;
>> -
>>   if (!QEMU_IS_ALIGNED(machine->ram_size, RAM_SIZES_ALIGN)) {
>>   error_report("RAM size must be multiple of %" PRIu64, 
>> RAM_SIZES_ALIGN);
>>   exit(EXIT_FAILURE);
>



Re: [PATCH 02/23] hw/ppc/e500: Reduce scope of env pointer

2024-09-25 Thread Bernhard Beschow



Am 23. September 2024 10:04:48 UTC schrieb BALATON Zoltan :
>On Mon, 23 Sep 2024, Bernhard Beschow wrote:
>> The env pointer isn't used outside the for loop, so move it inside. After 
>> that,
>> the firstenv pointer is never read, so remove it.
>
>It's probably the other way arouns, you remove firstenv (which is the bigger 
>part of this patch) then it's clear env is not needed outside of the loop any 
>more so can be moved there. The purpose of this seems to be to preserve the 
>env of the first CPU but as it's unused yet maybe it can be removed for now 
>and readded later when needed.

I'll fix the commit message.

Best regards,
Bernhard

>
>Regards,
>BALATON Zoltan
>
>> Signed-off-by: Bernhard Beschow 
>> ---
>> hw/ppc/e500.c | 9 +
>> 1 file changed, 1 insertion(+), 8 deletions(-)
>> 
>> diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
>> index 75b051009f..f68779a1ea 100644
>> --- a/hw/ppc/e500.c
>> +++ b/hw/ppc/e500.c
>> @@ -899,7 +899,6 @@ void ppce500_init(MachineState *machine)
>> const PPCE500MachineClass *pmc = PPCE500_MACHINE_GET_CLASS(machine);
>> MachineClass *mc = MACHINE_CLASS(pmc);
>> PCIBus *pci_bus;
>> -CPUPPCState *env = NULL;
>> uint64_t loadaddr;
>> hwaddr kernel_base = -1LL;
>> int kernel_size = 0;
>> @@ -921,7 +920,6 @@ void ppce500_init(MachineState *machine)
>> IrqLines *irqs;
>> DeviceState *dev, *mpicdev;
>> DriveInfo *dinfo;
>> -CPUPPCState *firstenv = NULL;
>> MemoryRegion *ccsr_addr_space;
>> SysBusDevice *s;
>> PPCE500CCSRState *ccsr;
>> @@ -930,6 +928,7 @@ void ppce500_init(MachineState *machine)
>> irqs = g_new0(IrqLines, smp_cpus);
>> for (i = 0; i < smp_cpus; i++) {
>> PowerPCCPU *cpu;
>> +CPUPPCState *env;
>> CPUState *cs;
>> 
>> cpu = POWERPC_CPU(object_new(machine->cpu_type));
>> @@ -950,10 +949,6 @@ void ppce500_init(MachineState *machine)
>>  &error_abort);
>> qdev_realize_and_unref(DEVICE(cs), NULL, &error_fatal);
>> 
>> -if (!firstenv) {
>> -firstenv = env;
>> -}
>> -
>> irqs[i].irq[OPENPIC_OUTPUT_INT] =
>> qdev_get_gpio_in(DEVICE(cpu), PPCE500_INPUT_INT);
>> irqs[i].irq[OPENPIC_OUTPUT_CINT] =
>> @@ -974,8 +969,6 @@ void ppce500_init(MachineState *machine)
>> }
>> }
>> 
>> -env = firstenv;
>> -
>> if (!QEMU_IS_ALIGNED(machine->ram_size, RAM_SIZES_ALIGN)) {
>> error_report("RAM size must be multiple of %" PRIu64, 
>> RAM_SIZES_ALIGN);
>> exit(EXIT_FAILURE);
>> 



Re: [PATCH 01/23] hw/ppc/e500: Do not leak struct boot_info

2024-09-25 Thread Bernhard Beschow



Am 23. September 2024 10:02:10 UTC schrieb BALATON Zoltan :
>On Mon, 23 Sep 2024, Bernhard Beschow wrote:
>> The struct is allocated once with g_new0() but never free()'d. Fix the 
>> leakage
>> by adding an attribute to struct PPCE500MachineState which avoids the
>> allocation.
>> 
>> Signed-off-by: Bernhard Beschow 
>> ---
>> hw/ppc/e500.h |  8 
>> hw/ppc/e500.c | 17 -
>> 2 files changed, 12 insertions(+), 13 deletions(-)
>> 
>> diff --git a/hw/ppc/e500.h b/hw/ppc/e500.h
>> index 8c09ef92e4..557ce6ad93 100644
>> --- a/hw/ppc/e500.h
>> +++ b/hw/ppc/e500.h
>> @@ -5,10 +5,18 @@
>> #include "hw/platform-bus.h"
>> #include "qom/object.h"
>> 
>> +typedef struct boot_info {
>> +uint32_t dt_base;
>> +uint32_t dt_size;
>> +uint32_t entry;
>> +} boot_info;
>> +
>> struct PPCE500MachineState {
>> /*< private >*/
>
>While at it you could remove these private markers...

Will do.

>
>> MachineState parent_obj;
>> 
>> +boot_info boot_info;
>> +
>
>...and drop the new line here so only the parent_obj is followed by a new line 
>as was suggested as reccomended style.

I'll merge struct boot_info below as Cédric suggested.

Best regards,
Bernhard

>
>Regatds,
>BALATON Zoltan
>
>> /* points to instance of TYPE_PLATFORM_BUS_DEVICE if
>>  * board supports dynamic sysbus devices
>>  */
>> diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
>> index 3bd12b54ab..75b051009f 100644
>> --- a/hw/ppc/e500.c
>> +++ b/hw/ppc/e500.c
>> @@ -80,13 +80,6 @@
>> 
>> #define PLATFORM_CLK_FREQ_HZ   (400 * 1000 * 1000)
>> 
>> -struct boot_info
>> -{
>> -uint32_t dt_base;
>> -uint32_t dt_size;
>> -uint32_t entry;
>> -};
>> -
>> static uint32_t *pci_map_create(void *fdt, uint32_t mpic, int first_slot,
>> int nr_slots, int *len)
>> {
>> @@ -919,7 +912,6 @@ void ppce500_init(MachineState *machine)
>> bool kernel_as_payload;
>> hwaddr bios_entry = 0;
>> target_long payload_size;
>> -struct boot_info *boot_info = NULL;
>> int dt_size;
>> int i;
>> unsigned int smp_cpus = machine->smp.cpus;
>> @@ -974,9 +966,8 @@ void ppce500_init(MachineState *machine)
>> /* Register reset handler */
>> if (!i) {
>> /* Primary CPU */
>> -boot_info = g_new0(struct boot_info, 1);
>> qemu_register_reset(ppce500_cpu_reset, cpu);
>> -env->load_info = boot_info;
>> +env->load_info = &pms->boot_info;
>> } else {
>> /* Secondary CPUs */
>> qemu_register_reset(ppce500_cpu_reset_sec, cpu);
>> @@ -1274,9 +1265,9 @@ void ppce500_init(MachineState *machine)
>> }
>> assert(dt_size < DTB_MAX_SIZE);
>> 
>> -boot_info->entry = bios_entry;
>> -boot_info->dt_base = dt_base;
>> -boot_info->dt_size = dt_size;
>> +pms->boot_info.entry = bios_entry;
>> +pms->boot_info.dt_base = dt_base;
>> +pms->boot_info.dt_size = dt_size;
>> }
>> 
>> static void e500_ccsr_initfn(Object *obj)
>> 



Re: [PATCH 07/23] hw/ppc/e500: Extract ppce500_ccsr.c

2024-09-24 Thread Bernhard Beschow



Am 23. September 2024 10:38:46 UTC schrieb BALATON Zoltan :
>On Mon, 23 Sep 2024, Bernhard Beschow wrote:
>> The device model already has a header file. Also extract its implementation 
>> into
>> an accompanying source file like other e500 devices.
>> 
>> This commit is also a preparation for the next commit.
>> 
>> Signed-off-by: Bernhard Beschow 
>> ---
>> MAINTAINERS   |  2 +-
>> hw/ppc/e500-ccsr.h|  2 ++
>> hw/ppc/e500.c | 17 -
>> hw/ppc/ppce500_ccsr.c | 38 ++
>
>Maybe you could call it e500_ccsr.c and also rename the header to e500_ccsr.h 
>(underscore instead of dash) to match them. Or if you want to match 
>ppce500_spin.c then maybe move contents of e500-ccsr.h to e500.h?

Yeah, naming is hard. I'd actually prefer something like fsl_immr.* (taking 
inspiration from device tree here) to not confuse the whole SoC with the CPU. 
With the ppce500 prefix I was sticking to the convention of the PCIE device. 
Though there is also mpc-i2c and fsl_etsec...

>(More below...)
>
>> hw/ppc/meson.build|  1 +
>> 5 files changed, 42 insertions(+), 18 deletions(-)
>> create mode 100644 hw/ppc/ppce500_ccsr.c
>> 
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index ffacd60f40..b7c8b7ae72 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -1433,7 +1433,7 @@ e500
>> L: qemu-...@nongnu.org
>> S: Orphan
>> F: hw/ppc/e500*
>> -F: hw/ppc/ppce500_spin.c
>> +F: hw/ppc/ppce500_*.c
>> F: hw/gpio/mpc8xxx.c
>> F: hw/i2c/mpc_i2c.c
>> F: hw/net/fsl_etsec/
>> diff --git a/hw/ppc/e500-ccsr.h b/hw/ppc/e500-ccsr.h
>> index 249c17be3b..3ab7e72568 100644
>> --- a/hw/ppc/e500-ccsr.h
>> +++ b/hw/ppc/e500-ccsr.h
>> @@ -4,6 +4,8 @@
>> #include "hw/sysbus.h"
>> #include "qom/object.h"
>> 
>> +#define MPC8544_CCSRBAR_SIZE   0x0010ULL
>> +
>> struct PPCE500CCSRState {
>> /*< private >*/
>> SysBusDevice parent;
>> diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
>> index 2225533e33..4ee4304a8a 100644
>> --- a/hw/ppc/e500.c
>> +++ b/hw/ppc/e500.c
>> @@ -61,7 +61,6 @@
>> #define RAM_SIZES_ALIGN(64 * MiB)
>> 
>> /* TODO: parameterize */
>> -#define MPC8544_CCSRBAR_SIZE   0x0010ULL
>> #define MPC8544_MPIC_REGS_OFFSET   0x4ULL
>> #define MPC8544_MSI_REGS_OFFSET   0x41600ULL
>> #define MPC8544_SERIAL0_REGS_OFFSET 0x4500ULL
>> @@ -1264,21 +1263,6 @@ void ppce500_init(MachineState *machine)
>> pms->boot_info.dt_size = dt_size;
>> }
>> 
>> -static void e500_ccsr_initfn(Object *obj)
>> -{
>> -PPCE500CCSRState *ccsr = CCSR(obj);
>> -memory_region_init(&ccsr->ccsr_space, obj, "e500-ccsr",
>> -   MPC8544_CCSRBAR_SIZE);
>> -sysbus_init_mmio(SYS_BUS_DEVICE(ccsr), &ccsr->ccsr_space);
>> -}
>> -
>> -static const TypeInfo e500_ccsr_info = {
>> -.name  = TYPE_CCSR,
>> -.parent= TYPE_SYS_BUS_DEVICE,
>> -.instance_size = sizeof(PPCE500CCSRState),
>> -.instance_init = e500_ccsr_initfn,
>> -};
>> -
>> static const TypeInfo ppce500_info = {
>> .name  = TYPE_PPCE500_MACHINE,
>> .parent= TYPE_MACHINE,
>> @@ -1289,7 +1273,6 @@ static const TypeInfo ppce500_info = {
>> 
>> static void e500_register_types(void)
>> {
>> -type_register_static(&e500_ccsr_info);
>> type_register_static(&ppce500_info);
>> }
>> 
>> diff --git a/hw/ppc/ppce500_ccsr.c b/hw/ppc/ppce500_ccsr.c
>> new file mode 100644
>> index 00..191a9ceec3
>> --- /dev/null
>> +++ b/hw/ppc/ppce500_ccsr.c
>> @@ -0,0 +1,38 @@
>> +/*
>> + * QEMU PowerPC E500 embedded processors CCSR space emulation
>> + *
>> + * Copyright (C) 2009 Freescale Semiconductor, Inc. All rights reserved.
>> + *
>> + * Author: Yu Liu, 
>> + *
>> + * This file is derived from hw/ppc440_bamboo.c,
>> + * the copyright for that material belongs to the original owners.
>
>I think CCSR is a Freescale thing so likely this has nothing to do with 
>ppc440_bamboo so this sentence was for other parts of e500.c not applicable to 
>this part.

Good point. IANAL so erred on the safe side and copied the whole license text. 
I'm happy to omit this and would also prefer SPDX license identifiers as long 
as I get the confirmation that this is legal.

Best regards,
Bernhard

>
>> + *
>> + * This is f

Re: [PATCH 08/23] hw/ppc/ppce500_ccsr: Log access to unimplemented registers

2024-09-24 Thread Bernhard Beschow



Am 24. September 2024 10:15:43 UTC schrieb BALATON Zoltan :
>On Mon, 23 Sep 2024, Bernhard Beschow wrote:
>> The CCSR space is just a container which is meant to be covered by platform
>> device memory regions. However, QEMU only implements a subset of these 
>> devices.
>> Add some logging to see which devices a guest attempts to access.
>
>An aleternative solution for a similar problem is this:
>https://patchew.org/QEMU/20240520101007.a25a34e6...@zero.eik.bme.hu/
>I don't know if that would be simpler for this device as well.

That was my first approach but I didn't like that `-d  unimp` causes unrelated 
logging. With tracing one can be very targeted.

Best regards,
Bernhard

>
>Regards,
>BALATON Zoltan
>
>> Signed-off-by: Bernhard Beschow 
>> ---
>> hw/ppc/ppce500_ccsr.c | 33 +++--
>> hw/ppc/trace-events   |  3 +++
>> 2 files changed, 34 insertions(+), 2 deletions(-)
>> 
>> diff --git a/hw/ppc/ppce500_ccsr.c b/hw/ppc/ppce500_ccsr.c
>> index 191a9ceec3..28942b2348 100644
>> --- a/hw/ppc/ppce500_ccsr.c
>> +++ b/hw/ppc/ppce500_ccsr.c
>> @@ -15,14 +15,43 @@
>>  */
>> 
>> #include "qemu/osdep.h"
>> +#include "qemu/log.h"
>> #include "e500-ccsr.h"
>> +#include "trace.h"
>> +
>> +static uint64_t ppce500_ccsr_io_read(void *opaque, hwaddr addr, unsigned 
>> size)
>> +{
>> +uint64_t value = 0;
>> +
>> +trace_ppce500_ccsr_io_read(addr, value, size);
>> +qemu_log_mask(LOG_UNIMP,
>> +  "%s: unimplemented [0x%" HWADDR_PRIx "] -> 0\n",
>> +  __func__, addr);
>> +
>> +return value;
>> +}
>> +
>> +static void ppce500_ccsr_io_write(void *opaque, hwaddr addr, uint64_t value,
>> +  unsigned size)
>> +{
>> +trace_ppce500_ccsr_io_write(addr, value, size);
>> +qemu_log_mask(LOG_UNIMP,
>> +  "%s: unimplemented [0x%" HWADDR_PRIx "] <- 0x%" PRIx32 
>> "\n",
>> +  __func__, addr, (uint32_t)value);
>> +}
>> +
>> +static const MemoryRegionOps ppce500_ccsr_ops = {
>> +.read = ppce500_ccsr_io_read,
>> +.write = ppce500_ccsr_io_write,
>> +.endianness = DEVICE_NATIVE_ENDIAN,
>> +};
>> 
>> static void e500_ccsr_init(Object *obj)
>> {
>> PPCE500CCSRState *ccsr = CCSR(obj);
>> 
>> -memory_region_init(&ccsr->ccsr_space, obj, "e500-ccsr",
>> -   MPC8544_CCSRBAR_SIZE);
>> +memory_region_init_io(&ccsr->ccsr_space, obj, &ppce500_ccsr_ops, obj,
>> +  "e500-ccsr", MPC8544_CCSRBAR_SIZE);
>> sysbus_init_mmio(SYS_BUS_DEVICE(ccsr), &ccsr->ccsr_space);
>> }
>> 
>> diff --git a/hw/ppc/trace-events b/hw/ppc/trace-events
>> index 1f125ce841..ca4c231c9f 100644
>> --- a/hw/ppc/trace-events
>> +++ b/hw/ppc/trace-events
>> @@ -143,6 +143,9 @@ ppc_irq_cpu(const char *action) "%s"
>> ppc_dcr_read(uint32_t addr, uint32_t val) "DRCN[0x%x] -> 0x%x"
>> ppc_dcr_write(uint32_t addr, uint32_t val) "DRCN[0x%x] <- 0x%x"
>> 
>> +ppce500_ccsr_io_read(uint32_t index, uint32_t val, uint8_t size) "[0x%" 
>> PRIx32 "] -> 0x%08x (size: 0x%" PRIu8 ")"
>> +ppce500_ccsr_io_write(uint32_t index, uint32_t val, uint8_t size) "[0x%" 
>> PRIx32 "] <- 0x%08x (size: 0x%" PRIu8 ")"
>> +
>> # prep_systemio.c
>> prep_systemio_read(uint32_t addr, uint32_t val) "read addr=0x%x val=0x%x"
>> prep_systemio_write(uint32_t addr, uint32_t val) "write addr=0x%x val=0x%x"
>> 



Re: [PATCH 09/23] hw/ppc/mpc8544_guts: Populate POR PLL ratio status register

2024-09-24 Thread Bernhard Beschow



Am 24. September 2024 09:59:21 UTC schrieb BALATON Zoltan :
>On Mon, 23 Sep 2024, Bernhard Beschow wrote:
>> Am 23. September 2024 10:43:19 UTC schrieb BALATON Zoltan 
>> :
>>> On Mon, 23 Sep 2024, Bernhard Beschow wrote:
>>>> Populate this read-only register with some arbitrary values which avoids
>>>> U-Boot's get_clocks() to hang().
>>> 
>>> Maybe this should be a property settable by the machine as each board may 
>>> have different values and it may need to use the correct value for the 
>>> machine.
>> 
>> I actually considered this but went with the pragmatic solution to avoid 
>> over-engineering. In particular, I wanted to avoid further machine-specitic 
>> attributes in the machine class struct. Or do you expect a new e500 machine 
>> to be added? In that case I'd set above arbitrary values as default and 
>> expect a new machine to override these properties.
>
>Can't override if there's no property for it. There's one machine I may be 
>interested in that uses a Freescale e500 SoC. That one seems to use 0x0606180c 
>for this value which I think corresponds to 0/1 Ratio both 3:1, DDR Ratio 12:1 
>and Plat Ratio 6:1. I think one property to set the 32 bit value without 
>individual fields would be enough and we can put comments next to the value if 
>needed to note what components it comes from. Or if you just need any value 
>here maybe you could take this one then that would be good for me as well.

Let's use your numbers then without a property. Any specific machine I should 
mention in the commit message? Tabor?

> (I have some patches adding second i2c bus and SPD data that are needed for 
> U-Boot for memory detection but it needs more clean up before I can submit it 
> and also waiting for these patches to avoid conflict.)

Neat. That means we'll get DDR3 support?

Best regards,
Bernhard

>
>Regards,
>BALATON Zoltan
>
>>>> Signed-off-by: Bernhard Beschow 
>>>> ---
>>>> hw/ppc/mpc8544_guts.c | 12 
>>>> 1 file changed, 12 insertions(+)
>>>> 
>>>> diff --git a/hw/ppc/mpc8544_guts.c b/hw/ppc/mpc8544_guts.c
>>>> index e3540b0281..6688fd44c3 100644
>>>> --- a/hw/ppc/mpc8544_guts.c
>>>> +++ b/hw/ppc/mpc8544_guts.c
>>>> @@ -29,6 +29,12 @@
>>>> #define MPC8544_GUTS_RSTCR_RESET  0x02
>>>> 
>>>> #define MPC8544_GUTS_ADDR_PORPLLSR0x00
>>>> +REG32(GUTS_PORPLLSR, 0x00)
>>>> +FIELD(GUTS_PORPLLSR, E500_1_RATIO, 16, 6)
>>>> +FIELD(GUTS_PORPLLSR, E500_0_RATIO, 16, 6)
>>>> +FIELD(GUTS_PORPLLSR, DDR_RATIO, 9, 5)
>>>> +FIELD(GUTS_PORPLLSR, PLAT_RATIO, 1, 5)
>>>> +
>>>> #define MPC8544_GUTS_ADDR_PORBMSR 0x04
>>>> #define MPC8544_GUTS_ADDR_PORIMPSCR   0x08
>>>> #define MPC8544_GUTS_ADDR_PORDEVSR0x0C
>>>> @@ -75,6 +81,12 @@ static uint64_t mpc8544_guts_read(void *opaque, hwaddr 
>>>> addr,
>>>> 
>>>> addr &= MPC8544_GUTS_MMIO_SIZE - 1;
>>>> switch (addr) {
>>>> +case MPC8544_GUTS_ADDR_PORPLLSR:
>>>> +value = FIELD_DP32(value, GUTS_PORPLLSR, E500_1_RATIO, 3); /* 3:2 
>>>> */
>>>> +value = FIELD_DP32(value, GUTS_PORPLLSR, E500_0_RATIO, 3); /* 3:2 
>>>> */
>>>> +value = FIELD_DP32(value, GUTS_PORPLLSR, DDR_RATIO, 6); /* 6:1 */
>>>> +value = FIELD_DP32(value, GUTS_PORPLLSR, PLAT_RATIO, 4); /* 4:1 */
>>>> +break;
>>>> case MPC8544_GUTS_ADDR_PVR:
>>>> value = env->spr[SPR_PVR];
>>>> break;
>>>> 
>> 
>> 



Re: [PATCH 11/23] hw/i2c/mpc_i2c: Prefer DEFINE_TYPES() macro

2024-09-23 Thread Bernhard Beschow



Am 23. September 2024 10:49:53 UTC schrieb BALATON Zoltan :
>On Mon, 23 Sep 2024, Bernhard Beschow wrote:
>> Signed-off-by: Bernhard Beschow 
>> ---
>> hw/i2c/mpc_i2c.c | 20 
>> 1 file changed, 8 insertions(+), 12 deletions(-)
>> 
>> diff --git a/hw/i2c/mpc_i2c.c b/hw/i2c/mpc_i2c.c
>> index 3d79c15653..16f4309ea9 100644
>> --- a/hw/i2c/mpc_i2c.c
>> +++ b/hw/i2c/mpc_i2c.c
>> @@ -20,7 +20,6 @@
>> #include "qemu/osdep.h"
>> #include "hw/i2c/i2c.h"
>> #include "hw/irq.h"
>> -#include "qemu/module.h"
>> #include "hw/sysbus.h"
>> #include "migration/vmstate.h"
>> #include "qom/object.h"
>> @@ -345,16 +344,13 @@ static void mpc_i2c_class_init(ObjectClass *klass, 
>> void *data)
>> dc->desc = "MPC I2C Controller";
>> }
>> 
>> -static const TypeInfo mpc_i2c_type_info = {
>> -.name  = TYPE_MPC_I2C,
>> -.parent= TYPE_SYS_BUS_DEVICE,
>> -.instance_size = sizeof(MPCI2CState),
>> -.class_init= mpc_i2c_class_init,
>> +static const TypeInfo types[] = {
>> +{
>> +.name  = TYPE_MPC_I2C,
>> +.parent= TYPE_SYS_BUS_DEVICE,
>> +.instance_size = sizeof(MPCI2CState),
>> +.class_init= mpc_i2c_class_init,
>> +},
>> };
>> 
>> -static void mpc_i2c_register_types(void)
>> -{
>> -type_register_static(&mpc_i2c_type_info);
>> -}
>> -
>> -type_init(mpc_i2c_register_types)
>> +DEFINE_TYPES(types)
>
>What's the advantage of this when we have a single device? For these devices 
>this looks like just code churn to me.

It is still shorter and also more modern style. As a nice side effect it also 
helps in my experimental branch (which may never ship).

Best regards,
Bernhard

>
>Regards,
>BALATON Zoltan



Re: [PATCH 09/23] hw/ppc/mpc8544_guts: Populate POR PLL ratio status register

2024-09-23 Thread Bernhard Beschow



Am 23. September 2024 10:43:19 UTC schrieb BALATON Zoltan :
>On Mon, 23 Sep 2024, Bernhard Beschow wrote:
>> Populate this read-only register with some arbitrary values which avoids
>> U-Boot's get_clocks() to hang().
>
>Maybe this should be a property settable by the machine as each board may have 
>different values and it may need to use the correct value for the machine.

I actually considered this but went with the pragmatic solution to avoid 
over-engineering. In particular, I wanted to avoid further machine-specitic 
attributes in the machine class struct. Or do you expect a new e500 machine to 
be added? In that case I'd set above arbitrary values as default and expect a 
new machine to override these properties.

Best regards,
Bernhard

>
>Regards,
>BALATON Zoltan
>
>> Signed-off-by: Bernhard Beschow 
>> ---
>> hw/ppc/mpc8544_guts.c | 12 
>> 1 file changed, 12 insertions(+)
>> 
>> diff --git a/hw/ppc/mpc8544_guts.c b/hw/ppc/mpc8544_guts.c
>> index e3540b0281..6688fd44c3 100644
>> --- a/hw/ppc/mpc8544_guts.c
>> +++ b/hw/ppc/mpc8544_guts.c
>> @@ -29,6 +29,12 @@
>> #define MPC8544_GUTS_RSTCR_RESET  0x02
>> 
>> #define MPC8544_GUTS_ADDR_PORPLLSR0x00
>> +REG32(GUTS_PORPLLSR, 0x00)
>> +FIELD(GUTS_PORPLLSR, E500_1_RATIO, 16, 6)
>> +FIELD(GUTS_PORPLLSR, E500_0_RATIO, 16, 6)
>> +FIELD(GUTS_PORPLLSR, DDR_RATIO, 9, 5)
>> +FIELD(GUTS_PORPLLSR, PLAT_RATIO, 1, 5)
>> +
>> #define MPC8544_GUTS_ADDR_PORBMSR 0x04
>> #define MPC8544_GUTS_ADDR_PORIMPSCR   0x08
>> #define MPC8544_GUTS_ADDR_PORDEVSR0x0C
>> @@ -75,6 +81,12 @@ static uint64_t mpc8544_guts_read(void *opaque, hwaddr 
>> addr,
>> 
>> addr &= MPC8544_GUTS_MMIO_SIZE - 1;
>> switch (addr) {
>> +case MPC8544_GUTS_ADDR_PORPLLSR:
>> +value = FIELD_DP32(value, GUTS_PORPLLSR, E500_1_RATIO, 3); /* 3:2 */
>> +value = FIELD_DP32(value, GUTS_PORPLLSR, E500_0_RATIO, 3); /* 3:2 */
>> +value = FIELD_DP32(value, GUTS_PORPLLSR, DDR_RATIO, 6); /* 6:1 */
>> +value = FIELD_DP32(value, GUTS_PORPLLSR, PLAT_RATIO, 4); /* 4:1 */
>> +break;
>> case MPC8544_GUTS_ADDR_PVR:
>> value = env->spr[SPR_PVR];
>> break;
>> 



Re: [PATCH 00/23] E500 Cleanup

2024-09-23 Thread Bernhard Beschow




Am 23. September 2024 20:23:54 UTC schrieb "Cédric Le Goater" :
>Hello Bernhard,

Hi Cédric,

>
>On 9/23/24 11:29, Bernhard Beschow wrote:
>> This series is part of a bigger series exploring data-driven machine creation
>> using device tree blobs on top of the e500 machines [1]. It contains patches 
>> to
>> make this exploration easier which are also expected to provide value in
>> themselves.
>> 
>> The cleanup starts with the e500 machine class itself, then proceeds with
>> machine-specific device models and concludes with more or less loosely 
>> related
>> devices. Device cleanup mostly consists of using the DEFINE_TYPES() macro.
>
>Since you recently took a look at the machine models, would you
>be willing to take over maintenance of the e500 ? It shouldn't
>be an enormous amount of work.

Are you referring to the machine and related devices or the CPU? I'm somewhat 
familiar with the P102x and could take over but the CPU would be a different 
beast.

Best regards,
Bernhard

>
>Thanks,
>
>C.
>
>
>
>> [1] https://github.com/shentok/qemu/tree/e500-fdt
>> 
>> Bernhard Beschow (23):
>>hw/ppc/e500: Do not leak struct boot_info
>>hw/ppc/e500: Reduce scope of env pointer
>>hw/ppc/e500: Prefer QOM cast
>>hw/ppc/e500: Remove unused "irqs" parameter
>>hw/ppc/e500: Add missing device tree properties to i2c controller node
>>hw/ppc/e500: Use SysBusDevice API to access TYPE_CCSR's internal
>>  resources
>>hw/ppc/e500: Extract ppce500_ccsr.c
>>hw/ppc/ppce500_ccsr: Log access to unimplemented registers
>>hw/ppc/mpc8544_guts: Populate POR PLL ratio status register
>>hw/i2c/mpc_i2c: Convert DPRINTF to trace events for register access
>>hw/i2c/mpc_i2c: Prefer DEFINE_TYPES() macro
>>hw/pci-host/ppce500: Reuse TYPE_PPC_E500_PCI_BRIDGE define
>>hw/pci-host/ppce500: Prefer DEFINE_TYPES() macro
>>hw/gpio/mpc8xxx: Prefer DEFINE_TYPES() macro
>>hw/ppc/mpc8544_guts: Prefer DEFINE_TYPES() macro
>>hw/net/fsl_etsec/etsec: Prefer DEFINE_TYPES() macro
>>hw/intc: Guard openpic_kvm.c by dedicated OPENPIC_KVM Kconfig switch
>>hw/sd/sdhci: Prefer DEFINE_TYPES() macro
>>hw/block/pflash_cfi01: Prefer DEFINE_TYPES() macro
>>hw/i2c/smbus_eeprom: Prefer DEFINE_TYPES() macro
>>hw/rtc/ds1338: Prefer DEFINE_TYPES() macro
>>hw/usb/hcd-ehci-sysbus: Prefer DEFINE_TYPES() macro
>>hw/vfio/platform: Let vfio_start_eventfd_injection() take
>>  VFIOPlatformDevice pointer
>> 
>>   MAINTAINERS  |   2 +-
>>   hw/ppc/e500-ccsr.h   |   2 +
>>   hw/ppc/e500.h|   8 +++
>>   hw/block/pflash_cfi01.c  |  21 +++
>>   hw/gpio/mpc8xxx.c|  22 +++-
>>   hw/i2c/mpc_i2c.c |  29 +-
>>   hw/i2c/smbus_eeprom.c|  19 +++
>>   hw/net/fsl_etsec/etsec.c |  22 +++-
>>   hw/pci-host/ppce500.c|  54 --
>>   hw/ppc/e500.c|  61 +---
>>   hw/ppc/mpc8544_guts.c|  32 +++
>>   hw/ppc/ppce500_ccsr.c|  67 ++
>>   hw/rtc/ds1338.c  |  20 +++
>>   hw/sd/sdhci.c|  62 +---
>>   hw/usb/hcd-ehci-sysbus.c | 118 +--
>>   hw/vfio/platform.c   |   7 +--
>>   hw/i2c/trace-events  |   5 ++
>>   hw/intc/Kconfig  |   4 ++
>>   hw/intc/meson.build  |   3 +-
>>   hw/ppc/meson.build   |   1 +
>>   hw/ppc/trace-events  |   3 +
>>   21 files changed, 285 insertions(+), 277 deletions(-)
>>   create mode 100644 hw/ppc/ppce500_ccsr.c
>> 
>



[PATCH 08/23] hw/ppc/ppce500_ccsr: Log access to unimplemented registers

2024-09-23 Thread Bernhard Beschow
The CCSR space is just a container which is meant to be covered by platform
device memory regions. However, QEMU only implements a subset of these devices.
Add some logging to see which devices a guest attempts to access.

Signed-off-by: Bernhard Beschow 
---
 hw/ppc/ppce500_ccsr.c | 33 +++--
 hw/ppc/trace-events   |  3 +++
 2 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/hw/ppc/ppce500_ccsr.c b/hw/ppc/ppce500_ccsr.c
index 191a9ceec3..28942b2348 100644
--- a/hw/ppc/ppce500_ccsr.c
+++ b/hw/ppc/ppce500_ccsr.c
@@ -15,14 +15,43 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu/log.h"
 #include "e500-ccsr.h"
+#include "trace.h"
+
+static uint64_t ppce500_ccsr_io_read(void *opaque, hwaddr addr, unsigned size)
+{
+uint64_t value = 0;
+
+trace_ppce500_ccsr_io_read(addr, value, size);
+qemu_log_mask(LOG_UNIMP,
+  "%s: unimplemented [0x%" HWADDR_PRIx "] -> 0\n",
+  __func__, addr);
+
+return value;
+}
+
+static void ppce500_ccsr_io_write(void *opaque, hwaddr addr, uint64_t value,
+  unsigned size)
+{
+trace_ppce500_ccsr_io_write(addr, value, size);
+qemu_log_mask(LOG_UNIMP,
+  "%s: unimplemented [0x%" HWADDR_PRIx "] <- 0x%" PRIx32 "\n",
+  __func__, addr, (uint32_t)value);
+}
+
+static const MemoryRegionOps ppce500_ccsr_ops = {
+.read = ppce500_ccsr_io_read,
+.write = ppce500_ccsr_io_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+};
 
 static void e500_ccsr_init(Object *obj)
 {
 PPCE500CCSRState *ccsr = CCSR(obj);
 
-memory_region_init(&ccsr->ccsr_space, obj, "e500-ccsr",
-   MPC8544_CCSRBAR_SIZE);
+memory_region_init_io(&ccsr->ccsr_space, obj, &ppce500_ccsr_ops, obj,
+  "e500-ccsr", MPC8544_CCSRBAR_SIZE);
 sysbus_init_mmio(SYS_BUS_DEVICE(ccsr), &ccsr->ccsr_space);
 }
 
diff --git a/hw/ppc/trace-events b/hw/ppc/trace-events
index 1f125ce841..ca4c231c9f 100644
--- a/hw/ppc/trace-events
+++ b/hw/ppc/trace-events
@@ -143,6 +143,9 @@ ppc_irq_cpu(const char *action) "%s"
 ppc_dcr_read(uint32_t addr, uint32_t val) "DRCN[0x%x] -> 0x%x"
 ppc_dcr_write(uint32_t addr, uint32_t val) "DRCN[0x%x] <- 0x%x"
 
+ppce500_ccsr_io_read(uint32_t index, uint32_t val, uint8_t size) "[0x%" PRIx32 
"] -> 0x%08x (size: 0x%" PRIu8 ")"
+ppce500_ccsr_io_write(uint32_t index, uint32_t val, uint8_t size) "[0x%" 
PRIx32 "] <- 0x%08x (size: 0x%" PRIu8 ")"
+
 # prep_systemio.c
 prep_systemio_read(uint32_t addr, uint32_t val) "read addr=0x%x val=0x%x"
 prep_systemio_write(uint32_t addr, uint32_t val) "write addr=0x%x val=0x%x"
-- 
2.46.1




[PATCH 11/23] hw/i2c/mpc_i2c: Prefer DEFINE_TYPES() macro

2024-09-23 Thread Bernhard Beschow
Signed-off-by: Bernhard Beschow 
---
 hw/i2c/mpc_i2c.c | 20 
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/hw/i2c/mpc_i2c.c b/hw/i2c/mpc_i2c.c
index 3d79c15653..16f4309ea9 100644
--- a/hw/i2c/mpc_i2c.c
+++ b/hw/i2c/mpc_i2c.c
@@ -20,7 +20,6 @@
 #include "qemu/osdep.h"
 #include "hw/i2c/i2c.h"
 #include "hw/irq.h"
-#include "qemu/module.h"
 #include "hw/sysbus.h"
 #include "migration/vmstate.h"
 #include "qom/object.h"
@@ -345,16 +344,13 @@ static void mpc_i2c_class_init(ObjectClass *klass, void 
*data)
 dc->desc = "MPC I2C Controller";
 }
 
-static const TypeInfo mpc_i2c_type_info = {
-.name  = TYPE_MPC_I2C,
-.parent= TYPE_SYS_BUS_DEVICE,
-.instance_size = sizeof(MPCI2CState),
-.class_init= mpc_i2c_class_init,
+static const TypeInfo types[] = {
+{
+.name  = TYPE_MPC_I2C,
+.parent= TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(MPCI2CState),
+.class_init= mpc_i2c_class_init,
+},
 };
 
-static void mpc_i2c_register_types(void)
-{
-type_register_static(&mpc_i2c_type_info);
-}
-
-type_init(mpc_i2c_register_types)
+DEFINE_TYPES(types)
-- 
2.46.1




[PATCH 10/23] hw/i2c/mpc_i2c: Convert DPRINTF to trace events for register access

2024-09-23 Thread Bernhard Beschow
Signed-off-by: Bernhard Beschow 
---
 hw/i2c/mpc_i2c.c| 9 +
 hw/i2c/trace-events | 5 +
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/hw/i2c/mpc_i2c.c b/hw/i2c/mpc_i2c.c
index 2467d1a9aa..3d79c15653 100644
--- a/hw/i2c/mpc_i2c.c
+++ b/hw/i2c/mpc_i2c.c
@@ -24,6 +24,7 @@
 #include "hw/sysbus.h"
 #include "migration/vmstate.h"
 #include "qom/object.h"
+#include "trace.h"
 
 /* #define DEBUG_I2C */
 
@@ -224,8 +225,8 @@ static uint64_t mpc_i2c_read(void *opaque, hwaddr addr, 
unsigned size)
 break;
 }
 
-DPRINTF("%s: addr " HWADDR_FMT_plx " %02" PRIx32 "\n", __func__,
- addr, value);
+trace_mpc_i2c_read(addr, value);
+
 return (uint64_t)value;
 }
 
@@ -234,8 +235,8 @@ static void mpc_i2c_write(void *opaque, hwaddr addr,
 {
 MPCI2CState *s = opaque;
 
-DPRINTF("%s: addr " HWADDR_FMT_plx " val %08" PRIx64 "\n", __func__,
- addr, value);
+trace_mpc_i2c_write(addr, value);
+
 switch (addr) {
 case MPC_I2C_ADR:
 s->adr = value & CADR_MASK;
diff --git a/hw/i2c/trace-events b/hw/i2c/trace-events
index 6900e06eda..f708a7ace1 100644
--- a/hw/i2c/trace-events
+++ b/hw/i2c/trace-events
@@ -35,6 +35,11 @@ aspeed_i2c_bus_write(uint32_t busid, uint64_t offset, 
unsigned size, uint64_t va
 aspeed_i2c_bus_send(const char *mode, int i, int count, uint8_t byte) "%s send 
%d/%d 0x%02x"
 aspeed_i2c_bus_recv(const char *mode, int i, int count, uint8_t byte) "%s recv 
%d/%d 0x%02x"
 
+# mpc_i2c.c
+
+mpc_i2c_read(uint64_t addr, uint32_t value) "[0x%" PRIx64 "] -> 0x%02" PRIx32
+mpc_i2c_write(uint64_t addr, uint32_t value) "[0x%" PRIx64 "] <- 0x%02" PRIx32
+
 # npcm7xx_smbus.c
 
 npcm7xx_smbus_read(const char *id, uint64_t offset, uint64_t value, unsigned 
size) "%s offset: 0x%04" PRIx64 " value: 0x%02" PRIx64 " size: %u"
-- 
2.46.1




[PATCH 06/23] hw/ppc/e500: Use SysBusDevice API to access TYPE_CCSR's internal resources

2024-09-23 Thread Bernhard Beschow
Rather than accessing the attributes of TYPE_CCSR directly, use the SysBusDevice
API which exists exactly for that purpose. Furthermore, registering the memory
region with the SysBusDevice API makes it show up in QMP's `info qom-tree`
command.

Signed-off-by: Bernhard Beschow 
---
 hw/pci-host/ppce500.c | 10 +-
 hw/ppc/e500.c |  8 
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/hw/pci-host/ppce500.c b/hw/pci-host/ppce500.c
index 95b983b2b3..97e5d47cec 100644
--- a/hw/pci-host/ppce500.c
+++ b/hw/pci-host/ppce500.c
@@ -16,7 +16,6 @@
 
 #include "qemu/osdep.h"
 #include "hw/irq.h"
-#include "hw/ppc/e500-ccsr.h"
 #include "hw/qdev-properties.h"
 #include "migration/vmstate.h"
 #include "hw/pci/pci_device.h"
@@ -419,11 +418,12 @@ static const VMStateDescription vmstate_ppce500_pci = {
 static void e500_pcihost_bridge_realize(PCIDevice *d, Error **errp)
 {
 PPCE500PCIBridgeState *b = PPC_E500_PCI_BRIDGE(d);
-PPCE500CCSRState *ccsr = CCSR(container_get(qdev_get_machine(),
-  "/e500-ccsr"));
+SysBusDevice *ccsr = SYS_BUS_DEVICE(container_get(qdev_get_machine(),
+  "/e500-ccsr"));
+MemoryRegion *ccsr_space = sysbus_mmio_get_region(ccsr, 0);
 
-memory_region_init_alias(&b->bar0, OBJECT(ccsr), "e500-pci-bar0", 
&ccsr->ccsr_space,
- 0, int128_get64(ccsr->ccsr_space.size));
+memory_region_init_alias(&b->bar0, OBJECT(ccsr), "e500-pci-bar0",
+ ccsr_space, 0, int128_get64(ccsr_space->size));
 pci_register_bar(d, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &b->bar0);
 }
 
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index e2a4f265a5..2225533e33 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -924,7 +924,6 @@ void ppce500_init(MachineState *machine)
 DriveInfo *dinfo;
 MemoryRegion *ccsr_addr_space;
 SysBusDevice *s;
-PPCE500CCSRState *ccsr;
 I2CBus *i2c;
 
 irqs = g_new0(IrqLines, smp_cpus);
@@ -980,10 +979,10 @@ void ppce500_init(MachineState *machine)
 memory_region_add_subregion(address_space_mem, 0, machine->ram);
 
 dev = qdev_new("e500-ccsr");
+s = SYS_BUS_DEVICE(dev);
 object_property_add_child(OBJECT(machine), "e500-ccsr", OBJECT(dev));
-sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
-ccsr = CCSR(dev);
-ccsr_addr_space = &ccsr->ccsr_space;
+sysbus_realize_and_unref(s, &error_fatal);
+ccsr_addr_space = sysbus_mmio_get_region(s, 0);
 memory_region_add_subregion(address_space_mem, pmc->ccsrbar_base,
 ccsr_addr_space);
 
@@ -1270,6 +1269,7 @@ static void e500_ccsr_initfn(Object *obj)
 PPCE500CCSRState *ccsr = CCSR(obj);
 memory_region_init(&ccsr->ccsr_space, obj, "e500-ccsr",
MPC8544_CCSRBAR_SIZE);
+sysbus_init_mmio(SYS_BUS_DEVICE(ccsr), &ccsr->ccsr_space);
 }
 
 static const TypeInfo e500_ccsr_info = {
-- 
2.46.1




[PATCH 09/23] hw/ppc/mpc8544_guts: Populate POR PLL ratio status register

2024-09-23 Thread Bernhard Beschow
Populate this read-only register with some arbitrary values which avoids
U-Boot's get_clocks() to hang().

Signed-off-by: Bernhard Beschow 
---
 hw/ppc/mpc8544_guts.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/hw/ppc/mpc8544_guts.c b/hw/ppc/mpc8544_guts.c
index e3540b0281..6688fd44c3 100644
--- a/hw/ppc/mpc8544_guts.c
+++ b/hw/ppc/mpc8544_guts.c
@@ -29,6 +29,12 @@
 #define MPC8544_GUTS_RSTCR_RESET  0x02
 
 #define MPC8544_GUTS_ADDR_PORPLLSR0x00
+REG32(GUTS_PORPLLSR, 0x00)
+FIELD(GUTS_PORPLLSR, E500_1_RATIO, 16, 6)
+FIELD(GUTS_PORPLLSR, E500_0_RATIO, 16, 6)
+FIELD(GUTS_PORPLLSR, DDR_RATIO, 9, 5)
+FIELD(GUTS_PORPLLSR, PLAT_RATIO, 1, 5)
+
 #define MPC8544_GUTS_ADDR_PORBMSR 0x04
 #define MPC8544_GUTS_ADDR_PORIMPSCR   0x08
 #define MPC8544_GUTS_ADDR_PORDEVSR0x0C
@@ -75,6 +81,12 @@ static uint64_t mpc8544_guts_read(void *opaque, hwaddr addr,
 
 addr &= MPC8544_GUTS_MMIO_SIZE - 1;
 switch (addr) {
+case MPC8544_GUTS_ADDR_PORPLLSR:
+value = FIELD_DP32(value, GUTS_PORPLLSR, E500_1_RATIO, 3); /* 3:2 */
+value = FIELD_DP32(value, GUTS_PORPLLSR, E500_0_RATIO, 3); /* 3:2 */
+value = FIELD_DP32(value, GUTS_PORPLLSR, DDR_RATIO, 6); /* 6:1 */
+value = FIELD_DP32(value, GUTS_PORPLLSR, PLAT_RATIO, 4); /* 4:1 */
+break;
 case MPC8544_GUTS_ADDR_PVR:
 value = env->spr[SPR_PVR];
 break;
-- 
2.46.1




[PATCH 03/23] hw/ppc/e500: Prefer QOM cast

2024-09-23 Thread Bernhard Beschow
Signed-off-by: Bernhard Beschow 
---
 hw/ppc/e500.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index f68779a1ea..32996c188e 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -1008,7 +1008,7 @@ void ppce500_init(MachineState *machine)
 sysbus_connect_irq(s, 0, qdev_get_gpio_in(mpicdev, MPC8544_I2C_IRQ));
 memory_region_add_subregion(ccsr_addr_space, MPC8544_I2C_REGS_OFFSET,
 sysbus_mmio_get_region(s, 0));
-i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");
+i2c = I2C_BUS(qdev_get_child_bus(dev, "i2c"));
 i2c_slave_create_simple(i2c, "ds1338", RTC_REGS_OFFSET);
 
 /* eSDHC */
@@ -1057,7 +1057,7 @@ void ppce500_init(MachineState *machine)
 memory_region_add_subregion(ccsr_addr_space, MPC8544_PCI_REGS_OFFSET,
 sysbus_mmio_get_region(s, 0));
 
-pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci.0");
+pci_bus = PCI_BUS(qdev_get_child_bus(dev, "pci.0"));
 if (!pci_bus)
 printf("couldn't create PCI controller!\n");
 
-- 
2.46.1




[PATCH 17/23] hw/intc: Guard openpic_kvm.c by dedicated OPENPIC_KVM Kconfig switch

2024-09-23 Thread Bernhard Beschow
Allows to clearly mark code sections relying on this device type.

Signed-off-by: Bernhard Beschow 
---
 hw/ppc/e500.c   | 2 +-
 hw/intc/Kconfig | 4 
 hw/intc/meson.build | 3 +--
 3 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index 4ee4304a8a..149e608324 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -828,7 +828,7 @@ static DeviceState 
*ppce500_init_mpic_qemu(PPCE500MachineState *pms,
 static DeviceState *ppce500_init_mpic_kvm(const PPCE500MachineClass *pmc,
   Error **errp)
 {
-#ifdef CONFIG_KVM
+#ifdef CONFIG_OPENPIC_KVM
 DeviceState *dev;
 CPUState *cs;
 
diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
index dd405bdb5d..a3df98ae59 100644
--- a/hw/intc/Kconfig
+++ b/hw/intc/Kconfig
@@ -16,6 +16,10 @@ config OPENPIC
 bool
 select MSI_NONBROKEN
 
+config OPENPIC_KVM
+bool
+depends on OPENPIC && KVM
+
 config APIC
 bool
 select MSI_NONBROKEN
diff --git a/hw/intc/meson.build b/hw/intc/meson.build
index 6bfdc4eb33..b9de6bf5c6 100644
--- a/hw/intc/meson.build
+++ b/hw/intc/meson.build
@@ -48,8 +48,7 @@ specific_ss.add(when: 'CONFIG_IOAPIC', if_true: 
files('ioapic.c'))
 specific_ss.add(when: 'CONFIG_LOONGSON_LIOINTC', if_true: 
files('loongson_liointc.c'))
 specific_ss.add(when: 'CONFIG_MIPS_CPS', if_true: files('mips_gic.c'))
 specific_ss.add(when: 'CONFIG_OMPIC', if_true: files('ompic.c'))
-specific_ss.add(when: ['CONFIG_KVM', 'CONFIG_OPENPIC'],
-   if_true: files('openpic_kvm.c'))
+specific_ss.add(when: 'CONFIG_OPENPIC_KVM', if_true: files('openpic_kvm.c'))
 specific_ss.add(when: 'CONFIG_POWERNV', if_true: files('xics_pnv.c', 
'pnv_xive.c', 'pnv_xive2.c'))
 specific_ss.add(when: 'CONFIG_PPC_UIC', if_true: files('ppc-uic.c'))
 specific_ss.add(when: 'CONFIG_RX_ICU', if_true: files('rx_icu.c'))
-- 
2.46.1




[PATCH 12/23] hw/pci-host/ppce500: Reuse TYPE_PPC_E500_PCI_BRIDGE define

2024-09-23 Thread Bernhard Beschow
Prefer a macro rather than a string literal when instantiaging device models.

Signed-off-by: Bernhard Beschow 
---
 hw/pci-host/ppce500.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/pci-host/ppce500.c b/hw/pci-host/ppce500.c
index 97e5d47cec..d7ff2ba778 100644
--- a/hw/pci-host/ppce500.c
+++ b/hw/pci-host/ppce500.c
@@ -475,7 +475,7 @@ static void e500_pcihost_realize(DeviceState *dev, Error 
**errp)
 address_space_init(&s->bm_as, &s->bm, "pci-bm");
 pci_setup_iommu(b, &ppce500_iommu_ops, s);
 
-pci_create_simple(b, 0, "e500-host-bridge");
+pci_create_simple(b, 0, TYPE_PPC_E500_PCI_BRIDGE);
 
 memory_region_init(&s->container, OBJECT(h), "pci-container", 
PCIE500_ALL_SIZE);
 memory_region_init_io(&h->conf_mem, OBJECT(h), &pci_host_conf_be_ops, h,
-- 
2.46.1




[PATCH 21/23] hw/rtc/ds1338: Prefer DEFINE_TYPES() macro

2024-09-23 Thread Bernhard Beschow
---
 hw/rtc/ds1338.c | 20 
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/hw/rtc/ds1338.c b/hw/rtc/ds1338.c
index a5fe221418..6de13caf99 100644
--- a/hw/rtc/ds1338.c
+++ b/hw/rtc/ds1338.c
@@ -14,7 +14,6 @@
 #include "hw/i2c/i2c.h"
 #include "migration/vmstate.h"
 #include "qemu/bcd.h"
-#include "qemu/module.h"
 #include "qom/object.h"
 #include "sysemu/rtc.h"
 
@@ -227,16 +226,13 @@ static void ds1338_class_init(ObjectClass *klass, void 
*data)
 dc->vmsd = &vmstate_ds1338;
 }
 
-static const TypeInfo ds1338_info = {
-.name  = TYPE_DS1338,
-.parent= TYPE_I2C_SLAVE,
-.instance_size = sizeof(DS1338State),
-.class_init= ds1338_class_init,
+static const TypeInfo types[] = {
+{
+.name  = TYPE_DS1338,
+.parent= TYPE_I2C_SLAVE,
+.instance_size = sizeof(DS1338State),
+.class_init= ds1338_class_init,
+},
 };
 
-static void ds1338_register_types(void)
-{
-type_register_static(&ds1338_info);
-}
-
-type_init(ds1338_register_types)
+DEFINE_TYPES(types)
-- 
2.46.1




[PATCH 22/23] hw/usb/hcd-ehci-sysbus: Prefer DEFINE_TYPES() macro

2024-09-23 Thread Bernhard Beschow
Signed-off-by: Bernhard Beschow 
---
 hw/usb/hcd-ehci-sysbus.c | 118 +--
 1 file changed, 50 insertions(+), 68 deletions(-)

diff --git a/hw/usb/hcd-ehci-sysbus.c b/hw/usb/hcd-ehci-sysbus.c
index 2b1652f7a8..87a3bebe3e 100644
--- a/hw/usb/hcd-ehci-sysbus.c
+++ b/hw/usb/hcd-ehci-sysbus.c
@@ -19,7 +19,6 @@
 #include "hw/qdev-properties.h"
 #include "hw/usb/hcd-ehci.h"
 #include "migration/vmstate.h"
-#include "qemu/module.h"
 
 static const VMStateDescription vmstate_ehci_sysbus = {
 .name= "ehci-sysbus",
@@ -97,17 +96,6 @@ static void ehci_sysbus_class_init(ObjectClass *klass, void 
*data)
 set_bit(DEVICE_CATEGORY_USB, dc->categories);
 }
 
-static const TypeInfo ehci_type_info = {
-.name  = TYPE_SYS_BUS_EHCI,
-.parent= TYPE_SYS_BUS_DEVICE,
-.instance_size = sizeof(EHCISysBusState),
-.instance_init = ehci_sysbus_init,
-.instance_finalize = ehci_sysbus_finalize,
-.abstract  = true,
-.class_init= ehci_sysbus_class_init,
-.class_size= sizeof(SysBusEHCIClass),
-};
-
 static void ehci_platform_class_init(ObjectClass *oc, void *data)
 {
 SysBusEHCIClass *sec = SYS_BUS_EHCI_CLASS(oc);
@@ -118,12 +106,6 @@ static void ehci_platform_class_init(ObjectClass *oc, void 
*data)
 set_bit(DEVICE_CATEGORY_USB, dc->categories);
 }
 
-static const TypeInfo ehci_platform_type_info = {
-.name  = TYPE_PLATFORM_EHCI,
-.parent= TYPE_SYS_BUS_EHCI,
-.class_init= ehci_platform_class_init,
-};
-
 static void ehci_exynos4210_class_init(ObjectClass *oc, void *data)
 {
 SysBusEHCIClass *sec = SYS_BUS_EHCI_CLASS(oc);
@@ -134,12 +116,6 @@ static void ehci_exynos4210_class_init(ObjectClass *oc, 
void *data)
 set_bit(DEVICE_CATEGORY_USB, dc->categories);
 }
 
-static const TypeInfo ehci_exynos4210_type_info = {
-.name  = TYPE_EXYNOS4210_EHCI,
-.parent= TYPE_SYS_BUS_EHCI,
-.class_init= ehci_exynos4210_class_init,
-};
-
 static void ehci_aw_h3_class_init(ObjectClass *oc, void *data)
 {
 SysBusEHCIClass *sec = SYS_BUS_EHCI_CLASS(oc);
@@ -150,12 +126,6 @@ static void ehci_aw_h3_class_init(ObjectClass *oc, void 
*data)
 set_bit(DEVICE_CATEGORY_USB, dc->categories);
 }
 
-static const TypeInfo ehci_aw_h3_type_info = {
-.name  = TYPE_AW_H3_EHCI,
-.parent= TYPE_SYS_BUS_EHCI,
-.class_init= ehci_aw_h3_class_init,
-};
-
 static void ehci_npcm7xx_class_init(ObjectClass *oc, void *data)
 {
 SysBusEHCIClass *sec = SYS_BUS_EHCI_CLASS(oc);
@@ -168,12 +138,6 @@ static void ehci_npcm7xx_class_init(ObjectClass *oc, void 
*data)
 set_bit(DEVICE_CATEGORY_USB, dc->categories);
 }
 
-static const TypeInfo ehci_npcm7xx_type_info = {
-.name  = TYPE_NPCM7XX_EHCI,
-.parent= TYPE_SYS_BUS_EHCI,
-.class_init= ehci_npcm7xx_class_init,
-};
-
 static void ehci_tegra2_class_init(ObjectClass *oc, void *data)
 {
 SysBusEHCIClass *sec = SYS_BUS_EHCI_CLASS(oc);
@@ -184,12 +148,6 @@ static void ehci_tegra2_class_init(ObjectClass *oc, void 
*data)
 set_bit(DEVICE_CATEGORY_USB, dc->categories);
 }
 
-static const TypeInfo ehci_tegra2_type_info = {
-.name  = TYPE_TEGRA2_EHCI,
-.parent= TYPE_SYS_BUS_EHCI,
-.class_init= ehci_tegra2_class_init,
-};
-
 static void ehci_ppc4xx_init(Object *o)
 {
 EHCISysBusState *s = SYS_BUS_EHCI(o);
@@ -207,13 +165,6 @@ static void ehci_ppc4xx_class_init(ObjectClass *oc, void 
*data)
 set_bit(DEVICE_CATEGORY_USB, dc->categories);
 }
 
-static const TypeInfo ehci_ppc4xx_type_info = {
-.name  = TYPE_PPC4xx_EHCI,
-.parent= TYPE_SYS_BUS_EHCI,
-.class_init= ehci_ppc4xx_class_init,
-.instance_init = ehci_ppc4xx_init,
-};
-
 /*
  * Faraday FUSBH200 USB 2.0 EHCI
  */
@@ -282,24 +233,55 @@ static void fusbh200_ehci_class_init(ObjectClass *oc, 
void *data)
 set_bit(DEVICE_CATEGORY_USB, dc->categories);
 }
 
-static const TypeInfo ehci_fusbh200_type_info = {
-.name  = TYPE_FUSBH200_EHCI,
-.parent= TYPE_SYS_BUS_EHCI,
-.instance_size = sizeof(FUSBH200EHCIState),
-.instance_init = fusbh200_ehci_init,
-.class_init= fusbh200_ehci_class_init,
+static const TypeInfo types[] = {
+{
+.name  = TYPE_SYS_BUS_EHCI,
+.parent= TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(EHCISysBusState),
+.instance_init = ehci_sysbus_init,
+.instance_finalize = ehci_sysbus_finalize,
+.abstract  = true,
+.class_init= ehci_sysbus_class_init,
+.class_size= sizeof(SysBusEHCIClass),
+},
+{
+.name  = TYPE_PLATFORM_EHCI,
+.parent= TYPE_SYS_BUS_EHCI,
+.class_init= ehci_platform_class_init,
+},
+{
+.name  = TYPE_EXYNOS4210_EHCI,
+.parent   

[PATCH 18/23] hw/sd/sdhci: Prefer DEFINE_TYPES() macro

2024-09-23 Thread Bernhard Beschow
Signed-off-by: Bernhard Beschow 
---
 hw/sd/sdhci.c | 62 +--
 1 file changed, 26 insertions(+), 36 deletions(-)

diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index 87122e4245..3ed2d8658a 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -37,7 +37,6 @@
 #include "migration/vmstate.h"
 #include "sdhci-internal.h"
 #include "qemu/log.h"
-#include "qemu/module.h"
 #include "trace.h"
 #include "qom/object.h"
 
@@ -1598,15 +1597,6 @@ static void sdhci_sysbus_class_init(ObjectClass *klass, 
void *data)
 sdhci_common_class_init(klass, data);
 }
 
-static const TypeInfo sdhci_sysbus_info = {
-.name = TYPE_SYSBUS_SDHCI,
-.parent = TYPE_SYS_BUS_DEVICE,
-.instance_size = sizeof(SDHCIState),
-.instance_init = sdhci_sysbus_init,
-.instance_finalize = sdhci_sysbus_finalize,
-.class_init = sdhci_sysbus_class_init,
-};
-
 /* --- qdev bus master --- */
 
 static void sdhci_bus_class_init(ObjectClass *klass, void *data)
@@ -1617,13 +1607,6 @@ static void sdhci_bus_class_init(ObjectClass *klass, 
void *data)
 sbc->set_readonly = sdhci_set_readonly;
 }
 
-static const TypeInfo sdhci_bus_info = {
-.name = TYPE_SDHCI_BUS,
-.parent = TYPE_SD_BUS,
-.instance_size = sizeof(SDBus),
-.class_init = sdhci_bus_class_init,
-};
-
 /* --- qdev i.MX eSDHC --- */
 
 #define USDHC_MIX_CTRL  0x48
@@ -1882,12 +1865,6 @@ static void imx_usdhc_init(Object *obj)
 s->quirks = SDHCI_QUIRK_NO_BUSY_IRQ;
 }
 
-static const TypeInfo imx_usdhc_info = {
-.name = TYPE_IMX_USDHC,
-.parent = TYPE_SYSBUS_SDHCI,
-.instance_init = imx_usdhc_init,
-};
-
 /* --- qdev Samsung s3c --- */
 
 #define S3C_SDHCI_CONTROL2  0x80
@@ -1946,18 +1923,31 @@ static void sdhci_s3c_init(Object *obj)
 s->io_ops = &sdhci_s3c_mmio_ops;
 }
 
-static const TypeInfo sdhci_s3c_info = {
-.name = TYPE_S3C_SDHCI  ,
-.parent = TYPE_SYSBUS_SDHCI,
-.instance_init = sdhci_s3c_init,
+static const TypeInfo types[] = {
+{
+.name = TYPE_SDHCI_BUS,
+.parent = TYPE_SD_BUS,
+.instance_size = sizeof(SDBus),
+.class_init = sdhci_bus_class_init,
+},
+{
+.name = TYPE_SYSBUS_SDHCI,
+.parent = TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(SDHCIState),
+.instance_init = sdhci_sysbus_init,
+.instance_finalize = sdhci_sysbus_finalize,
+.class_init = sdhci_sysbus_class_init,
+},
+{
+.name = TYPE_IMX_USDHC,
+.parent = TYPE_SYSBUS_SDHCI,
+.instance_init = imx_usdhc_init,
+},
+{
+.name = TYPE_S3C_SDHCI,
+.parent = TYPE_SYSBUS_SDHCI,
+.instance_init = sdhci_s3c_init,
+},
 };
 
-static void sdhci_register_types(void)
-{
-type_register_static(&sdhci_sysbus_info);
-type_register_static(&sdhci_bus_info);
-type_register_static(&imx_usdhc_info);
-type_register_static(&sdhci_s3c_info);
-}
-
-type_init(sdhci_register_types)
+DEFINE_TYPES(types)
-- 
2.46.1




[PATCH 16/23] hw/net/fsl_etsec/etsec: Prefer DEFINE_TYPES() macro

2024-09-23 Thread Bernhard Beschow
Signed-off-by: Bernhard Beschow 
---
 hw/net/fsl_etsec/etsec.c | 22 +-
 1 file changed, 9 insertions(+), 13 deletions(-)

diff --git a/hw/net/fsl_etsec/etsec.c b/hw/net/fsl_etsec/etsec.c
index 3fdd16ef2e..9bd886b996 100644
--- a/hw/net/fsl_etsec/etsec.c
+++ b/hw/net/fsl_etsec/etsec.c
@@ -36,7 +36,6 @@
 #include "registers.h"
 #include "qapi/error.h"
 #include "qemu/log.h"
-#include "qemu/module.h"
 
 /* #define HEX_DUMP */
 /* #define DEBUG_REGISTER */
@@ -431,17 +430,14 @@ static void etsec_class_init(ObjectClass *klass, void 
*data)
 dc->user_creatable = true;
 }
 
-static const TypeInfo etsec_info = {
-.name  = TYPE_ETSEC_COMMON,
-.parent= TYPE_SYS_BUS_DEVICE,
-.instance_size = sizeof(eTSEC),
-.class_init= etsec_class_init,
-.instance_init = etsec_instance_init,
+static const TypeInfo types[] = {
+{
+.name  = TYPE_ETSEC_COMMON,
+.parent= TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(eTSEC),
+.class_init= etsec_class_init,
+.instance_init = etsec_instance_init,
+},
 };
 
-static void etsec_register_types(void)
-{
-type_register_static(&etsec_info);
-}
-
-type_init(etsec_register_types)
+DEFINE_TYPES(types)
-- 
2.46.1




[PATCH 01/23] hw/ppc/e500: Do not leak struct boot_info

2024-09-23 Thread Bernhard Beschow
The struct is allocated once with g_new0() but never free()'d. Fix the leakage
by adding an attribute to struct PPCE500MachineState which avoids the
allocation.

Signed-off-by: Bernhard Beschow 
---
 hw/ppc/e500.h |  8 
 hw/ppc/e500.c | 17 -
 2 files changed, 12 insertions(+), 13 deletions(-)

diff --git a/hw/ppc/e500.h b/hw/ppc/e500.h
index 8c09ef92e4..557ce6ad93 100644
--- a/hw/ppc/e500.h
+++ b/hw/ppc/e500.h
@@ -5,10 +5,18 @@
 #include "hw/platform-bus.h"
 #include "qom/object.h"
 
+typedef struct boot_info {
+uint32_t dt_base;
+uint32_t dt_size;
+uint32_t entry;
+} boot_info;
+
 struct PPCE500MachineState {
 /*< private >*/
 MachineState parent_obj;
 
+boot_info boot_info;
+
 /* points to instance of TYPE_PLATFORM_BUS_DEVICE if
  * board supports dynamic sysbus devices
  */
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index 3bd12b54ab..75b051009f 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -80,13 +80,6 @@
 
 #define PLATFORM_CLK_FREQ_HZ   (400 * 1000 * 1000)
 
-struct boot_info
-{
-uint32_t dt_base;
-uint32_t dt_size;
-uint32_t entry;
-};
-
 static uint32_t *pci_map_create(void *fdt, uint32_t mpic, int first_slot,
 int nr_slots, int *len)
 {
@@ -919,7 +912,6 @@ void ppce500_init(MachineState *machine)
 bool kernel_as_payload;
 hwaddr bios_entry = 0;
 target_long payload_size;
-struct boot_info *boot_info = NULL;
 int dt_size;
 int i;
 unsigned int smp_cpus = machine->smp.cpus;
@@ -974,9 +966,8 @@ void ppce500_init(MachineState *machine)
 /* Register reset handler */
 if (!i) {
 /* Primary CPU */
-boot_info = g_new0(struct boot_info, 1);
 qemu_register_reset(ppce500_cpu_reset, cpu);
-env->load_info = boot_info;
+env->load_info = &pms->boot_info;
 } else {
 /* Secondary CPUs */
 qemu_register_reset(ppce500_cpu_reset_sec, cpu);
@@ -1274,9 +1265,9 @@ void ppce500_init(MachineState *machine)
 }
 assert(dt_size < DTB_MAX_SIZE);
 
-boot_info->entry = bios_entry;
-boot_info->dt_base = dt_base;
-boot_info->dt_size = dt_size;
+pms->boot_info.entry = bios_entry;
+pms->boot_info.dt_base = dt_base;
+pms->boot_info.dt_size = dt_size;
 }
 
 static void e500_ccsr_initfn(Object *obj)
-- 
2.46.1




[PATCH 04/23] hw/ppc/e500: Remove unused "irqs" parameter

2024-09-23 Thread Bernhard Beschow
Signed-off-by: Bernhard Beschow 
---
 hw/ppc/e500.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index 32996c188e..228287b457 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -825,7 +825,7 @@ static DeviceState 
*ppce500_init_mpic_qemu(PPCE500MachineState *pms,
 }
 
 static DeviceState *ppce500_init_mpic_kvm(const PPCE500MachineClass *pmc,
-  IrqLines *irqs, Error **errp)
+  Error **errp)
 {
 #ifdef CONFIG_KVM
 DeviceState *dev;
@@ -865,7 +865,7 @@ static DeviceState *ppce500_init_mpic(PPCE500MachineState 
*pms,
 Error *err = NULL;
 
 if (kvm_kernel_irqchip_allowed()) {
-dev = ppce500_init_mpic_kvm(pmc, irqs, &err);
+dev = ppce500_init_mpic_kvm(pmc, &err);
 }
 if (kvm_kernel_irqchip_required() && !dev) {
 error_reportf_err(err,
-- 
2.46.1




[PATCH 20/23] hw/i2c/smbus_eeprom: Prefer DEFINE_TYPES() macro

2024-09-23 Thread Bernhard Beschow
Signed-off-by: Bernhard Beschow 
---
 hw/i2c/smbus_eeprom.c | 19 ---
 1 file changed, 8 insertions(+), 11 deletions(-)

diff --git a/hw/i2c/smbus_eeprom.c b/hw/i2c/smbus_eeprom.c
index 9e62c27a1a..1d4d9704bf 100644
--- a/hw/i2c/smbus_eeprom.c
+++ b/hw/i2c/smbus_eeprom.c
@@ -151,19 +151,16 @@ static void smbus_eeprom_class_initfn(ObjectClass *klass, 
void *data)
 dc->user_creatable = false;
 }
 
-static const TypeInfo smbus_eeprom_info = {
-.name  = TYPE_SMBUS_EEPROM,
-.parent= TYPE_SMBUS_DEVICE,
-.instance_size = sizeof(SMBusEEPROMDevice),
-.class_init= smbus_eeprom_class_initfn,
+static const TypeInfo types[] = {
+{
+.name  = TYPE_SMBUS_EEPROM,
+.parent= TYPE_SMBUS_DEVICE,
+.instance_size = sizeof(SMBusEEPROMDevice),
+.class_init= smbus_eeprom_class_initfn,
+},
 };
 
-static void smbus_eeprom_register_types(void)
-{
-type_register_static(&smbus_eeprom_info);
-}
-
-type_init(smbus_eeprom_register_types)
+DEFINE_TYPES(types)
 
 void smbus_eeprom_init_one(I2CBus *smbus, uint8_t address, uint8_t *eeprom_buf)
 {
-- 
2.46.1




[PATCH 00/23] E500 Cleanup

2024-09-23 Thread Bernhard Beschow
This series is part of a bigger series exploring data-driven machine creation
using device tree blobs on top of the e500 machines [1]. It contains patches to
make this exploration easier which are also expected to provide value in
themselves.

The cleanup starts with the e500 machine class itself, then proceeds with
machine-specific device models and concludes with more or less loosely related
devices. Device cleanup mostly consists of using the DEFINE_TYPES() macro.

[1] https://github.com/shentok/qemu/tree/e500-fdt

Bernhard Beschow (23):
  hw/ppc/e500: Do not leak struct boot_info
  hw/ppc/e500: Reduce scope of env pointer
  hw/ppc/e500: Prefer QOM cast
  hw/ppc/e500: Remove unused "irqs" parameter
  hw/ppc/e500: Add missing device tree properties to i2c controller node
  hw/ppc/e500: Use SysBusDevice API to access TYPE_CCSR's internal
resources
  hw/ppc/e500: Extract ppce500_ccsr.c
  hw/ppc/ppce500_ccsr: Log access to unimplemented registers
  hw/ppc/mpc8544_guts: Populate POR PLL ratio status register
  hw/i2c/mpc_i2c: Convert DPRINTF to trace events for register access
  hw/i2c/mpc_i2c: Prefer DEFINE_TYPES() macro
  hw/pci-host/ppce500: Reuse TYPE_PPC_E500_PCI_BRIDGE define
  hw/pci-host/ppce500: Prefer DEFINE_TYPES() macro
  hw/gpio/mpc8xxx: Prefer DEFINE_TYPES() macro
  hw/ppc/mpc8544_guts: Prefer DEFINE_TYPES() macro
  hw/net/fsl_etsec/etsec: Prefer DEFINE_TYPES() macro
  hw/intc: Guard openpic_kvm.c by dedicated OPENPIC_KVM Kconfig switch
  hw/sd/sdhci: Prefer DEFINE_TYPES() macro
  hw/block/pflash_cfi01: Prefer DEFINE_TYPES() macro
  hw/i2c/smbus_eeprom: Prefer DEFINE_TYPES() macro
  hw/rtc/ds1338: Prefer DEFINE_TYPES() macro
  hw/usb/hcd-ehci-sysbus: Prefer DEFINE_TYPES() macro
  hw/vfio/platform: Let vfio_start_eventfd_injection() take
VFIOPlatformDevice pointer

 MAINTAINERS  |   2 +-
 hw/ppc/e500-ccsr.h   |   2 +
 hw/ppc/e500.h|   8 +++
 hw/block/pflash_cfi01.c  |  21 +++
 hw/gpio/mpc8xxx.c|  22 +++-
 hw/i2c/mpc_i2c.c |  29 +-
 hw/i2c/smbus_eeprom.c|  19 +++
 hw/net/fsl_etsec/etsec.c |  22 +++-
 hw/pci-host/ppce500.c|  54 --
 hw/ppc/e500.c|  61 +---
 hw/ppc/mpc8544_guts.c|  32 +++
 hw/ppc/ppce500_ccsr.c|  67 ++
 hw/rtc/ds1338.c  |  20 +++
 hw/sd/sdhci.c|  62 +---
 hw/usb/hcd-ehci-sysbus.c | 118 +--
 hw/vfio/platform.c   |   7 +--
 hw/i2c/trace-events  |   5 ++
 hw/intc/Kconfig  |   4 ++
 hw/intc/meson.build  |   3 +-
 hw/ppc/meson.build   |   1 +
 hw/ppc/trace-events  |   3 +
 21 files changed, 285 insertions(+), 277 deletions(-)
 create mode 100644 hw/ppc/ppce500_ccsr.c

-- 
2.46.1




[PATCH 23/23] hw/vfio/platform: Let vfio_start_eventfd_injection() take VFIOPlatformDevice pointer

2024-09-23 Thread Bernhard Beschow
Avoids one downcast, making the code more type-safe.

Signed-off-by: Bernhard Beschow 
---
 hw/vfio/platform.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/hw/vfio/platform.c b/hw/vfio/platform.c
index a85c199c76..77bbfbf62c 100644
--- a/hw/vfio/platform.c
+++ b/hw/vfio/platform.c
@@ -318,13 +318,12 @@ static void vfio_platform_eoi(VFIODevice *vbasedev)
 /**
  * vfio_start_eventfd_injection - starts the virtual IRQ injection using
  * user-side handled eventfds
- * @sbdev: the sysbus device handle
+ * @vdev: the VFIO platform device handle
  * @irq: the qemu irq handle
  */
 
-static void vfio_start_eventfd_injection(SysBusDevice *sbdev, qemu_irq irq)
+static void vfio_start_eventfd_injection(VFIOPlatformDevice *vdev, qemu_irq 
irq)
 {
-VFIOPlatformDevice *vdev = VFIO_PLATFORM_DEVICE(sbdev);
 VFIOINTp *intp;
 
 QLIST_FOREACH(intp, &vdev->intp_list, next) {
@@ -417,7 +416,7 @@ fail_vfio:
 kvm_irqchip_remove_irqfd_notifier(kvm_state, intp->interrupt, irq);
 abort();
 fail_irqfd:
-vfio_start_eventfd_injection(sbdev, irq);
+vfio_start_eventfd_injection(vdev, irq);
 return;
 }
 
-- 
2.46.1




[PATCH 13/23] hw/pci-host/ppce500: Prefer DEFINE_TYPES() macro

2024-09-23 Thread Bernhard Beschow
Signed-off-by: Bernhard Beschow 
---
 hw/pci-host/ppce500.c | 42 ++
 1 file changed, 18 insertions(+), 24 deletions(-)

diff --git a/hw/pci-host/ppce500.c b/hw/pci-host/ppce500.c
index d7ff2ba778..1ce79ea20c 100644
--- a/hw/pci-host/ppce500.c
+++ b/hw/pci-host/ppce500.c
@@ -21,7 +21,6 @@
 #include "hw/pci/pci_device.h"
 #include "hw/pci/pci_host.h"
 #include "qemu/bswap.h"
-#include "qemu/module.h"
 #include "hw/pci-host/ppce500.h"
 #include "qom/object.h"
 
@@ -508,17 +507,6 @@ static void e500_host_bridge_class_init(ObjectClass 
*klass, void *data)
 dc->user_creatable = false;
 }
 
-static const TypeInfo e500_host_bridge_info = {
-.name  = TYPE_PPC_E500_PCI_BRIDGE,
-.parent= TYPE_PCI_DEVICE,
-.instance_size = sizeof(PPCE500PCIBridgeState),
-.class_init= e500_host_bridge_class_init,
-.interfaces = (InterfaceInfo[]) {
-{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
-{ },
-},
-};
-
 static Property pcihost_properties[] = {
 DEFINE_PROP_UINT32("first_slot", PPCE500PCIState, first_slot, 0x11),
 DEFINE_PROP_UINT32("first_pin_irq", PPCE500PCIState, first_pin_irq, 0x1),
@@ -535,17 +523,23 @@ static void e500_pcihost_class_init(ObjectClass *klass, 
void *data)
 dc->vmsd = &vmstate_ppce500_pci;
 }
 
-static const TypeInfo e500_pcihost_info = {
-.name  = TYPE_PPC_E500_PCI_HOST_BRIDGE,
-.parent= TYPE_PCI_HOST_BRIDGE,
-.instance_size = sizeof(PPCE500PCIState),
-.class_init= e500_pcihost_class_init,
+static const TypeInfo types[] = {
+{
+.name  = TYPE_PPC_E500_PCI_BRIDGE,
+.parent= TYPE_PCI_DEVICE,
+.instance_size = sizeof(PPCE500PCIBridgeState),
+.class_init= e500_host_bridge_class_init,
+.interfaces= (InterfaceInfo[]) {
+{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
+{ },
+},
+},
+{
+.name  = TYPE_PPC_E500_PCI_HOST_BRIDGE,
+.parent= TYPE_PCI_HOST_BRIDGE,
+.instance_size = sizeof(PPCE500PCIState),
+.class_init= e500_pcihost_class_init,
+},
 };
 
-static void e500_pci_register_types(void)
-{
-type_register_static(&e500_pcihost_info);
-type_register_static(&e500_host_bridge_info);
-}
-
-type_init(e500_pci_register_types)
+DEFINE_TYPES(types)
-- 
2.46.1




[PATCH 19/23] hw/block/pflash_cfi01: Prefer DEFINE_TYPES() macro

2024-09-23 Thread Bernhard Beschow
Signed-off-by: Bernhard Beschow 
---
 hw/block/pflash_cfi01.c | 21 -
 1 file changed, 8 insertions(+), 13 deletions(-)

diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
index 7b6ec64442..cf11dada29 100644
--- a/hw/block/pflash_cfi01.c
+++ b/hw/block/pflash_cfi01.c
@@ -47,7 +47,6 @@
 #include "qemu/bitops.h"
 #include "qemu/host-utils.h"
 #include "qemu/log.h"
-#include "qemu/module.h"
 #include "qemu/option.h"
 #include "hw/sysbus.h"
 #include "migration/vmstate.h"
@@ -947,20 +946,16 @@ static void pflash_cfi01_class_init(ObjectClass *klass, 
void *data)
 set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
 }
 
-
-static const TypeInfo pflash_cfi01_info = {
-.name   = TYPE_PFLASH_CFI01,
-.parent = TYPE_SYS_BUS_DEVICE,
-.instance_size  = sizeof(PFlashCFI01),
-.class_init = pflash_cfi01_class_init,
+static const TypeInfo types[] = {
+{
+.name   = TYPE_PFLASH_CFI01,
+.parent = TYPE_SYS_BUS_DEVICE,
+.instance_size  = sizeof(PFlashCFI01),
+.class_init = pflash_cfi01_class_init,
+},
 };
 
-static void pflash_cfi01_register_types(void)
-{
-type_register_static(&pflash_cfi01_info);
-}
-
-type_init(pflash_cfi01_register_types)
+DEFINE_TYPES(types)
 
 PFlashCFI01 *pflash_cfi01_register(hwaddr base,
const char *name,
-- 
2.46.1




[PATCH 05/23] hw/ppc/e500: Add missing device tree properties to i2c controller node

2024-09-23 Thread Bernhard Beschow
When compiling a decompiled device tree blob created with dumpdtb, dtc complains
with:

  /soc@e000/i2c@3000: incorrect #address-cells for I2C bus
  /soc@e000/i2c@3000: incorrect #size-cells for I2C bus

Fix this by adding the missing device tree properties.

Signed-off-by: Bernhard Beschow 
---
 hw/ppc/e500.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index 228287b457..e2a4f265a5 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -196,6 +196,8 @@ static void dt_i2c_create(void *fdt, const char *soc, const 
char *mpic,
 qemu_fdt_setprop_cells(fdt, i2c, "cell-index", 0);
 qemu_fdt_setprop_cells(fdt, i2c, "interrupts", irq0, 0x2);
 qemu_fdt_setprop_phandle(fdt, i2c, "interrupt-parent", mpic);
+qemu_fdt_setprop_cell(fdt, i2c, "#size-cells", 0);
+qemu_fdt_setprop_cell(fdt, i2c, "#address-cells", 1);
 qemu_fdt_setprop_string(fdt, "/aliases", alias, i2c);
 
 g_free(i2c);
-- 
2.46.1




[PATCH 14/23] hw/gpio/mpc8xxx: Prefer DEFINE_TYPES() macro

2024-09-23 Thread Bernhard Beschow
Signed-off-by: Bernhard Beschow 
---
 hw/gpio/mpc8xxx.c | 22 +-
 1 file changed, 9 insertions(+), 13 deletions(-)

diff --git a/hw/gpio/mpc8xxx.c b/hw/gpio/mpc8xxx.c
index 63b7a5c881..de183c3be5 100644
--- a/hw/gpio/mpc8xxx.c
+++ b/hw/gpio/mpc8xxx.c
@@ -23,7 +23,6 @@
 #include "hw/irq.h"
 #include "hw/sysbus.h"
 #include "migration/vmstate.h"
-#include "qemu/module.h"
 #include "qom/object.h"
 
 #define TYPE_MPC8XXX_GPIO "mpc8xxx_gpio"
@@ -208,17 +207,14 @@ static void mpc8xxx_gpio_class_init(ObjectClass *klass, 
void *data)
 device_class_set_legacy_reset(dc, mpc8xxx_gpio_reset);
 }
 
-static const TypeInfo mpc8xxx_gpio_info = {
-.name  = TYPE_MPC8XXX_GPIO,
-.parent= TYPE_SYS_BUS_DEVICE,
-.instance_size = sizeof(MPC8XXXGPIOState),
-.instance_init = mpc8xxx_gpio_initfn,
-.class_init= mpc8xxx_gpio_class_init,
+static const TypeInfo types[] = {
+{
+.name  = TYPE_MPC8XXX_GPIO,
+.parent= TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(MPC8XXXGPIOState),
+.instance_init = mpc8xxx_gpio_initfn,
+.class_init= mpc8xxx_gpio_class_init,
+},
 };
 
-static void mpc8xxx_gpio_register_types(void)
-{
-type_register_static(&mpc8xxx_gpio_info);
-}
-
-type_init(mpc8xxx_gpio_register_types)
+DEFINE_TYPES(types)
-- 
2.46.1




[PATCH 15/23] hw/ppc/mpc8544_guts: Prefer DEFINE_TYPES() macro

2024-09-23 Thread Bernhard Beschow
Signed-off-by: Bernhard Beschow 
---
 hw/ppc/mpc8544_guts.c | 20 
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/hw/ppc/mpc8544_guts.c b/hw/ppc/mpc8544_guts.c
index 6688fd44c3..cbb1e3adda 100644
--- a/hw/ppc/mpc8544_guts.c
+++ b/hw/ppc/mpc8544_guts.c
@@ -18,7 +18,6 @@
  */
 
 #include "qemu/osdep.h"
-#include "qemu/module.h"
 #include "qemu/log.h"
 #include "sysemu/runstate.h"
 #include "cpu.h"
@@ -141,16 +140,13 @@ static void mpc8544_guts_initfn(Object *obj)
 sysbus_init_mmio(d, &s->iomem);
 }
 
-static const TypeInfo mpc8544_guts_info = {
-.name  = TYPE_MPC8544_GUTS,
-.parent= TYPE_SYS_BUS_DEVICE,
-.instance_size = sizeof(GutsState),
-.instance_init = mpc8544_guts_initfn,
+static const TypeInfo types[] = {
+{
+.name  = TYPE_MPC8544_GUTS,
+.parent= TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(GutsState),
+.instance_init = mpc8544_guts_initfn,
+},
 };
 
-static void mpc8544_guts_register_types(void)
-{
-type_register_static(&mpc8544_guts_info);
-}
-
-type_init(mpc8544_guts_register_types)
+DEFINE_TYPES(types)
-- 
2.46.1




[PATCH 07/23] hw/ppc/e500: Extract ppce500_ccsr.c

2024-09-23 Thread Bernhard Beschow
The device model already has a header file. Also extract its implementation into
an accompanying source file like other e500 devices.

This commit is also a preparation for the next commit.

Signed-off-by: Bernhard Beschow 
---
 MAINTAINERS   |  2 +-
 hw/ppc/e500-ccsr.h|  2 ++
 hw/ppc/e500.c | 17 -
 hw/ppc/ppce500_ccsr.c | 38 ++
 hw/ppc/meson.build|  1 +
 5 files changed, 42 insertions(+), 18 deletions(-)
 create mode 100644 hw/ppc/ppce500_ccsr.c

diff --git a/MAINTAINERS b/MAINTAINERS
index ffacd60f40..b7c8b7ae72 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1433,7 +1433,7 @@ e500
 L: qemu-...@nongnu.org
 S: Orphan
 F: hw/ppc/e500*
-F: hw/ppc/ppce500_spin.c
+F: hw/ppc/ppce500_*.c
 F: hw/gpio/mpc8xxx.c
 F: hw/i2c/mpc_i2c.c
 F: hw/net/fsl_etsec/
diff --git a/hw/ppc/e500-ccsr.h b/hw/ppc/e500-ccsr.h
index 249c17be3b..3ab7e72568 100644
--- a/hw/ppc/e500-ccsr.h
+++ b/hw/ppc/e500-ccsr.h
@@ -4,6 +4,8 @@
 #include "hw/sysbus.h"
 #include "qom/object.h"
 
+#define MPC8544_CCSRBAR_SIZE   0x0010ULL
+
 struct PPCE500CCSRState {
 /*< private >*/
 SysBusDevice parent;
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index 2225533e33..4ee4304a8a 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -61,7 +61,6 @@
 #define RAM_SIZES_ALIGN(64 * MiB)
 
 /* TODO: parameterize */
-#define MPC8544_CCSRBAR_SIZE   0x0010ULL
 #define MPC8544_MPIC_REGS_OFFSET   0x4ULL
 #define MPC8544_MSI_REGS_OFFSET   0x41600ULL
 #define MPC8544_SERIAL0_REGS_OFFSET 0x4500ULL
@@ -1264,21 +1263,6 @@ void ppce500_init(MachineState *machine)
 pms->boot_info.dt_size = dt_size;
 }
 
-static void e500_ccsr_initfn(Object *obj)
-{
-PPCE500CCSRState *ccsr = CCSR(obj);
-memory_region_init(&ccsr->ccsr_space, obj, "e500-ccsr",
-   MPC8544_CCSRBAR_SIZE);
-sysbus_init_mmio(SYS_BUS_DEVICE(ccsr), &ccsr->ccsr_space);
-}
-
-static const TypeInfo e500_ccsr_info = {
-.name  = TYPE_CCSR,
-.parent= TYPE_SYS_BUS_DEVICE,
-.instance_size = sizeof(PPCE500CCSRState),
-.instance_init = e500_ccsr_initfn,
-};
-
 static const TypeInfo ppce500_info = {
 .name  = TYPE_PPCE500_MACHINE,
 .parent= TYPE_MACHINE,
@@ -1289,7 +1273,6 @@ static const TypeInfo ppce500_info = {
 
 static void e500_register_types(void)
 {
-type_register_static(&e500_ccsr_info);
 type_register_static(&ppce500_info);
 }
 
diff --git a/hw/ppc/ppce500_ccsr.c b/hw/ppc/ppce500_ccsr.c
new file mode 100644
index 00..191a9ceec3
--- /dev/null
+++ b/hw/ppc/ppce500_ccsr.c
@@ -0,0 +1,38 @@
+/*
+ * QEMU PowerPC E500 embedded processors CCSR space emulation
+ *
+ * Copyright (C) 2009 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Author: Yu Liu, 
+ *
+ * This file is derived from hw/ppc440_bamboo.c,
+ * the copyright for that material belongs to the original owners.
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of  the GNU General  Public License as published by
+ * the Free Software Foundation;  either version 2 of the  License, or
+ * (at your option) any later version.
+ */
+
+#include "qemu/osdep.h"
+#include "e500-ccsr.h"
+
+static void e500_ccsr_init(Object *obj)
+{
+PPCE500CCSRState *ccsr = CCSR(obj);
+
+memory_region_init(&ccsr->ccsr_space, obj, "e500-ccsr",
+   MPC8544_CCSRBAR_SIZE);
+sysbus_init_mmio(SYS_BUS_DEVICE(ccsr), &ccsr->ccsr_space);
+}
+
+static const TypeInfo types[] = {
+{
+.name  = TYPE_CCSR,
+.parent= TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(PPCE500CCSRState),
+.instance_init = e500_ccsr_init,
+},
+};
+
+DEFINE_TYPES(types)
diff --git a/hw/ppc/meson.build b/hw/ppc/meson.build
index 7cd9189869..43c746795a 100644
--- a/hw/ppc/meson.build
+++ b/hw/ppc/meson.build
@@ -81,6 +81,7 @@ ppc_ss.add(when: 'CONFIG_MPC8544DS', if_true: 
files('mpc8544ds.c'))
 ppc_ss.add(when: 'CONFIG_E500', if_true: files(
   'e500.c',
   'mpc8544_guts.c',
+  'ppce500_ccsr.c',
   'ppce500_spin.c'
 ))
 # PowerPC 440 Xilinx ML507 reference board.
-- 
2.46.1




[PATCH 02/23] hw/ppc/e500: Reduce scope of env pointer

2024-09-23 Thread Bernhard Beschow
The env pointer isn't used outside the for loop, so move it inside. After that,
the firstenv pointer is never read, so remove it.

Signed-off-by: Bernhard Beschow 
---
 hw/ppc/e500.c | 9 +
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index 75b051009f..f68779a1ea 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -899,7 +899,6 @@ void ppce500_init(MachineState *machine)
 const PPCE500MachineClass *pmc = PPCE500_MACHINE_GET_CLASS(machine);
 MachineClass *mc = MACHINE_CLASS(pmc);
 PCIBus *pci_bus;
-CPUPPCState *env = NULL;
 uint64_t loadaddr;
 hwaddr kernel_base = -1LL;
 int kernel_size = 0;
@@ -921,7 +920,6 @@ void ppce500_init(MachineState *machine)
 IrqLines *irqs;
 DeviceState *dev, *mpicdev;
 DriveInfo *dinfo;
-CPUPPCState *firstenv = NULL;
 MemoryRegion *ccsr_addr_space;
 SysBusDevice *s;
 PPCE500CCSRState *ccsr;
@@ -930,6 +928,7 @@ void ppce500_init(MachineState *machine)
 irqs = g_new0(IrqLines, smp_cpus);
 for (i = 0; i < smp_cpus; i++) {
 PowerPCCPU *cpu;
+CPUPPCState *env;
 CPUState *cs;
 
 cpu = POWERPC_CPU(object_new(machine->cpu_type));
@@ -950,10 +949,6 @@ void ppce500_init(MachineState *machine)
  &error_abort);
 qdev_realize_and_unref(DEVICE(cs), NULL, &error_fatal);
 
-if (!firstenv) {
-firstenv = env;
-}
-
 irqs[i].irq[OPENPIC_OUTPUT_INT] =
 qdev_get_gpio_in(DEVICE(cpu), PPCE500_INPUT_INT);
 irqs[i].irq[OPENPIC_OUTPUT_CINT] =
@@ -974,8 +969,6 @@ void ppce500_init(MachineState *machine)
 }
 }
 
-env = firstenv;
-
 if (!QEMU_IS_ALIGNED(machine->ram_size, RAM_SIZES_ALIGN)) {
 error_report("RAM size must be multiple of %" PRIu64, RAM_SIZES_ALIGN);
 exit(EXIT_FAILURE);
-- 
2.46.1




Re: [PATCH v5 05/11] exec/ioport: Add portio_list_set_address()

2024-07-29 Thread Bernhard Beschow



Am 29. Juli 2024 09:26:19 UTC schrieb "Philippe Mathieu-Daudé" 
:
>On 14/1/24 13:39, Bernhard Beschow wrote:
>> Some SuperI/O devices such as the VIA south bridges or the PC87312 controller
>> are able to relocate their SuperI/O functions. Add a convenience function for
>> implementing this in the VIA south bridges.
>> 
>> This convenience function relies on previous simplifications in exec/ioport
>> which avoids some duplicate synchronization of I/O port base addresses. The
>> naming of the function is inspired by its memory_region_set_address() 
>> pendant.
>> 
>> Signed-off-by: Bernhard Beschow 
>> ---
>>   docs/devel/migration.rst |  5 +++--
>>   include/exec/ioport.h|  2 ++
>>   system/ioport.c  | 19 +++
>>   3 files changed, 24 insertions(+), 2 deletions(-)
>
>
>> +void portio_list_set_address(PortioList *piolist, uint32_t addr)
>> +{
>> +MemoryRegionPortioList *mrpio;
>> +unsigned i, j;
>> +
>
>   memory_region_transaction_begin();
>
>> +for (i = 0; i < piolist->nr; ++i) {
>> +mrpio = container_of(piolist->regions[i], MemoryRegionPortioList, 
>> mr);
>
>Should we check mrpio->mr is disabled before changing its base address?

Isn't that the responsibility of the guest? What should we do if the check 
fails?

>
>> +memory_region_set_address(&mrpio->mr,
>> +  mrpio->mr.addr - piolist->addr + addr);
>> +for (j = 0; mrpio->ports[j].size; ++j) {
>> +mrpio->ports[j].offset += addr - piolist->addr;
>> +}
>
>  memory_region_transaction_commit();
>
>> +}
>> +
>> +piolist->addr = addr;
>> +}
>> +
>>   static void memory_region_portio_list_finalize(Object *obj)
>>   {
>>   MemoryRegionPortioList *mrpio = MEMORY_REGION_PORTIO_LIST(obj);
>



Re: [PATCH v2 11/15] hw/southbridge/ich9: Add a AHCI function

2024-04-15 Thread Bernhard Beschow



Am 26. Februar 2024 11:14:10 UTC schrieb "Philippe Mathieu-Daudé" 
:
>Instantiate TYPE_ICH9_AHCI in TYPE_ICH9_SOUTHBRIDGE.
>
>Since the PC machines can disable SATA (see the
>PC_MACHINE_SATA dynamic property), add the 'sata-enabled'
>property to disable it.
>
>Signed-off-by: Philippe Mathieu-Daudé 
>---
> MAINTAINERS   |  2 ++
> include/hw/southbridge/ich9.h |  4 
> hw/i386/pc_q35.c  | 21 +++--
> hw/southbridge/ich9.c | 35 +++
> hw/i386/Kconfig   |  1 -
> hw/southbridge/Kconfig|  1 +
> 6 files changed, 41 insertions(+), 23 deletions(-)
>
>diff --git a/MAINTAINERS b/MAINTAINERS
>index 4576339053..7d1b3e0d99 100644
>--- a/MAINTAINERS
>+++ b/MAINTAINERS
>@@ -2615,10 +2615,12 @@ M: Marcel Apfelbaum 
> S: Supported
> F: hw/acpi/ich9*.c
> F: hw/i2c/smbus_ich9.c
>+F: hw/ide/ich9_ahci.c
> F: hw/isa/lpc_ich9.c
> F: hw/southbridge/ich9.c
> F: include/hw/acpi/ich9*.h
> F: include/hw/i2c/ich9_smbus.h
>+F: include/hw/ide/ahci-pci.h
> F: include/hw/pci-bridge/ich9_dmi.h
> F: include/hw/southbridge/ich9.h
> 
>diff --git a/include/hw/southbridge/ich9.h b/include/hw/southbridge/ich9.h
>index b9122d299d..ac7f9f4ff5 100644
>--- a/include/hw/southbridge/ich9.h
>+++ b/include/hw/southbridge/ich9.h
>@@ -166,10 +166,6 @@ struct ICH9LPCState {
> 
> #define ICH9_GPIO_GSI "gsi"
> 
>-/* D31:F2 SATA Controller #1 */
>-#define ICH9_SATA1_DEV  31
>-#define ICH9_SATA1_FUNC 2
>-
> /* D31:F0 power management I/O registers
>offset from the address ICH9_LPC_PMBASE */
> 
>diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
>index f951cf1e3a..6903719b97 100644
>--- a/hw/i386/pc_q35.c
>+++ b/hw/i386/pc_q35.c
>@@ -60,9 +60,6 @@
> #include "hw/i386/acpi-build.h"
> #include "target/i386/cpu.h"
> 
>-/* ICH9 AHCI has 6 ports */
>-#define MAX_SATA_PORTS 6
>-
> struct ehci_companions {
> const char *name;
> int func;
>@@ -134,7 +131,6 @@ static void pc_q35_init(MachineState *machine)
> ISABus *isa_bus;
> int i;
> ram_addr_t lowmem;
>-DriveInfo *hd[MAX_SATA_PORTS];
> MachineClass *mc = MACHINE_GET_CLASS(machine);
> bool acpi_pcihp;
> bool keep_pci_slot_hpc;
>@@ -227,6 +223,7 @@ static void pc_q35_init(MachineState *machine)
> object_property_set_link(OBJECT(ich9), "mch-pcie-bus",
>  OBJECT(pcms->pcibus), &error_abort);
> qdev_prop_set_bit(ich9, "d2p-enabled", false);
>+qdev_prop_set_bit(ich9, "sata-enabled", pcms->sata_enabled);
> qdev_realize_and_unref(ich9, NULL, &error_fatal);
> 
> /* create ISA bus */
>@@ -287,20 +284,8 @@ static void pc_q35_init(MachineState *machine)
>  0xff0104);
> 
> if (pcms->sata_enabled) {
>-PCIDevice *pdev;
>-AHCIPCIState *ich9;

The ahci include and perhaps all ide includes can be removed here.

Any plans for a v3?

Best regards,
Bernhard

>-
>-/* ahci and SATA device, for q35 1 ahci controller is built-in */
>-pdev = pci_create_simple_multifunction(pcms->pcibus,
>-   PCI_DEVFN(ICH9_SATA1_DEV,
>- ICH9_SATA1_FUNC),
>-   "ich9-ahci");
>-ich9 = ICH9_AHCI(pdev);
>-pcms->idebus[0] = qdev_get_child_bus(DEVICE(pdev), "ide.0");
>-pcms->idebus[1] = qdev_get_child_bus(DEVICE(pdev), "ide.1");
>-g_assert(MAX_SATA_PORTS == ich9->ahci.ports);
>-ide_drive_get(hd, ich9->ahci.ports);
>-ahci_ide_create_devs(&ich9->ahci, hd);
>+pcms->idebus[0] = qdev_get_child_bus(ich9, "ide.0");
>+pcms->idebus[1] = qdev_get_child_bus(ich9, "ide.1");
> }
> 
> if (machine_usb(machine)) {
>diff --git a/hw/southbridge/ich9.c b/hw/southbridge/ich9.c
>index 8c4356ff74..37255bb941 100644
>--- a/hw/southbridge/ich9.c
>+++ b/hw/southbridge/ich9.c
>@@ -13,22 +13,30 @@
> #include "hw/southbridge/ich9.h"
> #include "hw/pci/pci.h"
> #include "hw/pci-bridge/ich9_dmi.h"
>+#include "hw/ide/ahci-pci.h"
>+#include "hw/ide/ide-dev.h"
> 
> #define ICH9_D2P_DEVFN  PCI_DEVFN(30, 0)
>+#define ICH9_SATA1_DEVFNPCI_DEVFN(31, 2)
>+
>+#define SATA_PORTS  6
> 
> struct ICH9State {
> DeviceState parent_obj;
> 
> I82801b11Bridge d2p;
>+AHCIPCIState sata0;
> 
> PCIBus *pci_bus;
> bool d2p_enabled;
>+bool sata_enabled;
> };
> 
> static Property ich9_props[] = {
> DEFINE_PROP_LINK("mch-pcie-bus", ICH9State, pci_bus,
>  TYPE_PCIE_BUS, PCIBus *),
> DEFINE_PROP_BOOL("d2p-enabled", ICH9State, d2p_enabled, true),
>+DEFINE_PROP_BOOL("sata-enabled", ICH9State, sata_enabled, true),
> DEFINE_PROP_END_OF_LIST(),
> };
> 
>@@ -52,6 +60,29 @@ static bool ich9_realize_d2p(ICH9State *s, Error **errp)
> return true;
> }
> 
>+static bool ich9_realize_sata(ICH9State *s, Error **errp)
>+{
>+DriveInfo

Re: [PATCH v2 10/15] hw/southbridge/ich9: Add the DMI-to-PCI bridge

2024-02-26 Thread Bernhard Beschow



Am 26. Februar 2024 11:14:09 UTC schrieb "Philippe Mathieu-Daudé" 
:
>Instantiate TYPE_ICH_DMI_PCI_BRIDGE in TYPE_ICH9_SOUTHBRIDGE.
>
>Since the Q35 machine doesn't use it, add the 'd2p-enabled'
>property to disable it.
>
>Signed-off-by: Philippe Mathieu-Daudé 
>---
> include/hw/southbridge/ich9.h |  9 -
> hw/i386/pc_q35.c  |  1 +
> hw/southbridge/ich9.c | 27 +++
> hw/southbridge/Kconfig|  1 +
> 4 files changed, 29 insertions(+), 9 deletions(-)
>
>diff --git a/include/hw/southbridge/ich9.h b/include/hw/southbridge/ich9.h
>index 162ae3baa1..b9122d299d 100644
>--- a/include/hw/southbridge/ich9.h
>+++ b/include/hw/southbridge/ich9.h
>@@ -108,15 +108,6 @@ struct ICH9LPCState {
> #define ICH9_USB_UHCI1_DEV  29
> #define ICH9_USB_UHCI1_FUNC 0
> 
>-/* D30:F0 DMI-to-PCI bridge */
>-#define ICH9_D2P_BRIDGE "ICH9 D2P BRIDGE"
>-#define ICH9_D2P_BRIDGE_SAVEVM_VERSION  0
>-
>-#define ICH9_D2P_BRIDGE_DEV 30
>-#define ICH9_D2P_BRIDGE_FUNC0
>-
>-#define ICH9_D2P_SECONDARY_DEFAULT  (256 - 8)
>-
> /* D31:F0 LPC Processor Interface */
> #define ICH9_RST_CNT_IOPORT 0xCF9
> 
>diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
>index 8c8a2f65b8..f951cf1e3a 100644
>--- a/hw/i386/pc_q35.c
>+++ b/hw/i386/pc_q35.c
>@@ -226,6 +226,7 @@ static void pc_q35_init(MachineState *machine)
> object_property_add_child(OBJECT(machine), "ich9", OBJECT(ich9));
> object_property_set_link(OBJECT(ich9), "mch-pcie-bus",
>  OBJECT(pcms->pcibus), &error_abort);
>+qdev_prop_set_bit(ich9, "d2p-enabled", false);
> qdev_realize_and_unref(ich9, NULL, &error_fatal);
> 
> /* create ISA bus */
>diff --git a/hw/southbridge/ich9.c b/hw/southbridge/ich9.c
>index f3a9b932ab..8c4356ff74 100644
>--- a/hw/southbridge/ich9.c
>+++ b/hw/southbridge/ich9.c
>@@ -12,16 +12,23 @@
> #include "hw/qdev-properties.h"
> #include "hw/southbridge/ich9.h"
> #include "hw/pci/pci.h"
>+#include "hw/pci-bridge/ich9_dmi.h"
>+
>+#define ICH9_D2P_DEVFN  PCI_DEVFN(30, 0)

Something along the lines of ICH9_DMI_PCI_DEVFN seems more clear to me.

> 
> struct ICH9State {
> DeviceState parent_obj;
> 
>+I82801b11Bridge d2p;

Same here and essentially all identifiers and properties with "d2p" in their 
name.

Best regards,
Bernhard

>+
> PCIBus *pci_bus;
>+bool d2p_enabled;
> };
> 
> static Property ich9_props[] = {
> DEFINE_PROP_LINK("mch-pcie-bus", ICH9State, pci_bus,
>  TYPE_PCIE_BUS, PCIBus *),
>+DEFINE_PROP_BOOL("d2p-enabled", ICH9State, d2p_enabled, true),
> DEFINE_PROP_END_OF_LIST(),
> };
> 
>@@ -29,6 +36,22 @@ static void ich9_init(Object *obj)
> {
> }
> 
>+static bool ich9_realize_d2p(ICH9State *s, Error **errp)
>+{
>+if (!module_object_class_by_name(TYPE_ICH_DMI_PCI_BRIDGE)) {
>+error_setg(errp, "DMI-to-PCI function not available in this build");
>+return false;
>+}
>+object_initialize_child(OBJECT(s), "d2p", &s->d2p, 
>TYPE_ICH_DMI_PCI_BRIDGE);
>+qdev_prop_set_int32(DEVICE(&s->d2p), "addr", ICH9_D2P_DEVFN);
>+if (!qdev_realize(DEVICE(&s->d2p), BUS(s->pci_bus), errp)) {
>+return false;
>+}
>+object_property_add_alias(OBJECT(s), "pci.0", OBJECT(&s->d2p), "pci.0");
>+
>+return true;
>+}
>+
> static void ich9_realize(DeviceState *dev, Error **errp)
> {
> ICH9State *s = ICH9_SOUTHBRIDGE(dev);
>@@ -37,6 +60,10 @@ static void ich9_realize(DeviceState *dev, Error **errp)
> error_setg(errp, "'pcie-bus' property must be set");
> return;
> }
>+
>+if (s->d2p_enabled && !ich9_realize_d2p(s, errp)) {
>+return;
>+}
> }
> 
> static void ich9_class_init(ObjectClass *klass, void *data)
>diff --git a/hw/southbridge/Kconfig b/hw/southbridge/Kconfig
>index 852b7f346f..db7259bf6f 100644
>--- a/hw/southbridge/Kconfig
>+++ b/hw/southbridge/Kconfig
>@@ -3,3 +3,4 @@
> config ICH9
> bool
> depends on PCI_EXPRESS
>+imply I82801B11



Re: [PATCH v2 00/15] hw/southbridge: Extract ICH9 QOM container model

2024-02-26 Thread Bernhard Beschow



Am 26. Februar 2024 11:13:59 UTC schrieb "Philippe Mathieu-Daudé" 
:
>Since v1 [1]:
>- Rebased on top of Bernhard patches
>- Rename files with 'ich9_' prefix (Bernhard)
>
>Hi,
>
>I have a long standing southbridge QOM rework branches. Since
>Bernhard is actively working on the PIIX, I'll try to refresh
>and post. This is also motivated by the Dynamic Machine work
>where we are trying to figure the ideal DSL for QEMU, so having
>complex models well designed help.
>
>Here we introduce the ICH9 'southbridge' as a QOM container.
>Since the chipset comes as a whole, we shouldn't instantiate
>its components separately. However in order to maintain old
>code we expose some properties to configure the container and
>not introduce any change for the Q35 machine. There is no
>migration change, only QOM objects moved around.

I really like the simplicity of the machine code and that the ICH9 southbridge 
becomes a proper device rather than being scattered around in machine code. 
I've made some reviews in form of a branch: 
https://github.com/shentok/qemu/commits/philmd/ich9_qom-v2/

>
>More work remain in the LPC function (more code to remove from
>Q35). Maybe worth doing in parallel with the PIIX to clean both
>PC machines.

Would be nice if the pattern could then also be applied to the VIA 
southbridges, otherwise this could break my via-apollo-pro-133t branch: 
https://github.com/shentok/qemu/tree/via-apollo-pro-133t

Best regards,
Bernhard

>
>Also we'd need to decouple the cpu_interrupt() calls between hw/
>and target/.
>
>Note that GSI is currently broken [2]. Once the LPC/ISA part is
>done, it might be easier to fix it.
>
>[1] 
>https://lore.kernel.org/qemu-devel/20240219163855.87326-1-phi...@linaro.org/
>[2] 
>https://lore.kernel.org/qemu-devel/cd0e13c6-c03d-411f-83a5-1d4d28ea4...@linaro.org/
>
>Philippe Mathieu-Daudé (15):
>  MAINTAINERS: Add 'ICH9 South Bridge' section
>  hw/i386/q35: Add local 'lpc_obj' variable
>  hw/acpi/ich9: Restrict definitions from 'hw/southbridge/ich9.h'
>  hw/acpi/ich9_tco: Include 'ich9' in names
>  hw/acpi/ich9_tco: Restrict ich9_generate_smi() declaration
>  hw/ide: Rename ich.c -> ich9_ahci.c
>  hw/i2c/smbus: Extract QOM ICH9 definitions to 'ich9_smbus.h'
>  hw/pci-bridge: Extract QOM ICH definitions to 'ich9_dmi.h'
>  hw/southbridge/ich9: Introduce TYPE_ICH9_SOUTHBRIDGE stub
>  hw/southbridge/ich9: Add the DMI-to-PCI bridge
>  hw/southbridge/ich9: Add a AHCI function
>  hw/southbridge/ich9: Add the SMBus function
>  hw/southbridge/ich9: Add the USB EHCI/UHCI functions
>  hw/southbridge/ich9: Extract LPC definitions to 'hw/isa/ich9_lpc.h'
>  hw/southbridge/ich9: Add the LPC / ISA bridge function
>
> MAINTAINERS   |  21 +-
> include/hw/acpi/ich9.h|  15 ++
> include/hw/acpi/ich9_tco.h|   6 +-
> include/hw/i2c/ich9_smbus.h   |  25 +++
> include/hw/isa/ich9_lpc.h | 166 +++
> include/hw/pci-bridge/ich9_dmi.h  |  20 ++
> include/hw/southbridge/ich9.h | 235 +-
> hw/acpi/ich9.c|   9 +-
> hw/acpi/ich9_tco.c|   5 +-
> hw/i2c/{smbus_ich9.c => ich9_smbus.c} |  36 +++-
> hw/i386/acpi-build.c  |   1 +
> hw/i386/pc_q35.c  | 126 +++-
> hw/ide/{ich.c => ich9_ahci.c} |   0
> hw/isa/{lpc_ich9.c => ich9_lpc.c} |  37 +++-
> hw/pci-bridge/{i82801b11.c => ich9_dmi.c} |  11 +-
> hw/southbridge/ich9.c | 213 
> tests/qtest/tco-test.c|   2 +-
> hw/Kconfig|   1 +
> hw/i2c/meson.build|   2 +-
> hw/i386/Kconfig   |   3 +-
> hw/ide/meson.build|   2 +-
> hw/isa/meson.build|   2 +-
> hw/meson.build|   1 +
> hw/pci-bridge/meson.build |   2 +-
> hw/southbridge/Kconfig|  11 +
> hw/southbridge/meson.build|   3 +
> 26 files changed, 587 insertions(+), 368 deletions(-)
> create mode 100644 include/hw/i2c/ich9_smbus.h
> create mode 100644 include/hw/isa/ich9_lpc.h
> create mode 100644 include/hw/pci-bridge/ich9_dmi.h
> rename hw/i2c/{smbus_ich9.c => ich9_smbus.c} (77%)
> rename hw/ide/{ich.c => ich9_ahci.c} (100%)
> rename hw/isa/{lpc_ich9.c => ich9_lpc.c} (95%)
> rename hw/pci-bridge/{i82801b11.c => ich9_dmi.c} (95%)
> create mode 100644 hw/southbridge/ich9.c
> create mode 100644 hw/southbridge/Kconfig
> create mode 100644 hw/southbridge/meson.build
>



Re: [RFC PATCH 0/7] hw/qdev: Split 'wiring' phase from 'realize'

2024-02-09 Thread Bernhard Beschow
 | |
>| Expose properties   |
>INIT exit   +-+
>   <---
> ++
> | set properties |
> ||
> | set ClkIn  |
> ++  REALIZE enter
>   -->
>   +--+
>   | Use config properties|
>   |  |
>   | Realize children |
>   |  |
>   | Init GPIOs/IRQs  |
>   |  |
>   | Init MemoryRegions   |
>   +--+
>   REALIZE exit   <---
> +--+
> | Internal auto wiring |
> |   IRQs   |  (i.e. ISA bus)
> |   I/O / Mem  |
> |   ClkOut |
> +--+
><---   
>   "realized"
>+-+
>| External wiring:|
>|   IRQs  |
>|   I/O / Mem |
>|   ClkOut|
>+-+ RESET enter
>  "guest visible"
>->
>   +--+
>   | Reset default values |
>   +--+
>
>The "realized" point is not changed. "guest visible" concept only
>occurs *after* wiring, just before the reset phase.
>
>This series introduces the DeviceClass::wire handler within qdev
>core realization code, and convert devices using the implicit
>wiring to using that explicit handler.
>
>QDev API assertions patches will be posted later as another series.
>
>Thoughts?

Hi Phil,

What exactly are you trying to achieve? I assume that the goal is to make 
devices user-creatable which currently can't due to current limitations. For 
this I'm presenting an idea:

I'd probably not force the new discipline onto devices which aren't 
user-creatable -- that seems like too much gymnastics to me for no gain. 
Instead, I'd act on the suggestion of having an interface TYPE_USER_CREATABLE 
and put the wire method there.

This wire method would be responsible for performing *all* duties between the 
states "realized" and "guest-visible". Based on the parameters it is given by 
the user, it would find all resources it needs to wire up the device. It finds 
these resources by e.g. scanning the QOM tree. A good practice would be to pass 
the root node for the scanning as parameter, e.g. the current machine.

It could happen that a user-crrated device depends on another user-created 
device. To make this work, the part of QEMU that deals with user-created 
devices would perform a fixed point iteration over all not yet finished 
user-created devices. When there is no progress within one iteration, QEMU 
aborts with an error message. This error message could come from the `wire` 
invocation of any -- or even better -- all not yet finished devices.

To demonstrate the approach, one could probably pick just one device, add the 
interface and hack up something in the core handling of user-created devices.

Does this idea sound reasonable? Is this what you're ultimately after?

Best regards,
Bernhatd

>
>Regards,
>
>Phil.
>
>[1] https://lore.kernel.org/all/87o7d1i7ky@pond.sub.org/
>[2] 
>https://lore.kernel.org/qemu-devel/20231127052024.435743-1-gustavo.rom...@linaro.org/
>
>Cc: Eduardo Habkost 
>Cc: Markus Armbruster ' --cc '
>Cc: Edgar E. Iglesias '
>Cc: Richard Henderson 
>Cc: Mark Cave-Ayland 
>Cc: Thomas Huth 
>Cc: Paolo Bonzini 
>Cc: Alexander Graf 
>Cc: Bernhard Beschow 
>Cc: Stefan Hajnoczi 
>Cc: Peter Maydell 
>Cc: Cédric Le Goater 
>Cc: Luc Michel 
>Cc: Zhao Liu 
>Cc: Gustavo Romero 
>
>Philippe Mathieu-Daudé (7):
>  hw/qdev: Introduce DeviceClass::[un]wire() handlers
>  hw/input/pckbd: Connect i8042 GPIOs o

Re: [PATCH v5 00/11] hw/isa/vt82c686: Implement relocation and toggling of SuperI/O functions

2024-01-14 Thread Bernhard Beschow



Am 14. Januar 2024 13:03:07 UTC schrieb "Michael S. Tsirkin" :
>On Sun, Jan 14, 2024 at 12:52:53PM +0000, Bernhard Beschow wrote:
>> 
>> 
>> Am 14. Januar 2024 12:39:00 UTC schrieb Bernhard Beschow :
>> >This series implements relocation of the SuperI/O functions of the VIA south
>> >
>> >bridges which resolves some FIXME's. It is part of my via-apollo-pro-133t
>> >
>> >branch [1] which is an extension of bringing the VIA south bridges to the PC
>> >
>> >machine [2]. This branch is able to run some real-world X86 BIOSes in the 
>> >hope
>> >
>> >that it allows us to form a better understanding of the real vt82c686b 
>> >devices.
>> >
>> >Implementing relocation and toggling of the SuperI/O functions is one step 
>> >to
>> >
>> >make these BIOSes run without error messages, so here we go.
>> >
>> >
>> >
>> >The series is structured as follows: Patches 1-3 prepare the TYPE_ISA_FDC,
>> >
>> >TYPE_ISA_PARALLEL and TYPE_ISA_SERIAL to relocate and toggle 
>> >(enable/disable)
>> >
>> >themselves without breaking encapsulation of their respective device states.
>> >
>> >This is achieved by moving the MemoryRegions and PortioLists from the device
>> >
>> >states into the encapsulating ISA devices since they will be relocated and
>> >
>> >toggled.
>> >
>> >
>> >
>> >Inspired by the memory API patches 4-6 add two convenience functions to the
>> >
>> >portio_list API to toggle and relocate portio lists. Patch 5 is a 
>> >preparation
>> >
>> >for that which removes some redundancies which otherwise had to be dealt 
>> >with
>> >
>> >during relocation.
>> >
>> >
>> >
>> >Patches 7-9 implement toggling and relocation for types TYPE_ISA_FDC,
>> >
>> >TYPE_ISA_PARALLEL and TYPE_ISA_SERIAL. Patch 10 prepares the pegasos2 
>> >machine
>> >
>> >which would end up with all SuperI/O functions disabled if no -bios 
>> >argument is
>> >
>> >given. Patch 11 finally implements the main feature which now relies on
>> >
>> >firmware to configure the SuperI/O functions accordingly (except for 
>> >pegasos2).
>> >
>> >
>> >
>> >v5:
>> >
>> >* Use cpu_physical_memory_write() in pegasos2 (Zoltan)
>> >
>> >* Use an int as for loop variable (Zoltan)
>> >
>> >
>> >
>> >v4:
>> >
>> >* Drop incomplete SuperI/O vmstate handling (Zoltan)
>> >
>> >
>> >
>> >v3:
>> >
>> >* Rework various commit messages (Zoltan)
>> >
>> >* Drop patch "hw/char/serial: Free struct SerialState from MemoryRegion"
>> >
>> >  (Zoltan)
>> >
>> >* Generalize wording in migration.rst to include portio_list API (Zoltan)
>> >
>> >
>> >
>> >v2:
>> >
>> >* Improve commit messages (Zoltan)
>> >
>> >* Split pegasos2 from vt82c686 patch (Zoltan)
>> >
>> >* Avoid poking into device internals (Zoltan)
>> >
>> >
>> >
>> >Testing done:
>> >
>> >* `make check`
>> >
>> >* `make check-avocado`
>> >
>> >* Run MorphOS on pegasos2 with and without pegasos2.rom
>> >
>> >* Run Linux on amigaone
>> >
>> >* Run real-world BIOSes on via-apollo-pro-133t branch
>> >
>> >* Start rescue-yl on fuloong2e
>> >
>> >
>> >
>> >[1] https://github.com/shentok/qemu/tree/via-apollo-pro-133t
>> >
>> >[2] https://github.com/shentok/qemu/tree/pc-via
>> >
>> >
>> >
>> >Bernhard Beschow (11):
>> >
>> >  hw/block/fdc-isa: Move portio_list from FDCtrl to FDCtrlISABus
>> >
>> >  hw/block/fdc-sysbus: Move iomem from FDCtrl to FDCtrlSysBus
>> >
>> >  hw/char/parallel: Move portio_list from ParallelState to
>> >
>> >ISAParallelState
>> >
>> 
>> 
>> >  exec/ioport: Resolve redundant .base attribute in struct
>> >
>> >MemoryRegionPortio
>> >
>> >  exec/ioport: Add portio_list_set_address()
>> >
>> >  exec/ioport: Add portio_list_set_enabled()
>> >
>> >  hw/block/fdc-isa: Implement relocation and enabling/disabling for
>> 

Re: [PATCH v5 00/11] hw/isa/vt82c686: Implement relocation and toggling of SuperI/O functions

2024-01-14 Thread Bernhard Beschow



Am 14. Januar 2024 12:39:00 UTC schrieb Bernhard Beschow :
>This series implements relocation of the SuperI/O functions of the VIA south
>
>bridges which resolves some FIXME's. It is part of my via-apollo-pro-133t
>
>branch [1] which is an extension of bringing the VIA south bridges to the PC
>
>machine [2]. This branch is able to run some real-world X86 BIOSes in the hope
>
>that it allows us to form a better understanding of the real vt82c686b devices.
>
>Implementing relocation and toggling of the SuperI/O functions is one step to
>
>make these BIOSes run without error messages, so here we go.
>
>
>
>The series is structured as follows: Patches 1-3 prepare the TYPE_ISA_FDC,
>
>TYPE_ISA_PARALLEL and TYPE_ISA_SERIAL to relocate and toggle (enable/disable)
>
>themselves without breaking encapsulation of their respective device states.
>
>This is achieved by moving the MemoryRegions and PortioLists from the device
>
>states into the encapsulating ISA devices since they will be relocated and
>
>toggled.
>
>
>
>Inspired by the memory API patches 4-6 add two convenience functions to the
>
>portio_list API to toggle and relocate portio lists. Patch 5 is a preparation
>
>for that which removes some redundancies which otherwise had to be dealt with
>
>during relocation.
>
>
>
>Patches 7-9 implement toggling and relocation for types TYPE_ISA_FDC,
>
>TYPE_ISA_PARALLEL and TYPE_ISA_SERIAL. Patch 10 prepares the pegasos2 machine
>
>which would end up with all SuperI/O functions disabled if no -bios argument is
>
>given. Patch 11 finally implements the main feature which now relies on
>
>firmware to configure the SuperI/O functions accordingly (except for pegasos2).
>
>
>
>v5:
>
>* Use cpu_physical_memory_write() in pegasos2 (Zoltan)
>
>* Use an int as for loop variable (Zoltan)
>
>
>
>v4:
>
>* Drop incomplete SuperI/O vmstate handling (Zoltan)
>
>
>
>v3:
>
>* Rework various commit messages (Zoltan)
>
>* Drop patch "hw/char/serial: Free struct SerialState from MemoryRegion"
>
>  (Zoltan)
>
>* Generalize wording in migration.rst to include portio_list API (Zoltan)
>
>
>
>v2:
>
>* Improve commit messages (Zoltan)
>
>* Split pegasos2 from vt82c686 patch (Zoltan)
>
>* Avoid poking into device internals (Zoltan)
>
>
>
>Testing done:
>
>* `make check`
>
>* `make check-avocado`
>
>* Run MorphOS on pegasos2 with and without pegasos2.rom
>
>* Run Linux on amigaone
>
>* Run real-world BIOSes on via-apollo-pro-133t branch
>
>* Start rescue-yl on fuloong2e
>
>
>
>[1] https://github.com/shentok/qemu/tree/via-apollo-pro-133t
>
>[2] https://github.com/shentok/qemu/tree/pc-via
>
>
>
>Bernhard Beschow (11):
>
>  hw/block/fdc-isa: Move portio_list from FDCtrl to FDCtrlISABus
>
>  hw/block/fdc-sysbus: Move iomem from FDCtrl to FDCtrlSysBus
>
>  hw/char/parallel: Move portio_list from ParallelState to
>
>ISAParallelState
>


>  exec/ioport: Resolve redundant .base attribute in struct
>
>MemoryRegionPortio
>
>  exec/ioport: Add portio_list_set_address()
>
>  exec/ioport: Add portio_list_set_enabled()
>
>  hw/block/fdc-isa: Implement relocation and enabling/disabling for
>
>TYPE_ISA_FDC
>
>  hw/char/serial-isa: Implement relocation and enabling/disabling for
>
>TYPE_ISA_SERIAL
>
>  hw/char/parallel-isa: Implement relocation and enabling/disabling for
>
>TYPE_ISA_PARALLEL
>

Ping for the above six patches. These are critical for this series and haven't 
had comments from maintainers for five iterations, so pardon for the annoyance.

Best regards,
Bernhard

>  hw/ppc/pegasos2: Let pegasos2 machine configure SuperI/O functions
>
>  hw/isa/vt82c686: Implement relocation and toggling of SuperI/O
>
>functions
>
>
>
> docs/devel/migration.rst   |  6 ++--
>
> hw/block/fdc-internal.h|  4 ---
>
> include/exec/ioport.h  |  4 ++-
>
> include/hw/block/fdc.h |  3 ++
>
> include/hw/char/parallel-isa.h |  5 +++
>
> include/hw/char/parallel.h |  2 --
>
> include/hw/char/serial.h   |  2 ++
>
> hw/block/fdc-isa.c | 18 +-
>
> hw/block/fdc-sysbus.c  |  6 ++--
>
> hw/char/parallel-isa.c | 14 
>
> hw/char/parallel.c |  2 +-
>
> hw/char/serial-isa.c   | 14 
>
> hw/isa/vt82c686.c  | 65 --
>
> hw/ppc/pegasos2.c  | 12 +++
>
> system/ioport.c| 41 +
>
> 15 files changed, 168 insertions(+), 30 deletions(-)
>
>
>
>-- >
>2.43.0
>
>
>



[PATCH v5 09/11] hw/char/parallel-isa: Implement relocation and enabling/disabling for TYPE_ISA_PARALLEL

2024-01-14 Thread Bernhard Beschow
The real SuperI/O chips emulated by QEMU allow for relocating and enabling or
disabling their SuperI/O functions via software. So far this is not implemented.
Prepare for that by adding isa_parallel_set_{enabled,iobase}.

Signed-off-by: Bernhard Beschow 
---
 include/hw/char/parallel-isa.h |  3 +++
 hw/char/parallel-isa.c | 14 ++
 2 files changed, 17 insertions(+)

diff --git a/include/hw/char/parallel-isa.h b/include/hw/char/parallel-isa.h
index 3b783bd08d..5284b2ffec 100644
--- a/include/hw/char/parallel-isa.h
+++ b/include/hw/char/parallel-isa.h
@@ -29,4 +29,7 @@ struct ISAParallelState {
 PortioList portio_list;
 };
 
+void isa_parallel_set_iobase(ISADevice *parallel, hwaddr iobase);
+void isa_parallel_set_enabled(ISADevice *parallel, bool enabled);
+
 #endif /* HW_PARALLEL_ISA_H */
diff --git a/hw/char/parallel-isa.c b/hw/char/parallel-isa.c
index ab0f879998..a5ce6ee13a 100644
--- a/hw/char/parallel-isa.c
+++ b/hw/char/parallel-isa.c
@@ -41,3 +41,17 @@ void parallel_hds_isa_init(ISABus *bus, int n)
 }
 }
 }
+
+void isa_parallel_set_iobase(ISADevice *parallel, hwaddr iobase)
+{
+ISAParallelState *s = ISA_PARALLEL(parallel);
+
+parallel->ioport_id = iobase;
+s->iobase = iobase;
+portio_list_set_address(&s->portio_list, s->iobase);
+}
+
+void isa_parallel_set_enabled(ISADevice *parallel, bool enabled)
+{
+portio_list_set_enabled(&ISA_PARALLEL(parallel)->portio_list, enabled);
+}
-- 
2.43.0




[PATCH v5 10/11] hw/ppc/pegasos2: Let pegasos2 machine configure SuperI/O functions

2024-01-14 Thread Bernhard Beschow
This is a preparation for implementing relocation and toggling of SuperI/O
functions in the VT8231 device model. Upon reset, all SuperI/O functions will be
deactivated, so in case if no -bios is given, let the machine configure those
functions the same way Pegasos II firmware would do.

Signed-off-by: Bernhard Beschow 
Reviewed-by: BALATON Zoltan 
---
 hw/ppc/pegasos2.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
index d84f3f977d..04d6decb2b 100644
--- a/hw/ppc/pegasos2.c
+++ b/hw/ppc/pegasos2.c
@@ -285,6 +285,12 @@ static void pegasos2_pci_config_write(Pegasos2MachineState 
*pm, int bus,
 pegasos2_mv_reg_write(pm, pcicfg + 4, len, val);
 }
 
+static void pegasos2_superio_write(uint8_t addr, uint8_t val)
+{
+cpu_physical_memory_write(PCI1_IO_BASE + 0x3f0, &addr, 1);
+cpu_physical_memory_write(PCI1_IO_BASE + 0x3f1, &val, 1);
+}
+
 static void pegasos2_machine_reset(MachineState *machine, ShutdownCause reason)
 {
 Pegasos2MachineState *pm = PEGASOS2_MACHINE(machine);
@@ -310,6 +316,12 @@ static void pegasos2_machine_reset(MachineState *machine, 
ShutdownCause reason)
 
 pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
   PCI_INTERRUPT_LINE, 2, 0x9);
+pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
+  0x50, 1, 0x6);
+pegasos2_superio_write(0xf4, 0xbe);
+pegasos2_superio_write(0xf6, 0xef);
+pegasos2_superio_write(0xf7, 0xfc);
+pegasos2_superio_write(0xf2, 0x14);
 pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
   0x50, 1, 0x2);
 pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
-- 
2.43.0




[PATCH v5 04/11] exec/ioport: Resolve redundant .base attribute in struct MemoryRegionPortio

2024-01-14 Thread Bernhard Beschow
portio_list_add_1() creates a MemoryRegionPortioList instance which holds a
MemoryRegion `mr` and an array of MemoryRegionPortio elements named `ports`.
Each element in the array gets assigned the same value for its .base attribute.
The same value also ends up as the .addr attribute of `mr` due to the
memory_region_add_subregion() call. This means that all .base attributes are
the same as `mr.addr`.

The only usages of MemoryRegionPortio::base were in portio_read() and
portio_write(). Both functions get above MemoryRegionPortioList as their
opaque parameter. In both cases find_portio() can only return one of the
MemoryRegionPortio elements of the `ports` array. Due to above observation any
element will have the same .base value equal to `mr.addr` which is also
accessible.

Hence, `mrpio->mr.addr` is equivalent to `mrp->base` and
MemoryRegionPortio::base is redundant and can be removed.

Signed-off-by: Bernhard Beschow 
---
 include/exec/ioport.h |  1 -
 system/ioport.c   | 13 ++---
 2 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/include/exec/ioport.h b/include/exec/ioport.h
index e34f668998..95f1dc30d0 100644
--- a/include/exec/ioport.h
+++ b/include/exec/ioport.h
@@ -35,7 +35,6 @@ typedef struct MemoryRegionPortio {
 unsigned size;
 uint32_t (*read)(void *opaque, uint32_t address);
 void (*write)(void *opaque, uint32_t address, uint32_t data);
-uint32_t base; /* private field */
 } MemoryRegionPortio;
 
 #define PORTIO_END_OF_LIST() { }
diff --git a/system/ioport.c b/system/ioport.c
index 1824aa808c..a59e58b716 100644
--- a/system/ioport.c
+++ b/system/ioport.c
@@ -181,13 +181,13 @@ static uint64_t portio_read(void *opaque, hwaddr addr, 
unsigned size)
 
 data = ((uint64_t)1 << (size * 8)) - 1;
 if (mrp) {
-data = mrp->read(mrpio->portio_opaque, mrp->base + addr);
+data = mrp->read(mrpio->portio_opaque, mrpio->mr.addr + addr);
 } else if (size == 2) {
 mrp = find_portio(mrpio, addr, 1, false);
 if (mrp) {
-data = mrp->read(mrpio->portio_opaque, mrp->base + addr);
+data = mrp->read(mrpio->portio_opaque, mrpio->mr.addr + addr);
 if (addr + 1 < mrp->offset + mrp->len) {
-data |= mrp->read(mrpio->portio_opaque, mrp->base + addr + 1) 
<< 8;
+data |= mrp->read(mrpio->portio_opaque, mrpio->mr.addr + addr 
+ 1) << 8;
 } else {
 data |= 0xff00;
 }
@@ -203,13 +203,13 @@ static void portio_write(void *opaque, hwaddr addr, 
uint64_t data,
 const MemoryRegionPortio *mrp = find_portio(mrpio, addr, size, true);
 
 if (mrp) {
-mrp->write(mrpio->portio_opaque, mrp->base + addr, data);
+mrp->write(mrpio->portio_opaque, mrpio->mr.addr + addr, data);
 } else if (size == 2) {
 mrp = find_portio(mrpio, addr, 1, true);
 if (mrp) {
-mrp->write(mrpio->portio_opaque, mrp->base + addr, data & 0xff);
+mrp->write(mrpio->portio_opaque, mrpio->mr.addr + addr, data & 
0xff);
 if (addr + 1 < mrp->offset + mrp->len) {
-mrp->write(mrpio->portio_opaque, mrp->base + addr + 1, data >> 
8);
+mrp->write(mrpio->portio_opaque, mrpio->mr.addr + addr + 1, 
data >> 8);
 }
 }
 }
@@ -244,7 +244,6 @@ static void portio_list_add_1(PortioList *piolist,
 /* Adjust the offsets to all be zero-based for the region.  */
 for (i = 0; i < count; ++i) {
 mrpio->ports[i].offset -= off_low;
-mrpio->ports[i].base = start + off_low;
 }
 
 /*
-- 
2.43.0




[PATCH v5 08/11] hw/char/serial-isa: Implement relocation and enabling/disabling for TYPE_ISA_SERIAL

2024-01-14 Thread Bernhard Beschow
The real SuperI/O chips emulated by QEMU allow for relocating and enabling or
disabling their SuperI/O functions via software. So far this is not implemented.
Prepare for that by adding isa_serial_set_{enabled,iobase}.

Signed-off-by: Bernhard Beschow 
---
 include/hw/char/serial.h |  2 ++
 hw/char/serial-isa.c | 14 ++
 2 files changed, 16 insertions(+)

diff --git a/include/hw/char/serial.h b/include/hw/char/serial.h
index 8ba7eca3d6..6e14099ee7 100644
--- a/include/hw/char/serial.h
+++ b/include/hw/char/serial.h
@@ -112,5 +112,7 @@ SerialMM *serial_mm_init(MemoryRegion *address_space,
 
 #define TYPE_ISA_SERIAL "isa-serial"
 void serial_hds_isa_init(ISABus *bus, int from, int to);
+void isa_serial_set_iobase(ISADevice *serial, hwaddr iobase);
+void isa_serial_set_enabled(ISADevice *serial, bool enabled);
 
 #endif
diff --git a/hw/char/serial-isa.c b/hw/char/serial-isa.c
index 1c793b20f7..329b352b9a 100644
--- a/hw/char/serial-isa.c
+++ b/hw/char/serial-isa.c
@@ -184,3 +184,17 @@ void serial_hds_isa_init(ISABus *bus, int from, int to)
 }
 }
 }
+
+void isa_serial_set_iobase(ISADevice *serial, hwaddr iobase)
+{
+ISASerialState *s = ISA_SERIAL(serial);
+
+serial->ioport_id = iobase;
+s->iobase = iobase;
+memory_region_set_address(&s->state.io, s->iobase);
+}
+
+void isa_serial_set_enabled(ISADevice *serial, bool enabled)
+{
+memory_region_set_enabled(&ISA_SERIAL(serial)->state.io, enabled);
+}
-- 
2.43.0




[PATCH v5 03/11] hw/char/parallel: Move portio_list from ParallelState to ISAParallelState

2024-01-14 Thread Bernhard Beschow
ParallelState::portio_list isn't used inside ParallelState context but only
inside ISAParallelState context, so move it there.

Signed-off-by: Bernhard Beschow 
Reviewed-by: BALATON Zoltan 
---
 include/hw/char/parallel-isa.h | 2 ++
 include/hw/char/parallel.h | 2 --
 hw/char/parallel.c | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/include/hw/char/parallel-isa.h b/include/hw/char/parallel-isa.h
index d24ccecf05..3b783bd08d 100644
--- a/include/hw/char/parallel-isa.h
+++ b/include/hw/char/parallel-isa.h
@@ -12,6 +12,7 @@
 
 #include "parallel.h"
 
+#include "exec/ioport.h"
 #include "hw/isa/isa.h"
 #include "qom/object.h"
 
@@ -25,6 +26,7 @@ struct ISAParallelState {
 uint32_t iobase;
 uint32_t isairq;
 ParallelState state;
+PortioList portio_list;
 };
 
 #endif /* HW_PARALLEL_ISA_H */
diff --git a/include/hw/char/parallel.h b/include/hw/char/parallel.h
index 7b5a309a03..cfb97cc7cc 100644
--- a/include/hw/char/parallel.h
+++ b/include/hw/char/parallel.h
@@ -1,7 +1,6 @@
 #ifndef HW_PARALLEL_H
 #define HW_PARALLEL_H
 
-#include "exec/ioport.h"
 #include "exec/memory.h"
 #include "hw/isa/isa.h"
 #include "hw/irq.h"
@@ -22,7 +21,6 @@ typedef struct ParallelState {
 uint32_t last_read_offset; /* For debugging */
 /* Memory-mapped interface */
 int it_shift;
-PortioList portio_list;
 } ParallelState;
 
 void parallel_hds_isa_init(ISABus *bus, int n);
diff --git a/hw/char/parallel.c b/hw/char/parallel.c
index bd488cd7f9..c394635ada 100644
--- a/hw/char/parallel.c
+++ b/hw/char/parallel.c
@@ -532,7 +532,7 @@ static void parallel_isa_realizefn(DeviceState *dev, Error 
**errp)
 s->status = dummy;
 }
 
-isa_register_portio_list(isadev, &s->portio_list, base,
+isa_register_portio_list(isadev, &isa->portio_list, base,
  (s->hw_driver
   ? &isa_parallel_portio_hw_list[0]
   : &isa_parallel_portio_sw_list[0]),
-- 
2.43.0




[PATCH v5 00/11] hw/isa/vt82c686: Implement relocation and toggling of SuperI/O functions

2024-01-14 Thread Bernhard Beschow
This series implements relocation of the SuperI/O functions of the VIA south
bridges which resolves some FIXME's. It is part of my via-apollo-pro-133t
branch [1] which is an extension of bringing the VIA south bridges to the PC
machine [2]. This branch is able to run some real-world X86 BIOSes in the hope
that it allows us to form a better understanding of the real vt82c686b devices.
Implementing relocation and toggling of the SuperI/O functions is one step to
make these BIOSes run without error messages, so here we go.

The series is structured as follows: Patches 1-3 prepare the TYPE_ISA_FDC,
TYPE_ISA_PARALLEL and TYPE_ISA_SERIAL to relocate and toggle (enable/disable)
themselves without breaking encapsulation of their respective device states.
This is achieved by moving the MemoryRegions and PortioLists from the device
states into the encapsulating ISA devices since they will be relocated and
toggled.

Inspired by the memory API patches 4-6 add two convenience functions to the
portio_list API to toggle and relocate portio lists. Patch 5 is a preparation
for that which removes some redundancies which otherwise had to be dealt with
during relocation.

Patches 7-9 implement toggling and relocation for types TYPE_ISA_FDC,
TYPE_ISA_PARALLEL and TYPE_ISA_SERIAL. Patch 10 prepares the pegasos2 machine
which would end up with all SuperI/O functions disabled if no -bios argument is
given. Patch 11 finally implements the main feature which now relies on
firmware to configure the SuperI/O functions accordingly (except for pegasos2).

v5:
* Use cpu_physical_memory_write() in pegasos2 (Zoltan)
* Use an int as for loop variable (Zoltan)

v4:
* Drop incomplete SuperI/O vmstate handling (Zoltan)

v3:
* Rework various commit messages (Zoltan)
* Drop patch "hw/char/serial: Free struct SerialState from MemoryRegion"
  (Zoltan)
* Generalize wording in migration.rst to include portio_list API (Zoltan)

v2:
* Improve commit messages (Zoltan)
* Split pegasos2 from vt82c686 patch (Zoltan)
* Avoid poking into device internals (Zoltan)

Testing done:
* `make check`
* `make check-avocado`
* Run MorphOS on pegasos2 with and without pegasos2.rom
* Run Linux on amigaone
* Run real-world BIOSes on via-apollo-pro-133t branch
* Start rescue-yl on fuloong2e

[1] https://github.com/shentok/qemu/tree/via-apollo-pro-133t
[2] https://github.com/shentok/qemu/tree/pc-via

Bernhard Beschow (11):
  hw/block/fdc-isa: Move portio_list from FDCtrl to FDCtrlISABus
  hw/block/fdc-sysbus: Move iomem from FDCtrl to FDCtrlSysBus
  hw/char/parallel: Move portio_list from ParallelState to
ISAParallelState
  exec/ioport: Resolve redundant .base attribute in struct
MemoryRegionPortio
  exec/ioport: Add portio_list_set_address()
  exec/ioport: Add portio_list_set_enabled()
  hw/block/fdc-isa: Implement relocation and enabling/disabling for
TYPE_ISA_FDC
  hw/char/serial-isa: Implement relocation and enabling/disabling for
TYPE_ISA_SERIAL
  hw/char/parallel-isa: Implement relocation and enabling/disabling for
TYPE_ISA_PARALLEL
  hw/ppc/pegasos2: Let pegasos2 machine configure SuperI/O functions
  hw/isa/vt82c686: Implement relocation and toggling of SuperI/O
functions

 docs/devel/migration.rst   |  6 ++--
 hw/block/fdc-internal.h|  4 ---
 include/exec/ioport.h  |  4 ++-
 include/hw/block/fdc.h |  3 ++
 include/hw/char/parallel-isa.h |  5 +++
 include/hw/char/parallel.h |  2 --
 include/hw/char/serial.h   |  2 ++
 hw/block/fdc-isa.c | 18 +-
 hw/block/fdc-sysbus.c  |  6 ++--
 hw/char/parallel-isa.c | 14 
 hw/char/parallel.c |  2 +-
 hw/char/serial-isa.c   | 14 
 hw/isa/vt82c686.c  | 65 --
 hw/ppc/pegasos2.c  | 12 +++
 system/ioport.c| 41 +
 15 files changed, 168 insertions(+), 30 deletions(-)

-- 
2.43.0




[PATCH v5 07/11] hw/block/fdc-isa: Implement relocation and enabling/disabling for TYPE_ISA_FDC

2024-01-14 Thread Bernhard Beschow
The real SuperI/O chips emulated by QEMU allow for relocating and enabling or
disabling their SuperI/O functions via software. So far this is not implemented.
Prepare for that by adding isa_fdc_set_{enabled,iobase}.

Signed-off-by: Bernhard Beschow 
---
 include/hw/block/fdc.h |  3 +++
 hw/block/fdc-isa.c | 14 ++
 2 files changed, 17 insertions(+)

diff --git a/include/hw/block/fdc.h b/include/hw/block/fdc.h
index 35248c0837..c367c5efea 100644
--- a/include/hw/block/fdc.h
+++ b/include/hw/block/fdc.h
@@ -14,6 +14,9 @@ void fdctrl_init_sysbus(qemu_irq irq, hwaddr mmio_base, 
DriveInfo **fds);
 void sun4m_fdctrl_init(qemu_irq irq, hwaddr io_base,
DriveInfo **fds, qemu_irq *fdc_tc);
 
+void isa_fdc_set_iobase(ISADevice *fdc, hwaddr iobase);
+void isa_fdc_set_enabled(ISADevice *fdc, bool enabled);
+
 FloppyDriveType isa_fdc_get_drive_type(ISADevice *fdc, int i);
 int cmos_get_fd_drive_type(FloppyDriveType fd0);
 
diff --git a/hw/block/fdc-isa.c b/hw/block/fdc-isa.c
index 2d8a98ce7d..e43dc532af 100644
--- a/hw/block/fdc-isa.c
+++ b/hw/block/fdc-isa.c
@@ -192,6 +192,20 @@ static Aml *build_fdinfo_aml(int idx, FloppyDriveType type)
 return dev;
 }
 
+void isa_fdc_set_iobase(ISADevice *fdc, hwaddr iobase)
+{
+FDCtrlISABus *isa = ISA_FDC(fdc);
+
+fdc->ioport_id = iobase;
+isa->iobase = iobase;
+portio_list_set_address(&isa->portio_list, isa->iobase);
+}
+
+void isa_fdc_set_enabled(ISADevice *fdc, bool enabled)
+{
+portio_list_set_enabled(&ISA_FDC(fdc)->portio_list, enabled);
+}
+
 int cmos_get_fd_drive_type(FloppyDriveType fd0)
 {
 int val;
-- 
2.43.0




[PATCH v5 11/11] hw/isa/vt82c686: Implement relocation and toggling of SuperI/O functions

2024-01-14 Thread Bernhard Beschow
The VIA south bridges are able to relocate and toggle (enable or disable) their
SuperI/O functions. So far this is hardcoded such that all functions are always
enabled and are located at fixed addresses.

Some PC BIOSes seem to probe for I/O occupancy before activating such a function
and issue an error in case of a conflict. Since the functions are currently
enabled on reset, conflicts are always detected. Prevent that by implementing
relocation and toggling of the SuperI/O functions.

Note that all SuperI/O functions are now deactivated upon reset (except for
VT82C686B's serial ports where Fuloong 2e's rescue-yl seems to expect them to be
enabled by default). Rely on firmware to configure the functions accordingly.

Signed-off-by: Bernhard Beschow 
Reviewed-by: BALATON Zoltan 
---
 hw/isa/vt82c686.c | 65 +++
 1 file changed, 55 insertions(+), 10 deletions(-)

diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index d3e0f6d01f..485bb685b7 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -15,6 +15,9 @@
 
 #include "qemu/osdep.h"
 #include "hw/isa/vt82c686.h"
+#include "hw/block/fdc.h"
+#include "hw/char/parallel-isa.h"
+#include "hw/char/serial.h"
 #include "hw/pci/pci.h"
 #include "hw/qdev-properties.h"
 #include "hw/ide/pci.h"
@@ -323,6 +326,17 @@ static uint64_t via_superio_cfg_read(void *opaque, hwaddr 
addr, unsigned size)
 return val;
 }
 
+static void via_superio_devices_enable(ViaSuperIOState *s, uint8_t data)
+{
+ISASuperIOClass *ic = ISA_SUPERIO_GET_CLASS(s);
+
+isa_parallel_set_enabled(s->superio.parallel[0], (data & 0x3) != 3);
+for (int i = 0; i < ic->serial.count; i++) {
+isa_serial_set_enabled(s->superio.serial[i], data & BIT(i + 2));
+}
+isa_fdc_set_enabled(s->superio.floppy, data & BIT(4));
+}
+
 static void via_superio_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
@@ -368,7 +382,25 @@ static void vt82c686b_superio_cfg_write(void *opaque, 
hwaddr addr,
 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;
+via_superio_devices_enable(sc, data);
+break;
+case 0xe3:
+data &= 0xfc;
+isa_fdc_set_iobase(sc->superio.floppy, data << 2);
+break;
+case 0xe6:
+isa_parallel_set_iobase(sc->superio.parallel[0], data << 2);
+break;
+case 0xe7:
+data &= 0xfe;
+isa_serial_set_iobase(sc->superio.serial[0], data << 2);
+break;
+case 0xe8:
+data &= 0xfe;
+isa_serial_set_iobase(sc->superio.serial[1], data << 2);
+break;
 default:
 qemu_log_mask(LOG_UNIMP,
   "via_superio_cfg: unimplemented register 0x%x\n", idx);
@@ -395,9 +427,14 @@ static void vt82c686b_superio_reset(DeviceState *dev)
 /* Device ID */
 vt82c686b_superio_cfg_write(s, 0, 0xe0, 1);
 vt82c686b_superio_cfg_write(s, 1, 0x3c, 1);
-/* Function select - all disabled */
+/*
+ * Function select - only serial enabled
+ * Fuloong 2e's rescue-yl prints to the serial console w/o enabling it. 
This
+ * suggests that the serial ports are enabled by default, so override the
+ * datasheet.
+ */
 vt82c686b_superio_cfg_write(s, 0, 0xe2, 1);
-vt82c686b_superio_cfg_write(s, 1, 0x03, 1);
+vt82c686b_superio_cfg_write(s, 1, 0x0f, 1);
 /* Floppy ctrl base addr 0x3f0-7 */
 vt82c686b_superio_cfg_write(s, 0, 0xe3, 1);
 vt82c686b_superio_cfg_write(s, 1, 0xfc, 1);
@@ -465,6 +502,21 @@ static void vt8231_superio_cfg_write(void *opaque, hwaddr 
addr,
 case 0xfd:
 /* ignore write to read only registers */
 return;
+case 0xf2:
+data &= 0x17;
+via_superio_devices_enable(sc, data);
+break;
+case 0xf4:
+data &= 0xfe;
+isa_serial_set_iobase(sc->superio.serial[0], data << 2);
+break;
+case 0xf6:
+isa_parallel_set_iobase(sc->superio.parallel[0], data << 2);
+break;
+case 0xf7:
+data &= 0xfc;
+isa_fdc_set_iobase(sc->superio.floppy, data << 2);
+break;
 default:
 qemu_log_mask(LOG_UNIMP,
   "via_superio_cfg: unimplemented register 0x%x\n", idx);
@@ -513,12 +565,6 @@ static void vt8231_superio_init(Object *obj)
 VIA_SUPERIO(obj)->io_ops = &vt8231_superio_cfg_ops;
 }
 
-static uint16_t vt8231_superio_serial_iobase(ISASuperIODevice *sio,
- uint8_t index)
-{
-return 0x2f8; /* FIXME: This should be settable via registers f2-f4 */
-}
-
 static void vt82

[PATCH v5 02/11] hw/block/fdc-sysbus: Move iomem from FDCtrl to FDCtrlSysBus

2024-01-14 Thread Bernhard Beschow
FDCtrl::iomem isn't used inside FDCtrl context but only inside FDCtrlSysBus
context, so move it there.

Signed-off-by: Bernhard Beschow 
Reviewed-by: BALATON Zoltan 
---
 hw/block/fdc-internal.h | 2 --
 hw/block/fdc-sysbus.c   | 6 --
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/block/fdc-internal.h b/hw/block/fdc-internal.h
index fef2bfbbf5..e219623dc7 100644
--- a/hw/block/fdc-internal.h
+++ b/hw/block/fdc-internal.h
@@ -25,7 +25,6 @@
 #ifndef HW_BLOCK_FDC_INTERNAL_H
 #define HW_BLOCK_FDC_INTERNAL_H
 
-#include "exec/memory.h"
 #include "hw/block/block.h"
 #include "hw/block/fdc.h"
 #include "qapi/qapi-types-block.h"
@@ -91,7 +90,6 @@ typedef struct FDrive {
 } FDrive;
 
 struct FDCtrl {
-MemoryRegion iomem;
 qemu_irq irq;
 /* Controller state */
 QEMUTimer *result_timer;
diff --git a/hw/block/fdc-sysbus.c b/hw/block/fdc-sysbus.c
index 266bc4d145..035bc08975 100644
--- a/hw/block/fdc-sysbus.c
+++ b/hw/block/fdc-sysbus.c
@@ -26,6 +26,7 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "qom/object.h"
+#include "exec/memory.h"
 #include "hw/sysbus.h"
 #include "hw/block/fdc.h"
 #include "migration/vmstate.h"
@@ -52,6 +53,7 @@ struct FDCtrlSysBus {
 /*< public >*/
 
 struct FDCtrl state;
+MemoryRegion iomem;
 };
 
 static uint64_t fdctrl_read_mem(void *opaque, hwaddr reg, unsigned ize)
@@ -146,11 +148,11 @@ static void sysbus_fdc_common_instance_init(Object *obj)
 
 qdev_set_legacy_instance_id(dev, 0 /* io */, 2); /* FIXME */
 
-memory_region_init_io(&fdctrl->iomem, obj,
+memory_region_init_io(&sys->iomem, obj,
   sbdc->use_strict_io ? &fdctrl_mem_strict_ops
   : &fdctrl_mem_ops,
   fdctrl, "fdc", 0x08);
-sysbus_init_mmio(sbd, &fdctrl->iomem);
+sysbus_init_mmio(sbd, &sys->iomem);
 
 sysbus_init_irq(sbd, &fdctrl->irq);
 qdev_init_gpio_in(dev, fdctrl_handle_tc, 1);
-- 
2.43.0




[PATCH v5 06/11] exec/ioport: Add portio_list_set_enabled()

2024-01-14 Thread Bernhard Beschow
Some SuperI/O devices such as the VIA south bridges or the PC87312 controller
allow to enable or disable their SuperI/O functions. Add a convenience function
for implementing this in the VIA south bridges.

The naming of the functions is inspired by its memory_region_set_enabled()
pendant.

Signed-off-by: Bernhard Beschow 
---
 docs/devel/migration.rst | 1 +
 include/exec/ioport.h| 1 +
 system/ioport.c  | 9 +
 3 files changed, 11 insertions(+)

diff --git a/docs/devel/migration.rst b/docs/devel/migration.rst
index 30b05f0f74..1683fc6026 100644
--- a/docs/devel/migration.rst
+++ b/docs/devel/migration.rst
@@ -465,6 +465,7 @@ Examples of such API functions are:
   - memory_region_set_address()
   - memory_region_set_alias_offset()
   - portio_list_set_address()
+  - portio_list_set_enabled()
 
 Iterative device migration
 --
diff --git a/include/exec/ioport.h b/include/exec/ioport.h
index 96858e5ac3..4397f12f93 100644
--- a/include/exec/ioport.h
+++ b/include/exec/ioport.h
@@ -71,6 +71,7 @@ void portio_list_add(PortioList *piolist,
  struct MemoryRegion *address_space,
  uint32_t addr);
 void portio_list_del(PortioList *piolist);
+void portio_list_set_enabled(PortioList *piolist, bool enabled);
 void portio_list_set_address(PortioList *piolist, uint32_t addr);
 
 #endif /* IOPORT_H */
diff --git a/system/ioport.c b/system/ioport.c
index 000e0ee1af..fd551d0375 100644
--- a/system/ioport.c
+++ b/system/ioport.c
@@ -324,6 +324,15 @@ void portio_list_del(PortioList *piolist)
 }
 }
 
+void portio_list_set_enabled(PortioList *piolist, bool enabled)
+{
+unsigned i;
+
+for (i = 0; i < piolist->nr; ++i) {
+memory_region_set_enabled(piolist->regions[i], enabled);
+}
+}
+
 void portio_list_set_address(PortioList *piolist, uint32_t addr)
 {
 MemoryRegionPortioList *mrpio;
-- 
2.43.0




[PATCH v5 05/11] exec/ioport: Add portio_list_set_address()

2024-01-14 Thread Bernhard Beschow
Some SuperI/O devices such as the VIA south bridges or the PC87312 controller
are able to relocate their SuperI/O functions. Add a convenience function for
implementing this in the VIA south bridges.

This convenience function relies on previous simplifications in exec/ioport
which avoids some duplicate synchronization of I/O port base addresses. The
naming of the function is inspired by its memory_region_set_address() pendant.

Signed-off-by: Bernhard Beschow 
---
 docs/devel/migration.rst |  5 +++--
 include/exec/ioport.h|  2 ++
 system/ioport.c  | 19 +++
 3 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/docs/devel/migration.rst b/docs/devel/migration.rst
index 95351ba51f..30b05f0f74 100644
--- a/docs/devel/migration.rst
+++ b/docs/devel/migration.rst
@@ -452,10 +452,10 @@ data doesn't match the stored device data well; it allows 
an
 intermediate temporary structure to be populated with migration
 data and then transferred to the main structure.
 
-If you use memory API functions that update memory layout outside
+If you use memory or portio_list API functions that update memory layout 
outside
 initialization (i.e., in response to a guest action), this is a strong
 indication that you need to call these functions in a ``post_load`` callback.
-Examples of such memory API functions are:
+Examples of such API functions are:
 
   - memory_region_add_subregion()
   - memory_region_del_subregion()
@@ -464,6 +464,7 @@ Examples of such memory API functions are:
   - memory_region_set_enabled()
   - memory_region_set_address()
   - memory_region_set_alias_offset()
+  - portio_list_set_address()
 
 Iterative device migration
 --
diff --git a/include/exec/ioport.h b/include/exec/ioport.h
index 95f1dc30d0..96858e5ac3 100644
--- a/include/exec/ioport.h
+++ b/include/exec/ioport.h
@@ -54,6 +54,7 @@ typedef struct PortioList {
 const struct MemoryRegionPortio *ports;
 Object *owner;
 struct MemoryRegion *address_space;
+uint32_t addr;
 unsigned nr;
 struct MemoryRegion **regions;
 void *opaque;
@@ -70,5 +71,6 @@ void portio_list_add(PortioList *piolist,
  struct MemoryRegion *address_space,
  uint32_t addr);
 void portio_list_del(PortioList *piolist);
+void portio_list_set_address(PortioList *piolist, uint32_t addr);
 
 #endif /* IOPORT_H */
diff --git a/system/ioport.c b/system/ioport.c
index a59e58b716..000e0ee1af 100644
--- a/system/ioport.c
+++ b/system/ioport.c
@@ -133,6 +133,7 @@ void portio_list_init(PortioList *piolist,
 piolist->nr = 0;
 piolist->regions = g_new0(MemoryRegion *, n);
 piolist->address_space = NULL;
+piolist->addr = 0;
 piolist->opaque = opaque;
 piolist->owner = owner;
 piolist->name = name;
@@ -282,6 +283,7 @@ void portio_list_add(PortioList *piolist,
 unsigned int off_low, off_high, off_last, count;
 
 piolist->address_space = address_space;
+piolist->addr = start;
 
 /* Handle the first entry specially.  */
 off_last = off_low = pio_start->offset;
@@ -322,6 +324,23 @@ void portio_list_del(PortioList *piolist)
 }
 }
 
+void portio_list_set_address(PortioList *piolist, uint32_t addr)
+{
+MemoryRegionPortioList *mrpio;
+unsigned i, j;
+
+for (i = 0; i < piolist->nr; ++i) {
+mrpio = container_of(piolist->regions[i], MemoryRegionPortioList, mr);
+memory_region_set_address(&mrpio->mr,
+  mrpio->mr.addr - piolist->addr + addr);
+for (j = 0; mrpio->ports[j].size; ++j) {
+mrpio->ports[j].offset += addr - piolist->addr;
+}
+}
+
+piolist->addr = addr;
+}
+
 static void memory_region_portio_list_finalize(Object *obj)
 {
 MemoryRegionPortioList *mrpio = MEMORY_REGION_PORTIO_LIST(obj);
-- 
2.43.0




[PATCH v5 01/11] hw/block/fdc-isa: Move portio_list from FDCtrl to FDCtrlISABus

2024-01-14 Thread Bernhard Beschow
FDCtrl::portio_list isn't used inside FDCtrl context but only inside
FDCtrlISABus context, so move it there.

Signed-off-by: Bernhard Beschow 
Reviewed-by: BALATON Zoltan 
---
 hw/block/fdc-internal.h | 2 --
 hw/block/fdc-isa.c  | 4 +++-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/block/fdc-internal.h b/hw/block/fdc-internal.h
index 036392e9fc..fef2bfbbf5 100644
--- a/hw/block/fdc-internal.h
+++ b/hw/block/fdc-internal.h
@@ -26,7 +26,6 @@
 #define HW_BLOCK_FDC_INTERNAL_H
 
 #include "exec/memory.h"
-#include "exec/ioport.h"
 #include "hw/block/block.h"
 #include "hw/block/fdc.h"
 #include "qapi/qapi-types-block.h"
@@ -140,7 +139,6 @@ struct FDCtrl {
 /* Timers state */
 uint8_t timer0;
 uint8_t timer1;
-PortioList portio_list;
 };
 
 extern const FDFormat fd_formats[];
diff --git a/hw/block/fdc-isa.c b/hw/block/fdc-isa.c
index ad0921c7d3..2d8a98ce7d 100644
--- a/hw/block/fdc-isa.c
+++ b/hw/block/fdc-isa.c
@@ -42,6 +42,7 @@
 #include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "sysemu/sysemu.h"
+#include "exec/ioport.h"
 #include "qemu/log.h"
 #include "qemu/main-loop.h"
 #include "qemu/module.h"
@@ -60,6 +61,7 @@ struct FDCtrlISABus {
 uint32_t irq;
 uint32_t dma;
 struct FDCtrl state;
+PortioList portio_list;
 int32_t bootindexA;
 int32_t bootindexB;
 };
@@ -91,7 +93,7 @@ static void isabus_fdc_realize(DeviceState *dev, Error **errp)
 FDCtrl *fdctrl = &isa->state;
 Error *err = NULL;
 
-isa_register_portio_list(isadev, &fdctrl->portio_list,
+isa_register_portio_list(isadev, &isa->portio_list,
  isa->iobase, fdc_portio_list, fdctrl,
  "fdc");
 
-- 
2.43.0




Re: [PATCH v4 00/11] hw/isa/vt82c686: Implement relocation and toggling of SuperI/O functions

2024-01-09 Thread Bernhard Beschow



Am 8. Januar 2024 22:12:12 UTC schrieb Mark Cave-Ayland 
:
>On 08/01/2024 20:07, Bernhard Beschow wrote:
>
>> Am 7. Januar 2024 14:13:44 UTC schrieb Mark Cave-Ayland 
>> :
>>> On 06/01/2024 21:05, Bernhard Beschow wrote:
>>> 
>>>> This series implements relocation of the SuperI/O functions of the VIA 
>>>> south
>>>> bridges which resolves some FIXME's. It is part of my via-apollo-pro-133t
>>>> branch [1] which is an extension of bringing the VIA south bridges to the 
>>>> PC
>>>> machine [2]. This branch is able to run some real-world X86 BIOSes in the 
>>>> hope
>>>> that it allows us to form a better understanding of the real vt82c686b 
>>>> devices.
>>>> Implementing relocation and toggling of the SuperI/O functions is one step 
>>>> to
>>>> make these BIOSes run without error messages, so here we go.
>>>> 
>>>> The series is structured as follows: Patches 1-3 prepare the TYPE_ISA_FDC,
>>>> TYPE_ISA_PARALLEL and TYPE_ISA_SERIAL to relocate and toggle 
>>>> (enable/disable)
>>>> themselves without breaking encapsulation of their respective device 
>>>> states.
>>>> This is achieved by moving the MemoryRegions and PortioLists from the 
>>>> device
>>>> states into the encapsulating ISA devices since they will be relocated and
>>>> toggled.
>>>> 
>>>> Inspired by the memory API patches 4-6 add two convenience functions to the
>>>> portio_list API to toggle and relocate portio lists. Patch 5 is a 
>>>> preparation
>>>> for that which removes some redundancies which otherwise had to be dealt 
>>>> with
>>>> during relocation.
>>>> 
>>>> Patches 7-9 implement toggling and relocation for types TYPE_ISA_FDC,
>>>> TYPE_ISA_PARALLEL and TYPE_ISA_SERIAL. Patch 10 prepares the pegasos2 
>>>> machine
>>>> which would end up with all SuperI/O functions disabled if no -bios 
>>>> argument is
>>>> given. Patch 11 finally implements the main feature which now relies on
>>>> firmware to configure the SuperI/O functions accordingly (except for 
>>>> pegasos2).
>>>> 
>>>> v4:
>>>> * Drop incomplete SuperI/O vmstate handling (Zoltan)
>>>> 
>>>> v3:
>>>> * Rework various commit messages (Zoltan)
>>>> * Drop patch "hw/char/serial: Free struct SerialState from MemoryRegion"
>>>> (Zoltan)
>>>> * Generalize wording in migration.rst to include portio_list API (Zoltan)
>>>> 
>>>> v2:
>>>> * Improve commit messages (Zoltan)
>>>> * Split pegasos2 from vt82c686 patch (Zoltan)
>>>> * Avoid poking into device internals (Zoltan)
>>>> 
>>>> Testing done:
>>>> * `make check`
>>>> * `make check-avocado`
>>>> * Run MorphOS on pegasos2 with and without pegasos2.rom
>>>> * Run Linux on amigaone
>>>> * Run real-world BIOSes on via-apollo-pro-133t branch
>>>> * Start rescue-yl on fuloong2e
>>>> 
>>>> [1] https://github.com/shentok/qemu/tree/via-apollo-pro-133t
>>>> [2] https://github.com/shentok/qemu/tree/pc-via
>>>> 
>>>> Bernhard Beschow (11):
>>>> hw/block/fdc-isa: Move portio_list from FDCtrl to FDCtrlISABus
>>>> hw/block/fdc-sysbus: Move iomem from FDCtrl to FDCtrlSysBus
>>>> hw/char/parallel: Move portio_list from ParallelState to
>>>>   ISAParallelState
>>>> exec/ioport: Resolve redundant .base attribute in struct
>>>>   MemoryRegionPortio
>>>> exec/ioport: Add portio_list_set_address()
>>>> exec/ioport: Add portio_list_set_enabled()
>>>> hw/block/fdc-isa: Implement relocation and enabling/disabling for
>>>>   TYPE_ISA_FDC
>>>> hw/char/serial-isa: Implement relocation and enabling/disabling for
>>>>   TYPE_ISA_SERIAL
>>>> hw/char/parallel-isa: Implement relocation and enabling/disabling for
>>>>   TYPE_ISA_PARALLEL
>>>> hw/ppc/pegasos2: Let pegasos2 machine configure SuperI/O functions
>>>> hw/isa/vt82c686: Implement relocation and toggling of SuperI/O
>>>>   functions
>>>> 
>>>>docs/devel/migration.rst   |  6 ++--
>>>>hw/block/fdc-internal.h|  4 ---
>>>>include/exec/io

Re: [PATCH v4 00/11] hw/isa/vt82c686: Implement relocation and toggling of SuperI/O functions

2024-01-08 Thread Bernhard Beschow



Am 7. Januar 2024 14:13:44 UTC schrieb Mark Cave-Ayland 
:
>On 06/01/2024 21:05, Bernhard Beschow wrote:
>
>> This series implements relocation of the SuperI/O functions of the VIA south
>> bridges which resolves some FIXME's. It is part of my via-apollo-pro-133t
>> branch [1] which is an extension of bringing the VIA south bridges to the PC
>> machine [2]. This branch is able to run some real-world X86 BIOSes in the 
>> hope
>> that it allows us to form a better understanding of the real vt82c686b 
>> devices.
>> Implementing relocation and toggling of the SuperI/O functions is one step to
>> make these BIOSes run without error messages, so here we go.
>> 
>> The series is structured as follows: Patches 1-3 prepare the TYPE_ISA_FDC,
>> TYPE_ISA_PARALLEL and TYPE_ISA_SERIAL to relocate and toggle (enable/disable)
>> themselves without breaking encapsulation of their respective device states.
>> This is achieved by moving the MemoryRegions and PortioLists from the device
>> states into the encapsulating ISA devices since they will be relocated and
>> toggled.
>> 
>> Inspired by the memory API patches 4-6 add two convenience functions to the
>> portio_list API to toggle and relocate portio lists. Patch 5 is a preparation
>> for that which removes some redundancies which otherwise had to be dealt with
>> during relocation.
>> 
>> Patches 7-9 implement toggling and relocation for types TYPE_ISA_FDC,
>> TYPE_ISA_PARALLEL and TYPE_ISA_SERIAL. Patch 10 prepares the pegasos2 machine
>> which would end up with all SuperI/O functions disabled if no -bios argument 
>> is
>> given. Patch 11 finally implements the main feature which now relies on
>> firmware to configure the SuperI/O functions accordingly (except for 
>> pegasos2).
>> 
>> v4:
>> * Drop incomplete SuperI/O vmstate handling (Zoltan)
>> 
>> v3:
>> * Rework various commit messages (Zoltan)
>> * Drop patch "hw/char/serial: Free struct SerialState from MemoryRegion"
>>(Zoltan)
>> * Generalize wording in migration.rst to include portio_list API (Zoltan)
>> 
>> v2:
>> * Improve commit messages (Zoltan)
>> * Split pegasos2 from vt82c686 patch (Zoltan)
>> * Avoid poking into device internals (Zoltan)
>> 
>> Testing done:
>> * `make check`
>> * `make check-avocado`
>> * Run MorphOS on pegasos2 with and without pegasos2.rom
>> * Run Linux on amigaone
>> * Run real-world BIOSes on via-apollo-pro-133t branch
>> * Start rescue-yl on fuloong2e
>> 
>> [1] https://github.com/shentok/qemu/tree/via-apollo-pro-133t
>> [2] https://github.com/shentok/qemu/tree/pc-via
>> 
>> Bernhard Beschow (11):
>>hw/block/fdc-isa: Move portio_list from FDCtrl to FDCtrlISABus
>>hw/block/fdc-sysbus: Move iomem from FDCtrl to FDCtrlSysBus
>>hw/char/parallel: Move portio_list from ParallelState to
>>  ISAParallelState
>>exec/ioport: Resolve redundant .base attribute in struct
>>  MemoryRegionPortio
>>exec/ioport: Add portio_list_set_address()
>>exec/ioport: Add portio_list_set_enabled()
>>hw/block/fdc-isa: Implement relocation and enabling/disabling for
>>  TYPE_ISA_FDC
>>hw/char/serial-isa: Implement relocation and enabling/disabling for
>>  TYPE_ISA_SERIAL
>>hw/char/parallel-isa: Implement relocation and enabling/disabling for
>>  TYPE_ISA_PARALLEL
>>hw/ppc/pegasos2: Let pegasos2 machine configure SuperI/O functions
>>hw/isa/vt82c686: Implement relocation and toggling of SuperI/O
>>  functions
>> 
>>   docs/devel/migration.rst   |  6 ++--
>>   hw/block/fdc-internal.h|  4 ---
>>   include/exec/ioport.h  |  4 ++-
>>   include/hw/block/fdc.h |  3 ++
>>   include/hw/char/parallel-isa.h |  5 +++
>>   include/hw/char/parallel.h |  2 --
>>   include/hw/char/serial.h   |  2 ++
>>   hw/block/fdc-isa.c | 18 +-
>>   hw/block/fdc-sysbus.c  |  6 ++--
>>   hw/char/parallel-isa.c | 14 
>>   hw/char/parallel.c |  2 +-
>>   hw/char/serial-isa.c   | 14 
>>   hw/isa/vt82c686.c  | 66 --
>>   hw/ppc/pegasos2.c  | 15 
>>   system/ioport.c| 41 +
>>   15 files changed, 172 insertions(+), 30 deletions(-)
>
>I think this series generally looks good: the only thing I think it's worth 
>checking is whether portio lists are considered exclusive to ISA devices or 
>not

Re: [PATCH v4 10/11] hw/ppc/pegasos2: Let pegasos2 machine configure SuperI/O functions

2024-01-08 Thread Bernhard Beschow



Am 7. Januar 2024 13:54:57 UTC schrieb BALATON Zoltan :
>On Sat, 6 Jan 2024, Bernhard Beschow wrote:
>> This is a preparation for implementing relocation and toggling of SuperI/O
>> functions in the VT8231 device model. Upon reset, all SuperI/O functions 
>> will be
>> deactivated, so in case if no -bios is given, let the machine configure those
>> functions the same way Pegasos II firmware would do.
>> 
>> Signed-off-by: Bernhard Beschow 
>> ---
>> hw/ppc/pegasos2.c | 15 +++
>> 1 file changed, 15 insertions(+)
>> 
>> diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
>> index 3203a4a728..0a40ebd542 100644
>> --- a/hw/ppc/pegasos2.c
>> +++ b/hw/ppc/pegasos2.c
>> @@ -285,6 +285,15 @@ static void 
>> pegasos2_pci_config_write(Pegasos2MachineState *pm, int bus,
>> pegasos2_mv_reg_write(pm, pcicfg + 4, len, val);
>> }
>> 
>> +static void pegasos2_superio_write(Pegasos2MachineState *pm, uint32_t addr,
>> +   uint32_t val)
>> +{
>> +AddressSpace *as = CPU(pm->cpu)->as;
>
>I think this function should not need Pegasos2MachineState *pm and can just 
>use cpu_physical_memory_write() instead.

Okay, I'll change it.

Best regards,
Bernhard

> Otherwise
>
>Reviewed-by: BALATON Zoltan 
>
>> +
>> +stb_phys(as, PCI1_IO_BASE + 0x3f0, addr);
>> +stb_phys(as, PCI1_IO_BASE + 0x3f1, val);
>> +}
>> +
>> static void pegasos2_machine_reset(MachineState *machine, ShutdownCause 
>> reason)
>> {
>> Pegasos2MachineState *pm = PEGASOS2_MACHINE(machine);
>> @@ -310,6 +319,12 @@ static void pegasos2_machine_reset(MachineState 
>> *machine, ShutdownCause reason)
>> 
>> pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
>>   PCI_INTERRUPT_LINE, 2, 0x9);
>> +pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
>> +  0x50, 1, 0x6);
>> +pegasos2_superio_write(pm, 0xf4, 0xbe);
>> +pegasos2_superio_write(pm, 0xf6, 0xef);
>> +pegasos2_superio_write(pm, 0xf7, 0xfc);
>> +pegasos2_superio_write(pm, 0xf2, 0x14);
>> pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
>>   0x50, 1, 0x2);
>> pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
>> 



Re: [PATCH v4 11/11] hw/isa/vt82c686: Implement relocation and toggling of SuperI/O functions

2024-01-08 Thread Bernhard Beschow



Am 7. Januar 2024 13:59:44 UTC schrieb BALATON Zoltan :
>On Sat, 6 Jan 2024, Bernhard Beschow wrote:
>> The VIA south bridges are able to relocate and toggle (enable or disable) 
>> their
>> SuperI/O functions. So far this is hardcoded such that all functions are 
>> always
>> enabled and are located at fixed addresses.
>> 
>> Some PC BIOSes seem to probe for I/O occupancy before activating such a 
>> function
>> and issue an error in case of a conflict. Since the functions are currently
>> enabled on reset, conflicts are always detected. Prevent that by implementing
>> relocation and toggling of the SuperI/O functions.
>> 
>> Note that all SuperI/O functions are now deactivated upon reset (except for
>> VT82C686B's serial ports where Fuloong 2e's rescue-yl seems to expect them 
>> to be
>> enabled by default). Rely on firmware to configure the functions accordingly.
>> 
>> Signed-off-by: Bernhard Beschow 
>> ---
>> hw/isa/vt82c686.c | 66 ---
>> 1 file changed, 56 insertions(+), 10 deletions(-)
>> 
>> diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
>> index d3e0f6d01f..9f62fb5964 100644
>> --- a/hw/isa/vt82c686.c
>> +++ b/hw/isa/vt82c686.c
>> @@ -15,6 +15,9 @@
>> 
>> #include "qemu/osdep.h"
>> #include "hw/isa/vt82c686.h"
>> +#include "hw/block/fdc.h"
>> +#include "hw/char/parallel-isa.h"
>> +#include "hw/char/serial.h"
>> #include "hw/pci/pci.h"
>> #include "hw/qdev-properties.h"
>> #include "hw/ide/pci.h"
>> @@ -323,6 +326,18 @@ static uint64_t via_superio_cfg_read(void *opaque, 
>> hwaddr addr, unsigned size)
>> return val;
>> }
>> 
>> +static void via_superio_devices_enable(ViaSuperIOState *s, uint8_t data)
>> +{
>> +ISASuperIOClass *ic = ISA_SUPERIO_GET_CLASS(s);
>> +size_t i;
>
>The expected value for i is 0 or 1 (maybe up to 3 sometimes it there are more 
>serial ports in a chip). so why use such big type?

serial.count is of type size_t, that's why I chose it. Let me know if you still 
want an int, otherwise I'd leave it as is.

Best regards,
Bernhard

> This should just be int. Newly it's also allowed to declare it within the for 
> so if you want that you could do so but I have no preference on that and 
> declaring it here is also OK. Otherwise:
>
>Reviewed-by: BALATON Zoltan 
>
>> +
>> +isa_parallel_set_enabled(s->superio.parallel[0], (data & 0x3) != 3);
>> +for (i = 0; i < ic->serial.count; i++) {
>> +isa_serial_set_enabled(s->superio.serial[i], data & BIT(i + 2));
>> +}
>> +isa_fdc_set_enabled(s->superio.floppy, data & BIT(4));
>> +}
>> +
>> static void via_superio_class_init(ObjectClass *klass, void *data)
>> {
>> DeviceClass *dc = DEVICE_CLASS(klass);
>> @@ -368,7 +383,25 @@ static void vt82c686b_superio_cfg_write(void *opaque, 
>> hwaddr addr,
>> 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;
>> +via_superio_devices_enable(sc, data);
>> +break;
>> +case 0xe3:
>> +data &= 0xfc;
>> +isa_fdc_set_iobase(sc->superio.floppy, data << 2);
>> +break;
>> +case 0xe6:
>> +isa_parallel_set_iobase(sc->superio.parallel[0], data << 2);
>> +break;
>> +case 0xe7:
>> +data &= 0xfe;
>> +isa_serial_set_iobase(sc->superio.serial[0], data << 2);
>> +break;
>> +case 0xe8:
>> +data &= 0xfe;
>> +isa_serial_set_iobase(sc->superio.serial[1], data << 2);
>> +break;
>> default:
>> qemu_log_mask(LOG_UNIMP,
>>   "via_superio_cfg: unimplemented register 0x%x\n", idx);
>> @@ -395,9 +428,14 @@ static void vt82c686b_superio_reset(DeviceState *dev)
>> /* Device ID */
>> vt82c686b_superio_cfg_write(s, 0, 0xe0, 1);
>> vt82c686b_superio_cfg_write(s, 1, 0x3c, 1);
>> -/* Function select - all disabled */
>> +/*
>> + * Function select - only serial enabled
>> + * Fuloong 2e's rescue-yl prints to the serial console w/o enabling it. 
>> This
>> + * suggests that the serial ports are enabled by default, so over

Re: [PATCH v2 12/12] hw/isa/vt82c686: Implement relocation and toggling of SuperI/O functions

2024-01-06 Thread Bernhard Beschow



Am 3. Januar 2024 12:26:07 UTC schrieb BALATON Zoltan :
>On Tue, 2 Jan 2024, Bernhard Beschow wrote:
>> Am 24. Dezember 2023 00:51:53 UTC schrieb BALATON Zoltan 
>> :
>>> On Tue, 19 Dec 2023, Bernhard Beschow wrote:
>>>> Am 19. Dezember 2023 00:26:15 UTC schrieb BALATON Zoltan 
>>>> :
>>>>> On Mon, 18 Dec 2023, Bernhard Beschow wrote:
>>>>>> The VIA south bridges are able to relocate and toggle (enable or 
>>>>>> disable) their
>>>>>> SuperI/O functions. So far this is hardcoded such that all functions are 
>>>>>> always
>>>>>> enabled and are located at fixed addresses.
>>>>>> 
>>>>>> Some PC BIOSes seem to probe for I/O occupancy before activating such a 
>>>>>> function
>>>>>> and issue an error in case of a conflict. Since the functions are 
>>>>>> enabled on
>>>>>> reset, conflicts are always detected. Prevent that by implementing 
>>>>>> relocation
>>>>>> and toggling of the SuperI/O functions.
>>>>>> 
>>>>>> Note that all SuperI/O functions are now deactivated upon reset (except 
>>>>>> for
>>>>>> VT82C686B's serial ports where Fuloong 2e's rescue-yl seems to expect 
>>>>>> them to be
>>>>>> enabled by default). Rely on firmware -- or in case of pegasos2 on board 
>>>>>> code if
>>>>>> no -bios is given -- to configure the functions accordingly.
>>>>> 
>>>>> Pegasos2 emulates firmware when no -bios is given, this was explained in 
>>>>> previos commit so maybe not needed to be explained it here again so you 
>>>>> could drop the comment between -- -- but I don't mind.
>>>>> 
>>>>>> Signed-off-by: Bernhard Beschow 
>>>>>> ---
>>>>>> hw/isa/vt82c686.c | 121 ++
>>>>>> 1 file changed, 90 insertions(+), 31 deletions(-)
>>>>>> 
>>>>>> diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
>>>>>> index 9c2333a277..be202d23cf 100644
>>>>>> --- a/hw/isa/vt82c686.c
>>>>>> +++ b/hw/isa/vt82c686.c
>>>>>> @@ -15,6 +15,9 @@
>>>>>> 
>>>>>> #include "qemu/osdep.h"
>>>>>> #include "hw/isa/vt82c686.h"
>>>>>> +#include "hw/block/fdc.h"
>>>>>> +#include "hw/char/parallel-isa.h"
>>>>>> +#include "hw/char/serial.h"
>>>>>> #include "hw/pci/pci.h"
>>>>>> #include "hw/qdev-properties.h"
>>>>>> #include "hw/ide/pci.h"
>>>>>> @@ -343,6 +346,35 @@ static const TypeInfo via_superio_info = {
>>>>>> 
>>>>>> #define TYPE_VT82C686B_SUPERIO "vt82c686b-superio"
>>>>>> 
>>>>>> +static void vt82c686b_superio_update(ViaSuperIOState *s)
>>>>>> +{
>>>>>> +isa_parallel_set_enabled(s->superio.parallel[0],
>>>>>> + (s->regs[0xe2] & 0x3) != 3);
>>>>>> +isa_serial_set_enabled(s->superio.serial[0], s->regs[0xe2] & 
>>>>>> BIT(2));
>>>>>> +isa_serial_set_enabled(s->superio.serial[1], s->regs[0xe2] & 
>>>>>> BIT(3));
>>>>>> +isa_fdc_set_enabled(s->superio.floppy, s->regs[0xe2] & BIT(4));
>>>>>> +
>>>>>> +isa_fdc_set_iobase(s->superio.floppy, (s->regs[0xe3] & 0xfc) << 2);
>>>>>> +isa_parallel_set_iobase(s->superio.parallel[0], s->regs[0xe6] << 2);
>>>>>> +isa_serial_set_iobase(s->superio.serial[0], (s->regs[0xe7] & 0xfe) 
>>>>>> << 2);
>>>>>> +isa_serial_set_iobase(s->superio.serial[1], (s->regs[0xe8] & 0xfe) 
>>>>>> << 2);
>>>>>> +}
>>>>> 
>>>>> I wonder if some code duplication could be saved by adding a shared 
>>>>> via_superio_update() for this further up in the abstract via-superio 
>>>>> class instead of this method and vt8231_superio_update() below. This 
>>>>> common method in abstract class would need to handle the differences 
>>>>

[PATCH v4 00/11] hw/isa/vt82c686: Implement relocation and toggling of SuperI/O functions

2024-01-06 Thread Bernhard Beschow
This series implements relocation of the SuperI/O functions of the VIA south
bridges which resolves some FIXME's. It is part of my via-apollo-pro-133t
branch [1] which is an extension of bringing the VIA south bridges to the PC
machine [2]. This branch is able to run some real-world X86 BIOSes in the hope
that it allows us to form a better understanding of the real vt82c686b devices.
Implementing relocation and toggling of the SuperI/O functions is one step to
make these BIOSes run without error messages, so here we go.

The series is structured as follows: Patches 1-3 prepare the TYPE_ISA_FDC,
TYPE_ISA_PARALLEL and TYPE_ISA_SERIAL to relocate and toggle (enable/disable)
themselves without breaking encapsulation of their respective device states.
This is achieved by moving the MemoryRegions and PortioLists from the device
states into the encapsulating ISA devices since they will be relocated and
toggled.

Inspired by the memory API patches 4-6 add two convenience functions to the
portio_list API to toggle and relocate portio lists. Patch 5 is a preparation
for that which removes some redundancies which otherwise had to be dealt with
during relocation.

Patches 7-9 implement toggling and relocation for types TYPE_ISA_FDC,
TYPE_ISA_PARALLEL and TYPE_ISA_SERIAL. Patch 10 prepares the pegasos2 machine
which would end up with all SuperI/O functions disabled if no -bios argument is
given. Patch 11 finally implements the main feature which now relies on
firmware to configure the SuperI/O functions accordingly (except for pegasos2).

v4:
* Drop incomplete SuperI/O vmstate handling (Zoltan)

v3:
* Rework various commit messages (Zoltan)
* Drop patch "hw/char/serial: Free struct SerialState from MemoryRegion"
  (Zoltan)
* Generalize wording in migration.rst to include portio_list API (Zoltan)

v2:
* Improve commit messages (Zoltan)
* Split pegasos2 from vt82c686 patch (Zoltan)
* Avoid poking into device internals (Zoltan)

Testing done:
* `make check`
* `make check-avocado`
* Run MorphOS on pegasos2 with and without pegasos2.rom
* Run Linux on amigaone
* Run real-world BIOSes on via-apollo-pro-133t branch
* Start rescue-yl on fuloong2e

[1] https://github.com/shentok/qemu/tree/via-apollo-pro-133t
[2] https://github.com/shentok/qemu/tree/pc-via

Bernhard Beschow (11):
  hw/block/fdc-isa: Move portio_list from FDCtrl to FDCtrlISABus
  hw/block/fdc-sysbus: Move iomem from FDCtrl to FDCtrlSysBus
  hw/char/parallel: Move portio_list from ParallelState to
ISAParallelState
  exec/ioport: Resolve redundant .base attribute in struct
MemoryRegionPortio
  exec/ioport: Add portio_list_set_address()
  exec/ioport: Add portio_list_set_enabled()
  hw/block/fdc-isa: Implement relocation and enabling/disabling for
TYPE_ISA_FDC
  hw/char/serial-isa: Implement relocation and enabling/disabling for
TYPE_ISA_SERIAL
  hw/char/parallel-isa: Implement relocation and enabling/disabling for
TYPE_ISA_PARALLEL
  hw/ppc/pegasos2: Let pegasos2 machine configure SuperI/O functions
  hw/isa/vt82c686: Implement relocation and toggling of SuperI/O
functions

 docs/devel/migration.rst   |  6 ++--
 hw/block/fdc-internal.h|  4 ---
 include/exec/ioport.h  |  4 ++-
 include/hw/block/fdc.h |  3 ++
 include/hw/char/parallel-isa.h |  5 +++
 include/hw/char/parallel.h |  2 --
 include/hw/char/serial.h   |  2 ++
 hw/block/fdc-isa.c | 18 +-
 hw/block/fdc-sysbus.c  |  6 ++--
 hw/char/parallel-isa.c | 14 
 hw/char/parallel.c |  2 +-
 hw/char/serial-isa.c   | 14 
 hw/isa/vt82c686.c  | 66 --
 hw/ppc/pegasos2.c  | 15 
 system/ioport.c| 41 +
 15 files changed, 172 insertions(+), 30 deletions(-)

-- 
2.43.0




[PATCH v4 06/11] exec/ioport: Add portio_list_set_enabled()

2024-01-06 Thread Bernhard Beschow
Some SuperI/O devices such as the VIA south bridges or the PC87312 controller
allow to enable or disable their SuperI/O functions. Add a convenience function
for implementing this in the VIA south bridges.

The naming of the functions is inspired by its memory_region_set_enabled()
pendant.

Signed-off-by: Bernhard Beschow 
---
 docs/devel/migration.rst | 1 +
 include/exec/ioport.h| 1 +
 system/ioport.c  | 9 +
 3 files changed, 11 insertions(+)

diff --git a/docs/devel/migration.rst b/docs/devel/migration.rst
index 30b05f0f74..1683fc6026 100644
--- a/docs/devel/migration.rst
+++ b/docs/devel/migration.rst
@@ -465,6 +465,7 @@ Examples of such API functions are:
   - memory_region_set_address()
   - memory_region_set_alias_offset()
   - portio_list_set_address()
+  - portio_list_set_enabled()
 
 Iterative device migration
 --
diff --git a/include/exec/ioport.h b/include/exec/ioport.h
index 96858e5ac3..4397f12f93 100644
--- a/include/exec/ioport.h
+++ b/include/exec/ioport.h
@@ -71,6 +71,7 @@ void portio_list_add(PortioList *piolist,
  struct MemoryRegion *address_space,
  uint32_t addr);
 void portio_list_del(PortioList *piolist);
+void portio_list_set_enabled(PortioList *piolist, bool enabled);
 void portio_list_set_address(PortioList *piolist, uint32_t addr);
 
 #endif /* IOPORT_H */
diff --git a/system/ioport.c b/system/ioport.c
index 000e0ee1af..fd551d0375 100644
--- a/system/ioport.c
+++ b/system/ioport.c
@@ -324,6 +324,15 @@ void portio_list_del(PortioList *piolist)
 }
 }
 
+void portio_list_set_enabled(PortioList *piolist, bool enabled)
+{
+unsigned i;
+
+for (i = 0; i < piolist->nr; ++i) {
+memory_region_set_enabled(piolist->regions[i], enabled);
+}
+}
+
 void portio_list_set_address(PortioList *piolist, uint32_t addr)
 {
 MemoryRegionPortioList *mrpio;
-- 
2.43.0




[PATCH v4 03/11] hw/char/parallel: Move portio_list from ParallelState to ISAParallelState

2024-01-06 Thread Bernhard Beschow
ParallelState::portio_list isn't used inside ParallelState context but only
inside ISAParallelState context, so move it there.

Signed-off-by: Bernhard Beschow 
Reviewed-by: BALATON Zoltan 
---
 include/hw/char/parallel-isa.h | 2 ++
 include/hw/char/parallel.h | 2 --
 hw/char/parallel.c | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/include/hw/char/parallel-isa.h b/include/hw/char/parallel-isa.h
index d24ccecf05..3b783bd08d 100644
--- a/include/hw/char/parallel-isa.h
+++ b/include/hw/char/parallel-isa.h
@@ -12,6 +12,7 @@
 
 #include "parallel.h"
 
+#include "exec/ioport.h"
 #include "hw/isa/isa.h"
 #include "qom/object.h"
 
@@ -25,6 +26,7 @@ struct ISAParallelState {
 uint32_t iobase;
 uint32_t isairq;
 ParallelState state;
+PortioList portio_list;
 };
 
 #endif /* HW_PARALLEL_ISA_H */
diff --git a/include/hw/char/parallel.h b/include/hw/char/parallel.h
index 7b5a309a03..cfb97cc7cc 100644
--- a/include/hw/char/parallel.h
+++ b/include/hw/char/parallel.h
@@ -1,7 +1,6 @@
 #ifndef HW_PARALLEL_H
 #define HW_PARALLEL_H
 
-#include "exec/ioport.h"
 #include "exec/memory.h"
 #include "hw/isa/isa.h"
 #include "hw/irq.h"
@@ -22,7 +21,6 @@ typedef struct ParallelState {
 uint32_t last_read_offset; /* For debugging */
 /* Memory-mapped interface */
 int it_shift;
-PortioList portio_list;
 } ParallelState;
 
 void parallel_hds_isa_init(ISABus *bus, int n);
diff --git a/hw/char/parallel.c b/hw/char/parallel.c
index bd488cd7f9..c394635ada 100644
--- a/hw/char/parallel.c
+++ b/hw/char/parallel.c
@@ -532,7 +532,7 @@ static void parallel_isa_realizefn(DeviceState *dev, Error 
**errp)
 s->status = dummy;
 }
 
-isa_register_portio_list(isadev, &s->portio_list, base,
+isa_register_portio_list(isadev, &isa->portio_list, base,
  (s->hw_driver
   ? &isa_parallel_portio_hw_list[0]
   : &isa_parallel_portio_sw_list[0]),
-- 
2.43.0




[PATCH v4 04/11] exec/ioport: Resolve redundant .base attribute in struct MemoryRegionPortio

2024-01-06 Thread Bernhard Beschow
portio_list_add_1() creates a MemoryRegionPortioList instance which holds a
MemoryRegion `mr` and an array of MemoryRegionPortio elements named `ports`.
Each element in the array gets assigned the same value for its .base attribute.
The same value also ends up as the .addr attribute of `mr` due to the
memory_region_add_subregion() call. This means that all .base attributes are
the same as `mr.addr`.

The only usages of MemoryRegionPortio::base were in portio_read() and
portio_write(). Both functions get above MemoryRegionPortioList as their
opaque parameter. In both cases find_portio() can only return one of the
MemoryRegionPortio elements of the `ports` array. Due to above observation any
element will have the same .base value equal to `mr.addr` which is also
accessible.

Hence, `mrpio->mr.addr` is equivalent to `mrp->base` and
MemoryRegionPortio::base is redundant and can be removed.

Signed-off-by: Bernhard Beschow 
---
 include/exec/ioport.h |  1 -
 system/ioport.c   | 13 ++---
 2 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/include/exec/ioport.h b/include/exec/ioport.h
index e34f668998..95f1dc30d0 100644
--- a/include/exec/ioport.h
+++ b/include/exec/ioport.h
@@ -35,7 +35,6 @@ typedef struct MemoryRegionPortio {
 unsigned size;
 uint32_t (*read)(void *opaque, uint32_t address);
 void (*write)(void *opaque, uint32_t address, uint32_t data);
-uint32_t base; /* private field */
 } MemoryRegionPortio;
 
 #define PORTIO_END_OF_LIST() { }
diff --git a/system/ioport.c b/system/ioport.c
index 1824aa808c..a59e58b716 100644
--- a/system/ioport.c
+++ b/system/ioport.c
@@ -181,13 +181,13 @@ static uint64_t portio_read(void *opaque, hwaddr addr, 
unsigned size)
 
 data = ((uint64_t)1 << (size * 8)) - 1;
 if (mrp) {
-data = mrp->read(mrpio->portio_opaque, mrp->base + addr);
+data = mrp->read(mrpio->portio_opaque, mrpio->mr.addr + addr);
 } else if (size == 2) {
 mrp = find_portio(mrpio, addr, 1, false);
 if (mrp) {
-data = mrp->read(mrpio->portio_opaque, mrp->base + addr);
+data = mrp->read(mrpio->portio_opaque, mrpio->mr.addr + addr);
 if (addr + 1 < mrp->offset + mrp->len) {
-data |= mrp->read(mrpio->portio_opaque, mrp->base + addr + 1) 
<< 8;
+data |= mrp->read(mrpio->portio_opaque, mrpio->mr.addr + addr 
+ 1) << 8;
 } else {
 data |= 0xff00;
 }
@@ -203,13 +203,13 @@ static void portio_write(void *opaque, hwaddr addr, 
uint64_t data,
 const MemoryRegionPortio *mrp = find_portio(mrpio, addr, size, true);
 
 if (mrp) {
-mrp->write(mrpio->portio_opaque, mrp->base + addr, data);
+mrp->write(mrpio->portio_opaque, mrpio->mr.addr + addr, data);
 } else if (size == 2) {
 mrp = find_portio(mrpio, addr, 1, true);
 if (mrp) {
-mrp->write(mrpio->portio_opaque, mrp->base + addr, data & 0xff);
+mrp->write(mrpio->portio_opaque, mrpio->mr.addr + addr, data & 
0xff);
 if (addr + 1 < mrp->offset + mrp->len) {
-mrp->write(mrpio->portio_opaque, mrp->base + addr + 1, data >> 
8);
+mrp->write(mrpio->portio_opaque, mrpio->mr.addr + addr + 1, 
data >> 8);
 }
 }
 }
@@ -244,7 +244,6 @@ static void portio_list_add_1(PortioList *piolist,
 /* Adjust the offsets to all be zero-based for the region.  */
 for (i = 0; i < count; ++i) {
 mrpio->ports[i].offset -= off_low;
-mrpio->ports[i].base = start + off_low;
 }
 
 /*
-- 
2.43.0




[PATCH v4 08/11] hw/char/serial-isa: Implement relocation and enabling/disabling for TYPE_ISA_SERIAL

2024-01-06 Thread Bernhard Beschow
The real SuperI/O chips emulated by QEMU allow for relocating and enabling or
disabling their SuperI/O functions via software. So far this is not implemented.
Prepare for that by adding isa_serial_set_{enabled,iobase}.

Signed-off-by: Bernhard Beschow 
---
 include/hw/char/serial.h |  2 ++
 hw/char/serial-isa.c | 14 ++
 2 files changed, 16 insertions(+)

diff --git a/include/hw/char/serial.h b/include/hw/char/serial.h
index 8ba7eca3d6..6e14099ee7 100644
--- a/include/hw/char/serial.h
+++ b/include/hw/char/serial.h
@@ -112,5 +112,7 @@ SerialMM *serial_mm_init(MemoryRegion *address_space,
 
 #define TYPE_ISA_SERIAL "isa-serial"
 void serial_hds_isa_init(ISABus *bus, int from, int to);
+void isa_serial_set_iobase(ISADevice *serial, hwaddr iobase);
+void isa_serial_set_enabled(ISADevice *serial, bool enabled);
 
 #endif
diff --git a/hw/char/serial-isa.c b/hw/char/serial-isa.c
index 1c793b20f7..329b352b9a 100644
--- a/hw/char/serial-isa.c
+++ b/hw/char/serial-isa.c
@@ -184,3 +184,17 @@ void serial_hds_isa_init(ISABus *bus, int from, int to)
 }
 }
 }
+
+void isa_serial_set_iobase(ISADevice *serial, hwaddr iobase)
+{
+ISASerialState *s = ISA_SERIAL(serial);
+
+serial->ioport_id = iobase;
+s->iobase = iobase;
+memory_region_set_address(&s->state.io, s->iobase);
+}
+
+void isa_serial_set_enabled(ISADevice *serial, bool enabled)
+{
+memory_region_set_enabled(&ISA_SERIAL(serial)->state.io, enabled);
+}
-- 
2.43.0




[PATCH v4 10/11] hw/ppc/pegasos2: Let pegasos2 machine configure SuperI/O functions

2024-01-06 Thread Bernhard Beschow
This is a preparation for implementing relocation and toggling of SuperI/O
functions in the VT8231 device model. Upon reset, all SuperI/O functions will be
deactivated, so in case if no -bios is given, let the machine configure those
functions the same way Pegasos II firmware would do.

Signed-off-by: Bernhard Beschow 
---
 hw/ppc/pegasos2.c | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
index 3203a4a728..0a40ebd542 100644
--- a/hw/ppc/pegasos2.c
+++ b/hw/ppc/pegasos2.c
@@ -285,6 +285,15 @@ static void pegasos2_pci_config_write(Pegasos2MachineState 
*pm, int bus,
 pegasos2_mv_reg_write(pm, pcicfg + 4, len, val);
 }
 
+static void pegasos2_superio_write(Pegasos2MachineState *pm, uint32_t addr,
+   uint32_t val)
+{
+AddressSpace *as = CPU(pm->cpu)->as;
+
+stb_phys(as, PCI1_IO_BASE + 0x3f0, addr);
+stb_phys(as, PCI1_IO_BASE + 0x3f1, val);
+}
+
 static void pegasos2_machine_reset(MachineState *machine, ShutdownCause reason)
 {
 Pegasos2MachineState *pm = PEGASOS2_MACHINE(machine);
@@ -310,6 +319,12 @@ static void pegasos2_machine_reset(MachineState *machine, 
ShutdownCause reason)
 
 pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
   PCI_INTERRUPT_LINE, 2, 0x9);
+pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
+  0x50, 1, 0x6);
+pegasos2_superio_write(pm, 0xf4, 0xbe);
+pegasos2_superio_write(pm, 0xf6, 0xef);
+pegasos2_superio_write(pm, 0xf7, 0xfc);
+pegasos2_superio_write(pm, 0xf2, 0x14);
 pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
   0x50, 1, 0x2);
 pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
-- 
2.43.0




[PATCH v4 05/11] exec/ioport: Add portio_list_set_address()

2024-01-06 Thread Bernhard Beschow
Some SuperI/O devices such as the VIA south bridges or the PC87312 controller
are able to relocate their SuperI/O functions. Add a convenience function for
implementing this in the VIA south bridges.

This convenience function relies on previous simplifications in exec/ioport
which avoids some duplicate synchronization of I/O port base addresses. The
naming of the function is inspired by its memory_region_set_address() pendant.

Signed-off-by: Bernhard Beschow 
---
 docs/devel/migration.rst |  5 +++--
 include/exec/ioport.h|  2 ++
 system/ioport.c  | 19 +++
 3 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/docs/devel/migration.rst b/docs/devel/migration.rst
index 95351ba51f..30b05f0f74 100644
--- a/docs/devel/migration.rst
+++ b/docs/devel/migration.rst
@@ -452,10 +452,10 @@ data doesn't match the stored device data well; it allows 
an
 intermediate temporary structure to be populated with migration
 data and then transferred to the main structure.
 
-If you use memory API functions that update memory layout outside
+If you use memory or portio_list API functions that update memory layout 
outside
 initialization (i.e., in response to a guest action), this is a strong
 indication that you need to call these functions in a ``post_load`` callback.
-Examples of such memory API functions are:
+Examples of such API functions are:
 
   - memory_region_add_subregion()
   - memory_region_del_subregion()
@@ -464,6 +464,7 @@ Examples of such memory API functions are:
   - memory_region_set_enabled()
   - memory_region_set_address()
   - memory_region_set_alias_offset()
+  - portio_list_set_address()
 
 Iterative device migration
 --
diff --git a/include/exec/ioport.h b/include/exec/ioport.h
index 95f1dc30d0..96858e5ac3 100644
--- a/include/exec/ioport.h
+++ b/include/exec/ioport.h
@@ -54,6 +54,7 @@ typedef struct PortioList {
 const struct MemoryRegionPortio *ports;
 Object *owner;
 struct MemoryRegion *address_space;
+uint32_t addr;
 unsigned nr;
 struct MemoryRegion **regions;
 void *opaque;
@@ -70,5 +71,6 @@ void portio_list_add(PortioList *piolist,
  struct MemoryRegion *address_space,
  uint32_t addr);
 void portio_list_del(PortioList *piolist);
+void portio_list_set_address(PortioList *piolist, uint32_t addr);
 
 #endif /* IOPORT_H */
diff --git a/system/ioport.c b/system/ioport.c
index a59e58b716..000e0ee1af 100644
--- a/system/ioport.c
+++ b/system/ioport.c
@@ -133,6 +133,7 @@ void portio_list_init(PortioList *piolist,
 piolist->nr = 0;
 piolist->regions = g_new0(MemoryRegion *, n);
 piolist->address_space = NULL;
+piolist->addr = 0;
 piolist->opaque = opaque;
 piolist->owner = owner;
 piolist->name = name;
@@ -282,6 +283,7 @@ void portio_list_add(PortioList *piolist,
 unsigned int off_low, off_high, off_last, count;
 
 piolist->address_space = address_space;
+piolist->addr = start;
 
 /* Handle the first entry specially.  */
 off_last = off_low = pio_start->offset;
@@ -322,6 +324,23 @@ void portio_list_del(PortioList *piolist)
 }
 }
 
+void portio_list_set_address(PortioList *piolist, uint32_t addr)
+{
+MemoryRegionPortioList *mrpio;
+unsigned i, j;
+
+for (i = 0; i < piolist->nr; ++i) {
+mrpio = container_of(piolist->regions[i], MemoryRegionPortioList, mr);
+memory_region_set_address(&mrpio->mr,
+  mrpio->mr.addr - piolist->addr + addr);
+for (j = 0; mrpio->ports[j].size; ++j) {
+mrpio->ports[j].offset += addr - piolist->addr;
+}
+}
+
+piolist->addr = addr;
+}
+
 static void memory_region_portio_list_finalize(Object *obj)
 {
 MemoryRegionPortioList *mrpio = MEMORY_REGION_PORTIO_LIST(obj);
-- 
2.43.0




[PATCH v4 01/11] hw/block/fdc-isa: Move portio_list from FDCtrl to FDCtrlISABus

2024-01-06 Thread Bernhard Beschow
FDCtrl::portio_list isn't used inside FDCtrl context but only inside
FDCtrlISABus context, so move it there.

Signed-off-by: Bernhard Beschow 
Reviewed-by: BALATON Zoltan 
---
 hw/block/fdc-internal.h | 2 --
 hw/block/fdc-isa.c  | 4 +++-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/block/fdc-internal.h b/hw/block/fdc-internal.h
index 036392e9fc..fef2bfbbf5 100644
--- a/hw/block/fdc-internal.h
+++ b/hw/block/fdc-internal.h
@@ -26,7 +26,6 @@
 #define HW_BLOCK_FDC_INTERNAL_H
 
 #include "exec/memory.h"
-#include "exec/ioport.h"
 #include "hw/block/block.h"
 #include "hw/block/fdc.h"
 #include "qapi/qapi-types-block.h"
@@ -140,7 +139,6 @@ struct FDCtrl {
 /* Timers state */
 uint8_t timer0;
 uint8_t timer1;
-PortioList portio_list;
 };
 
 extern const FDFormat fd_formats[];
diff --git a/hw/block/fdc-isa.c b/hw/block/fdc-isa.c
index ad0921c7d3..2d8a98ce7d 100644
--- a/hw/block/fdc-isa.c
+++ b/hw/block/fdc-isa.c
@@ -42,6 +42,7 @@
 #include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "sysemu/sysemu.h"
+#include "exec/ioport.h"
 #include "qemu/log.h"
 #include "qemu/main-loop.h"
 #include "qemu/module.h"
@@ -60,6 +61,7 @@ struct FDCtrlISABus {
 uint32_t irq;
 uint32_t dma;
 struct FDCtrl state;
+PortioList portio_list;
 int32_t bootindexA;
 int32_t bootindexB;
 };
@@ -91,7 +93,7 @@ static void isabus_fdc_realize(DeviceState *dev, Error **errp)
 FDCtrl *fdctrl = &isa->state;
 Error *err = NULL;
 
-isa_register_portio_list(isadev, &fdctrl->portio_list,
+isa_register_portio_list(isadev, &isa->portio_list,
  isa->iobase, fdc_portio_list, fdctrl,
  "fdc");
 
-- 
2.43.0




[PATCH v4 02/11] hw/block/fdc-sysbus: Move iomem from FDCtrl to FDCtrlSysBus

2024-01-06 Thread Bernhard Beschow
FDCtrl::iomem isn't used inside FDCtrl context but only inside FDCtrlSysBus
context, so move it there.

Signed-off-by: Bernhard Beschow 
Reviewed-by: BALATON Zoltan 
---
 hw/block/fdc-internal.h | 2 --
 hw/block/fdc-sysbus.c   | 6 --
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/block/fdc-internal.h b/hw/block/fdc-internal.h
index fef2bfbbf5..e219623dc7 100644
--- a/hw/block/fdc-internal.h
+++ b/hw/block/fdc-internal.h
@@ -25,7 +25,6 @@
 #ifndef HW_BLOCK_FDC_INTERNAL_H
 #define HW_BLOCK_FDC_INTERNAL_H
 
-#include "exec/memory.h"
 #include "hw/block/block.h"
 #include "hw/block/fdc.h"
 #include "qapi/qapi-types-block.h"
@@ -91,7 +90,6 @@ typedef struct FDrive {
 } FDrive;
 
 struct FDCtrl {
-MemoryRegion iomem;
 qemu_irq irq;
 /* Controller state */
 QEMUTimer *result_timer;
diff --git a/hw/block/fdc-sysbus.c b/hw/block/fdc-sysbus.c
index 266bc4d145..035bc08975 100644
--- a/hw/block/fdc-sysbus.c
+++ b/hw/block/fdc-sysbus.c
@@ -26,6 +26,7 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "qom/object.h"
+#include "exec/memory.h"
 #include "hw/sysbus.h"
 #include "hw/block/fdc.h"
 #include "migration/vmstate.h"
@@ -52,6 +53,7 @@ struct FDCtrlSysBus {
 /*< public >*/
 
 struct FDCtrl state;
+MemoryRegion iomem;
 };
 
 static uint64_t fdctrl_read_mem(void *opaque, hwaddr reg, unsigned ize)
@@ -146,11 +148,11 @@ static void sysbus_fdc_common_instance_init(Object *obj)
 
 qdev_set_legacy_instance_id(dev, 0 /* io */, 2); /* FIXME */
 
-memory_region_init_io(&fdctrl->iomem, obj,
+memory_region_init_io(&sys->iomem, obj,
   sbdc->use_strict_io ? &fdctrl_mem_strict_ops
   : &fdctrl_mem_ops,
   fdctrl, "fdc", 0x08);
-sysbus_init_mmio(sbd, &fdctrl->iomem);
+sysbus_init_mmio(sbd, &sys->iomem);
 
 sysbus_init_irq(sbd, &fdctrl->irq);
 qdev_init_gpio_in(dev, fdctrl_handle_tc, 1);
-- 
2.43.0




[PATCH v4 07/11] hw/block/fdc-isa: Implement relocation and enabling/disabling for TYPE_ISA_FDC

2024-01-06 Thread Bernhard Beschow
The real SuperI/O chips emulated by QEMU allow for relocating and enabling or
disabling their SuperI/O functions via software. So far this is not implemented.
Prepare for that by adding isa_fdc_set_{enabled,iobase}.

Signed-off-by: Bernhard Beschow 
---
 include/hw/block/fdc.h |  3 +++
 hw/block/fdc-isa.c | 14 ++
 2 files changed, 17 insertions(+)

diff --git a/include/hw/block/fdc.h b/include/hw/block/fdc.h
index 35248c0837..c367c5efea 100644
--- a/include/hw/block/fdc.h
+++ b/include/hw/block/fdc.h
@@ -14,6 +14,9 @@ void fdctrl_init_sysbus(qemu_irq irq, hwaddr mmio_base, 
DriveInfo **fds);
 void sun4m_fdctrl_init(qemu_irq irq, hwaddr io_base,
DriveInfo **fds, qemu_irq *fdc_tc);
 
+void isa_fdc_set_iobase(ISADevice *fdc, hwaddr iobase);
+void isa_fdc_set_enabled(ISADevice *fdc, bool enabled);
+
 FloppyDriveType isa_fdc_get_drive_type(ISADevice *fdc, int i);
 int cmos_get_fd_drive_type(FloppyDriveType fd0);
 
diff --git a/hw/block/fdc-isa.c b/hw/block/fdc-isa.c
index 2d8a98ce7d..e43dc532af 100644
--- a/hw/block/fdc-isa.c
+++ b/hw/block/fdc-isa.c
@@ -192,6 +192,20 @@ static Aml *build_fdinfo_aml(int idx, FloppyDriveType type)
 return dev;
 }
 
+void isa_fdc_set_iobase(ISADevice *fdc, hwaddr iobase)
+{
+FDCtrlISABus *isa = ISA_FDC(fdc);
+
+fdc->ioport_id = iobase;
+isa->iobase = iobase;
+portio_list_set_address(&isa->portio_list, isa->iobase);
+}
+
+void isa_fdc_set_enabled(ISADevice *fdc, bool enabled)
+{
+portio_list_set_enabled(&ISA_FDC(fdc)->portio_list, enabled);
+}
+
 int cmos_get_fd_drive_type(FloppyDriveType fd0)
 {
 int val;
-- 
2.43.0




[PATCH v4 11/11] hw/isa/vt82c686: Implement relocation and toggling of SuperI/O functions

2024-01-06 Thread Bernhard Beschow
The VIA south bridges are able to relocate and toggle (enable or disable) their
SuperI/O functions. So far this is hardcoded such that all functions are always
enabled and are located at fixed addresses.

Some PC BIOSes seem to probe for I/O occupancy before activating such a function
and issue an error in case of a conflict. Since the functions are currently
enabled on reset, conflicts are always detected. Prevent that by implementing
relocation and toggling of the SuperI/O functions.

Note that all SuperI/O functions are now deactivated upon reset (except for
VT82C686B's serial ports where Fuloong 2e's rescue-yl seems to expect them to be
enabled by default). Rely on firmware to configure the functions accordingly.

Signed-off-by: Bernhard Beschow 
---
 hw/isa/vt82c686.c | 66 ---
 1 file changed, 56 insertions(+), 10 deletions(-)

diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index d3e0f6d01f..9f62fb5964 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -15,6 +15,9 @@
 
 #include "qemu/osdep.h"
 #include "hw/isa/vt82c686.h"
+#include "hw/block/fdc.h"
+#include "hw/char/parallel-isa.h"
+#include "hw/char/serial.h"
 #include "hw/pci/pci.h"
 #include "hw/qdev-properties.h"
 #include "hw/ide/pci.h"
@@ -323,6 +326,18 @@ static uint64_t via_superio_cfg_read(void *opaque, hwaddr 
addr, unsigned size)
 return val;
 }
 
+static void via_superio_devices_enable(ViaSuperIOState *s, uint8_t data)
+{
+ISASuperIOClass *ic = ISA_SUPERIO_GET_CLASS(s);
+size_t i;
+
+isa_parallel_set_enabled(s->superio.parallel[0], (data & 0x3) != 3);
+for (i = 0; i < ic->serial.count; i++) {
+isa_serial_set_enabled(s->superio.serial[i], data & BIT(i + 2));
+}
+isa_fdc_set_enabled(s->superio.floppy, data & BIT(4));
+}
+
 static void via_superio_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
@@ -368,7 +383,25 @@ static void vt82c686b_superio_cfg_write(void *opaque, 
hwaddr addr,
 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;
+via_superio_devices_enable(sc, data);
+break;
+case 0xe3:
+data &= 0xfc;
+isa_fdc_set_iobase(sc->superio.floppy, data << 2);
+break;
+case 0xe6:
+isa_parallel_set_iobase(sc->superio.parallel[0], data << 2);
+break;
+case 0xe7:
+data &= 0xfe;
+isa_serial_set_iobase(sc->superio.serial[0], data << 2);
+break;
+case 0xe8:
+data &= 0xfe;
+isa_serial_set_iobase(sc->superio.serial[1], data << 2);
+break;
 default:
 qemu_log_mask(LOG_UNIMP,
   "via_superio_cfg: unimplemented register 0x%x\n", idx);
@@ -395,9 +428,14 @@ static void vt82c686b_superio_reset(DeviceState *dev)
 /* Device ID */
 vt82c686b_superio_cfg_write(s, 0, 0xe0, 1);
 vt82c686b_superio_cfg_write(s, 1, 0x3c, 1);
-/* Function select - all disabled */
+/*
+ * Function select - only serial enabled
+ * Fuloong 2e's rescue-yl prints to the serial console w/o enabling it. 
This
+ * suggests that the serial ports are enabled by default, so override the
+ * datasheet.
+ */
 vt82c686b_superio_cfg_write(s, 0, 0xe2, 1);
-vt82c686b_superio_cfg_write(s, 1, 0x03, 1);
+vt82c686b_superio_cfg_write(s, 1, 0x0f, 1);
 /* Floppy ctrl base addr 0x3f0-7 */
 vt82c686b_superio_cfg_write(s, 0, 0xe3, 1);
 vt82c686b_superio_cfg_write(s, 1, 0xfc, 1);
@@ -465,6 +503,21 @@ static void vt8231_superio_cfg_write(void *opaque, hwaddr 
addr,
 case 0xfd:
 /* ignore write to read only registers */
 return;
+case 0xf2:
+data &= 0x17;
+via_superio_devices_enable(sc, data);
+break;
+case 0xf4:
+data &= 0xfe;
+isa_serial_set_iobase(sc->superio.serial[0], data << 2);
+break;
+case 0xf6:
+isa_parallel_set_iobase(sc->superio.parallel[0], data << 2);
+break;
+case 0xf7:
+data &= 0xfc;
+isa_fdc_set_iobase(sc->superio.floppy, data << 2);
+break;
 default:
 qemu_log_mask(LOG_UNIMP,
   "via_superio_cfg: unimplemented register 0x%x\n", idx);
@@ -513,12 +566,6 @@ static void vt8231_superio_init(Object *obj)
 VIA_SUPERIO(obj)->io_ops = &vt8231_superio_cfg_ops;
 }
 
-static uint16_t vt8231_superio_serial_iobase(ISASuperIODevice *sio,
- uint8_t index)
-{
-return 0x2f8; /* FIXME: This should be settable via registers f2-f4 */
-}
-
 static void vt8231_superio_class_i

[PATCH v4 09/11] hw/char/parallel-isa: Implement relocation and enabling/disabling for TYPE_ISA_PARALLEL

2024-01-06 Thread Bernhard Beschow
The real SuperI/O chips emulated by QEMU allow for relocating and enabling or
disabling their SuperI/O functions via software. So far this is not implemented.
Prepare for that by adding isa_parallel_set_{enabled,iobase}.

Signed-off-by: Bernhard Beschow 
---
 include/hw/char/parallel-isa.h |  3 +++
 hw/char/parallel-isa.c | 14 ++
 2 files changed, 17 insertions(+)

diff --git a/include/hw/char/parallel-isa.h b/include/hw/char/parallel-isa.h
index 3b783bd08d..5284b2ffec 100644
--- a/include/hw/char/parallel-isa.h
+++ b/include/hw/char/parallel-isa.h
@@ -29,4 +29,7 @@ struct ISAParallelState {
 PortioList portio_list;
 };
 
+void isa_parallel_set_iobase(ISADevice *parallel, hwaddr iobase);
+void isa_parallel_set_enabled(ISADevice *parallel, bool enabled);
+
 #endif /* HW_PARALLEL_ISA_H */
diff --git a/hw/char/parallel-isa.c b/hw/char/parallel-isa.c
index ab0f879998..a5ce6ee13a 100644
--- a/hw/char/parallel-isa.c
+++ b/hw/char/parallel-isa.c
@@ -41,3 +41,17 @@ void parallel_hds_isa_init(ISABus *bus, int n)
 }
 }
 }
+
+void isa_parallel_set_iobase(ISADevice *parallel, hwaddr iobase)
+{
+ISAParallelState *s = ISA_PARALLEL(parallel);
+
+parallel->ioport_id = iobase;
+s->iobase = iobase;
+portio_list_set_address(&s->portio_list, s->iobase);
+}
+
+void isa_parallel_set_enabled(ISADevice *parallel, bool enabled)
+{
+portio_list_set_enabled(&ISA_PARALLEL(parallel)->portio_list, enabled);
+}
-- 
2.43.0




Re: [PATCH v2 12/12] hw/isa/vt82c686: Implement relocation and toggling of SuperI/O functions

2024-01-02 Thread Bernhard Beschow



Am 24. Dezember 2023 00:51:53 UTC schrieb BALATON Zoltan :
>On Tue, 19 Dec 2023, Bernhard Beschow wrote:
>> Am 19. Dezember 2023 00:26:15 UTC schrieb BALATON Zoltan 
>> :
>>> On Mon, 18 Dec 2023, Bernhard Beschow wrote:
>>>> The VIA south bridges are able to relocate and toggle (enable or disable) 
>>>> their
>>>> SuperI/O functions. So far this is hardcoded such that all functions are 
>>>> always
>>>> enabled and are located at fixed addresses.
>>>> 
>>>> Some PC BIOSes seem to probe for I/O occupancy before activating such a 
>>>> function
>>>> and issue an error in case of a conflict. Since the functions are enabled 
>>>> on
>>>> reset, conflicts are always detected. Prevent that by implementing 
>>>> relocation
>>>> and toggling of the SuperI/O functions.
>>>> 
>>>> Note that all SuperI/O functions are now deactivated upon reset (except for
>>>> VT82C686B's serial ports where Fuloong 2e's rescue-yl seems to expect them 
>>>> to be
>>>> enabled by default). Rely on firmware -- or in case of pegasos2 on board 
>>>> code if
>>>> no -bios is given -- to configure the functions accordingly.
>>> 
>>> Pegasos2 emulates firmware when no -bios is given, this was explained in 
>>> previos commit so maybe not needed to be explained it here again so you 
>>> could drop the comment between -- -- but I don't mind.
>>> 
>>>> Signed-off-by: Bernhard Beschow 
>>>> ---
>>>> hw/isa/vt82c686.c | 121 ++
>>>> 1 file changed, 90 insertions(+), 31 deletions(-)
>>>> 
>>>> diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
>>>> index 9c2333a277..be202d23cf 100644
>>>> --- a/hw/isa/vt82c686.c
>>>> +++ b/hw/isa/vt82c686.c
>>>> @@ -15,6 +15,9 @@
>>>> 
>>>> #include "qemu/osdep.h"
>>>> #include "hw/isa/vt82c686.h"
>>>> +#include "hw/block/fdc.h"
>>>> +#include "hw/char/parallel-isa.h"
>>>> +#include "hw/char/serial.h"
>>>> #include "hw/pci/pci.h"
>>>> #include "hw/qdev-properties.h"
>>>> #include "hw/ide/pci.h"
>>>> @@ -343,6 +346,35 @@ static const TypeInfo via_superio_info = {
>>>> 
>>>> #define TYPE_VT82C686B_SUPERIO "vt82c686b-superio"
>>>> 
>>>> +static void vt82c686b_superio_update(ViaSuperIOState *s)
>>>> +{
>>>> +isa_parallel_set_enabled(s->superio.parallel[0],
>>>> + (s->regs[0xe2] & 0x3) != 3);
>>>> +isa_serial_set_enabled(s->superio.serial[0], s->regs[0xe2] & BIT(2));
>>>> +isa_serial_set_enabled(s->superio.serial[1], s->regs[0xe2] & BIT(3));
>>>> +isa_fdc_set_enabled(s->superio.floppy, s->regs[0xe2] & BIT(4));
>>>> +
>>>> +isa_fdc_set_iobase(s->superio.floppy, (s->regs[0xe3] & 0xfc) << 2);
>>>> +isa_parallel_set_iobase(s->superio.parallel[0], s->regs[0xe6] << 2);
>>>> +isa_serial_set_iobase(s->superio.serial[0], (s->regs[0xe7] & 0xfe) << 
>>>> 2);
>>>> +isa_serial_set_iobase(s->superio.serial[1], (s->regs[0xe8] & 0xfe) << 
>>>> 2);
>>>> +}
>>> 
>>> I wonder if some code duplication could be saved by adding a shared 
>>> via_superio_update() for this further up in the abstract via-superio class 
>>> instead of this method and vt8231_superio_update() below. This common 
>>> method in abstract class would need to handle the differences which seem to 
>>> be reg addresses offset by 0x10 and VT8231 having only 1 serial port. These 
>>> could either be handled by adding function parameters or fields to 
>>> ViaSuperIOState for this that the subclasses can set and the method check. 
>>> (Such as reg base=0xe2 for vt82c686 and 0xf2 for vt8231 and num_serial or 
>>> similar for how many ports are there then can have a for loop for those 
>>> that would only run once for vt8231).
>> 
>> Only the enable bits and the parallel port base address line up, the serial 
>> port(s) and the floppy would need special treatment. Not worth it IMO.
>
>Missed this part in previous reply. The serial ports would be taken care of by 
>a loop for number of ports s

Re: [PATCH v2 1/5] system/cpus: rename qemu_mutex_lock_iothread() to bql_lock()

2024-01-02 Thread Bernhard Beschow



Am 12. Dezember 2023 15:39:00 UTC schrieb Stefan Hajnoczi :
>The Big QEMU Lock (BQL) has many names and they are confusing. The
>actual QemuMutex variable is called qemu_global_mutex but it's commonly
>referred to as the BQL in discussions and some code comments. The
>locking APIs, however, are called qemu_mutex_lock_iothread() and
>qemu_mutex_unlock_iothread().
>
>The "iothread" name is historic and comes from when the main thread was
>split into into KVM vcpu threads and the "iothread" (now called the main

Duplicate "into" here.

>loop thread). I have contributed to the confusion myself by introducing
>a separate --object iothread, a separate concept unrelated to the BQL.
>
>The "iothread" name is no longer appropriate for the BQL. Rename the
>locking APIs to:
>- void bql_lock(void)
>- void bql_unlock(void)
>- bool bql_locked(void)
>
>There are more APIs with "iothread" in their names. Subsequent patches
>will rename them. There are also comments and documentation that will be
>updated in later patches.
>
>Signed-off-by: Stefan Hajnoczi 
>Reviewed-by: Paul Durrant 
>Acked-by: Fabiano Rosas 
>Acked-by: David Woodhouse 
>Reviewed-by: Cédric Le Goater 
>Acked-by: Peter Xu 
>Acked-by: Eric Farman 
>Reviewed-by: Harsh Prateek Bora 



[PATCH v3 09/11] hw/char/parallel-isa: Implement relocation and enabling/disabling for TYPE_ISA_PARALLEL

2023-12-21 Thread Bernhard Beschow
The real SuperI/O chips emulated by QEMU allow for relocating and enabling or
disabling their SuperI/O functions via software. So far this is not implemented.
Prepare for that by adding isa_parallel_set_{enabled,iobase}.

Signed-off-by: Bernhard Beschow 
---
 include/hw/char/parallel-isa.h |  3 +++
 hw/char/parallel-isa.c | 14 ++
 2 files changed, 17 insertions(+)

diff --git a/include/hw/char/parallel-isa.h b/include/hw/char/parallel-isa.h
index 3b783bd08d..5284b2ffec 100644
--- a/include/hw/char/parallel-isa.h
+++ b/include/hw/char/parallel-isa.h
@@ -29,4 +29,7 @@ struct ISAParallelState {
 PortioList portio_list;
 };
 
+void isa_parallel_set_iobase(ISADevice *parallel, hwaddr iobase);
+void isa_parallel_set_enabled(ISADevice *parallel, bool enabled);
+
 #endif /* HW_PARALLEL_ISA_H */
diff --git a/hw/char/parallel-isa.c b/hw/char/parallel-isa.c
index ab0f879998..a5ce6ee13a 100644
--- a/hw/char/parallel-isa.c
+++ b/hw/char/parallel-isa.c
@@ -41,3 +41,17 @@ void parallel_hds_isa_init(ISABus *bus, int n)
 }
 }
 }
+
+void isa_parallel_set_iobase(ISADevice *parallel, hwaddr iobase)
+{
+ISAParallelState *s = ISA_PARALLEL(parallel);
+
+parallel->ioport_id = iobase;
+s->iobase = iobase;
+portio_list_set_address(&s->portio_list, s->iobase);
+}
+
+void isa_parallel_set_enabled(ISADevice *parallel, bool enabled)
+{
+portio_list_set_enabled(&ISA_PARALLEL(parallel)->portio_list, enabled);
+}
-- 
2.43.0




[PATCH v3 10/11] hw/ppc/pegasos2: Let pegasos2 machine configure SuperI/O functions

2023-12-21 Thread Bernhard Beschow
This is a preparation for implementing relocation and toggling of SuperI/O
functions in the VT8231 device model. Upon reset, all SuperI/O functions will be
deactivated, so in case if no -bios is given, let the machine configure those
functions the same way Pegasos II firmware would do.

Signed-off-by: Bernhard Beschow 
---
 hw/ppc/pegasos2.c | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
index 3203a4a728..0a40ebd542 100644
--- a/hw/ppc/pegasos2.c
+++ b/hw/ppc/pegasos2.c
@@ -285,6 +285,15 @@ static void pegasos2_pci_config_write(Pegasos2MachineState 
*pm, int bus,
 pegasos2_mv_reg_write(pm, pcicfg + 4, len, val);
 }
 
+static void pegasos2_superio_write(Pegasos2MachineState *pm, uint32_t addr,
+   uint32_t val)
+{
+AddressSpace *as = CPU(pm->cpu)->as;
+
+stb_phys(as, PCI1_IO_BASE + 0x3f0, addr);
+stb_phys(as, PCI1_IO_BASE + 0x3f1, val);
+}
+
 static void pegasos2_machine_reset(MachineState *machine, ShutdownCause reason)
 {
 Pegasos2MachineState *pm = PEGASOS2_MACHINE(machine);
@@ -310,6 +319,12 @@ static void pegasos2_machine_reset(MachineState *machine, 
ShutdownCause reason)
 
 pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
   PCI_INTERRUPT_LINE, 2, 0x9);
+pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
+  0x50, 1, 0x6);
+pegasos2_superio_write(pm, 0xf4, 0xbe);
+pegasos2_superio_write(pm, 0xf6, 0xef);
+pegasos2_superio_write(pm, 0xf7, 0xfc);
+pegasos2_superio_write(pm, 0xf2, 0x14);
 pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
   0x50, 1, 0x2);
 pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
-- 
2.43.0




[PATCH v3 11/11] hw/isa/vt82c686: Implement relocation and toggling of SuperI/O functions

2023-12-21 Thread Bernhard Beschow
The VIA south bridges are able to relocate and toggle (enable or disable) their
SuperI/O functions. So far this is hardcoded such that all functions are always
enabled and are located at fixed addresses.

Some PC BIOSes seem to probe for I/O occupancy before activating such a function
and issue an error in case of a conflict. Since the functions are currently
enabled on reset, conflicts are always detected. Prevent that by implementing
relocation and toggling of the SuperI/O functions.

Note that all SuperI/O functions are now deactivated upon reset (except for
VT82C686B's serial ports where Fuloong 2e's rescue-yl seems to expect them to be
enabled by default). Rely on firmware to configure the functions accordingly.

Signed-off-by: Bernhard Beschow 
---
 hw/isa/vt82c686.c | 115 +-
 1 file changed, 84 insertions(+), 31 deletions(-)

diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index 9c2333a277..983cb321b9 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -15,6 +15,9 @@
 
 #include "qemu/osdep.h"
 #include "hw/isa/vt82c686.h"
+#include "hw/block/fdc.h"
+#include "hw/char/parallel-isa.h"
+#include "hw/char/serial.h"
 #include "hw/pci/pci.h"
 #include "hw/qdev-properties.h"
 #include "hw/ide/pci.h"
@@ -343,6 +346,32 @@ static const TypeInfo via_superio_info = {
 
 #define TYPE_VT82C686B_SUPERIO "vt82c686b-superio"
 
+static void vt82c686b_superio_update(ViaSuperIOState *s)
+{
+isa_parallel_set_enabled(s->superio.parallel[0],
+ (s->regs[0xe2] & 0x3) != 3);
+isa_serial_set_enabled(s->superio.serial[0], s->regs[0xe2] & BIT(2));
+isa_serial_set_enabled(s->superio.serial[1], s->regs[0xe2] & BIT(3));
+isa_fdc_set_enabled(s->superio.floppy, s->regs[0xe2] & BIT(4));
+
+isa_fdc_set_iobase(s->superio.floppy, (s->regs[0xe3] & 0xfc) << 2);
+isa_parallel_set_iobase(s->superio.parallel[0], s->regs[0xe6] << 2);
+isa_serial_set_iobase(s->superio.serial[0], (s->regs[0xe7] & 0xfe) << 2);
+isa_serial_set_iobase(s->superio.serial[1], (s->regs[0xe8] & 0xfe) << 2);
+}
+
+static int vmstate_vt82c686b_superio_post_load(void *opaque, int version_id)
+{
+vt82c686b_superio_update(opaque);
+return 0;
+}
+
+static const VMStateDescription vmstate_vt82c686b_superio = {
+.name = "vt82c686b_superio",
+.version_id = 1,
+.post_load = vmstate_vt82c686b_superio_post_load,
+};
+
 static void vt82c686b_superio_cfg_write(void *opaque, hwaddr addr,
 uint64_t data, unsigned size)
 {
@@ -368,7 +397,11 @@ static void vt82c686b_superio_cfg_write(void *opaque, 
hwaddr addr,
 case 0xfd ... 0xff:
 /* ignore write to read only registers */
 return;
-/* case 0xe6 ... 0xe8: Should set base port of parallel and serial */
+case 0xe2 ... 0xe3:
+case 0xe6 ... 0xe8:
+sc->regs[idx] = data;
+vt82c686b_superio_update(sc);
+return;
 default:
 qemu_log_mask(LOG_UNIMP,
   "via_superio_cfg: unimplemented register 0x%x\n", idx);
@@ -393,25 +426,24 @@ static void vt82c686b_superio_reset(DeviceState *dev)
 
 memset(s->regs, 0, sizeof(s->regs));
 /* Device ID */
-vt82c686b_superio_cfg_write(s, 0, 0xe0, 1);
-vt82c686b_superio_cfg_write(s, 1, 0x3c, 1);
-/* Function select - all disabled */
-vt82c686b_superio_cfg_write(s, 0, 0xe2, 1);
-vt82c686b_superio_cfg_write(s, 1, 0x03, 1);
+s->regs[0xe0] = 0x3c;
+/*
+ * Function select - only serial enabled
+ * Fuloong 2e's rescue-yl prints to the serial console w/o enabling it. 
This
+ * suggests that the serial ports are enabled by default, so override the
+ * datasheet.
+ */
+s->regs[0xe2] = 0x0f;
 /* Floppy ctrl base addr 0x3f0-7 */
-vt82c686b_superio_cfg_write(s, 0, 0xe3, 1);
-vt82c686b_superio_cfg_write(s, 1, 0xfc, 1);
+s->regs[0xe3] = 0xfc;
 /* Parallel port base addr 0x378-f */
-vt82c686b_superio_cfg_write(s, 0, 0xe6, 1);
-vt82c686b_superio_cfg_write(s, 1, 0xde, 1);
+s->regs[0xe6] = 0xde;
 /* Serial port 1 base addr 0x3f8-f */
-vt82c686b_superio_cfg_write(s, 0, 0xe7, 1);
-vt82c686b_superio_cfg_write(s, 1, 0xfe, 1);
+s->regs[0xe7] = 0xfe;
 /* Serial port 2 base addr 0x2f8-f */
-vt82c686b_superio_cfg_write(s, 0, 0xe8, 1);
-vt82c686b_superio_cfg_write(s, 1, 0xbe, 1);
+s->regs[0xe8] = 0xbe;
 
-vt82c686b_superio_cfg_write(s, 0, 0, 1);
+vt82c686b_superio_update(s);
 }
 
 static void vt82c686b_superio_init(Object *obj)
@@ -429,6 +461,7 @@ static void vt82c686b_superio_class_init(ObjectClass 
*klass, void *data)
 sc->parallel.count = 1;
 sc->ide.count = 0; /* emulated by via-ide */

[PATCH v3 07/11] hw/block/fdc-isa: Implement relocation and enabling/disabling for TYPE_ISA_FDC

2023-12-21 Thread Bernhard Beschow
The real SuperI/O chips emulated by QEMU allow for relocating and enabling or
disabling their SuperI/O functions via software. So far this is not implemented.
Prepare for that by adding isa_fdc_set_{enabled,iobase}.

Signed-off-by: Bernhard Beschow 
---
 include/hw/block/fdc.h |  3 +++
 hw/block/fdc-isa.c | 14 ++
 2 files changed, 17 insertions(+)

diff --git a/include/hw/block/fdc.h b/include/hw/block/fdc.h
index 35248c0837..c367c5efea 100644
--- a/include/hw/block/fdc.h
+++ b/include/hw/block/fdc.h
@@ -14,6 +14,9 @@ void fdctrl_init_sysbus(qemu_irq irq, hwaddr mmio_base, 
DriveInfo **fds);
 void sun4m_fdctrl_init(qemu_irq irq, hwaddr io_base,
DriveInfo **fds, qemu_irq *fdc_tc);
 
+void isa_fdc_set_iobase(ISADevice *fdc, hwaddr iobase);
+void isa_fdc_set_enabled(ISADevice *fdc, bool enabled);
+
 FloppyDriveType isa_fdc_get_drive_type(ISADevice *fdc, int i);
 int cmos_get_fd_drive_type(FloppyDriveType fd0);
 
diff --git a/hw/block/fdc-isa.c b/hw/block/fdc-isa.c
index b4c92b40b3..c989325de3 100644
--- a/hw/block/fdc-isa.c
+++ b/hw/block/fdc-isa.c
@@ -192,6 +192,20 @@ static Aml *build_fdinfo_aml(int idx, FloppyDriveType type)
 return dev;
 }
 
+void isa_fdc_set_iobase(ISADevice *fdc, hwaddr iobase)
+{
+FDCtrlISABus *isa = ISA_FDC(fdc);
+
+fdc->ioport_id = iobase;
+isa->iobase = iobase;
+portio_list_set_address(&isa->portio_list, isa->iobase);
+}
+
+void isa_fdc_set_enabled(ISADevice *fdc, bool enabled)
+{
+portio_list_set_enabled(&ISA_FDC(fdc)->portio_list, enabled);
+}
+
 int cmos_get_fd_drive_type(FloppyDriveType fd0)
 {
 int val;
-- 
2.43.0




[PATCH v3 00/11] hw/isa/vt82c686: Implement relocation and toggling of SuperI/O functions

2023-12-21 Thread Bernhard Beschow
This series implements relocation of the SuperI/O functions of the VIA south
bridges which resolves some FIXME's. It is part of my via-apollo-pro-133t
branch [1] which is an extension of bringing the VIA south bridges to the PC
machine [2]. This branch is able to run some real-world X86 BIOSes in the hope
that it allows us to form a better understanding of the real vt82c686b devices.
Implementing relocation and toggling of the SuperI/O functions is one step to
make these BIOSes run without error messages, so here we go.

The series is structured as follows: Patches 1-3 prepare the TYPE_ISA_FDC,
TYPE_ISA_PARALLEL and TYPE_ISA_SERIAL to relocate and toggle (enable/disable)
themselves without breaking encapsulation of their respective device states.
This is achieved by moving the MemoryRegions and PortioLists from the device
states into the encapsulating ISA devices since they will be relocated and
toggled.

Inspired by the memory API patches 4-6 add two convenience functions to the
portio_list API to toggle and relocate portio lists. Patch 5 is a preparation
for that which removes some redundancies which otherwise had to be dealt with
during relocation.

Patches 7-9 implement toggling and relocation for types TYPE_ISA_FDC,
TYPE_ISA_PARALLEL and TYPE_ISA_SERIAL. Patch 10 prepares the pegasos2 machine
which would end up with all SuperI/O functions disabled if no -bios argument is
given. Patch 11 finally implements the main feature which now relies on
firmware to configure the SuperI/O functions accordingly (except for pegasos2).

v3:
* Rework various commit messages (Zoltan)
* Drop patch "hw/char/serial: Free struct SerialState from MemoryRegion"
  (Zoltan)
* Generalize wording in migration.rst to include portio_list API (Zoltan)

v2:
* Improve commit message (Zoltan)
* Split pegasos2 from vt82c686 patch (Zoltan)
* Avoid poking into device internals (Zoltan)

Testing done:
* make check
* make check-avocado
* Run MorphOS on pegasos2 with and without pegasos2.rom
* Run Linux on amigaone
* Run real-world BIOSes on via-apollo-pro-133t branch
* Start rescue-yl on fuloong2e

[1] https://github.com/shentok/qemu/tree/via-apollo-pro-133t
[2] https://github.com/shentok/qemu/tree/pc-via

Bernhard Beschow (11):
  hw/block/fdc-isa: Move portio_list from FDCtrl to FDCtrlISABus
  hw/block/fdc-sysbus: Move iomem from FDCtrl to FDCtrlSysBus
  hw/char/parallel: Move portio_list from ParallelState to
ISAParallelState
  exec/ioport: Resolve redundant .base attribute in struct
MemoryRegionPortio
  exec/ioport: Add portio_list_set_address()
  exec/ioport: Add portio_list_set_enabled()
  hw/block/fdc-isa: Implement relocation and enabling/disabling for
TYPE_ISA_FDC
  hw/char/serial-isa: Implement relocation and enabling/disabling for
TYPE_ISA_SERIAL
  hw/char/parallel-isa: Implement relocation and enabling/disabling for
TYPE_ISA_PARALLEL
  hw/ppc/pegasos2: Let pegasos2 machine configure SuperI/O functions
  hw/isa/vt82c686: Implement relocation and toggling of SuperI/O
functions

 docs/devel/migration.rst   |   6 +-
 hw/block/fdc-internal.h|   4 --
 include/exec/ioport.h  |   4 +-
 include/hw/block/fdc.h |   3 +
 include/hw/char/parallel-isa.h |   5 ++
 include/hw/char/parallel.h |   2 -
 include/hw/char/serial.h   |   2 +
 hw/block/fdc-isa.c |  18 +-
 hw/block/fdc-sysbus.c  |   6 +-
 hw/char/parallel-isa.c |  14 
 hw/char/parallel.c |   2 +-
 hw/char/serial-isa.c   |  14 
 hw/isa/vt82c686.c  | 115 -
 hw/ppc/pegasos2.c  |  15 +
 system/ioport.c|  41 ++--
 15 files changed, 200 insertions(+), 51 deletions(-)

-- 
2.43.0




[PATCH v3 02/11] hw/block/fdc-sysbus: Move iomem from FDCtrl to FDCtrlSysBus

2023-12-21 Thread Bernhard Beschow
FDCtrl::iomem isn't used inside FDCtrl context but only inside FDCtrlSysBus
context, so move it there.

Signed-off-by: Bernhard Beschow 
Reviewed-by: BALATON Zoltan 
---
 hw/block/fdc-internal.h | 2 --
 hw/block/fdc-sysbus.c   | 6 --
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/block/fdc-internal.h b/hw/block/fdc-internal.h
index fef2bfbbf5..e219623dc7 100644
--- a/hw/block/fdc-internal.h
+++ b/hw/block/fdc-internal.h
@@ -25,7 +25,6 @@
 #ifndef HW_BLOCK_FDC_INTERNAL_H
 #define HW_BLOCK_FDC_INTERNAL_H
 
-#include "exec/memory.h"
 #include "hw/block/block.h"
 #include "hw/block/fdc.h"
 #include "qapi/qapi-types-block.h"
@@ -91,7 +90,6 @@ typedef struct FDrive {
 } FDrive;
 
 struct FDCtrl {
-MemoryRegion iomem;
 qemu_irq irq;
 /* Controller state */
 QEMUTimer *result_timer;
diff --git a/hw/block/fdc-sysbus.c b/hw/block/fdc-sysbus.c
index 86ea51d003..e197b97262 100644
--- a/hw/block/fdc-sysbus.c
+++ b/hw/block/fdc-sysbus.c
@@ -26,6 +26,7 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "qom/object.h"
+#include "exec/memory.h"
 #include "hw/sysbus.h"
 #include "hw/block/fdc.h"
 #include "migration/vmstate.h"
@@ -52,6 +53,7 @@ struct FDCtrlSysBus {
 /*< public >*/
 
 struct FDCtrl state;
+MemoryRegion iomem;
 };
 
 static uint64_t fdctrl_read_mem(void *opaque, hwaddr reg, unsigned ize)
@@ -146,11 +148,11 @@ static void sysbus_fdc_common_instance_init(Object *obj)
 
 qdev_set_legacy_instance_id(dev, 0 /* io */, 2); /* FIXME */
 
-memory_region_init_io(&fdctrl->iomem, obj,
+memory_region_init_io(&sys->iomem, obj,
   sbdc->use_strict_io ? &fdctrl_mem_strict_ops
   : &fdctrl_mem_ops,
   fdctrl, "fdc", 0x08);
-sysbus_init_mmio(sbd, &fdctrl->iomem);
+sysbus_init_mmio(sbd, &sys->iomem);
 
 sysbus_init_irq(sbd, &fdctrl->irq);
 qdev_init_gpio_in(dev, fdctrl_handle_tc, 1);
-- 
2.43.0




[PATCH v3 04/11] exec/ioport: Resolve redundant .base attribute in struct MemoryRegionPortio

2023-12-21 Thread Bernhard Beschow
portio_list_add_1() creates a MemoryRegionPortioList instance which holds a
MemoryRegion `mr` and an array of MemoryRegionPortio elements named `ports`.
Each element in the array gets assigned the same value for its .base attribute.
The same value also ends up as the .addr attribute of `mr` due to the
memory_region_add_subregion() call. This means that all .base attributes are
the same as `mr.addr`.

The only usages of MemoryRegionPortio::base were in portio_read() and
portio_write(). Both functions get above MemoryRegionPortioList as their
opaque parameter. In both cases find_portio() can only return one of the
MemoryRegionPortio elements of the `ports` array. Due to above observation any
element will have the same .base value equal to `mr.addr` which is also
accessible.

Hence, `mrpio->mr.addr` is equivalent to `mrp->base` and
MemoryRegionPortio::base is redundant and can be removed.

Signed-off-by: Bernhard Beschow 
---
 include/exec/ioport.h |  1 -
 system/ioport.c   | 13 ++---
 2 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/include/exec/ioport.h b/include/exec/ioport.h
index e34f668998..95f1dc30d0 100644
--- a/include/exec/ioport.h
+++ b/include/exec/ioport.h
@@ -35,7 +35,6 @@ typedef struct MemoryRegionPortio {
 unsigned size;
 uint32_t (*read)(void *opaque, uint32_t address);
 void (*write)(void *opaque, uint32_t address, uint32_t data);
-uint32_t base; /* private field */
 } MemoryRegionPortio;
 
 #define PORTIO_END_OF_LIST() { }
diff --git a/system/ioport.c b/system/ioport.c
index 1824aa808c..a59e58b716 100644
--- a/system/ioport.c
+++ b/system/ioport.c
@@ -181,13 +181,13 @@ static uint64_t portio_read(void *opaque, hwaddr addr, 
unsigned size)
 
 data = ((uint64_t)1 << (size * 8)) - 1;
 if (mrp) {
-data = mrp->read(mrpio->portio_opaque, mrp->base + addr);
+data = mrp->read(mrpio->portio_opaque, mrpio->mr.addr + addr);
 } else if (size == 2) {
 mrp = find_portio(mrpio, addr, 1, false);
 if (mrp) {
-data = mrp->read(mrpio->portio_opaque, mrp->base + addr);
+data = mrp->read(mrpio->portio_opaque, mrpio->mr.addr + addr);
 if (addr + 1 < mrp->offset + mrp->len) {
-data |= mrp->read(mrpio->portio_opaque, mrp->base + addr + 1) 
<< 8;
+data |= mrp->read(mrpio->portio_opaque, mrpio->mr.addr + addr 
+ 1) << 8;
 } else {
 data |= 0xff00;
 }
@@ -203,13 +203,13 @@ static void portio_write(void *opaque, hwaddr addr, 
uint64_t data,
 const MemoryRegionPortio *mrp = find_portio(mrpio, addr, size, true);
 
 if (mrp) {
-mrp->write(mrpio->portio_opaque, mrp->base + addr, data);
+mrp->write(mrpio->portio_opaque, mrpio->mr.addr + addr, data);
 } else if (size == 2) {
 mrp = find_portio(mrpio, addr, 1, true);
 if (mrp) {
-mrp->write(mrpio->portio_opaque, mrp->base + addr, data & 0xff);
+mrp->write(mrpio->portio_opaque, mrpio->mr.addr + addr, data & 
0xff);
 if (addr + 1 < mrp->offset + mrp->len) {
-mrp->write(mrpio->portio_opaque, mrp->base + addr + 1, data >> 
8);
+mrp->write(mrpio->portio_opaque, mrpio->mr.addr + addr + 1, 
data >> 8);
 }
 }
 }
@@ -244,7 +244,6 @@ static void portio_list_add_1(PortioList *piolist,
 /* Adjust the offsets to all be zero-based for the region.  */
 for (i = 0; i < count; ++i) {
 mrpio->ports[i].offset -= off_low;
-mrpio->ports[i].base = start + off_low;
 }
 
 /*
-- 
2.43.0




[PATCH v3 03/11] hw/char/parallel: Move portio_list from ParallelState to ISAParallelState

2023-12-21 Thread Bernhard Beschow
ParallelState::portio_list isn't used inside ParallelState context but only
inside ISAParallelState context, so move it there.

Signed-off-by: Bernhard Beschow 
Reviewed-by: BALATON Zoltan 
---
 include/hw/char/parallel-isa.h | 2 ++
 include/hw/char/parallel.h | 2 --
 hw/char/parallel.c | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/include/hw/char/parallel-isa.h b/include/hw/char/parallel-isa.h
index d24ccecf05..3b783bd08d 100644
--- a/include/hw/char/parallel-isa.h
+++ b/include/hw/char/parallel-isa.h
@@ -12,6 +12,7 @@
 
 #include "parallel.h"
 
+#include "exec/ioport.h"
 #include "hw/isa/isa.h"
 #include "qom/object.h"
 
@@ -25,6 +26,7 @@ struct ISAParallelState {
 uint32_t iobase;
 uint32_t isairq;
 ParallelState state;
+PortioList portio_list;
 };
 
 #endif /* HW_PARALLEL_ISA_H */
diff --git a/include/hw/char/parallel.h b/include/hw/char/parallel.h
index 7b5a309a03..cfb97cc7cc 100644
--- a/include/hw/char/parallel.h
+++ b/include/hw/char/parallel.h
@@ -1,7 +1,6 @@
 #ifndef HW_PARALLEL_H
 #define HW_PARALLEL_H
 
-#include "exec/ioport.h"
 #include "exec/memory.h"
 #include "hw/isa/isa.h"
 #include "hw/irq.h"
@@ -22,7 +21,6 @@ typedef struct ParallelState {
 uint32_t last_read_offset; /* For debugging */
 /* Memory-mapped interface */
 int it_shift;
-PortioList portio_list;
 } ParallelState;
 
 void parallel_hds_isa_init(ISABus *bus, int n);
diff --git a/hw/char/parallel.c b/hw/char/parallel.c
index 147c900f0d..c1747cbb75 100644
--- a/hw/char/parallel.c
+++ b/hw/char/parallel.c
@@ -532,7 +532,7 @@ static void parallel_isa_realizefn(DeviceState *dev, Error 
**errp)
 s->status = dummy;
 }
 
-isa_register_portio_list(isadev, &s->portio_list, base,
+isa_register_portio_list(isadev, &isa->portio_list, base,
  (s->hw_driver
   ? &isa_parallel_portio_hw_list[0]
   : &isa_parallel_portio_sw_list[0]),
-- 
2.43.0




[PATCH v3 05/11] exec/ioport: Add portio_list_set_address()

2023-12-21 Thread Bernhard Beschow
Some SuperI/O devices such as the VIA south bridges or the PC87312 controller
are able to relocate their SuperI/O functions. Add a convenience function for
implementing this in the VIA south bridges.

This convenience function relies on previous simplifications in exec/ioport
which avoids some duplicate synchronization of I/O port base addresses. The
naming of the function is inspired by its memory_region_set_address() pendant.

Signed-off-by: Bernhard Beschow 
---
 docs/devel/migration.rst |  5 +++--
 include/exec/ioport.h|  2 ++
 system/ioport.c  | 19 +++
 3 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/docs/devel/migration.rst b/docs/devel/migration.rst
index ec55089b25..dc35a17461 100644
--- a/docs/devel/migration.rst
+++ b/docs/devel/migration.rst
@@ -452,10 +452,10 @@ data doesn't match the stored device data well; it allows 
an
 intermediate temporary structure to be populated with migration
 data and then transferred to the main structure.
 
-If you use memory API functions that update memory layout outside
+If you use memory or portio_list API functions that update memory layout 
outside
 initialization (i.e., in response to a guest action), this is a strong
 indication that you need to call these functions in a ``post_load`` callback.
-Examples of such memory API functions are:
+Examples of such API functions are:
 
   - memory_region_add_subregion()
   - memory_region_del_subregion()
@@ -464,6 +464,7 @@ Examples of such memory API functions are:
   - memory_region_set_enabled()
   - memory_region_set_address()
   - memory_region_set_alias_offset()
+  - portio_list_set_address()
 
 Iterative device migration
 --
diff --git a/include/exec/ioport.h b/include/exec/ioport.h
index 95f1dc30d0..96858e5ac3 100644
--- a/include/exec/ioport.h
+++ b/include/exec/ioport.h
@@ -54,6 +54,7 @@ typedef struct PortioList {
 const struct MemoryRegionPortio *ports;
 Object *owner;
 struct MemoryRegion *address_space;
+uint32_t addr;
 unsigned nr;
 struct MemoryRegion **regions;
 void *opaque;
@@ -70,5 +71,6 @@ void portio_list_add(PortioList *piolist,
  struct MemoryRegion *address_space,
  uint32_t addr);
 void portio_list_del(PortioList *piolist);
+void portio_list_set_address(PortioList *piolist, uint32_t addr);
 
 #endif /* IOPORT_H */
diff --git a/system/ioport.c b/system/ioport.c
index a59e58b716..000e0ee1af 100644
--- a/system/ioport.c
+++ b/system/ioport.c
@@ -133,6 +133,7 @@ void portio_list_init(PortioList *piolist,
 piolist->nr = 0;
 piolist->regions = g_new0(MemoryRegion *, n);
 piolist->address_space = NULL;
+piolist->addr = 0;
 piolist->opaque = opaque;
 piolist->owner = owner;
 piolist->name = name;
@@ -282,6 +283,7 @@ void portio_list_add(PortioList *piolist,
 unsigned int off_low, off_high, off_last, count;
 
 piolist->address_space = address_space;
+piolist->addr = start;
 
 /* Handle the first entry specially.  */
 off_last = off_low = pio_start->offset;
@@ -322,6 +324,23 @@ void portio_list_del(PortioList *piolist)
 }
 }
 
+void portio_list_set_address(PortioList *piolist, uint32_t addr)
+{
+MemoryRegionPortioList *mrpio;
+unsigned i, j;
+
+for (i = 0; i < piolist->nr; ++i) {
+mrpio = container_of(piolist->regions[i], MemoryRegionPortioList, mr);
+memory_region_set_address(&mrpio->mr,
+  mrpio->mr.addr - piolist->addr + addr);
+for (j = 0; mrpio->ports[j].size; ++j) {
+mrpio->ports[j].offset += addr - piolist->addr;
+}
+}
+
+piolist->addr = addr;
+}
+
 static void memory_region_portio_list_finalize(Object *obj)
 {
 MemoryRegionPortioList *mrpio = MEMORY_REGION_PORTIO_LIST(obj);
-- 
2.43.0




[PATCH v3 06/11] exec/ioport: Add portio_list_set_enabled()

2023-12-21 Thread Bernhard Beschow
Some SuperI/O devices such as the VIA south bridges or the PC87312 controller
allow to enable or disable their SuperI/O functions. Add a convenience function
for implementing this in the VIA south bridges.

The naming of the functions is inspired by its memory_region_set_enabled()
pendant.

Signed-off-by: Bernhard Beschow 
---
 docs/devel/migration.rst | 1 +
 include/exec/ioport.h| 1 +
 system/ioport.c  | 9 +
 3 files changed, 11 insertions(+)

diff --git a/docs/devel/migration.rst b/docs/devel/migration.rst
index dc35a17461..9317091d1a 100644
--- a/docs/devel/migration.rst
+++ b/docs/devel/migration.rst
@@ -465,6 +465,7 @@ Examples of such API functions are:
   - memory_region_set_address()
   - memory_region_set_alias_offset()
   - portio_list_set_address()
+  - portio_list_set_enabled()
 
 Iterative device migration
 --
diff --git a/include/exec/ioport.h b/include/exec/ioport.h
index 96858e5ac3..4397f12f93 100644
--- a/include/exec/ioport.h
+++ b/include/exec/ioport.h
@@ -71,6 +71,7 @@ void portio_list_add(PortioList *piolist,
  struct MemoryRegion *address_space,
  uint32_t addr);
 void portio_list_del(PortioList *piolist);
+void portio_list_set_enabled(PortioList *piolist, bool enabled);
 void portio_list_set_address(PortioList *piolist, uint32_t addr);
 
 #endif /* IOPORT_H */
diff --git a/system/ioport.c b/system/ioport.c
index 000e0ee1af..fd551d0375 100644
--- a/system/ioport.c
+++ b/system/ioport.c
@@ -324,6 +324,15 @@ void portio_list_del(PortioList *piolist)
 }
 }
 
+void portio_list_set_enabled(PortioList *piolist, bool enabled)
+{
+unsigned i;
+
+for (i = 0; i < piolist->nr; ++i) {
+memory_region_set_enabled(piolist->regions[i], enabled);
+}
+}
+
 void portio_list_set_address(PortioList *piolist, uint32_t addr)
 {
 MemoryRegionPortioList *mrpio;
-- 
2.43.0




[PATCH v3 01/11] hw/block/fdc-isa: Move portio_list from FDCtrl to FDCtrlISABus

2023-12-21 Thread Bernhard Beschow
FDCtrl::portio_list isn't used inside FDCtrl context but only inside
FDCtrlISABus context, so move it there.

Signed-off-by: Bernhard Beschow 
Reviewed-by: BALATON Zoltan 
---
 hw/block/fdc-internal.h | 2 --
 hw/block/fdc-isa.c  | 4 +++-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/block/fdc-internal.h b/hw/block/fdc-internal.h
index 036392e9fc..fef2bfbbf5 100644
--- a/hw/block/fdc-internal.h
+++ b/hw/block/fdc-internal.h
@@ -26,7 +26,6 @@
 #define HW_BLOCK_FDC_INTERNAL_H
 
 #include "exec/memory.h"
-#include "exec/ioport.h"
 #include "hw/block/block.h"
 #include "hw/block/fdc.h"
 #include "qapi/qapi-types-block.h"
@@ -140,7 +139,6 @@ struct FDCtrl {
 /* Timers state */
 uint8_t timer0;
 uint8_t timer1;
-PortioList portio_list;
 };
 
 extern const FDFormat fd_formats[];
diff --git a/hw/block/fdc-isa.c b/hw/block/fdc-isa.c
index 7ec075e470..b4c92b40b3 100644
--- a/hw/block/fdc-isa.c
+++ b/hw/block/fdc-isa.c
@@ -42,6 +42,7 @@
 #include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "sysemu/sysemu.h"
+#include "exec/ioport.h"
 #include "qemu/log.h"
 #include "qemu/main-loop.h"
 #include "qemu/module.h"
@@ -60,6 +61,7 @@ struct FDCtrlISABus {
 uint32_t irq;
 uint32_t dma;
 struct FDCtrl state;
+PortioList portio_list;
 int32_t bootindexA;
 int32_t bootindexB;
 };
@@ -91,7 +93,7 @@ static void isabus_fdc_realize(DeviceState *dev, Error **errp)
 FDCtrl *fdctrl = &isa->state;
 Error *err = NULL;
 
-isa_register_portio_list(isadev, &fdctrl->portio_list,
+isa_register_portio_list(isadev, &isa->portio_list,
  isa->iobase, fdc_portio_list, fdctrl,
  "fdc");
 
-- 
2.43.0




[PATCH v3 08/11] hw/char/serial-isa: Implement relocation and enabling/disabling for TYPE_ISA_SERIAL

2023-12-21 Thread Bernhard Beschow
The real SuperI/O chips emulated by QEMU allow for relocating and enabling or
disabling their SuperI/O functions via software. So far this is not implemented.
Prepare for that by adding isa_serial_set_{enabled,iobase}.

Signed-off-by: Bernhard Beschow 
---
 include/hw/char/serial.h |  2 ++
 hw/char/serial-isa.c | 14 ++
 2 files changed, 16 insertions(+)

diff --git a/include/hw/char/serial.h b/include/hw/char/serial.h
index 8ba7eca3d6..6e14099ee7 100644
--- a/include/hw/char/serial.h
+++ b/include/hw/char/serial.h
@@ -112,5 +112,7 @@ SerialMM *serial_mm_init(MemoryRegion *address_space,
 
 #define TYPE_ISA_SERIAL "isa-serial"
 void serial_hds_isa_init(ISABus *bus, int from, int to);
+void isa_serial_set_iobase(ISADevice *serial, hwaddr iobase);
+void isa_serial_set_enabled(ISADevice *serial, bool enabled);
 
 #endif
diff --git a/hw/char/serial-isa.c b/hw/char/serial-isa.c
index 141a6cb168..62fb529e39 100644
--- a/hw/char/serial-isa.c
+++ b/hw/char/serial-isa.c
@@ -184,3 +184,17 @@ void serial_hds_isa_init(ISABus *bus, int from, int to)
 }
 }
 }
+
+void isa_serial_set_iobase(ISADevice *serial, hwaddr iobase)
+{
+ISASerialState *s = ISA_SERIAL(serial);
+
+serial->ioport_id = iobase;
+s->iobase = iobase;
+memory_region_set_address(&s->state.io, s->iobase);
+}
+
+void isa_serial_set_enabled(ISADevice *serial, bool enabled)
+{
+memory_region_set_enabled(&ISA_SERIAL(serial)->state.io, enabled);
+}
-- 
2.43.0




Re: [PATCH v2 11/12] hw/ppc/pegasos2: Let pegasos2 machine configure SuperI/O functions

2023-12-21 Thread Bernhard Beschow



Am 19. Dezember 2023 00:11:37 UTC schrieb BALATON Zoltan :
>On Mon, 18 Dec 2023, Bernhard Beschow wrote:
>> This is a preparation for implementing relocation and toggling of SuperI/O
>> functions in the VT8231 device model. Upon reset, all SuperI/O functions 
>> will be
>> deactivated, so in case if no -bios is given, let the machine configure those
>> functions the same way pegasos2.rom would do. For now the meantime this will 
>> be
>
>"same way pegasos2 firmware would do".

Good idea. Will change.

> You can drop the last sentence about no-op as it does not make much sense as 
> it is or reword it if you want to keep it.

Yeah, I messed up the last sentence somehow. I'll drop it then.

Best regards,
Bernhard

>
>Regards,
>BALATON Zoltan
>
>> a no-op.
>> 
>> Signed-off-by: Bernhard Beschow 
>> ---
>> hw/ppc/pegasos2.c | 15 +++
>> 1 file changed, 15 insertions(+)
>> 
>> diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
>> index 3203a4a728..0a40ebd542 100644
>> --- a/hw/ppc/pegasos2.c
>> +++ b/hw/ppc/pegasos2.c
>> @@ -285,6 +285,15 @@ static void 
>> pegasos2_pci_config_write(Pegasos2MachineState *pm, int bus,
>> pegasos2_mv_reg_write(pm, pcicfg + 4, len, val);
>> }
>> 
>> +static void pegasos2_superio_write(Pegasos2MachineState *pm, uint32_t addr,
>> +   uint32_t val)
>> +{
>> +AddressSpace *as = CPU(pm->cpu)->as;
>> +
>> +stb_phys(as, PCI1_IO_BASE + 0x3f0, addr);
>> +stb_phys(as, PCI1_IO_BASE + 0x3f1, val);
>> +}
>> +
>> static void pegasos2_machine_reset(MachineState *machine, ShutdownCause 
>> reason)
>> {
>> Pegasos2MachineState *pm = PEGASOS2_MACHINE(machine);
>> @@ -310,6 +319,12 @@ static void pegasos2_machine_reset(MachineState 
>> *machine, ShutdownCause reason)
>> 
>> pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
>>   PCI_INTERRUPT_LINE, 2, 0x9);
>> +pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
>> +  0x50, 1, 0x6);
>> +pegasos2_superio_write(pm, 0xf4, 0xbe);
>> +pegasos2_superio_write(pm, 0xf6, 0xef);
>> +pegasos2_superio_write(pm, 0xf7, 0xfc);
>> +pegasos2_superio_write(pm, 0xf2, 0x14);
>> pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
>>   0x50, 1, 0x2);
>> pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
>> 



Re: [PATCH v2 08/12] hw/block/fdc-isa: Implement relocation and toggling for TYPE_ISA_FDC

2023-12-21 Thread Bernhard Beschow



Am 19. Dezember 2023 00:09:23 UTC schrieb BALATON Zoltan :
>On Mon, 18 Dec 2023, Bernhard Beschow wrote:
>> Implement isa_fdc_set_{enabled,iobase} in order to implement relocation and
>> toggling of SuperI/O functions in the VIA south bridges without breaking
>> encapsulation.
>
>You may want to revise these commit messages. What toggling means is only 
>defined in the last patch but I can't think of a better name for it other than 
>spelling out enable/disable.

I'll use enable/disable then.

> It's probably also not relevant in this commit message to mention VIA south 
> bridges as this is a generic function not specific to that usage only.

I'll refer to SuperI/O chips rather than VIA specifically since I want to point 
out the distinction to properties.

Best regards,
Bernhard

>
>Regards,
>BALATON Zoltan
>
>> Signed-off-by: Bernhard Beschow 
>> ---
>> include/hw/block/fdc.h |  3 +++
>> hw/block/fdc-isa.c | 14 ++
>> 2 files changed, 17 insertions(+)
>> 
>> diff --git a/include/hw/block/fdc.h b/include/hw/block/fdc.h
>> index 35248c0837..c367c5efea 100644
>> --- a/include/hw/block/fdc.h
>> +++ b/include/hw/block/fdc.h
>> @@ -14,6 +14,9 @@ void fdctrl_init_sysbus(qemu_irq irq, hwaddr mmio_base, 
>> DriveInfo **fds);
>> void sun4m_fdctrl_init(qemu_irq irq, hwaddr io_base,
>>DriveInfo **fds, qemu_irq *fdc_tc);
>> 
>> +void isa_fdc_set_iobase(ISADevice *fdc, hwaddr iobase);
>> +void isa_fdc_set_enabled(ISADevice *fdc, bool enabled);
>> +
>> FloppyDriveType isa_fdc_get_drive_type(ISADevice *fdc, int i);
>> int cmos_get_fd_drive_type(FloppyDriveType fd0);
>> 
>> diff --git a/hw/block/fdc-isa.c b/hw/block/fdc-isa.c
>> index b4c92b40b3..c989325de3 100644
>> --- a/hw/block/fdc-isa.c
>> +++ b/hw/block/fdc-isa.c
>> @@ -192,6 +192,20 @@ static Aml *build_fdinfo_aml(int idx, FloppyDriveType 
>> type)
>> return dev;
>> }
>> 
>> +void isa_fdc_set_iobase(ISADevice *fdc, hwaddr iobase)
>> +{
>> +FDCtrlISABus *isa = ISA_FDC(fdc);
>> +
>> +fdc->ioport_id = iobase;
>> +isa->iobase = iobase;
>> +portio_list_set_address(&isa->portio_list, isa->iobase);
>> +}
>> +
>> +void isa_fdc_set_enabled(ISADevice *fdc, bool enabled)
>> +{
>> +portio_list_set_enabled(&ISA_FDC(fdc)->portio_list, enabled);
>> +}
>> +
>> int cmos_get_fd_drive_type(FloppyDriveType fd0)
>> {
>> int val;
>> 



Re: [PATCH v2 12/12] hw/isa/vt82c686: Implement relocation and toggling of SuperI/O functions

2023-12-19 Thread Bernhard Beschow



Am 19. Dezember 2023 00:26:15 UTC schrieb BALATON Zoltan :
>On Mon, 18 Dec 2023, Bernhard Beschow wrote:
>> The VIA south bridges are able to relocate and toggle (enable or disable) 
>> their
>> SuperI/O functions. So far this is hardcoded such that all functions are 
>> always
>> enabled and are located at fixed addresses.
>> 
>> Some PC BIOSes seem to probe for I/O occupancy before activating such a 
>> function
>> and issue an error in case of a conflict. Since the functions are enabled on
>> reset, conflicts are always detected. Prevent that by implementing relocation
>> and toggling of the SuperI/O functions.
>> 
>> Note that all SuperI/O functions are now deactivated upon reset (except for
>> VT82C686B's serial ports where Fuloong 2e's rescue-yl seems to expect them 
>> to be
>> enabled by default). Rely on firmware -- or in case of pegasos2 on board 
>> code if
>> no -bios is given -- to configure the functions accordingly.
>
>Pegasos2 emulates firmware when no -bios is given, this was explained in 
>previos commit so maybe not needed to be explained it here again so you could 
>drop the comment between -- -- but I don't mind.
>
>> Signed-off-by: Bernhard Beschow 
>> ---
>> hw/isa/vt82c686.c | 121 ++
>> 1 file changed, 90 insertions(+), 31 deletions(-)
>> 
>> diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
>> index 9c2333a277..be202d23cf 100644
>> --- a/hw/isa/vt82c686.c
>> +++ b/hw/isa/vt82c686.c
>> @@ -15,6 +15,9 @@
>> 
>> #include "qemu/osdep.h"
>> #include "hw/isa/vt82c686.h"
>> +#include "hw/block/fdc.h"
>> +#include "hw/char/parallel-isa.h"
>> +#include "hw/char/serial.h"
>> #include "hw/pci/pci.h"
>> #include "hw/qdev-properties.h"
>> #include "hw/ide/pci.h"
>> @@ -343,6 +346,35 @@ static const TypeInfo via_superio_info = {
>> 
>> #define TYPE_VT82C686B_SUPERIO "vt82c686b-superio"
>> 
>> +static void vt82c686b_superio_update(ViaSuperIOState *s)
>> +{
>> +isa_parallel_set_enabled(s->superio.parallel[0],
>> + (s->regs[0xe2] & 0x3) != 3);
>> +isa_serial_set_enabled(s->superio.serial[0], s->regs[0xe2] & BIT(2));
>> +isa_serial_set_enabled(s->superio.serial[1], s->regs[0xe2] & BIT(3));
>> +isa_fdc_set_enabled(s->superio.floppy, s->regs[0xe2] & BIT(4));
>> +
>> +isa_fdc_set_iobase(s->superio.floppy, (s->regs[0xe3] & 0xfc) << 2);
>> +isa_parallel_set_iobase(s->superio.parallel[0], s->regs[0xe6] << 2);
>> +isa_serial_set_iobase(s->superio.serial[0], (s->regs[0xe7] & 0xfe) << 
>> 2);
>> +isa_serial_set_iobase(s->superio.serial[1], (s->regs[0xe8] & 0xfe) << 
>> 2);
>> +}
>
>I wonder if some code duplication could be saved by adding a shared 
>via_superio_update() for this further up in the abstract via-superio class 
>instead of this method and vt8231_superio_update() below. This common method 
>in abstract class would need to handle the differences which seem to be reg 
>addresses offset by 0x10 and VT8231 having only 1 serial port. These could 
>either be handled by adding function parameters or fields to ViaSuperIOState 
>for this that the subclasses can set and the method check. (Such as reg 
>base=0xe2 for vt82c686 and 0xf2 for vt8231 and num_serial or similar for how 
>many ports are there then can have a for loop for those that would only run 
>once for vt8231).

Only the enable bits and the parallel port base address line up, the serial 
port(s) and the floppy would need special treatment. Not worth it IMO.

>
>> +static int vmstate_vt82c686b_superio_post_load(void *opaque, int version_id)
>> +{
>> +ViaSuperIOState *s = opaque;
>> +
>> +vt82c686b_superio_update(s);
>> +
>> +return 0;
>
>You could lose some blank lines here. You seem to love them, half of your 
>cover letter is just blank lines :-)

Yes, I want people to see the light rather than a wall (of text) ;-)

> but I'm the opposite and like more code to fit in one screen even on todays 
> displays that are wider than tall. So this funciton would take less space 
> without blank lines. (Even the local variable may not be necessary as you 
> don't access any fields within and void * should just cast without a warning 
> but for spelling out the desired type as a reminder I'm ok with leaving that 
> but no excessive blank lines please if you don&#x

[PATCH v2 10/12] hw/char/parallel-isa: Implement relocation and toggling for TYPE_ISA_PARALLEL

2023-12-18 Thread Bernhard Beschow
Implement isa_parallel_set_{enabled,iobase} in order to implement relocation and
toggling of SuperI/O functions in the VIA south bridges without breaking
encapsulation.

Signed-off-by: Bernhard Beschow 
---
 include/hw/char/parallel-isa.h |  3 +++
 hw/char/parallel-isa.c | 14 ++
 2 files changed, 17 insertions(+)

diff --git a/include/hw/char/parallel-isa.h b/include/hw/char/parallel-isa.h
index 3b783bd08d..5284b2ffec 100644
--- a/include/hw/char/parallel-isa.h
+++ b/include/hw/char/parallel-isa.h
@@ -29,4 +29,7 @@ struct ISAParallelState {
 PortioList portio_list;
 };
 
+void isa_parallel_set_iobase(ISADevice *parallel, hwaddr iobase);
+void isa_parallel_set_enabled(ISADevice *parallel, bool enabled);
+
 #endif /* HW_PARALLEL_ISA_H */
diff --git a/hw/char/parallel-isa.c b/hw/char/parallel-isa.c
index ab0f879998..a5ce6ee13a 100644
--- a/hw/char/parallel-isa.c
+++ b/hw/char/parallel-isa.c
@@ -41,3 +41,17 @@ void parallel_hds_isa_init(ISABus *bus, int n)
 }
 }
 }
+
+void isa_parallel_set_iobase(ISADevice *parallel, hwaddr iobase)
+{
+ISAParallelState *s = ISA_PARALLEL(parallel);
+
+parallel->ioport_id = iobase;
+s->iobase = iobase;
+portio_list_set_address(&s->portio_list, s->iobase);
+}
+
+void isa_parallel_set_enabled(ISADevice *parallel, bool enabled)
+{
+portio_list_set_enabled(&ISA_PARALLEL(parallel)->portio_list, enabled);
+}
-- 
2.43.0




[PATCH v2 12/12] hw/isa/vt82c686: Implement relocation and toggling of SuperI/O functions

2023-12-18 Thread Bernhard Beschow
The VIA south bridges are able to relocate and toggle (enable or disable) their
SuperI/O functions. So far this is hardcoded such that all functions are always
enabled and are located at fixed addresses.

Some PC BIOSes seem to probe for I/O occupancy before activating such a function
and issue an error in case of a conflict. Since the functions are enabled on
reset, conflicts are always detected. Prevent that by implementing relocation
and toggling of the SuperI/O functions.

Note that all SuperI/O functions are now deactivated upon reset (except for
VT82C686B's serial ports where Fuloong 2e's rescue-yl seems to expect them to be
enabled by default). Rely on firmware -- or in case of pegasos2 on board code if
no -bios is given -- to configure the functions accordingly.

Signed-off-by: Bernhard Beschow 
---
 hw/isa/vt82c686.c | 121 ++
 1 file changed, 90 insertions(+), 31 deletions(-)

diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index 9c2333a277..be202d23cf 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -15,6 +15,9 @@
 
 #include "qemu/osdep.h"
 #include "hw/isa/vt82c686.h"
+#include "hw/block/fdc.h"
+#include "hw/char/parallel-isa.h"
+#include "hw/char/serial.h"
 #include "hw/pci/pci.h"
 #include "hw/qdev-properties.h"
 #include "hw/ide/pci.h"
@@ -343,6 +346,35 @@ static const TypeInfo via_superio_info = {
 
 #define TYPE_VT82C686B_SUPERIO "vt82c686b-superio"
 
+static void vt82c686b_superio_update(ViaSuperIOState *s)
+{
+isa_parallel_set_enabled(s->superio.parallel[0],
+ (s->regs[0xe2] & 0x3) != 3);
+isa_serial_set_enabled(s->superio.serial[0], s->regs[0xe2] & BIT(2));
+isa_serial_set_enabled(s->superio.serial[1], s->regs[0xe2] & BIT(3));
+isa_fdc_set_enabled(s->superio.floppy, s->regs[0xe2] & BIT(4));
+
+isa_fdc_set_iobase(s->superio.floppy, (s->regs[0xe3] & 0xfc) << 2);
+isa_parallel_set_iobase(s->superio.parallel[0], s->regs[0xe6] << 2);
+isa_serial_set_iobase(s->superio.serial[0], (s->regs[0xe7] & 0xfe) << 2);
+isa_serial_set_iobase(s->superio.serial[1], (s->regs[0xe8] & 0xfe) << 2);
+}
+
+static int vmstate_vt82c686b_superio_post_load(void *opaque, int version_id)
+{
+ViaSuperIOState *s = opaque;
+
+vt82c686b_superio_update(s);
+
+return 0;
+}
+
+static const VMStateDescription vmstate_vt82c686b_superio = {
+.name = "vt82c686b_superio",
+.version_id = 1,
+.post_load = vmstate_vt82c686b_superio_post_load,
+};
+
 static void vt82c686b_superio_cfg_write(void *opaque, hwaddr addr,
 uint64_t data, unsigned size)
 {
@@ -368,7 +400,11 @@ static void vt82c686b_superio_cfg_write(void *opaque, 
hwaddr addr,
 case 0xfd ... 0xff:
 /* ignore write to read only registers */
 return;
-/* case 0xe6 ... 0xe8: Should set base port of parallel and serial */
+case 0xe2 ... 0xe3:
+case 0xe6 ... 0xe8:
+sc->regs[idx] = data;
+vt82c686b_superio_update(sc);
+return;
 default:
 qemu_log_mask(LOG_UNIMP,
   "via_superio_cfg: unimplemented register 0x%x\n", idx);
@@ -393,25 +429,24 @@ static void vt82c686b_superio_reset(DeviceState *dev)
 
 memset(s->regs, 0, sizeof(s->regs));
 /* Device ID */
-vt82c686b_superio_cfg_write(s, 0, 0xe0, 1);
-vt82c686b_superio_cfg_write(s, 1, 0x3c, 1);
-/* Function select - all disabled */
-vt82c686b_superio_cfg_write(s, 0, 0xe2, 1);
-vt82c686b_superio_cfg_write(s, 1, 0x03, 1);
+s->regs[0xe0] = 0x3c;
+/*
+ * Function select - only serial enabled
+ * Fuloong 2e's rescue-yl prints to the serial console w/o enabling it. 
This
+ * suggests that the serial ports are enabled by default, so override the
+ * datasheet.
+ */
+s->regs[0xe2] = 0x0f;
 /* Floppy ctrl base addr 0x3f0-7 */
-vt82c686b_superio_cfg_write(s, 0, 0xe3, 1);
-vt82c686b_superio_cfg_write(s, 1, 0xfc, 1);
+s->regs[0xe3] = 0xfc;
 /* Parallel port base addr 0x378-f */
-vt82c686b_superio_cfg_write(s, 0, 0xe6, 1);
-vt82c686b_superio_cfg_write(s, 1, 0xde, 1);
+s->regs[0xe6] = 0xde;
 /* Serial port 1 base addr 0x3f8-f */
-vt82c686b_superio_cfg_write(s, 0, 0xe7, 1);
-vt82c686b_superio_cfg_write(s, 1, 0xfe, 1);
+s->regs[0xe7] = 0xfe;
 /* Serial port 2 base addr 0x2f8-f */
-vt82c686b_superio_cfg_write(s, 0, 0xe8, 1);
-vt82c686b_superio_cfg_write(s, 1, 0xbe, 1);
+s->regs[0xe8] = 0xbe;
 
-vt82c686b_superio_cfg_write(s, 0, 0, 1);
+vt82c686b_superio_update(s);
 }
 
 static void vt82c686b_superio_init(Object *obj)
@@ -429,6 +464,7 @@ static void vt82c686b_superio_class_init(ObjectClass 
*klass, void *d

[PATCH v2 05/12] exec/ioport: Resolve redundant .base attribute in struct MemoryRegionPortio

2023-12-18 Thread Bernhard Beschow
portio_list_add_1() creates a MemoryRegionPortioList instance which holds a
MemoryRegion `mr` and an array of MemoryRegionPortio elements named `ports`.
Each element in the array gets assigned the same value for its .base attribute.
The same value also ends up as the .addr attribute of `mr` due to the
memory_region_add_subregion() call. This means that all .base attributes are
the same as `mr.addr`.

The only usages of MemoryRegionPortio::base were in portio_read() and
portio_write(). Both functions get above MemoryRegionPortioList as their
opaque parameter. In both cases find_portio() can only return one of the
MemoryRegionPortio elements of the `ports` array. Due to above observation any
element will have the same .base value equal to `mr.addr` which is also
accessible.

Hence, `mrpio->mr.addr` is equivalent to `mrp->base` and
MemoryRegionPortio::base is redundant and can be removed.

Signed-off-by: Bernhard Beschow 
---
 include/exec/ioport.h |  1 -
 system/ioport.c   | 13 ++---
 2 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/include/exec/ioport.h b/include/exec/ioport.h
index e34f668998..95f1dc30d0 100644
--- a/include/exec/ioport.h
+++ b/include/exec/ioport.h
@@ -35,7 +35,6 @@ typedef struct MemoryRegionPortio {
 unsigned size;
 uint32_t (*read)(void *opaque, uint32_t address);
 void (*write)(void *opaque, uint32_t address, uint32_t data);
-uint32_t base; /* private field */
 } MemoryRegionPortio;
 
 #define PORTIO_END_OF_LIST() { }
diff --git a/system/ioport.c b/system/ioport.c
index 1824aa808c..a59e58b716 100644
--- a/system/ioport.c
+++ b/system/ioport.c
@@ -181,13 +181,13 @@ static uint64_t portio_read(void *opaque, hwaddr addr, 
unsigned size)
 
 data = ((uint64_t)1 << (size * 8)) - 1;
 if (mrp) {
-data = mrp->read(mrpio->portio_opaque, mrp->base + addr);
+data = mrp->read(mrpio->portio_opaque, mrpio->mr.addr + addr);
 } else if (size == 2) {
 mrp = find_portio(mrpio, addr, 1, false);
 if (mrp) {
-data = mrp->read(mrpio->portio_opaque, mrp->base + addr);
+data = mrp->read(mrpio->portio_opaque, mrpio->mr.addr + addr);
 if (addr + 1 < mrp->offset + mrp->len) {
-data |= mrp->read(mrpio->portio_opaque, mrp->base + addr + 1) 
<< 8;
+data |= mrp->read(mrpio->portio_opaque, mrpio->mr.addr + addr 
+ 1) << 8;
 } else {
 data |= 0xff00;
 }
@@ -203,13 +203,13 @@ static void portio_write(void *opaque, hwaddr addr, 
uint64_t data,
 const MemoryRegionPortio *mrp = find_portio(mrpio, addr, size, true);
 
 if (mrp) {
-mrp->write(mrpio->portio_opaque, mrp->base + addr, data);
+mrp->write(mrpio->portio_opaque, mrpio->mr.addr + addr, data);
 } else if (size == 2) {
 mrp = find_portio(mrpio, addr, 1, true);
 if (mrp) {
-mrp->write(mrpio->portio_opaque, mrp->base + addr, data & 0xff);
+mrp->write(mrpio->portio_opaque, mrpio->mr.addr + addr, data & 
0xff);
 if (addr + 1 < mrp->offset + mrp->len) {
-mrp->write(mrpio->portio_opaque, mrp->base + addr + 1, data >> 
8);
+mrp->write(mrpio->portio_opaque, mrpio->mr.addr + addr + 1, 
data >> 8);
 }
 }
 }
@@ -244,7 +244,6 @@ static void portio_list_add_1(PortioList *piolist,
 /* Adjust the offsets to all be zero-based for the region.  */
 for (i = 0; i < count; ++i) {
 mrpio->ports[i].offset -= off_low;
-mrpio->ports[i].base = start + off_low;
 }
 
 /*
-- 
2.43.0




Re: [PATCH 04/12] hw/block/fdc: Expose internal header

2023-12-18 Thread Bernhard Beschow



Am 18. Dezember 2023 10:54:56 UTC schrieb BALATON Zoltan :
>On Sun, 17 Dec 2023, Bernhard Beschow wrote:
>> Am 17. Dezember 2023 15:47:33 UTC schrieb BALATON Zoltan 
>> :
>>> On Sun, 17 Dec 2023, Bernhard Beschow wrote:
>>>> Exposing the internal header allows for exposing struct FDCtrlISABus which 
>>>> is
>>>> encuraged by qdev guidelines.
>>> 
>>> Hopefully the guidelines don't encourage this as object orientation indeed 
>>> encourages object encapsulation so only the object itseld should poke its 
>>> internals and other objects should use methods the change object state. In 
>>> QOM some object states were exposed in public headers to allow embedding 
>>> those objects in other objects becuase C needs the struct size to allow 
>>> that. This was to simplify memory management so the embedded objects don't 
>>> need to be tracked and freed but would be created and freed with the other 
>>> object embedding it but this does not mean the other object should poke 
>>> into these object or that this is a general guideline to expose internal 
>>> object state. I'd say the exposed objects are an exception instead of 
>>> recommended guideline and only allowed for objects that need to be embeded 
>>> in others but generally object encapsulation would be better to preserve 
>>> where possible. This patch exposes objects so others can poke into them 
>>> which would make those other objects depe
>ndent on the implementation of these objects making these harder to chnage in 
>the future so a better way may be to add methods to fdc and serial to allow 
>changing their base address and map/unmap their ports and keep their internals 
>unexposed.
>> 
>> Each ISADevice sub class would need concenience methods as well as each 
>> state class. This series touches three of each: fdc, parallel, serial. And 
>> each of those need two convenience methods: set_enabled() and set_address(). 
>> This would add another 12 functions on top of the current ones.
>
>If all ISA devices need this then these should really be methods of ISADevice 
>but since that's just an empty wrapper over devices each of which handles its 
>own ports, the ISADevice does not know about those and since each device may 
>have different ports and not all of them uses portio lists for this, moving 
>port handling to ISADevice might be too big refactoring to do for this. 
>Keeping these functions with the superio component devices so their 
>implementation is kept private still worth it in my opinion so even if that 
>adds 2 functions to superio component devices (which is not all ISA devices 
>just a limited set) seems to be a better approach to me than breaking 
>encapsulation of objects. These are simple access methods for internal object 
>state which are common in object otiented programming.
>
>> Then ISASuperIODevice would require at least 6 more such methods (not 
>> counting the unneeded ones for IDE which might be desirable for 
>> consistency). So in the end we'd have at least 18 more methods. Is this 
>> really worth it?
>
>We may do without these if we say superio is just a container of components so 
>don't add forwarding methods but we can call the accessor methods of component 
>objects from vt82c686.c. That's still better than reaching into object 
>internals from foreign objects.

Version 2 is out which should address all of your comments.

Best regards,
Bernhard

>
>Regards,
>BALATON Zoltan
>
>> I didn't feel very comfortable going this route, so ended up with the 
>> current solution poking the states directly. I'm open to different 
>> approaches including the one above but I'd really like to know the opinion 
>> of the maintainers, too.
>> 
>> Best regards,
>> Bernhard
>> 
>>> 
>>> Regards,
>>> BALATON Zoltan
>>> 
>>>> Signed-off-by: Bernhard Beschow 
>>>> ---
>>>> MAINTAINERS   | 2 +-
>>>> hw/block/fdc-internal.h => include/hw/block/fdc.h | 4 ++--
>>>> hw/block/fdc-isa.c| 2 +-
>>>> hw/block/fdc-sysbus.c | 2 +-
>>>> hw/block/fdc.c| 2 +-
>>>> 5 files changed, 6 insertions(+), 6 deletions(-)
>>>> rename hw/block/fdc-internal.h => include/hw/block/fdc.h (98%)
>>>> 
>>>> diff --git a/MAINTAINERS b/MAINTAINERS
>>>> index b4718fcf59..939f518701 100644
>>>> --- a/MAINTAINERS
>>>> ++

[PATCH v2 06/12] exec/ioport: Add portio_list_set_address()

2023-12-18 Thread Bernhard Beschow
Some SuperI/O devices such as the VIA south bridges or the PC87312 controller
are able to relocate their SuperI/O functions. Add a convenience function for
implementing this in the VIA south bridges.

This convenience function relies on previous simplifications in exec/ioport
which avoids some duplicate synchronization of I/O port base addresses. The
naming of the function is inspired by its memory_region_set_address() pendant.

Signed-off-by: Bernhard Beschow 
---
 docs/devel/migration.rst |  1 +
 include/exec/ioport.h|  2 ++
 system/ioport.c  | 19 +++
 3 files changed, 22 insertions(+)

diff --git a/docs/devel/migration.rst b/docs/devel/migration.rst
index ec55089b25..389fa24bde 100644
--- a/docs/devel/migration.rst
+++ b/docs/devel/migration.rst
@@ -464,6 +464,7 @@ Examples of such memory API functions are:
   - memory_region_set_enabled()
   - memory_region_set_address()
   - memory_region_set_alias_offset()
+  - portio_list_set_address()
 
 Iterative device migration
 --
diff --git a/include/exec/ioport.h b/include/exec/ioport.h
index 95f1dc30d0..96858e5ac3 100644
--- a/include/exec/ioport.h
+++ b/include/exec/ioport.h
@@ -54,6 +54,7 @@ typedef struct PortioList {
 const struct MemoryRegionPortio *ports;
 Object *owner;
 struct MemoryRegion *address_space;
+uint32_t addr;
 unsigned nr;
 struct MemoryRegion **regions;
 void *opaque;
@@ -70,5 +71,6 @@ void portio_list_add(PortioList *piolist,
  struct MemoryRegion *address_space,
  uint32_t addr);
 void portio_list_del(PortioList *piolist);
+void portio_list_set_address(PortioList *piolist, uint32_t addr);
 
 #endif /* IOPORT_H */
diff --git a/system/ioport.c b/system/ioport.c
index a59e58b716..000e0ee1af 100644
--- a/system/ioport.c
+++ b/system/ioport.c
@@ -133,6 +133,7 @@ void portio_list_init(PortioList *piolist,
 piolist->nr = 0;
 piolist->regions = g_new0(MemoryRegion *, n);
 piolist->address_space = NULL;
+piolist->addr = 0;
 piolist->opaque = opaque;
 piolist->owner = owner;
 piolist->name = name;
@@ -282,6 +283,7 @@ void portio_list_add(PortioList *piolist,
 unsigned int off_low, off_high, off_last, count;
 
 piolist->address_space = address_space;
+piolist->addr = start;
 
 /* Handle the first entry specially.  */
 off_last = off_low = pio_start->offset;
@@ -322,6 +324,23 @@ void portio_list_del(PortioList *piolist)
 }
 }
 
+void portio_list_set_address(PortioList *piolist, uint32_t addr)
+{
+MemoryRegionPortioList *mrpio;
+unsigned i, j;
+
+for (i = 0; i < piolist->nr; ++i) {
+mrpio = container_of(piolist->regions[i], MemoryRegionPortioList, mr);
+memory_region_set_address(&mrpio->mr,
+  mrpio->mr.addr - piolist->addr + addr);
+for (j = 0; mrpio->ports[j].size; ++j) {
+mrpio->ports[j].offset += addr - piolist->addr;
+}
+}
+
+piolist->addr = addr;
+}
+
 static void memory_region_portio_list_finalize(Object *obj)
 {
 MemoryRegionPortioList *mrpio = MEMORY_REGION_PORTIO_LIST(obj);
-- 
2.43.0




[PATCH v2 04/12] hw/char/parallel: Free struct ParallelState from PortioList

2023-12-18 Thread Bernhard Beschow
ParallelState::portio_list isn't used inside ParallelState context but only
inside ISAParallelState context, so more it there.

Signed-off-by: Bernhard Beschow 
---
 include/hw/char/parallel-isa.h | 2 ++
 include/hw/char/parallel.h | 2 --
 hw/char/parallel.c | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/include/hw/char/parallel-isa.h b/include/hw/char/parallel-isa.h
index d24ccecf05..3b783bd08d 100644
--- a/include/hw/char/parallel-isa.h
+++ b/include/hw/char/parallel-isa.h
@@ -12,6 +12,7 @@
 
 #include "parallel.h"
 
+#include "exec/ioport.h"
 #include "hw/isa/isa.h"
 #include "qom/object.h"
 
@@ -25,6 +26,7 @@ struct ISAParallelState {
 uint32_t iobase;
 uint32_t isairq;
 ParallelState state;
+PortioList portio_list;
 };
 
 #endif /* HW_PARALLEL_ISA_H */
diff --git a/include/hw/char/parallel.h b/include/hw/char/parallel.h
index 7b5a309a03..cfb97cc7cc 100644
--- a/include/hw/char/parallel.h
+++ b/include/hw/char/parallel.h
@@ -1,7 +1,6 @@
 #ifndef HW_PARALLEL_H
 #define HW_PARALLEL_H
 
-#include "exec/ioport.h"
 #include "exec/memory.h"
 #include "hw/isa/isa.h"
 #include "hw/irq.h"
@@ -22,7 +21,6 @@ typedef struct ParallelState {
 uint32_t last_read_offset; /* For debugging */
 /* Memory-mapped interface */
 int it_shift;
-PortioList portio_list;
 } ParallelState;
 
 void parallel_hds_isa_init(ISABus *bus, int n);
diff --git a/hw/char/parallel.c b/hw/char/parallel.c
index 147c900f0d..c1747cbb75 100644
--- a/hw/char/parallel.c
+++ b/hw/char/parallel.c
@@ -532,7 +532,7 @@ static void parallel_isa_realizefn(DeviceState *dev, Error 
**errp)
 s->status = dummy;
 }
 
-isa_register_portio_list(isadev, &s->portio_list, base,
+isa_register_portio_list(isadev, &isa->portio_list, base,
  (s->hw_driver
   ? &isa_parallel_portio_hw_list[0]
   : &isa_parallel_portio_sw_list[0]),
-- 
2.43.0




[PATCH v2 07/12] exec/ioport: Add portio_list_set_enabled()

2023-12-18 Thread Bernhard Beschow
Some SuperI/O devices such as the VIA south bridges or the PC87312 controller
allow to enable or disable their SuperI/O functions. Add a convenience function
for implementing this in the VIA south bridges.

The naming of the functions is inspired by its memory_region_set_enabled()
pendant.

Signed-off-by: Bernhard Beschow 
---
 docs/devel/migration.rst | 1 +
 include/exec/ioport.h| 1 +
 system/ioport.c  | 9 +
 3 files changed, 11 insertions(+)

diff --git a/docs/devel/migration.rst b/docs/devel/migration.rst
index 389fa24bde..466be609a2 100644
--- a/docs/devel/migration.rst
+++ b/docs/devel/migration.rst
@@ -465,6 +465,7 @@ Examples of such memory API functions are:
   - memory_region_set_address()
   - memory_region_set_alias_offset()
   - portio_list_set_address()
+  - portio_list_set_enabled()
 
 Iterative device migration
 --
diff --git a/include/exec/ioport.h b/include/exec/ioport.h
index 96858e5ac3..4397f12f93 100644
--- a/include/exec/ioport.h
+++ b/include/exec/ioport.h
@@ -71,6 +71,7 @@ void portio_list_add(PortioList *piolist,
  struct MemoryRegion *address_space,
  uint32_t addr);
 void portio_list_del(PortioList *piolist);
+void portio_list_set_enabled(PortioList *piolist, bool enabled);
 void portio_list_set_address(PortioList *piolist, uint32_t addr);
 
 #endif /* IOPORT_H */
diff --git a/system/ioport.c b/system/ioport.c
index 000e0ee1af..fd551d0375 100644
--- a/system/ioport.c
+++ b/system/ioport.c
@@ -324,6 +324,15 @@ void portio_list_del(PortioList *piolist)
 }
 }
 
+void portio_list_set_enabled(PortioList *piolist, bool enabled)
+{
+unsigned i;
+
+for (i = 0; i < piolist->nr; ++i) {
+memory_region_set_enabled(piolist->regions[i], enabled);
+}
+}
+
 void portio_list_set_address(PortioList *piolist, uint32_t addr)
 {
 MemoryRegionPortioList *mrpio;
-- 
2.43.0




[PATCH v2 02/12] hw/block/fdc-sysbus: Free struct FDCtrl from MemoryRegion

2023-12-18 Thread Bernhard Beschow
FDCtrl::iomem isn't used inside FDCtrl context but only inside FDCtrlSysBus
context, so more it there.

Signed-off-by: Bernhard Beschow 
---
 hw/block/fdc-internal.h | 2 --
 hw/block/fdc-sysbus.c   | 6 --
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/block/fdc-internal.h b/hw/block/fdc-internal.h
index fef2bfbbf5..e219623dc7 100644
--- a/hw/block/fdc-internal.h
+++ b/hw/block/fdc-internal.h
@@ -25,7 +25,6 @@
 #ifndef HW_BLOCK_FDC_INTERNAL_H
 #define HW_BLOCK_FDC_INTERNAL_H
 
-#include "exec/memory.h"
 #include "hw/block/block.h"
 #include "hw/block/fdc.h"
 #include "qapi/qapi-types-block.h"
@@ -91,7 +90,6 @@ typedef struct FDrive {
 } FDrive;
 
 struct FDCtrl {
-MemoryRegion iomem;
 qemu_irq irq;
 /* Controller state */
 QEMUTimer *result_timer;
diff --git a/hw/block/fdc-sysbus.c b/hw/block/fdc-sysbus.c
index 86ea51d003..e197b97262 100644
--- a/hw/block/fdc-sysbus.c
+++ b/hw/block/fdc-sysbus.c
@@ -26,6 +26,7 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "qom/object.h"
+#include "exec/memory.h"
 #include "hw/sysbus.h"
 #include "hw/block/fdc.h"
 #include "migration/vmstate.h"
@@ -52,6 +53,7 @@ struct FDCtrlSysBus {
 /*< public >*/
 
 struct FDCtrl state;
+MemoryRegion iomem;
 };
 
 static uint64_t fdctrl_read_mem(void *opaque, hwaddr reg, unsigned ize)
@@ -146,11 +148,11 @@ static void sysbus_fdc_common_instance_init(Object *obj)
 
 qdev_set_legacy_instance_id(dev, 0 /* io */, 2); /* FIXME */
 
-memory_region_init_io(&fdctrl->iomem, obj,
+memory_region_init_io(&sys->iomem, obj,
   sbdc->use_strict_io ? &fdctrl_mem_strict_ops
   : &fdctrl_mem_ops,
   fdctrl, "fdc", 0x08);
-sysbus_init_mmio(sbd, &fdctrl->iomem);
+sysbus_init_mmio(sbd, &sys->iomem);
 
 sysbus_init_irq(sbd, &fdctrl->irq);
 qdev_init_gpio_in(dev, fdctrl_handle_tc, 1);
-- 
2.43.0




[PATCH v2 03/12] hw/char/serial: Free struct SerialState from MemoryRegion

2023-12-18 Thread Bernhard Beschow
SerialState::io isn't used within TYPE_SERIAL directly. Push it to its users to
make them the owner of the MemoryRegion.

Signed-off-by: Bernhard Beschow 
---
 include/hw/char/serial.h   | 2 +-
 hw/char/serial-isa.c   | 7 +--
 hw/char/serial-pci-multi.c | 7 ---
 hw/char/serial-pci.c   | 7 +--
 hw/char/serial.c   | 4 ++--
 5 files changed, 17 insertions(+), 10 deletions(-)

diff --git a/include/hw/char/serial.h b/include/hw/char/serial.h
index 8ba7eca3d6..eb4254edde 100644
--- a/include/hw/char/serial.h
+++ b/include/hw/char/serial.h
@@ -77,7 +77,6 @@ struct SerialState {
 int poll_msl;
 
 QEMUTimer *modem_status_poll;
-MemoryRegion io;
 };
 typedef struct SerialState SerialState;
 
@@ -85,6 +84,7 @@ struct SerialMM {
 SysBusDevice parent;
 
 SerialState serial;
+MemoryRegion io;
 
 uint8_t regshift;
 uint8_t endianness;
diff --git a/hw/char/serial-isa.c b/hw/char/serial-isa.c
index 141a6cb168..2be8be980b 100644
--- a/hw/char/serial-isa.c
+++ b/hw/char/serial-isa.c
@@ -26,6 +26,7 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "qemu/module.h"
+#include "exec/memory.h"
 #include "sysemu/sysemu.h"
 #include "hw/acpi/acpi_aml_interface.h"
 #include "hw/char/serial.h"
@@ -43,6 +44,7 @@ struct ISASerialState {
 uint32_t iobase;
 uint32_t isairq;
 SerialState state;
+MemoryRegion io;
 };
 
 static const int isa_serial_io[MAX_ISA_SERIAL_PORTS] = {
@@ -79,8 +81,9 @@ static void serial_isa_realizefn(DeviceState *dev, Error 
**errp)
 qdev_realize(DEVICE(s), NULL, errp);
 qdev_set_legacy_instance_id(dev, isa->iobase, 3);
 
-memory_region_init_io(&s->io, OBJECT(isa), &serial_io_ops, s, "serial", 8);
-isa_register_ioport(isadev, &s->io, isa->iobase);
+memory_region_init_io(&isa->io, OBJECT(isa), &serial_io_ops, s, "serial",
+  8);
+isa_register_ioport(isadev, &isa->io, isa->iobase);
 }
 
 static void serial_isa_build_aml(AcpiDevAmlIf *adev, Aml *scope)
diff --git a/hw/char/serial-pci-multi.c b/hw/char/serial-pci-multi.c
index 5d65c534cb..16cb2faad7 100644
--- a/hw/char/serial-pci-multi.c
+++ b/hw/char/serial-pci-multi.c
@@ -44,6 +44,7 @@ typedef struct PCIMultiSerialState {
 uint32_t ports;
 char *name[PCI_SERIAL_MAX_PORTS];
 SerialState  state[PCI_SERIAL_MAX_PORTS];
+MemoryRegion io[PCI_SERIAL_MAX_PORTS];
 uint32_t level[PCI_SERIAL_MAX_PORTS];
 qemu_irq *irqs;
 uint8_t  prog_if;
@@ -58,7 +59,7 @@ static void multi_serial_pci_exit(PCIDevice *dev)
 for (i = 0; i < pci->ports; i++) {
 s = pci->state + i;
 qdev_unrealize(DEVICE(s));
-memory_region_del_subregion(&pci->iobar, &s->io);
+memory_region_del_subregion(&pci->iobar, &pci->io[i]);
 g_free(pci->name[i]);
 }
 qemu_free_irqs(pci->irqs, pci->ports);
@@ -112,9 +113,9 @@ static void multi_serial_pci_realize(PCIDevice *dev, Error 
**errp)
 }
 s->irq = pci->irqs[i];
 pci->name[i] = g_strdup_printf("uart #%zu", i + 1);
-memory_region_init_io(&s->io, OBJECT(pci), &serial_io_ops, s,
+memory_region_init_io(&pci->io[i], OBJECT(pci), &serial_io_ops, s,
   pci->name[i], 8);
-memory_region_add_subregion(&pci->iobar, 8 * i, &s->io);
+memory_region_add_subregion(&pci->iobar, 8 * i, &pci->io[i]);
 pci->ports++;
 }
 }
diff --git a/hw/char/serial-pci.c b/hw/char/serial-pci.c
index 087da3059a..ab3d0e56b5 100644
--- a/hw/char/serial-pci.c
+++ b/hw/char/serial-pci.c
@@ -28,6 +28,7 @@
 #include "qemu/osdep.h"
 #include "qapi/error.h"
 #include "qemu/module.h"
+#include "exec/memory.h"
 #include "hw/char/serial.h"
 #include "hw/irq.h"
 #include "hw/pci/pci_device.h"
@@ -38,6 +39,7 @@
 struct PCISerialState {
 PCIDevice dev;
 SerialState state;
+MemoryRegion io;
 uint8_t prog_if;
 };
 
@@ -57,8 +59,9 @@ static void serial_pci_realize(PCIDevice *dev, Error **errp)
 pci->dev.config[PCI_INTERRUPT_PIN] = 0x01;
 s->irq = pci_allocate_irq(&pci->dev);
 
-memory_region_init_io(&s->io, OBJECT(pci), &serial_io_ops, s, "serial", 8);
-pci_register_bar(&pci->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io);
+memory_region_init_io(&pci->io, OBJECT(pci), &serial_io_ops, s, "serial",
+  8);
+pci_register_bar(&pci->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &pci->io);
 }
 
 static void serial_pci_exit(PCIDevice *dev)
diff --git a/hw/char/serial.c b/hw/char/serial.c
index a32eb25f58..83b642aec3 100644
--- a/hw/char/s

  1   2   3   4   5   6   7   >