diff mbox series

[04/11] mos6522: switch over to use qdev gpios for IRQs

Message ID 20220127205405.23499-5-mark.cave-ayland@ilande.co.uk
State New
Headers show
Series mos6522: switch to gpios, add control line edge-triggering and extra debugging | expand

Commit Message

Mark Cave-Ayland Jan. 27, 2022, 8:53 p.m. UTC
For historical reasons each mos6522 instance implements its own setting and
update of the IFR flag bits using methods exposed by MOS6522DeviceClass. As
of today this is no longer required, and it is now possible to implement
the mos6522 IRQs as standard qdev gpios.

Switch over to use qdev gpios for the mos6522 device and update all instances
accordingly.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
 hw/misc/mac_via.c         | 56 +++++++--------------------------------
 hw/misc/macio/cuda.c      |  5 ++--
 hw/misc/macio/pmu.c       |  4 +--
 hw/misc/mos6522.c         | 15 +++++++++++
 include/hw/misc/mac_via.h |  6 +----
 include/hw/misc/mos6522.h |  2 ++
 6 files changed, 32 insertions(+), 56 deletions(-)

Comments

Peter Maydell Feb. 7, 2022, 7:29 p.m. UTC | #1
On Thu, 27 Jan 2022 at 21:01, Mark Cave-Ayland
<mark.cave-ayland@ilande.co.uk> wrote:
>
> For historical reasons each mos6522 instance implements its own setting and
> update of the IFR flag bits using methods exposed by MOS6522DeviceClass. As
> of today this is no longer required, and it is now possible to implement
> the mos6522 IRQs as standard qdev gpios.
>
> Switch over to use qdev gpios for the mos6522 device and update all instances
> accordingly.
>
> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
> ---
>  hw/misc/mac_via.c         | 56 +++++++--------------------------------
>  hw/misc/macio/cuda.c      |  5 ++--
>  hw/misc/macio/pmu.c       |  4 +--
>  hw/misc/mos6522.c         | 15 +++++++++++
>  include/hw/misc/mac_via.h |  6 +----
>  include/hw/misc/mos6522.h |  2 ++
>  6 files changed, 32 insertions(+), 56 deletions(-)


> -static void via2_nubus_irq_request(void *opaque, int irq, int level)
> +static void via2_nubus_irq_request(void *opaque, int n, int level)
>  {
>      MOS6522Q800VIA2State *v2s = opaque;
>      MOS6522State *s = MOS6522(v2s);
> -    MOS6522DeviceClass *mdc = MOS6522_GET_CLASS(s);
> +    qemu_irq irq = qdev_get_gpio_in(DEVICE(s), VIA2_IRQ_NUBUS_BIT);
>
>      if (level) {
>          /* Port A nubus IRQ inputs are active LOW */
> -        s->a &= ~(1 << irq);
> -        s->ifr |= 1 << VIA2_IRQ_NUBUS_BIT;
> +        s->a &= ~(1 << n);
>      } else {
> -        s->a |= (1 << irq);
> -        s->ifr &= ~(1 << VIA2_IRQ_NUBUS_BIT);
> +        s->a |= (1 << n);
>      }
>
> -    mdc->update_irq(s);
> +    qemu_set_irq(irq, level);
>  }

It feels a bit inconsistent here that we're still reaching into
the MOS6522State to set s->a, but I guess this is still
better than what we had before.

> -#define VIA1_IRQ_NB             8
> -
>  #define VIA1_IRQ_ONE_SECOND     (1 << VIA1_IRQ_ONE_SECOND_BIT)
>  #define VIA1_IRQ_60HZ           (1 << VIA1_IRQ_60HZ_BIT)
>  #define VIA1_IRQ_ADB_READY      (1 << VIA1_IRQ_ADB_READY_BIT)
> @@ -42,7 +40,7 @@ struct MOS6522Q800VIA1State {
>
>      MemoryRegion via_mem;
>
> -    qemu_irq irqs[VIA1_IRQ_NB];
> +    qemu_irq irqs[VIA_NUM_INTS];

This irqs[] array appears to be entirely unused. You could
delete it as a separate patch before this one.

>      qemu_irq auxmode_irq;
>      uint8_t last_b;
>
> @@ -85,8 +83,6 @@ struct MOS6522Q800VIA1State {
>  #define VIA2_IRQ_SCSI_BIT       CB2_INT_BIT
>  #define VIA2_IRQ_ASC_BIT        CB1_INT_BIT
>
> -#define VIA2_IRQ_NB             8
> -
>  #define VIA2_IRQ_SCSI_DATA      (1 << VIA2_IRQ_SCSI_DATA_BIT)
>  #define VIA2_IRQ_NUBUS          (1 << VIA2_IRQ_NUBUS_BIT)
>  #define VIA2_IRQ_UNUSED         (1 << VIA2_IRQ_SCSI_BIT)
> diff --git a/include/hw/misc/mos6522.h b/include/hw/misc/mos6522.h
> index 12abd8b8d2..ced8a670bf 100644
> --- a/include/hw/misc/mos6522.h
> +++ b/include/hw/misc/mos6522.h
> @@ -57,6 +57,8 @@
>  #define T2_INT             (1 << T2_INT_BIT)
>  #define T1_INT             (1 << T1_INT_BIT)
>
> +#define VIA_NUM_INTS       5

Were we not using 5,6,7 previously ?

Anyway,
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM
Mark Cave-Ayland Feb. 20, 2022, 11:01 a.m. UTC | #2
On 07/02/2022 19:29, Peter Maydell wrote:

> On Thu, 27 Jan 2022 at 21:01, Mark Cave-Ayland
> <mark.cave-ayland@ilande.co.uk> wrote:
>>
>> For historical reasons each mos6522 instance implements its own setting and
>> update of the IFR flag bits using methods exposed by MOS6522DeviceClass. As
>> of today this is no longer required, and it is now possible to implement
>> the mos6522 IRQs as standard qdev gpios.
>>
>> Switch over to use qdev gpios for the mos6522 device and update all instances
>> accordingly.
>>
>> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
>> ---
>>   hw/misc/mac_via.c         | 56 +++++++--------------------------------
>>   hw/misc/macio/cuda.c      |  5 ++--
>>   hw/misc/macio/pmu.c       |  4 +--
>>   hw/misc/mos6522.c         | 15 +++++++++++
>>   include/hw/misc/mac_via.h |  6 +----
>>   include/hw/misc/mos6522.h |  2 ++
>>   6 files changed, 32 insertions(+), 56 deletions(-)
> 
> 
>> -static void via2_nubus_irq_request(void *opaque, int irq, int level)
>> +static void via2_nubus_irq_request(void *opaque, int n, int level)
>>   {
>>       MOS6522Q800VIA2State *v2s = opaque;
>>       MOS6522State *s = MOS6522(v2s);
>> -    MOS6522DeviceClass *mdc = MOS6522_GET_CLASS(s);
>> +    qemu_irq irq = qdev_get_gpio_in(DEVICE(s), VIA2_IRQ_NUBUS_BIT);
>>
>>       if (level) {
>>           /* Port A nubus IRQ inputs are active LOW */
>> -        s->a &= ~(1 << irq);
>> -        s->ifr |= 1 << VIA2_IRQ_NUBUS_BIT;
>> +        s->a &= ~(1 << n);
>>       } else {
>> -        s->a |= (1 << irq);
>> -        s->ifr &= ~(1 << VIA2_IRQ_NUBUS_BIT);
>> +        s->a |= (1 << n);
>>       }
>>
>> -    mdc->update_irq(s);
>> +    qemu_set_irq(irq, level);
>>   }
> 
> It feels a bit inconsistent here that we're still reaching into
> the MOS6522State to set s->a, but I guess this is still
> better than what we had before.

Yeah it's a little bit messy. On the Mac the Nubus IRQs are ORd to produce the VIA 
interrupt line, but the individual Nubus IRQ lines are wired to the VIA port A to 
allow the state of each line to be determined. The VIA port IO lines are 
bi-directional, so rather than try and implement this with GPIOs it's easiest to have 
a separate VIA2 Nubus GPIOs that also handle the port IO lines as above.

>> -#define VIA1_IRQ_NB             8
>> -
>>   #define VIA1_IRQ_ONE_SECOND     (1 << VIA1_IRQ_ONE_SECOND_BIT)
>>   #define VIA1_IRQ_60HZ           (1 << VIA1_IRQ_60HZ_BIT)
>>   #define VIA1_IRQ_ADB_READY      (1 << VIA1_IRQ_ADB_READY_BIT)
>> @@ -42,7 +40,7 @@ struct MOS6522Q800VIA1State {
>>
>>       MemoryRegion via_mem;
>>
>> -    qemu_irq irqs[VIA1_IRQ_NB];
>> +    qemu_irq irqs[VIA_NUM_INTS];
> 
> This irqs[] array appears to be entirely unused. You could
> delete it as a separate patch before this one.

Ah yes, before this patch each VIA had its own GPIOs which used the methods in 
MOS6522DeviceClass to manipulate the IFR bit. Since the Q800 VIAs have the MOS6522 
device as a parent class, the GPIOs are inherited from that and so this array should 
actually be removed as part of this patch.

>>       qemu_irq auxmode_irq;
>>       uint8_t last_b;
>>
>> @@ -85,8 +83,6 @@ struct MOS6522Q800VIA1State {
>>   #define VIA2_IRQ_SCSI_BIT       CB2_INT_BIT
>>   #define VIA2_IRQ_ASC_BIT        CB1_INT_BIT
>>
>> -#define VIA2_IRQ_NB             8
>> -
>>   #define VIA2_IRQ_SCSI_DATA      (1 << VIA2_IRQ_SCSI_DATA_BIT)
>>   #define VIA2_IRQ_NUBUS          (1 << VIA2_IRQ_NUBUS_BIT)
>>   #define VIA2_IRQ_UNUSED         (1 << VIA2_IRQ_SCSI_BIT)
>> diff --git a/include/hw/misc/mos6522.h b/include/hw/misc/mos6522.h
>> index 12abd8b8d2..ced8a670bf 100644
>> --- a/include/hw/misc/mos6522.h
>> +++ b/include/hw/misc/mos6522.h
>> @@ -57,6 +57,8 @@
>>   #define T2_INT             (1 << T2_INT_BIT)
>>   #define T1_INT             (1 << T1_INT_BIT)
>>
>> +#define VIA_NUM_INTS       5
> 
> Were we not using 5,6,7 previously ?

5 and 6 are for the in-built timers, and 7 is a set/clear flag so they are not 
externally accessible.

> Anyway,
> Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
> 
> thanks
> -- PMM


ATB,

Mark.
diff mbox series

Patch

diff --git a/hw/misc/mac_via.c b/hw/misc/mac_via.c
index b378e6b305..0756374f1b 100644
--- a/hw/misc/mac_via.c
+++ b/hw/misc/mac_via.c
@@ -325,10 +325,9 @@  static void via1_sixty_hz(void *opaque)
 {
     MOS6522Q800VIA1State *v1s = opaque;
     MOS6522State *s = MOS6522(v1s);
-    MOS6522DeviceClass *mdc = MOS6522_GET_CLASS(s);
+    qemu_irq irq = qdev_get_gpio_in(DEVICE(s), VIA1_IRQ_60HZ_BIT);
 
-    s->ifr |= VIA1_IRQ_60HZ;
-    mdc->update_irq(s);
+    qemu_set_irq(irq, 1);
 
     via1_sixty_hz_update(v1s);
 }
@@ -337,44 +336,13 @@  static void via1_one_second(void *opaque)
 {
     MOS6522Q800VIA1State *v1s = opaque;
     MOS6522State *s = MOS6522(v1s);
-    MOS6522DeviceClass *mdc = MOS6522_GET_CLASS(s);
+    qemu_irq irq = qdev_get_gpio_in(DEVICE(s), VIA1_IRQ_ONE_SECOND_BIT);
 
-    s->ifr |= VIA1_IRQ_ONE_SECOND;
-    mdc->update_irq(s);
+    qemu_set_irq(irq, 1);
 
     via1_one_second_update(v1s);
 }
 
-static void via1_irq_request(void *opaque, int irq, int level)
-{
-    MOS6522Q800VIA1State *v1s = opaque;
-    MOS6522State *s = MOS6522(v1s);
-    MOS6522DeviceClass *mdc = MOS6522_GET_CLASS(s);
-
-    if (level) {
-        s->ifr |= 1 << irq;
-    } else {
-        s->ifr &= ~(1 << irq);
-    }
-
-    mdc->update_irq(s);
-}
-
-static void via2_irq_request(void *opaque, int irq, int level)
-{
-    MOS6522Q800VIA2State *v2s = opaque;
-    MOS6522State *s = MOS6522(v2s);
-    MOS6522DeviceClass *mdc = MOS6522_GET_CLASS(s);
-
-    if (level) {
-        s->ifr |= 1 << irq;
-    } else {
-        s->ifr &= ~(1 << irq);
-    }
-
-    mdc->update_irq(s);
-}
-
 
 static void pram_update(MOS6522Q800VIA1State *v1s)
 {
@@ -1061,8 +1029,6 @@  static void mos6522_q800_via1_init(Object *obj)
     qbus_init((BusState *)&v1s->adb_bus, sizeof(v1s->adb_bus),
               TYPE_ADB_BUS, DEVICE(v1s), "adb.0");
 
-    qdev_init_gpio_in(DEVICE(obj), via1_irq_request, VIA1_IRQ_NB);
-
     /* A/UX mode */
     qdev_init_gpio_out(DEVICE(obj), &v1s->auxmode_irq, 1);
 }
@@ -1150,22 +1116,20 @@  static void mos6522_q800_via2_reset(DeviceState *dev)
     ms->a = 0x7f;
 }
 
-static void via2_nubus_irq_request(void *opaque, int irq, int level)
+static void via2_nubus_irq_request(void *opaque, int n, int level)
 {
     MOS6522Q800VIA2State *v2s = opaque;
     MOS6522State *s = MOS6522(v2s);
-    MOS6522DeviceClass *mdc = MOS6522_GET_CLASS(s);
+    qemu_irq irq = qdev_get_gpio_in(DEVICE(s), VIA2_IRQ_NUBUS_BIT);
 
     if (level) {
         /* Port A nubus IRQ inputs are active LOW */
-        s->a &= ~(1 << irq);
-        s->ifr |= 1 << VIA2_IRQ_NUBUS_BIT;
+        s->a &= ~(1 << n);
     } else {
-        s->a |= (1 << irq);
-        s->ifr &= ~(1 << VIA2_IRQ_NUBUS_BIT);
+        s->a |= (1 << n);
     }
 
-    mdc->update_irq(s);
+    qemu_set_irq(irq, level);
 }
 
 static void mos6522_q800_via2_init(Object *obj)
@@ -1177,8 +1141,6 @@  static void mos6522_q800_via2_init(Object *obj)
                           "via2", VIA_SIZE);
     sysbus_init_mmio(sbd, &v2s->via_mem);
 
-    qdev_init_gpio_in(DEVICE(obj), via2_irq_request, VIA2_IRQ_NB);
-
     qdev_init_gpio_in_named(DEVICE(obj), via2_nubus_irq_request, "nubus-irq",
                             VIA2_NUBUS_IRQ_NB);
 }
diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
index e917a6a095..f76d9227d3 100644
--- a/hw/misc/macio/cuda.c
+++ b/hw/misc/macio/cuda.c
@@ -25,6 +25,7 @@ 
 
 #include "qemu/osdep.h"
 #include "qemu-common.h"
+#include "hw/irq.h"
 #include "hw/ppc/mac.h"
 #include "hw/qdev-properties.h"
 #include "migration/vmstate.h"
@@ -96,9 +97,9 @@  static void cuda_set_sr_int(void *opaque)
     CUDAState *s = opaque;
     MOS6522CUDAState *mcs = &s->mos6522_cuda;
     MOS6522State *ms = MOS6522(mcs);
-    MOS6522DeviceClass *mdc = MOS6522_GET_CLASS(ms);
+    qemu_irq irq = qdev_get_gpio_in(DEVICE(ms), SR_INT_BIT);
 
-    mdc->set_sr_int(ms);
+    qemu_set_irq(irq, 1);
 }
 
 static void cuda_delay_set_sr_int(CUDAState *s)
diff --git a/hw/misc/macio/pmu.c b/hw/misc/macio/pmu.c
index eb39c64694..6e80fe1cfa 100644
--- a/hw/misc/macio/pmu.c
+++ b/hw/misc/macio/pmu.c
@@ -75,9 +75,9 @@  static void via_set_sr_int(void *opaque)
     PMUState *s = opaque;
     MOS6522PMUState *mps = MOS6522_PMU(&s->mos6522_pmu);
     MOS6522State *ms = MOS6522(mps);
-    MOS6522DeviceClass *mdc = MOS6522_GET_CLASS(ms);
+    qemu_irq irq = qdev_get_gpio_in(DEVICE(ms), SR_INT_BIT);
 
-    mdc->set_sr_int(ms);
+    qemu_set_irq(irq, 1);
 }
 
 static void pmu_update_extirq(PMUState *s)
diff --git a/hw/misc/mos6522.c b/hw/misc/mos6522.c
index 1c57332b40..6be6853dc2 100644
--- a/hw/misc/mos6522.c
+++ b/hw/misc/mos6522.c
@@ -52,6 +52,19 @@  static void mos6522_update_irq(MOS6522State *s)
     }
 }
 
+static void mos6522_set_irq(void *opaque, int n, int level)
+{
+    MOS6522State *s = MOS6522(opaque);
+
+    if (level) {
+        s->ifr |= 1 << n;
+    } else {
+        s->ifr &= ~(1 << n);
+    }
+
+    mos6522_update_irq(s);
+}
+
 static uint64_t get_counter_value(MOS6522State *s, MOS6522Timer *ti)
 {
     MOS6522DeviceClass *mdc = MOS6522_GET_CLASS(s);
@@ -488,6 +501,8 @@  static void mos6522_init(Object *obj)
 
     s->timers[0].timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, mos6522_timer1, s);
     s->timers[1].timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, mos6522_timer2, s);
+
+    qdev_init_gpio_in(DEVICE(obj), mos6522_set_irq, VIA_NUM_INTS);
 }
 
 static void mos6522_finalize(Object *obj)
diff --git a/include/hw/misc/mac_via.h b/include/hw/misc/mac_via.h
index 2df1ab01b6..bffeba38ee 100644
--- a/include/hw/misc/mac_via.h
+++ b/include/hw/misc/mac_via.h
@@ -24,8 +24,6 @@ 
 #define VIA1_IRQ_ADB_DATA_BIT   CB2_INT_BIT
 #define VIA1_IRQ_ADB_CLOCK_BIT  CB1_INT_BIT
 
-#define VIA1_IRQ_NB             8
-
 #define VIA1_IRQ_ONE_SECOND     (1 << VIA1_IRQ_ONE_SECOND_BIT)
 #define VIA1_IRQ_60HZ           (1 << VIA1_IRQ_60HZ_BIT)
 #define VIA1_IRQ_ADB_READY      (1 << VIA1_IRQ_ADB_READY_BIT)
@@ -42,7 +40,7 @@  struct MOS6522Q800VIA1State {
 
     MemoryRegion via_mem;
 
-    qemu_irq irqs[VIA1_IRQ_NB];
+    qemu_irq irqs[VIA_NUM_INTS];
     qemu_irq auxmode_irq;
     uint8_t last_b;
 
@@ -85,8 +83,6 @@  struct MOS6522Q800VIA1State {
 #define VIA2_IRQ_SCSI_BIT       CB2_INT_BIT
 #define VIA2_IRQ_ASC_BIT        CB1_INT_BIT
 
-#define VIA2_IRQ_NB             8
-
 #define VIA2_IRQ_SCSI_DATA      (1 << VIA2_IRQ_SCSI_DATA_BIT)
 #define VIA2_IRQ_NUBUS          (1 << VIA2_IRQ_NUBUS_BIT)
 #define VIA2_IRQ_UNUSED         (1 << VIA2_IRQ_SCSI_BIT)
diff --git a/include/hw/misc/mos6522.h b/include/hw/misc/mos6522.h
index 12abd8b8d2..ced8a670bf 100644
--- a/include/hw/misc/mos6522.h
+++ b/include/hw/misc/mos6522.h
@@ -57,6 +57,8 @@ 
 #define T2_INT             (1 << T2_INT_BIT)
 #define T1_INT             (1 << T1_INT_BIT)
 
+#define VIA_NUM_INTS       5
+
 /* Bits in ACR */
 #define T1MODE             0xc0    /* Timer 1 mode */
 #define T1MODE_CONT        0x40    /*  continuous interrupts */