Re: [PATCH 2/3] q800: add djMEMC memory controller

2019-12-14 Thread Mark Cave-Ayland
On 12/12/2019 20:01, Laurent Vivier wrote:

> Current implementation is based on GLUE, an early implementation
> of the memory controller found in Macintosh II series.
> 
> Quadra 800 uses in fact djMEMC:
> 
> The djMEMC is an Apple custom integrated circuit chip that performs a
> variety of functions (RAM management, clock generation, ...).
> It receives interrupt requests from various devices, assign priority to
> each, and asserts one or more interrupt line to the CPU.
> 
> Signed-off-by: Laurent Vivier 
> ---
>  MAINTAINERS  |   2 +
>  hw/m68k/Kconfig  |   1 +
>  hw/m68k/q800.c   |  61 --
>  hw/misc/Kconfig  |   3 +
>  hw/misc/Makefile.objs|   1 +
>  hw/misc/djmemc.c | 176 +++
>  hw/misc/trace-events |   4 +
>  include/hw/misc/djmemc.h |  34 
>  8 files changed, 237 insertions(+), 45 deletions(-)
>  create mode 100644 hw/misc/djmemc.c
>  create mode 100644 include/hw/misc/djmemc.h
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 5e5e3e52d6..07224a2fa2 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -925,11 +925,13 @@ F: hw/misc/mac_via.c
>  F: hw/nubus/*
>  F: hw/display/macfb.c
>  F: hw/block/swim.c
> +F: hw/misc/djmemc.c
>  F: hw/m68k/bootinfo.h
>  F: include/hw/misc/mac_via.h
>  F: include/hw/nubus/*
>  F: include/hw/display/macfb.h
>  F: include/hw/block/swim.h
> +F: include/hw/misc/djmemc.c
>  
>  MicroBlaze Machines
>  ---
> diff --git a/hw/m68k/Kconfig b/hw/m68k/Kconfig
> index c757e7dfa4..bdc43a798a 100644
> --- a/hw/m68k/Kconfig
> +++ b/hw/m68k/Kconfig
> @@ -22,3 +22,4 @@ config Q800
>  select ESCC
>  select ESP
>  select DP8393X
> +select DJMEMC
> diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c
> index ef0014f4c4..9ee0cb1141 100644
> --- a/hw/m68k/q800.c
> +++ b/hw/m68k/q800.c
> @@ -46,6 +46,7 @@
>  #include "sysemu/qtest.h"
>  #include "sysemu/runstate.h"
>  #include "sysemu/reset.h"
> +#include "hw/misc/djmemc.h"
>  
>  #define MACROM_ADDR 0x4000
>  #define MACROM_SIZE 0x0010
> @@ -68,6 +69,7 @@
>  #define SONIC_PROM_BASE   (IO_BASE + 0x08000)
>  #define SONIC_BASE(IO_BASE + 0x0a000)
>  #define SCC_BASE  (IO_BASE + 0x0c000)
> +#define DJMEMC_BASE   (IO_BASE + 0x0e000)
>  #define ESP_BASE  (IO_BASE + 0x1)
>  #define ESP_PDMA  (IO_BASE + 0x10100)
>  #define ASC_BASE  (IO_BASE + 0x14000)
> @@ -85,39 +87,6 @@
>  
>  #define MAC_CLOCK  3686418
>  
> -/*
> - * The GLUE (General Logic Unit) is an Apple custom integrated circuit chip
> - * that performs a variety of functions (RAM management, clock generation, 
> ...).
> - * The GLUE chip receives interrupt requests from various devices,
> - * assign priority to each, and asserts one or more interrupt line to the
> - * CPU.
> - */
> -
> -typedef struct {
> -M68kCPU *cpu;
> -uint8_t ipr;
> -} GLUEState;
> -
> -static void GLUE_set_irq(void *opaque, int irq, int level)
> -{
> -GLUEState *s = opaque;
> -int i;
> -
> -if (level) {
> -s->ipr |= 1 << irq;
> -} else {
> -s->ipr &= ~(1 << irq);
> -}
> -
> -for (i = 7; i >= 0; i--) {
> -if ((s->ipr >> i) & 1) {
> -m68k_set_irq_level(s->cpu, i + 1, i + 25);
> -return;
> -}
> -}
> -m68k_set_irq_level(s->cpu, 0, 0);
> -}
> -
>  static void main_cpu_reset(void *opaque)
>  {
>  M68kCPU *cpu = opaque;
> @@ -149,6 +118,7 @@ static void q800_init(MachineState *machine)
>  const char *kernel_cmdline = machine->kernel_cmdline;
>  hwaddr parameters_base;
>  CPUState *cs;
> +DeviceState *djmemc_dev;
>  DeviceState *dev;
>  DeviceState *via_dev;
>  SysBusESPState *sysbus_esp;
> @@ -156,8 +126,6 @@ static void q800_init(MachineState *machine)
>  SysBusDevice *sysbus;
>  BusState *adb_bus;
>  NubusBus *nubus;
> -GLUEState *irq;
> -qemu_irq *pic;
>  
>  linux_boot = (kernel_filename != NULL);
>  
> @@ -191,11 +159,13 @@ static void q800_init(MachineState *machine)
>  g_free(name);
>  }
>  
> -/* IRQ Glue */
> +/* djMEMC memory and interrupt controller */
>  
> -irq = g_new0(GLUEState, 1);
> -irq->cpu = cpu;
> -pic = qemu_allocate_irqs(GLUE_set_irq, irq, 8);
> +djmemc_dev = qdev_create(NULL, TYPE_DJMEMC);
> +object_property_set_link(OBJECT(djmemc_dev), OBJECT(cpu), "cpu",
> + _abort);
> +qdev_init_nofail(djmemc_dev);
> +sysbus_mmio_map(SYS_BUS_DEVICE(djmemc_dev), 0, DJMEMC_BASE);
>  
>  /* VIA */
>  
> @@ -203,9 +173,10 @@ static void q800_init(MachineState *machine)
>  qdev_init_nofail(via_dev);
>  sysbus = SYS_BUS_DEVICE(via_dev);
>  sysbus_mmio_map(sysbus, 0, VIA_BASE);
> -qdev_connect_gpio_out_named(DEVICE(sysbus), "irq", 0, pic[0]);
> -qdev_connect_gpio_out_named(DEVICE(sysbus), "irq", 1, pic[1]);
> -
> +

Re: [PATCH 2/3] q800: add djMEMC memory controller

2019-12-12 Thread Philippe Mathieu-Daudé

On 12/12/19 9:01 PM, Laurent Vivier wrote:

Current implementation is based on GLUE, an early implementation
of the memory controller found in Macintosh II series.

Quadra 800 uses in fact djMEMC:

The djMEMC is an Apple custom integrated circuit chip that performs a
variety of functions (RAM management, clock generation, ...).
It receives interrupt requests from various devices, assign priority to
each, and asserts one or more interrupt line to the CPU.

Signed-off-by: Laurent Vivier 
---
  MAINTAINERS  |   2 +
  hw/m68k/Kconfig  |   1 +
  hw/m68k/q800.c   |  61 --
  hw/misc/Kconfig  |   3 +
  hw/misc/Makefile.objs|   1 +
  hw/misc/djmemc.c | 176 +++
  hw/misc/trace-events |   4 +
  include/hw/misc/djmemc.h |  34 
  8 files changed, 237 insertions(+), 45 deletions(-)
  create mode 100644 hw/misc/djmemc.c
  create mode 100644 include/hw/misc/djmemc.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 5e5e3e52d6..07224a2fa2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -925,11 +925,13 @@ F: hw/misc/mac_via.c
  F: hw/nubus/*
  F: hw/display/macfb.c
  F: hw/block/swim.c
+F: hw/misc/djmemc.c
  F: hw/m68k/bootinfo.h
  F: include/hw/misc/mac_via.h
  F: include/hw/nubus/*
  F: include/hw/display/macfb.h
  F: include/hw/block/swim.h
+F: include/hw/misc/djmemc.c
  
  MicroBlaze Machines

  ---
diff --git a/hw/m68k/Kconfig b/hw/m68k/Kconfig
index c757e7dfa4..bdc43a798a 100644
--- a/hw/m68k/Kconfig
+++ b/hw/m68k/Kconfig
@@ -22,3 +22,4 @@ config Q800
  select ESCC
  select ESP
  select DP8393X
+select DJMEMC
diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c
index ef0014f4c4..9ee0cb1141 100644
--- a/hw/m68k/q800.c
+++ b/hw/m68k/q800.c
@@ -46,6 +46,7 @@
  #include "sysemu/qtest.h"
  #include "sysemu/runstate.h"
  #include "sysemu/reset.h"
+#include "hw/misc/djmemc.h"
  
  #define MACROM_ADDR 0x4000

  #define MACROM_SIZE 0x0010
@@ -68,6 +69,7 @@
  #define SONIC_PROM_BASE   (IO_BASE + 0x08000)
  #define SONIC_BASE(IO_BASE + 0x0a000)
  #define SCC_BASE  (IO_BASE + 0x0c000)
+#define DJMEMC_BASE   (IO_BASE + 0x0e000)
  #define ESP_BASE  (IO_BASE + 0x1)
  #define ESP_PDMA  (IO_BASE + 0x10100)
  #define ASC_BASE  (IO_BASE + 0x14000)
@@ -85,39 +87,6 @@
  
  #define MAC_CLOCK  3686418
  
-/*

- * The GLUE (General Logic Unit) is an Apple custom integrated circuit chip
- * that performs a variety of functions (RAM management, clock generation, 
...).
- * The GLUE chip receives interrupt requests from various devices,
- * assign priority to each, and asserts one or more interrupt line to the
- * CPU.
- */
-
-typedef struct {
-M68kCPU *cpu;
-uint8_t ipr;
-} GLUEState;
-
-static void GLUE_set_irq(void *opaque, int irq, int level)
-{
-GLUEState *s = opaque;
-int i;
-
-if (level) {
-s->ipr |= 1 << irq;
-} else {
-s->ipr &= ~(1 << irq);
-}
-
-for (i = 7; i >= 0; i--) {
-if ((s->ipr >> i) & 1) {
-m68k_set_irq_level(s->cpu, i + 1, i + 25);
-return;
-}
-}
-m68k_set_irq_level(s->cpu, 0, 0);
-}
-
  static void main_cpu_reset(void *opaque)
  {
  M68kCPU *cpu = opaque;
@@ -149,6 +118,7 @@ static void q800_init(MachineState *machine)
  const char *kernel_cmdline = machine->kernel_cmdline;
  hwaddr parameters_base;
  CPUState *cs;
+DeviceState *djmemc_dev;
  DeviceState *dev;
  DeviceState *via_dev;
  SysBusESPState *sysbus_esp;
@@ -156,8 +126,6 @@ static void q800_init(MachineState *machine)
  SysBusDevice *sysbus;
  BusState *adb_bus;
  NubusBus *nubus;
-GLUEState *irq;
-qemu_irq *pic;
  
  linux_boot = (kernel_filename != NULL);
  
@@ -191,11 +159,13 @@ static void q800_init(MachineState *machine)

  g_free(name);
  }
  
-/* IRQ Glue */

+/* djMEMC memory and interrupt controller */
  
-irq = g_new0(GLUEState, 1);

-irq->cpu = cpu;
-pic = qemu_allocate_irqs(GLUE_set_irq, irq, 8);


Glad to see you add a QOM INTC and use QDEV API.


+djmemc_dev = qdev_create(NULL, TYPE_DJMEMC);
+object_property_set_link(OBJECT(djmemc_dev), OBJECT(cpu), "cpu",
+ _abort);
+qdev_init_nofail(djmemc_dev);
+sysbus_mmio_map(SYS_BUS_DEVICE(djmemc_dev), 0, DJMEMC_BASE);
  
  /* VIA */
  
@@ -203,9 +173,10 @@ static void q800_init(MachineState *machine)

  qdev_init_nofail(via_dev);
  sysbus = SYS_BUS_DEVICE(via_dev);
  sysbus_mmio_map(sysbus, 0, VIA_BASE);
-qdev_connect_gpio_out_named(DEVICE(sysbus), "irq", 0, pic[0]);
-qdev_connect_gpio_out_named(DEVICE(sysbus), "irq", 1, pic[1]);
-
+qdev_connect_gpio_out_named(DEVICE(sysbus), "irq", 0,
+qdev_get_gpio_in(djmemc_dev, 0));
+qdev_connect_gpio_out_named(DEVICE(sysbus),
+"irq", 1, 

Re: [PATCH 2/3] q800: add djMEMC memory controller

2019-12-12 Thread BALATON Zoltan

On Thu, 12 Dec 2019, Laurent Vivier wrote:

Current implementation is based on GLUE, an early implementation
of the memory controller found in Macintosh II series.

Quadra 800 uses in fact djMEMC:

The djMEMC is an Apple custom integrated circuit chip that performs a
variety of functions (RAM management, clock generation, ...).
It receives interrupt requests from various devices, assign priority to
each, and asserts one or more interrupt line to the CPU.

Signed-off-by: Laurent Vivier 
---
MAINTAINERS  |   2 +
hw/m68k/Kconfig  |   1 +
hw/m68k/q800.c   |  61 --
hw/misc/Kconfig  |   3 +
hw/misc/Makefile.objs|   1 +
hw/misc/djmemc.c | 176 +++
hw/misc/trace-events |   4 +
include/hw/misc/djmemc.h |  34 
8 files changed, 237 insertions(+), 45 deletions(-)
create mode 100644 hw/misc/djmemc.c
create mode 100644 include/hw/misc/djmemc.h


[...]

diff --git a/hw/misc/djmemc.c b/hw/misc/djmemc.c
new file mode 100644
index 00..b494e82a60
--- /dev/null
+++ b/hw/misc/djmemc.c
@@ -0,0 +1,176 @@
+/*
+ * djMEMC, macintosh memory and interrupt controller
+ * (Quadra 610/650/800 & Centris 610/650)
+ *
+ *https://mac68k.info/wiki/display/mac68k/djMEMC+Information
+ *
+ * The djMEMC is an Apple custom integrated circuit chip that performs a
+ * variety of functions (RAM management, clock generation, ...).
+ * It receives interrupt requests from various devices, assign priority to
+ * each, and asserts one or more interrupt line to the CPU.
+ */
+
+#include "qemu/osdep.h"
+#include "migration/vmstate.h"
+#include "hw/misc/djmemc.h"
+#include "hw/qdev-properties.h"
+#include "trace.h"
+
+#define DJMEMC_SIZE   0x2000
+
+#define InterleaveConf0
+#define Bank0Conf 1
+#define Bank1Conf 2
+#define Bank2Conf 3
+#define Bank3Conf 4
+#define Bank4Conf 5
+#define Bank5Conf 6
+#define Bank6Conf 7
+#define Bank7Conf 8
+#define Bank8Conf 9
+#define Bank9Conf 10
+#define MemTop11
+#define Config12
+#define Refresh   13


Should this be an enum so the compiler can better verify values and if all 
cases are handled?


Regards,
BALATON Zoltan



[PATCH 2/3] q800: add djMEMC memory controller

2019-12-12 Thread Laurent Vivier
Current implementation is based on GLUE, an early implementation
of the memory controller found in Macintosh II series.

Quadra 800 uses in fact djMEMC:

The djMEMC is an Apple custom integrated circuit chip that performs a
variety of functions (RAM management, clock generation, ...).
It receives interrupt requests from various devices, assign priority to
each, and asserts one or more interrupt line to the CPU.

Signed-off-by: Laurent Vivier 
---
 MAINTAINERS  |   2 +
 hw/m68k/Kconfig  |   1 +
 hw/m68k/q800.c   |  61 --
 hw/misc/Kconfig  |   3 +
 hw/misc/Makefile.objs|   1 +
 hw/misc/djmemc.c | 176 +++
 hw/misc/trace-events |   4 +
 include/hw/misc/djmemc.h |  34 
 8 files changed, 237 insertions(+), 45 deletions(-)
 create mode 100644 hw/misc/djmemc.c
 create mode 100644 include/hw/misc/djmemc.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 5e5e3e52d6..07224a2fa2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -925,11 +925,13 @@ F: hw/misc/mac_via.c
 F: hw/nubus/*
 F: hw/display/macfb.c
 F: hw/block/swim.c
+F: hw/misc/djmemc.c
 F: hw/m68k/bootinfo.h
 F: include/hw/misc/mac_via.h
 F: include/hw/nubus/*
 F: include/hw/display/macfb.h
 F: include/hw/block/swim.h
+F: include/hw/misc/djmemc.c
 
 MicroBlaze Machines
 ---
diff --git a/hw/m68k/Kconfig b/hw/m68k/Kconfig
index c757e7dfa4..bdc43a798a 100644
--- a/hw/m68k/Kconfig
+++ b/hw/m68k/Kconfig
@@ -22,3 +22,4 @@ config Q800
 select ESCC
 select ESP
 select DP8393X
+select DJMEMC
diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c
index ef0014f4c4..9ee0cb1141 100644
--- a/hw/m68k/q800.c
+++ b/hw/m68k/q800.c
@@ -46,6 +46,7 @@
 #include "sysemu/qtest.h"
 #include "sysemu/runstate.h"
 #include "sysemu/reset.h"
+#include "hw/misc/djmemc.h"
 
 #define MACROM_ADDR 0x4000
 #define MACROM_SIZE 0x0010
@@ -68,6 +69,7 @@
 #define SONIC_PROM_BASE   (IO_BASE + 0x08000)
 #define SONIC_BASE(IO_BASE + 0x0a000)
 #define SCC_BASE  (IO_BASE + 0x0c000)
+#define DJMEMC_BASE   (IO_BASE + 0x0e000)
 #define ESP_BASE  (IO_BASE + 0x1)
 #define ESP_PDMA  (IO_BASE + 0x10100)
 #define ASC_BASE  (IO_BASE + 0x14000)
@@ -85,39 +87,6 @@
 
 #define MAC_CLOCK  3686418
 
-/*
- * The GLUE (General Logic Unit) is an Apple custom integrated circuit chip
- * that performs a variety of functions (RAM management, clock generation, 
...).
- * The GLUE chip receives interrupt requests from various devices,
- * assign priority to each, and asserts one or more interrupt line to the
- * CPU.
- */
-
-typedef struct {
-M68kCPU *cpu;
-uint8_t ipr;
-} GLUEState;
-
-static void GLUE_set_irq(void *opaque, int irq, int level)
-{
-GLUEState *s = opaque;
-int i;
-
-if (level) {
-s->ipr |= 1 << irq;
-} else {
-s->ipr &= ~(1 << irq);
-}
-
-for (i = 7; i >= 0; i--) {
-if ((s->ipr >> i) & 1) {
-m68k_set_irq_level(s->cpu, i + 1, i + 25);
-return;
-}
-}
-m68k_set_irq_level(s->cpu, 0, 0);
-}
-
 static void main_cpu_reset(void *opaque)
 {
 M68kCPU *cpu = opaque;
@@ -149,6 +118,7 @@ static void q800_init(MachineState *machine)
 const char *kernel_cmdline = machine->kernel_cmdline;
 hwaddr parameters_base;
 CPUState *cs;
+DeviceState *djmemc_dev;
 DeviceState *dev;
 DeviceState *via_dev;
 SysBusESPState *sysbus_esp;
@@ -156,8 +126,6 @@ static void q800_init(MachineState *machine)
 SysBusDevice *sysbus;
 BusState *adb_bus;
 NubusBus *nubus;
-GLUEState *irq;
-qemu_irq *pic;
 
 linux_boot = (kernel_filename != NULL);
 
@@ -191,11 +159,13 @@ static void q800_init(MachineState *machine)
 g_free(name);
 }
 
-/* IRQ Glue */
+/* djMEMC memory and interrupt controller */
 
-irq = g_new0(GLUEState, 1);
-irq->cpu = cpu;
-pic = qemu_allocate_irqs(GLUE_set_irq, irq, 8);
+djmemc_dev = qdev_create(NULL, TYPE_DJMEMC);
+object_property_set_link(OBJECT(djmemc_dev), OBJECT(cpu), "cpu",
+ _abort);
+qdev_init_nofail(djmemc_dev);
+sysbus_mmio_map(SYS_BUS_DEVICE(djmemc_dev), 0, DJMEMC_BASE);
 
 /* VIA */
 
@@ -203,9 +173,10 @@ static void q800_init(MachineState *machine)
 qdev_init_nofail(via_dev);
 sysbus = SYS_BUS_DEVICE(via_dev);
 sysbus_mmio_map(sysbus, 0, VIA_BASE);
-qdev_connect_gpio_out_named(DEVICE(sysbus), "irq", 0, pic[0]);
-qdev_connect_gpio_out_named(DEVICE(sysbus), "irq", 1, pic[1]);
-
+qdev_connect_gpio_out_named(DEVICE(sysbus), "irq", 0,
+qdev_get_gpio_in(djmemc_dev, 0));
+qdev_connect_gpio_out_named(DEVICE(sysbus),
+"irq", 1, qdev_get_gpio_in(djmemc_dev, 1));
 
 adb_bus = qdev_get_child_bus(via_dev, "adb.0");
 dev = qdev_create(adb_bus, TYPE_ADB_KEYBOARD);
@@ -244,7 +215,7 @@ static void