Re: [PATCH v4 07/18] ppc/pnv: Add a HOMER model to POWER10

2022-03-10 Thread Cédric Le Goater

On 3/11/22 07:05, Alexey Kardashevskiy wrote:
What is that HOMER thing anyway? 


I don't remember what the acronym stands for, I think "HOst MEmory
Region". Vaidy or Mahesh could tell.


skiboot and qemu mention it a lot but I cannot find traces in any available 
spec.


It is really deep deep under the hood.

It is a logic (PBA) bridging system memory, power bus, OCC SRAM.
It exposes a memory region that can be accessed through the OCC,
FSP/BMC and the host. There, are mapped the power state table,
the sensor table among other things.

  See commit 8f09231631c7 ("ppc/pnv: Introduce PBA registers")

There are some experimental QEMU patches exposing these tables
which would be interesting to tune our skiboot and Linux support
in these areas. They were never completed.

Thanks,

C.



On 3/1/22 02:52, Cédric Le Goater wrote:

Reviewed-by: David Gibson 
Signed-off-by: Cédric Le Goater 
---
  include/hw/ppc/pnv.h   | 10 ++
  include/hw/ppc/pnv_homer.h |  3 ++
  include/hw/ppc/pnv_xscom.h |  3 ++
  hw/ppc/pnv.c   | 20 
  hw/ppc/pnv_homer.c | 64 ++
  5 files changed, 100 insertions(+)

diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index e5141851faed..1e34ddd502d8 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -129,6 +129,7 @@ struct Pnv10Chip {
  Pnv9Psi  psi;
  PnvLpcController lpc;
  PnvOCC   occ;
+    PnvHomer homer;
  uint32_t nr_quads;
  PnvQuad  *quads;
@@ -364,4 +365,13 @@ void pnv_bmc_set_pnor(IPMIBmc *bmc, PnvPnor *pnor);
  #define PNV10_XIVE2_END_SIZE    0x0200ull
  #define PNV10_XIVE2_END_BASE(chip)  PNV10_CHIP_BASE(chip, 
0x00060600ull)
+#define PNV10_OCC_COMMON_AREA_SIZE  0x0080ull
+#define PNV10_OCC_COMMON_AREA_BASE  0x300fff80ull
+#define PNV10_OCC_SENSOR_BASE(chip) (PNV10_OCC_COMMON_AREA_BASE +   \
+    PNV_OCC_SENSOR_DATA_BLOCK_BASE((chip)->chip_id))
+
+#define PNV10_HOMER_SIZE  0x0040ull
+#define PNV10_HOMER_BASE(chip)   \
+    (0x300ffd80ll + ((uint64_t)(chip)->chip_id) * PNV10_HOMER_SIZE)
+
  #endif /* PPC_PNV_H */
diff --git a/include/hw/ppc/pnv_homer.h b/include/hw/ppc/pnv_homer.h
index 1889e3083c57..07e8b193116e 100644
--- a/include/hw/ppc/pnv_homer.h
+++ b/include/hw/ppc/pnv_homer.h
@@ -32,6 +32,9 @@ DECLARE_INSTANCE_CHECKER(PnvHomer, PNV8_HOMER,
  #define TYPE_PNV9_HOMER TYPE_PNV_HOMER "-POWER9"
  DECLARE_INSTANCE_CHECKER(PnvHomer, PNV9_HOMER,
   TYPE_PNV9_HOMER)
+#define TYPE_PNV10_HOMER TYPE_PNV_HOMER "-POWER10"
+DECLARE_INSTANCE_CHECKER(PnvHomer, PNV10_HOMER,
+ TYPE_PNV10_HOMER)
  struct PnvHomer {
  DeviceState parent;
diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h
index 75db33d46af6..7c7440de0c40 100644
--- a/include/hw/ppc/pnv_xscom.h
+++ b/include/hw/ppc/pnv_xscom.h
@@ -134,6 +134,9 @@ struct PnvXScomInterfaceClass {
  #define PNV10_XSCOM_OCC_BASE   PNV9_XSCOM_OCC_BASE
  #define PNV10_XSCOM_OCC_SIZE   PNV9_XSCOM_OCC_SIZE
+#define PNV10_XSCOM_PBA_BASE   0x01010CDA
+#define PNV10_XSCOM_PBA_SIZE   0x40
+
  #define PNV10_XSCOM_XIVE2_BASE 0x2010800
  #define PNV10_XSCOM_XIVE2_SIZE 0x400
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 8ecdfb1884b4..0b53406fe29c 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -1595,6 +1595,7 @@ static void pnv_chip_power10_instance_init(Object *obj)
  object_initialize_child(obj, "psi", >psi, TYPE_PNV10_PSI);
  object_initialize_child(obj, "lpc", >lpc, TYPE_PNV10_LPC);
  object_initialize_child(obj, "occ",  >occ, TYPE_PNV10_OCC);
+    object_initialize_child(obj, "homer", >homer, TYPE_PNV10_HOMER);
  if (defaults_enabled()) {
  chip->num_pecs = pcc->num_pecs;
@@ -1731,6 +1732,25 @@ static void pnv_chip_power10_realize(DeviceState *dev, 
Error **errp)
  pnv_xscom_add_subregion(chip, PNV10_XSCOM_OCC_BASE,
  >occ.xscom_regs);
+    /* OCC SRAM model */
+    memory_region_add_subregion(get_system_memory(),
+    PNV10_OCC_SENSOR_BASE(chip),
+    >occ.sram_regs);
+
+    /* HOMER */
+    object_property_set_link(OBJECT(>homer), "chip", OBJECT(chip),
+ _abort);
+    if (!qdev_realize(DEVICE(>homer), NULL, errp)) {
+    return;
+    }
+    /* Homer Xscom region */
+    pnv_xscom_add_subregion(chip, PNV10_XSCOM_PBA_BASE,
+    >homer.pba_regs);
+
+    /* Homer mmio region */
+    memory_region_add_subregion(get_system_memory(), PNV10_HOMER_BASE(chip),
+    >homer.regs);
+
  /* PHBs */
  pnv_chip_power10_phb_realize(chip, _err);
  if (local_err) {
diff --git a/hw/ppc/pnv_homer.c b/hw/ppc/pnv_homer.c
index 9a262629b73a..ea73919e54ca 100644
--- a/hw/ppc/pnv_homer.c
+++ b/hw/ppc/pnv_homer.c
@@ -332,6 +332,69 @@ 

Re: [PATCH v4 07/18] ppc/pnv: Add a HOMER model to POWER10

2022-03-10 Thread Alexey Kardashevskiy
What is that HOMER thing anyway? skiboot and qemu mention it a lot but I 
cannot find traces in any available spec.



On 3/1/22 02:52, Cédric Le Goater wrote:

Reviewed-by: David Gibson 
Signed-off-by: Cédric Le Goater 
---
  include/hw/ppc/pnv.h   | 10 ++
  include/hw/ppc/pnv_homer.h |  3 ++
  include/hw/ppc/pnv_xscom.h |  3 ++
  hw/ppc/pnv.c   | 20 
  hw/ppc/pnv_homer.c | 64 ++
  5 files changed, 100 insertions(+)

diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index e5141851faed..1e34ddd502d8 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -129,6 +129,7 @@ struct Pnv10Chip {
  Pnv9Psi  psi;
  PnvLpcController lpc;
  PnvOCC   occ;
+PnvHomer homer;
  
  uint32_t nr_quads;

  PnvQuad  *quads;
@@ -364,4 +365,13 @@ void pnv_bmc_set_pnor(IPMIBmc *bmc, PnvPnor *pnor);
  #define PNV10_XIVE2_END_SIZE0x0200ull
  #define PNV10_XIVE2_END_BASE(chip)  PNV10_CHIP_BASE(chip, 
0x00060600ull)
  
+#define PNV10_OCC_COMMON_AREA_SIZE  0x0080ull

+#define PNV10_OCC_COMMON_AREA_BASE  0x300fff80ull
+#define PNV10_OCC_SENSOR_BASE(chip) (PNV10_OCC_COMMON_AREA_BASE +   \
+PNV_OCC_SENSOR_DATA_BLOCK_BASE((chip)->chip_id))
+
+#define PNV10_HOMER_SIZE  0x0040ull
+#define PNV10_HOMER_BASE(chip)   \
+(0x300ffd80ll + ((uint64_t)(chip)->chip_id) * PNV10_HOMER_SIZE)
+
  #endif /* PPC_PNV_H */
diff --git a/include/hw/ppc/pnv_homer.h b/include/hw/ppc/pnv_homer.h
index 1889e3083c57..07e8b193116e 100644
--- a/include/hw/ppc/pnv_homer.h
+++ b/include/hw/ppc/pnv_homer.h
@@ -32,6 +32,9 @@ DECLARE_INSTANCE_CHECKER(PnvHomer, PNV8_HOMER,
  #define TYPE_PNV9_HOMER TYPE_PNV_HOMER "-POWER9"
  DECLARE_INSTANCE_CHECKER(PnvHomer, PNV9_HOMER,
   TYPE_PNV9_HOMER)
+#define TYPE_PNV10_HOMER TYPE_PNV_HOMER "-POWER10"
+DECLARE_INSTANCE_CHECKER(PnvHomer, PNV10_HOMER,
+ TYPE_PNV10_HOMER)
  
  struct PnvHomer {

  DeviceState parent;
diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h
index 75db33d46af6..7c7440de0c40 100644
--- a/include/hw/ppc/pnv_xscom.h
+++ b/include/hw/ppc/pnv_xscom.h
@@ -134,6 +134,9 @@ struct PnvXScomInterfaceClass {
  #define PNV10_XSCOM_OCC_BASE   PNV9_XSCOM_OCC_BASE
  #define PNV10_XSCOM_OCC_SIZE   PNV9_XSCOM_OCC_SIZE
  
+#define PNV10_XSCOM_PBA_BASE   0x01010CDA

+#define PNV10_XSCOM_PBA_SIZE   0x40
+
  #define PNV10_XSCOM_XIVE2_BASE 0x2010800
  #define PNV10_XSCOM_XIVE2_SIZE 0x400
  
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c

index 8ecdfb1884b4..0b53406fe29c 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -1595,6 +1595,7 @@ static void pnv_chip_power10_instance_init(Object *obj)
  object_initialize_child(obj, "psi", >psi, TYPE_PNV10_PSI);
  object_initialize_child(obj, "lpc", >lpc, TYPE_PNV10_LPC);
  object_initialize_child(obj, "occ",  >occ, TYPE_PNV10_OCC);
+object_initialize_child(obj, "homer", >homer, TYPE_PNV10_HOMER);
  
  if (defaults_enabled()) {

  chip->num_pecs = pcc->num_pecs;
@@ -1731,6 +1732,25 @@ static void pnv_chip_power10_realize(DeviceState *dev, 
Error **errp)
  pnv_xscom_add_subregion(chip, PNV10_XSCOM_OCC_BASE,
  >occ.xscom_regs);
  
+/* OCC SRAM model */

+memory_region_add_subregion(get_system_memory(),
+PNV10_OCC_SENSOR_BASE(chip),
+>occ.sram_regs);
+
+/* HOMER */
+object_property_set_link(OBJECT(>homer), "chip", OBJECT(chip),
+ _abort);
+if (!qdev_realize(DEVICE(>homer), NULL, errp)) {
+return;
+}
+/* Homer Xscom region */
+pnv_xscom_add_subregion(chip, PNV10_XSCOM_PBA_BASE,
+>homer.pba_regs);
+
+/* Homer mmio region */
+memory_region_add_subregion(get_system_memory(), PNV10_HOMER_BASE(chip),
+>homer.regs);
+
  /* PHBs */
  pnv_chip_power10_phb_realize(chip, _err);
  if (local_err) {
diff --git a/hw/ppc/pnv_homer.c b/hw/ppc/pnv_homer.c
index 9a262629b73a..ea73919e54ca 100644
--- a/hw/ppc/pnv_homer.c
+++ b/hw/ppc/pnv_homer.c
@@ -332,6 +332,69 @@ static const TypeInfo pnv_homer_power9_type_info = {
  .class_init= pnv_homer_power9_class_init,
  };
  
+static uint64_t pnv_homer_power10_pba_read(void *opaque, hwaddr addr,

+  unsigned size)
+{
+PnvHomer *homer = PNV_HOMER(opaque);
+PnvChip *chip = homer->chip;
+uint32_t reg = addr >> 3;
+uint64_t val = 0;
+
+switch (reg) {
+case PBA_BAR0:
+val = PNV10_HOMER_BASE(chip);
+break;
+case PBA_BARMASK0: /* P10 homer region mask */
+val = (PNV10_HOMER_SIZE - 1) & 0x30;
+break;
+case PBA_BAR2: /* P10 occ common area */
+val = 

[PATCH v4 07/18] ppc/pnv: Add a HOMER model to POWER10

2022-02-28 Thread Cédric Le Goater
Reviewed-by: David Gibson 
Signed-off-by: Cédric Le Goater 
---
 include/hw/ppc/pnv.h   | 10 ++
 include/hw/ppc/pnv_homer.h |  3 ++
 include/hw/ppc/pnv_xscom.h |  3 ++
 hw/ppc/pnv.c   | 20 
 hw/ppc/pnv_homer.c | 64 ++
 5 files changed, 100 insertions(+)

diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index e5141851faed..1e34ddd502d8 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -129,6 +129,7 @@ struct Pnv10Chip {
 Pnv9Psi  psi;
 PnvLpcController lpc;
 PnvOCC   occ;
+PnvHomer homer;
 
 uint32_t nr_quads;
 PnvQuad  *quads;
@@ -364,4 +365,13 @@ void pnv_bmc_set_pnor(IPMIBmc *bmc, PnvPnor *pnor);
 #define PNV10_XIVE2_END_SIZE0x0200ull
 #define PNV10_XIVE2_END_BASE(chip)  PNV10_CHIP_BASE(chip, 
0x00060600ull)
 
+#define PNV10_OCC_COMMON_AREA_SIZE  0x0080ull
+#define PNV10_OCC_COMMON_AREA_BASE  0x300fff80ull
+#define PNV10_OCC_SENSOR_BASE(chip) (PNV10_OCC_COMMON_AREA_BASE +   \
+PNV_OCC_SENSOR_DATA_BLOCK_BASE((chip)->chip_id))
+
+#define PNV10_HOMER_SIZE  0x0040ull
+#define PNV10_HOMER_BASE(chip)   \
+(0x300ffd80ll + ((uint64_t)(chip)->chip_id) * PNV10_HOMER_SIZE)
+
 #endif /* PPC_PNV_H */
diff --git a/include/hw/ppc/pnv_homer.h b/include/hw/ppc/pnv_homer.h
index 1889e3083c57..07e8b193116e 100644
--- a/include/hw/ppc/pnv_homer.h
+++ b/include/hw/ppc/pnv_homer.h
@@ -32,6 +32,9 @@ DECLARE_INSTANCE_CHECKER(PnvHomer, PNV8_HOMER,
 #define TYPE_PNV9_HOMER TYPE_PNV_HOMER "-POWER9"
 DECLARE_INSTANCE_CHECKER(PnvHomer, PNV9_HOMER,
  TYPE_PNV9_HOMER)
+#define TYPE_PNV10_HOMER TYPE_PNV_HOMER "-POWER10"
+DECLARE_INSTANCE_CHECKER(PnvHomer, PNV10_HOMER,
+ TYPE_PNV10_HOMER)
 
 struct PnvHomer {
 DeviceState parent;
diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h
index 75db33d46af6..7c7440de0c40 100644
--- a/include/hw/ppc/pnv_xscom.h
+++ b/include/hw/ppc/pnv_xscom.h
@@ -134,6 +134,9 @@ struct PnvXScomInterfaceClass {
 #define PNV10_XSCOM_OCC_BASE   PNV9_XSCOM_OCC_BASE
 #define PNV10_XSCOM_OCC_SIZE   PNV9_XSCOM_OCC_SIZE
 
+#define PNV10_XSCOM_PBA_BASE   0x01010CDA
+#define PNV10_XSCOM_PBA_SIZE   0x40
+
 #define PNV10_XSCOM_XIVE2_BASE 0x2010800
 #define PNV10_XSCOM_XIVE2_SIZE 0x400
 
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 8ecdfb1884b4..0b53406fe29c 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -1595,6 +1595,7 @@ static void pnv_chip_power10_instance_init(Object *obj)
 object_initialize_child(obj, "psi", >psi, TYPE_PNV10_PSI);
 object_initialize_child(obj, "lpc", >lpc, TYPE_PNV10_LPC);
 object_initialize_child(obj, "occ",  >occ, TYPE_PNV10_OCC);
+object_initialize_child(obj, "homer", >homer, TYPE_PNV10_HOMER);
 
 if (defaults_enabled()) {
 chip->num_pecs = pcc->num_pecs;
@@ -1731,6 +1732,25 @@ static void pnv_chip_power10_realize(DeviceState *dev, 
Error **errp)
 pnv_xscom_add_subregion(chip, PNV10_XSCOM_OCC_BASE,
 >occ.xscom_regs);
 
+/* OCC SRAM model */
+memory_region_add_subregion(get_system_memory(),
+PNV10_OCC_SENSOR_BASE(chip),
+>occ.sram_regs);
+
+/* HOMER */
+object_property_set_link(OBJECT(>homer), "chip", OBJECT(chip),
+ _abort);
+if (!qdev_realize(DEVICE(>homer), NULL, errp)) {
+return;
+}
+/* Homer Xscom region */
+pnv_xscom_add_subregion(chip, PNV10_XSCOM_PBA_BASE,
+>homer.pba_regs);
+
+/* Homer mmio region */
+memory_region_add_subregion(get_system_memory(), PNV10_HOMER_BASE(chip),
+>homer.regs);
+
 /* PHBs */
 pnv_chip_power10_phb_realize(chip, _err);
 if (local_err) {
diff --git a/hw/ppc/pnv_homer.c b/hw/ppc/pnv_homer.c
index 9a262629b73a..ea73919e54ca 100644
--- a/hw/ppc/pnv_homer.c
+++ b/hw/ppc/pnv_homer.c
@@ -332,6 +332,69 @@ static const TypeInfo pnv_homer_power9_type_info = {
 .class_init= pnv_homer_power9_class_init,
 };
 
+static uint64_t pnv_homer_power10_pba_read(void *opaque, hwaddr addr,
+  unsigned size)
+{
+PnvHomer *homer = PNV_HOMER(opaque);
+PnvChip *chip = homer->chip;
+uint32_t reg = addr >> 3;
+uint64_t val = 0;
+
+switch (reg) {
+case PBA_BAR0:
+val = PNV10_HOMER_BASE(chip);
+break;
+case PBA_BARMASK0: /* P10 homer region mask */
+val = (PNV10_HOMER_SIZE - 1) & 0x30;
+break;
+case PBA_BAR2: /* P10 occ common area */
+val = PNV10_OCC_COMMON_AREA_BASE;
+break;
+case PBA_BARMASK2: /* P10 occ common area size */
+val = (PNV10_OCC_COMMON_AREA_SIZE - 1) & 0x70;
+break;
+default:
+