Patchwork [v3,8/8] prep: Use i82378 PCI->ISA bridge for 'prep' machine

login
register
mail settings
Submitter Andreas Färber
Date Jan. 13, 2012, 3:09 a.m.
Message ID <1326424168-15705-9-git-send-email-andreas.faerber@web.de>
Download mbox | patch
Permalink /patch/135711/
State New
Headers show

Comments

Andreas Färber - Jan. 13, 2012, 3:09 a.m.
Speaker I/O, ISA bus, i8259 PIC, RTC and DMA are no longer set up
individually by the machine. Effectively, no-op speaker I/O is replaced
by pcspk; PIT and i82374 DMA are introduced.

Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>

Remove related dead, alternative code.
Access i8259 IRQs via ISA bus to resolve cyclic dependency with PCI
host bridge.

Signed-off-by: Andreas Färber <andreas.faerber@web.de>
Cc: Alexander Graf <agraf@suse.de>
Cc: Jan Kiszka <jan.kiszka@siemens.com>
---
 hw/ppc_prep.c |   54 +++++++++++-------------------------------------------
 1 files changed, 11 insertions(+), 43 deletions(-)
Jan Kiszka - Jan. 13, 2012, 9:21 a.m.
On 2012-01-13 04:09, Andreas Färber wrote:
> Speaker I/O, ISA bus, i8259 PIC, RTC and DMA are no longer set up
> individually by the machine. Effectively, no-op speaker I/O is replaced
> by pcspk; PIT and i82374 DMA are introduced.
> 
> Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
> 
> Remove related dead, alternative code.
> Access i8259 IRQs via ISA bus to resolve cyclic dependency with PCI
> host bridge.
> 
> Signed-off-by: Andreas Färber <andreas.faerber@web.de>
> Cc: Alexander Graf <agraf@suse.de>
> Cc: Jan Kiszka <jan.kiszka@siemens.com>
> ---
>  hw/ppc_prep.c |   54 +++++++++++-------------------------------------------
>  1 files changed, 11 insertions(+), 43 deletions(-)
> 
> diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c
> index 747539f..9485d45 100644
> --- a/hw/ppc_prep.c
> +++ b/hw/ppc_prep.c
> @@ -83,37 +83,9 @@ static const int ide_irq[2] = { 13, 13 };
>  static uint32_t ne2000_io[NE2000_NB_MAX] = { 0x300, 0x320, 0x340, 0x360, 0x280, 0x380 };
>  static int ne2000_irq[NE2000_NB_MAX] = { 9, 10, 11, 3, 4, 5 };
>  
> -//static ISADevice *pit;
> -
>  /* ISA IO ports bridge */
>  #define PPC_IO_BASE 0x80000000
>  
> -#if 0
> -/* Speaker port 0x61 */
> -static int speaker_data_on;
> -static int dummy_refresh_clock;
> -#endif
> -
> -static void speaker_ioport_write (void *opaque, uint32_t addr, uint32_t val)
> -{
> -#if 0
> -    speaker_data_on = (val >> 1) & 1;
> -    pit_set_gate(pit, 2, val & 1);
> -#endif
> -}
> -
> -static uint32_t speaker_ioport_read (void *opaque, uint32_t addr)
> -{
> -#if 0
> -    int out;
> -    out = pit_get_out(pit, 2, qemu_get_clock_ns(vm_clock));
> -    dummy_refresh_clock ^= 1;
> -    return (speaker_data_on << 1) | pit_get_gate(pit, 2) | (out << 5) |
> -        (dummy_refresh_clock << 4);
> -#endif
> -    return 0;
> -}
> -
>  /* PCI intack register */
>  /* Read-only register (?) */
>  static void PPC_intack_write (void *opaque, target_phys_addr_t addr,
> @@ -526,6 +498,7 @@ static void ppc_prep_init (ram_addr_t ram_size,
>      SysBusDevice *sys;
>      PCIHostState *pcihost;
>      PCIBus *pci_bus;
> +    PCIDevice *pci;
>      ISABus *isa_bus;
>      qemu_irq *i8259;
>      qemu_irq *cpu_exit_irq;
> @@ -629,13 +602,9 @@ static void ppc_prep_init (ram_addr_t ram_size,
>          }
>      }
>  
> -    isa_mem_base = 0xc0000000;
>      if (PPC_INPUT(env) != PPC_FLAGS_INPUT_6xx) {
>          hw_error("Only 6xx bus is supported on PREP machine\n");
>      }
> -    /* Hmm, prep has no pci-isa bridge ??? */
> -    isa_bus = isa_bus_new(NULL, get_system_io());
> -    i8259 = i8259_init(isa_bus, first_cpu->irq_inputs[PPC6xx_INPUT_INT]);
>  
>      dev = qdev_create(NULL, "raven-pcihost");
>      sys = sysbus_from_qdev(dev);
> @@ -648,13 +617,21 @@ static void ppc_prep_init (ram_addr_t ram_size,
>          fprintf(stderr, "Couldn't create PCI host controller.\n");
>          exit(1);
>      }
> +
> +    /* PCI -> ISA bridge */
> +    pci = pci_create_simple(pci_bus, PCI_DEVFN(1, 0), "i82378");
> +    cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1);
> +    qdev_connect_gpio_out(&pci->qdev, 0,
> +                          first_cpu->irq_inputs[PPC6xx_INPUT_INT]);
> +    qdev_connect_gpio_out(&pci->qdev, 1, *cpu_exit_irq);
> +    isa_bus = DO_UPCAST(ISABus, qbus, qdev_get_child_bus(&pci->qdev, "isa.0"));
> +
> +    i8259 = isa_bus->irqs;

I think this is unneeded. You only access i8259[8] later on for
initializing the m48t59. But that one should be creatable as ISA device
now (m48t59_init_isa), no? Please check.

Jan
Andreas Färber - Jan. 13, 2012, 3:57 p.m.
Am 13.01.2012 10:21, schrieb Jan Kiszka:
> On 2012-01-13 04:09, Andreas Färber wrote:
>> +    isa_bus = DO_UPCAST(ISABus, qbus, qdev_get_child_bus(&pci->qdev, "isa.0"));
>> +
>> +    i8259 = isa_bus->irqs;
> 
> I think this is unneeded.

The problem here was that isa_get_irq() needs an ISADevice*, not just
the ISABus*, so I had to access ->irqs directly at this point.

Some of the later ISA devices are optional, others will be moved to the
pc87312. The i8042 might be an option if we really have to.

> You only access i8259[8] later on for
> initializing the m48t59.

And immediately following your quote i8259[9] and i8259[11] for the host
bridge.

The alternative would be to access the i8259's IRQs (initialized in the
PCI-ISA bridge needing the PCI host bridge) via a QOM property from
here. Or access the PCI host bridge from the PCI-ISA bridge init.

> But that one should be creatable as ISA device
> now (m48t59_init_isa), no? Please check.

Ah, that matches a patch by Hervé confusingly named "fix compilation".
Using the ISA version even resolves the m48t59 io_base issue I reported
earlier. I'll send a separate patch and rebase onto that.

Andreas
Jan Kiszka - Jan. 13, 2012, 4:08 p.m.
On 2012-01-13 16:57, Andreas Färber wrote:
> Am 13.01.2012 10:21, schrieb Jan Kiszka:
>> On 2012-01-13 04:09, Andreas Färber wrote:
>>> +    isa_bus = DO_UPCAST(ISABus, qbus, qdev_get_child_bus(&pci->qdev, "isa.0"));
>>> +
>>> +    i8259 = isa_bus->irqs;
>>
>> I think this is unneeded.
> 
> The problem here was that isa_get_irq() needs an ISADevice*, not just
> the ISABus*, so I had to access ->irqs directly at this point.

Which is a hack that should not be merged.

> 
> Some of the later ISA devices are optional, others will be moved to the
> pc87312. The i8042 might be an option if we really have to.
> 
>> You only access i8259[8] later on for
>> initializing the m48t59.
> 
> And immediately following your quote i8259[9] and i8259[11] for the host
> bridge.

I was looking at upstream. Which patch is this?

> 
> The alternative would be to access the i8259's IRQs (initialized in the
> PCI-ISA bridge needing the PCI host bridge) via a QOM property from
> here. Or access the PCI host bridge from the PCI-ISA bridge init.
> 
>> But that one should be creatable as ISA device
>> now (m48t59_init_isa), no? Please check.
> 
> Ah, that matches a patch by Hervé confusingly named "fix compilation".
> Using the ISA version even resolves the m48t59 io_base issue I reported
> earlier. I'll send a separate patch and rebase onto that.

What about the other IRQs? Can they be associated with ISADevices as well?

Jan
Alexander Graf - Jan. 13, 2012, 4:23 p.m.
On 13.01.2012, at 17:08, Jan Kiszka wrote:

> On 2012-01-13 16:57, Andreas Färber wrote:
>> Am 13.01.2012 10:21, schrieb Jan Kiszka:
>>> On 2012-01-13 04:09, Andreas Färber wrote:
>>>> +    isa_bus = DO_UPCAST(ISABus, qbus, qdev_get_child_bus(&pci->qdev, "isa.0"));
>>>> +
>>>> +    i8259 = isa_bus->irqs;
>>> 
>>> I think this is unneeded.
>> 
>> The problem here was that isa_get_irq() needs an ISADevice*, not just
>> the ISABus*, so I had to access ->irqs directly at this point.
> 
> Which is a hack that should not be merged.
> 
>> 
>> Some of the later ISA devices are optional, others will be moved to the
>> pc87312. The i8042 might be an option if we really have to.
>> 
>>> You only access i8259[8] later on for
>>> initializing the m48t59.
>> 
>> And immediately following your quote i8259[9] and i8259[11] for the host
>> bridge.
> 
> I was looking at upstream. Which patch is this?

The patch you were commenting on :)

Alex
Jan Kiszka - Jan. 13, 2012, 4:45 p.m.
On 2012-01-13 17:23, Alexander Graf wrote:
> 
> On 13.01.2012, at 17:08, Jan Kiszka wrote:
> 
>> On 2012-01-13 16:57, Andreas Färber wrote:
>>> Am 13.01.2012 10:21, schrieb Jan Kiszka:
>>>> On 2012-01-13 04:09, Andreas Färber wrote:
>>>>> +    isa_bus = DO_UPCAST(ISABus, qbus, qdev_get_child_bus(&pci->qdev, "isa.0"));
>>>>> +
>>>>> +    i8259 = isa_bus->irqs;
>>>>
>>>> I think this is unneeded.
>>>
>>> The problem here was that isa_get_irq() needs an ISADevice*, not just
>>> the ISABus*, so I had to access ->irqs directly at this point.
>>
>> Which is a hack that should not be merged.
>>
>>>
>>> Some of the later ISA devices are optional, others will be moved to the
>>> pc87312. The i8042 might be an option if we really have to.
>>>
>>>> You only access i8259[8] later on for
>>>> initializing the m48t59.
>>>
>>> And immediately following your quote i8259[9] and i8259[11] for the host
>>> bridge.
>>
>> I was looking at upstream. Which patch is this?
> 
> The patch you were commenting on :)

I see now. It just doesn't introduce it. :)

OK, so the problem is that the creator of the PIC does not export the
input IRQs in a way that they can be used by non-ISA chipset-external
devices as well. It's that fixable? Via GPIO pins of the chipset e.g.?

Jan

Patch

diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c
index 747539f..9485d45 100644
--- a/hw/ppc_prep.c
+++ b/hw/ppc_prep.c
@@ -83,37 +83,9 @@  static const int ide_irq[2] = { 13, 13 };
 static uint32_t ne2000_io[NE2000_NB_MAX] = { 0x300, 0x320, 0x340, 0x360, 0x280, 0x380 };
 static int ne2000_irq[NE2000_NB_MAX] = { 9, 10, 11, 3, 4, 5 };
 
-//static ISADevice *pit;
-
 /* ISA IO ports bridge */
 #define PPC_IO_BASE 0x80000000
 
-#if 0
-/* Speaker port 0x61 */
-static int speaker_data_on;
-static int dummy_refresh_clock;
-#endif
-
-static void speaker_ioport_write (void *opaque, uint32_t addr, uint32_t val)
-{
-#if 0
-    speaker_data_on = (val >> 1) & 1;
-    pit_set_gate(pit, 2, val & 1);
-#endif
-}
-
-static uint32_t speaker_ioport_read (void *opaque, uint32_t addr)
-{
-#if 0
-    int out;
-    out = pit_get_out(pit, 2, qemu_get_clock_ns(vm_clock));
-    dummy_refresh_clock ^= 1;
-    return (speaker_data_on << 1) | pit_get_gate(pit, 2) | (out << 5) |
-        (dummy_refresh_clock << 4);
-#endif
-    return 0;
-}
-
 /* PCI intack register */
 /* Read-only register (?) */
 static void PPC_intack_write (void *opaque, target_phys_addr_t addr,
@@ -526,6 +498,7 @@  static void ppc_prep_init (ram_addr_t ram_size,
     SysBusDevice *sys;
     PCIHostState *pcihost;
     PCIBus *pci_bus;
+    PCIDevice *pci;
     ISABus *isa_bus;
     qemu_irq *i8259;
     qemu_irq *cpu_exit_irq;
@@ -629,13 +602,9 @@  static void ppc_prep_init (ram_addr_t ram_size,
         }
     }
 
-    isa_mem_base = 0xc0000000;
     if (PPC_INPUT(env) != PPC_FLAGS_INPUT_6xx) {
         hw_error("Only 6xx bus is supported on PREP machine\n");
     }
-    /* Hmm, prep has no pci-isa bridge ??? */
-    isa_bus = isa_bus_new(NULL, get_system_io());
-    i8259 = i8259_init(isa_bus, first_cpu->irq_inputs[PPC6xx_INPUT_INT]);
 
     dev = qdev_create(NULL, "raven-pcihost");
     sys = sysbus_from_qdev(dev);
@@ -648,13 +617,21 @@  static void ppc_prep_init (ram_addr_t ram_size,
         fprintf(stderr, "Couldn't create PCI host controller.\n");
         exit(1);
     }
+
+    /* PCI -> ISA bridge */
+    pci = pci_create_simple(pci_bus, PCI_DEVFN(1, 0), "i82378");
+    cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1);
+    qdev_connect_gpio_out(&pci->qdev, 0,
+                          first_cpu->irq_inputs[PPC6xx_INPUT_INT]);
+    qdev_connect_gpio_out(&pci->qdev, 1, *cpu_exit_irq);
+    isa_bus = DO_UPCAST(ISABus, qbus, qdev_get_child_bus(&pci->qdev, "isa.0"));
+
+    i8259 = isa_bus->irqs;
     sysbus_connect_irq(&pcihost->busdev, 0, i8259[9]);
     sysbus_connect_irq(&pcihost->busdev, 1, i8259[11]);
     sysbus_connect_irq(&pcihost->busdev, 2, i8259[9]);
     sysbus_connect_irq(&pcihost->busdev, 3, i8259[11]);
 
-    isa_bus_irqs(isa_bus, i8259);
-    //    pci_bus = i440fx_init();
     /* Register 8 MB of ISA IO space (needed for non-contiguous map) */
     memory_region_init_io(PPC_io_memory, &PPC_prep_io_ops, sysctrl,
                           "ppc-io", 0x00800000);
@@ -662,9 +639,6 @@  static void ppc_prep_init (ram_addr_t ram_size,
 
     /* init basic PC hardware */
     pci_vga_init(pci_bus);
-    //    openpic = openpic_init(0x00000000, 0xF0000000, 1);
-    //    pit = pit_init(0x40, 0);
-    rtc_init(isa_bus, 2000, NULL);
 
     if (serial_hds[0])
         serial_isa_init(isa_bus, 0, serial_hds[0]);
@@ -691,9 +665,6 @@  static void ppc_prep_init (ram_addr_t ram_size,
     }
     isa_create_simple(isa_bus, "i8042");
 
-    cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1);
-    DMA_init(1, cpu_exit_irq);
-
     //    SB16_init();
 
     for(i = 0; i < MAX_FD; i++) {
@@ -701,9 +672,6 @@  static void ppc_prep_init (ram_addr_t ram_size,
     }
     fdctrl_init_isa(isa_bus, fd);
 
-    /* Register speaker port */
-    register_ioport_read(0x61, 1, 1, speaker_ioport_read, NULL);
-    register_ioport_write(0x61, 1, 1, speaker_ioport_write, NULL);
     /* Register fake IO ports for PREP */
     sysctrl->reset_irq = first_cpu->irq_inputs[PPC6xx_INPUT_HRESET];
     register_ioport_read(0x398, 2, 1, &PREP_io_read, sysctrl);