Re: [PATCH v4 1/3] hw/ppc: Add pnv pervasive common chiplet units

2023-11-11 Thread Cédric Le Goater

Hello Chalapathi,

Please add to your ~/.gitconfig :

  [diff]
  orderFile = /path/to/qemu/scripts/git.orderfile

It will order the header file first in the patch.

On 11/7/23 08:41, Chalapathi V wrote:

From: Chalapathi V 

This part of the patchset creates a common pervasive chiplet model where it
houses the common units of a chiplets.

The chiplet control unit is common across chiplets and this commit implements
the pervasive chiplet model with chiplet control registers.

Signed-off-by: Chalapathi V 
---
  hw/ppc/meson.build |   1 +
  hw/ppc/pnv_pervasive.c | 213 +
  include/hw/ppc/pnv_pervasive.h |  39 
  include/hw/ppc/pnv_xscom.h |   3 +
  4 files changed, 256 insertions(+)
  create mode 100644 hw/ppc/pnv_pervasive.c
  create mode 100644 include/hw/ppc/pnv_pervasive.h

diff --git a/hw/ppc/meson.build b/hw/ppc/meson.build
index 7c2c524..c80d2f6 100644
--- a/hw/ppc/meson.build
+++ b/hw/ppc/meson.build
@@ -50,6 +50,7 @@ ppc_ss.add(when: 'CONFIG_POWERNV', if_true: files(
'pnv_bmc.c',
'pnv_homer.c',
'pnv_pnor.c',
+  'pnv_pervasive.c',
  ))
  # PowerPC 4xx boards
  ppc_ss.add(when: 'CONFIG_PPC405', if_true: files(
diff --git a/hw/ppc/pnv_pervasive.c b/hw/ppc/pnv_pervasive.c
new file mode 100644
index 000..40f60b5
--- /dev/null
+++ b/hw/ppc/pnv_pervasive.c
@@ -0,0 +1,213 @@
+/*
+ * QEMU PowerPC pervasive common chiplet model
+ *
+ * Copyright (c) 2023, IBM Corporation.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This code is licensed under the GPL version 2 or later. See the
+ * COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "hw/qdev-properties.h"
+#include "hw/ppc/pnv.h"
+#include "hw/ppc/pnv_xscom.h"
+#include "hw/ppc/pnv_pervasive.h"
+#include "hw/ppc/fdt.h"
+#include 
+
+#define CPLT_CONF0   0x08
+#define CPLT_CONF0_OR0x18
+#define CPLT_CONF0_CLEAR 0x28
+#define CPLT_CONF1   0x09
+#define CPLT_CONF1_OR0x19
+#define CPLT_CONF1_CLEAR 0x29
+#define CPLT_STAT0   0x100
+#define CPLT_MASK0   0x101
+#define CPLT_PROTECT_MODE0x3FE
+#define CPLT_ATOMIC_CLOCK0x3FF
+
+static uint64_t pnv_chiplet_ctrl_read(void *opaque, hwaddr addr,
+ unsigned size)
+{
+PnvPervChiplet *perv_chiplet = PNV_PERVCHIPLET(opaque);
+int reg = addr >> 3;
+uint64_t val = ~0ull;


White line please


+/* CPLT_CTRL0 to CPLT_CTRL5 */
+for (int i = 0; i <= 5; i++) {


I would introduce a #define for this "5" value, and use it in ControlRegs also.


+if (reg == i) {
+val = perv_chiplet->control_regs.cplt_ctrl[i];
+return val;


or may be :

   return perv_chiplet->control_regs.cplt_ctrl[i];  ?
 


+} else if ((reg == (i + 0x10)) || (reg == (i + 0x20))) {
+qemu_log_mask(LOG_GUEST_ERROR, "%s: Write only register, ignoring "
+   "xscom read at 0x%" PRIx64 "\n",
+   __func__, (unsigned long)reg);
+return val;
+}
+}
+
+switch (reg) {
+case CPLT_CONF0:
+val = perv_chiplet->control_regs.cplt_cfg0;
+break;
+case CPLT_CONF0_OR:
+case CPLT_CONF0_CLEAR:
+qemu_log_mask(LOG_GUEST_ERROR, "%s: Write only register, ignoring "
+   "xscom read at 0x%" PRIx64 "\n",
+   __func__, (unsigned long)reg);
+break;
+case CPLT_CONF1:
+val = perv_chiplet->control_regs.cplt_cfg1;
+break;
+case CPLT_CONF1_OR:
+case CPLT_CONF1_CLEAR:
+qemu_log_mask(LOG_GUEST_ERROR, "%s: Write only register, ignoring "
+   "xscom read at 0x%" PRIx64 "\n",
+   __func__, (unsigned long)reg);
+break;
+case CPLT_STAT0:
+val = perv_chiplet->control_regs.cplt_stat0;
+break;
+case CPLT_MASK0:
+val = perv_chiplet->control_regs.cplt_mask0;
+break;
+case CPLT_PROTECT_MODE:
+val = perv_chiplet->control_regs.ctrl_protect_mode;
+break;
+case CPLT_ATOMIC_CLOCK:
+val = perv_chiplet->control_regs.ctrl_atomic_lock;
+break;
+default:
+qemu_log_mask(LOG_UNIMP, "%s: Chiplet_control_regs: Invalid xscom "
+ "read at 0x%" PRIx64 "\n", __func__, (unsigned long)reg);
+}
+return val;
+}
+
+static void pnv_chiplet_ctrl_write(void *opaque, hwaddr addr,
+ uint64_t val, unsigned size)
+{
+PnvPervChiplet *perv_chiplet = PNV_PERVCHIPLET(opaque);
+int reg = addr >> 3;
+/* CPLT_CTRL0 to CPLT_CTRL5 */
+for (int i = 0; i <= 5; i++) {
+if (reg == i) {
+perv_chiplet->control_regs.cplt_ctrl[i] = val;
+return;
+} else if (reg == (i + 0x10)) 

[PATCH v4 1/3] hw/ppc: Add pnv pervasive common chiplet units

2023-11-07 Thread Chalapathi V
From: Chalapathi V 

This part of the patchset creates a common pervasive chiplet model where it
houses the common units of a chiplets.

The chiplet control unit is common across chiplets and this commit implements
the pervasive chiplet model with chiplet control registers.

Signed-off-by: Chalapathi V 
---
 hw/ppc/meson.build |   1 +
 hw/ppc/pnv_pervasive.c | 213 +
 include/hw/ppc/pnv_pervasive.h |  39 
 include/hw/ppc/pnv_xscom.h |   3 +
 4 files changed, 256 insertions(+)
 create mode 100644 hw/ppc/pnv_pervasive.c
 create mode 100644 include/hw/ppc/pnv_pervasive.h

diff --git a/hw/ppc/meson.build b/hw/ppc/meson.build
index 7c2c524..c80d2f6 100644
--- a/hw/ppc/meson.build
+++ b/hw/ppc/meson.build
@@ -50,6 +50,7 @@ ppc_ss.add(when: 'CONFIG_POWERNV', if_true: files(
   'pnv_bmc.c',
   'pnv_homer.c',
   'pnv_pnor.c',
+  'pnv_pervasive.c',
 ))
 # PowerPC 4xx boards
 ppc_ss.add(when: 'CONFIG_PPC405', if_true: files(
diff --git a/hw/ppc/pnv_pervasive.c b/hw/ppc/pnv_pervasive.c
new file mode 100644
index 000..40f60b5
--- /dev/null
+++ b/hw/ppc/pnv_pervasive.c
@@ -0,0 +1,213 @@
+/*
+ * QEMU PowerPC pervasive common chiplet model
+ *
+ * Copyright (c) 2023, IBM Corporation.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This code is licensed under the GPL version 2 or later. See the
+ * COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "hw/qdev-properties.h"
+#include "hw/ppc/pnv.h"
+#include "hw/ppc/pnv_xscom.h"
+#include "hw/ppc/pnv_pervasive.h"
+#include "hw/ppc/fdt.h"
+#include 
+
+#define CPLT_CONF0   0x08
+#define CPLT_CONF0_OR0x18
+#define CPLT_CONF0_CLEAR 0x28
+#define CPLT_CONF1   0x09
+#define CPLT_CONF1_OR0x19
+#define CPLT_CONF1_CLEAR 0x29
+#define CPLT_STAT0   0x100
+#define CPLT_MASK0   0x101
+#define CPLT_PROTECT_MODE0x3FE
+#define CPLT_ATOMIC_CLOCK0x3FF
+
+static uint64_t pnv_chiplet_ctrl_read(void *opaque, hwaddr addr,
+ unsigned size)
+{
+PnvPervChiplet *perv_chiplet = PNV_PERVCHIPLET(opaque);
+int reg = addr >> 3;
+uint64_t val = ~0ull;
+/* CPLT_CTRL0 to CPLT_CTRL5 */
+for (int i = 0; i <= 5; i++) {
+if (reg == i) {
+val = perv_chiplet->control_regs.cplt_ctrl[i];
+return val;
+} else if ((reg == (i + 0x10)) || (reg == (i + 0x20))) {
+qemu_log_mask(LOG_GUEST_ERROR, "%s: Write only register, ignoring "
+   "xscom read at 0x%" PRIx64 "\n",
+   __func__, (unsigned long)reg);
+return val;
+}
+}
+
+switch (reg) {
+case CPLT_CONF0:
+val = perv_chiplet->control_regs.cplt_cfg0;
+break;
+case CPLT_CONF0_OR:
+case CPLT_CONF0_CLEAR:
+qemu_log_mask(LOG_GUEST_ERROR, "%s: Write only register, ignoring "
+   "xscom read at 0x%" PRIx64 "\n",
+   __func__, (unsigned long)reg);
+break;
+case CPLT_CONF1:
+val = perv_chiplet->control_regs.cplt_cfg1;
+break;
+case CPLT_CONF1_OR:
+case CPLT_CONF1_CLEAR:
+qemu_log_mask(LOG_GUEST_ERROR, "%s: Write only register, ignoring "
+   "xscom read at 0x%" PRIx64 "\n",
+   __func__, (unsigned long)reg);
+break;
+case CPLT_STAT0:
+val = perv_chiplet->control_regs.cplt_stat0;
+break;
+case CPLT_MASK0:
+val = perv_chiplet->control_regs.cplt_mask0;
+break;
+case CPLT_PROTECT_MODE:
+val = perv_chiplet->control_regs.ctrl_protect_mode;
+break;
+case CPLT_ATOMIC_CLOCK:
+val = perv_chiplet->control_regs.ctrl_atomic_lock;
+break;
+default:
+qemu_log_mask(LOG_UNIMP, "%s: Chiplet_control_regs: Invalid xscom "
+ "read at 0x%" PRIx64 "\n", __func__, (unsigned long)reg);
+}
+return val;
+}
+
+static void pnv_chiplet_ctrl_write(void *opaque, hwaddr addr,
+ uint64_t val, unsigned size)
+{
+PnvPervChiplet *perv_chiplet = PNV_PERVCHIPLET(opaque);
+int reg = addr >> 3;
+/* CPLT_CTRL0 to CPLT_CTRL5 */
+for (int i = 0; i <= 5; i++) {
+if (reg == i) {
+perv_chiplet->control_regs.cplt_ctrl[i] = val;
+return;
+} else if (reg == (i + 0x10)) {
+perv_chiplet->control_regs.cplt_ctrl[i] |= val;
+return;
+} else if (reg == (i + 0x20)) {
+perv_chiplet->control_regs.cplt_ctrl[i] &= ~val;
+return;
+}
+}
+
+switch (reg) {
+case CPLT_CONF0:
+perv_chiplet->control_regs.cplt_cfg0 = val;
+break;
+case CPLT_CONF0_OR:
+perv_chiplet->control_regs.cplt_cfg0