Re: [PATCH v3 04/20] ppc4xx: Use Ppc4xxSdramBank in ppc4xx_sdram_banks()

2022-09-14 Thread Cédric Le Goater

On 9/13/22 21:52, BALATON Zoltan wrote:

Change ppc4xx_sdram_banks() to take one Ppc4xxSdramBank array instead
of the separate arrays and adjust ppc4xx_sdram_init() and
ppc440_sdram_init() accordingly as well as machines using these.

Signed-off-by: BALATON Zoltan 


Reviewed-by: Cédric Le Goater 

Thanks,

C.



---
v2: Use pointer for ram_banks in the prototype of the init funcs as
an array of struct seems to confuse gcc 12.2.1 and provoke a warning

  hw/ppc/ppc405.h |  4 +---
  hw/ppc/ppc405_uc.c  | 10 +-
  hw/ppc/ppc440.h |  5 ++---
  hw/ppc/ppc440_bamboo.c  | 15 ++-
  hw/ppc/ppc440_uc.c  |  9 -
  hw/ppc/ppc4xx_devs.c| 21 +
  hw/ppc/sam460ex.c   | 15 +--
  include/hw/ppc/ppc4xx.h |  9 +++--
  8 files changed, 35 insertions(+), 53 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index 756865621b..ca0972b88b 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -167,9 +167,7 @@ struct Ppc405SoCState {
  DeviceState parent_obj;
  
  /* Public */

-MemoryRegion ram_banks[2];
-hwaddr ram_bases[2], ram_sizes[2];
-
+Ppc4xxSdramBank ram_banks[2];
  MemoryRegion *dram_mr;
  hwaddr ram_size;
  
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c

index 1e02347e57..bcbf35bc14 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -1074,14 +1074,14 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
  
  /* SDRAM controller */

  /* XXX 405EP has no ECC interrupt */
-s->ram_bases[0] = 0;
-s->ram_sizes[0] = s->ram_size;
-memory_region_init_alias(&s->ram_banks[0], OBJECT(s),
+s->ram_banks[0].base = 0;
+s->ram_banks[0].size = s->ram_size;
+memory_region_init_alias(&s->ram_banks[0].ram, OBJECT(s),
   "ppc405.sdram0", s->dram_mr,
- s->ram_bases[0], s->ram_sizes[0]);
+ s->ram_banks[0].base, s->ram_banks[0].size);
  
  ppc4xx_sdram_init(env, qdev_get_gpio_in(DEVICE(&s->uic), 17), 1,

-  s->ram_banks, s->ram_bases, s->ram_sizes);
+  s->ram_banks);
  
  /* External bus controller */

  if (!ppc4xx_dcr_realize(PPC4xx_DCR_DEVICE(&s->ebc), &s->cpu, errp)) {
diff --git a/hw/ppc/ppc440.h b/hw/ppc/ppc440.h
index 7cef936125..e6c905b7d6 100644
--- a/hw/ppc/ppc440.h
+++ b/hw/ppc/ppc440.h
@@ -11,14 +11,13 @@
  #ifndef PPC440_H
  #define PPC440_H
  
-#include "hw/ppc/ppc.h"

+#include "hw/ppc/ppc4xx.h"
  
  void ppc4xx_l2sram_init(CPUPPCState *env);

  void ppc4xx_cpr_init(CPUPPCState *env);
  void ppc4xx_sdr_init(CPUPPCState *env);
  void ppc440_sdram_init(CPUPPCState *env, int nbanks,
-   MemoryRegion *ram_memories,
-   hwaddr *ram_bases, hwaddr *ram_sizes,
+   Ppc4xxSdramBank *ram_banks,
 int do_init);
  void ppc4xx_ahb_init(CPUPPCState *env);
  void ppc4xx_dma_init(CPUPPCState *env, int dcr_base);
diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c
index e3412c4fcd..2aac8a3fe9 100644
--- a/hw/ppc/ppc440_bamboo.c
+++ b/hw/ppc/ppc440_bamboo.c
@@ -168,9 +168,8 @@ static void bamboo_init(MachineState *machine)
  unsigned int pci_irq_nrs[4] = { 28, 27, 26, 25 };
  MemoryRegion *address_space_mem = get_system_memory();
  MemoryRegion *isa = g_new(MemoryRegion, 1);
-MemoryRegion *ram_memories = g_new(MemoryRegion, PPC440EP_SDRAM_NR_BANKS);
-hwaddr ram_bases[PPC440EP_SDRAM_NR_BANKS] = {0};
-hwaddr ram_sizes[PPC440EP_SDRAM_NR_BANKS] = {0};
+Ppc4xxSdramBank *ram_banks = g_new0(Ppc4xxSdramBank,
+PPC440EP_SDRAM_NR_BANKS);
  PCIBus *pcibus;
  PowerPCCPU *cpu;
  CPUPPCState *env;
@@ -205,13 +204,11 @@ static void bamboo_init(MachineState *machine)
 qdev_get_gpio_in(DEVICE(cpu), PPC40x_INPUT_CINT));
  
  /* SDRAM controller */

-ppc4xx_sdram_banks(machine->ram, PPC440EP_SDRAM_NR_BANKS, ram_memories,
-   ram_bases, ram_sizes, ppc440ep_sdram_bank_sizes);
+ppc4xx_sdram_banks(machine->ram, PPC440EP_SDRAM_NR_BANKS, ram_banks,
+   ppc440ep_sdram_bank_sizes);
  /* XXX 440EP's ECC interrupts are on UIC1, but we've only created UIC0. */
-ppc4xx_sdram_init(env,
-  qdev_get_gpio_in(uicdev, 14),
-  PPC440EP_SDRAM_NR_BANKS, ram_memories,
-  ram_bases, ram_sizes);
+ppc4xx_sdram_init(env, qdev_get_gpio_in(uicdev, 14),
+  PPC440EP_SDRAM_NR_BANKS, ram_banks);
  /* Enable SDRAM memory regions, this should be done by the firmware */
  if (ppc_dcr_write(env->dcr_env, SDRAM0_CFGADDR, 0x20) ||
  ppc_dcr_write(env->dcr_env, SDRAM0_CFGDATA, 0x8000)) {
diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c
index 6ab0ad7985..5db59d1190 100644
--- a/hw/ppc/ppc440_uc.c
+++ b/hw/ppc/ppc440_uc.c
@

Re: [PATCH v3 06/20] ppc4xx_sdram: Move size check to ppc4xx_sdram_init()

2022-09-14 Thread Cédric Le Goater

On 9/13/22 21:52, BALATON Zoltan wrote:

Instead of checking if memory size is valid in board code move this
check to ppc4xx_sdram_init() as this is a restriction imposed by the
SDRAM controller.



So, we are relying on ppc4xx_sdram_banks() to check the RAM size
and report the error. The problem is the exit.

You also need to change the prototypes of some routine to take an
"Error **errp" parameter as realize routines do.

qdev_realize(DEVICE(&ppc405->soc), NULL, &error_fatal);
ppc405_soc_realize(DeviceState *dev, Error **errp)
 ppc4xx_sdram_init()
  ppc4xx_sdram_banks()

at least, ppc4xx_sdram_banks() should be changed. The next patch
doing the QOMification takes care of ppc4xx_sdram_init()

Thanks,

C.





Signed-off-by: BALATON Zoltan 
---
  hw/ppc/ppc405.h |  2 --
  hw/ppc/ppc405_boards.c  | 10 --
  hw/ppc/ppc405_uc.c  | 11 ++-
  hw/ppc/ppc440_bamboo.c  | 10 +-
  hw/ppc/ppc4xx_devs.c| 14 ++
  include/hw/ppc/ppc4xx.h |  2 +-
  6 files changed, 10 insertions(+), 39 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index ca0972b88b..ad54dff542 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -167,9 +167,7 @@ struct Ppc405SoCState {
  DeviceState parent_obj;
  
  /* Public */

-Ppc4xxSdramBank ram_banks[2];
  MemoryRegion *dram_mr;
-hwaddr ram_size;
  
  PowerPCCPU cpu;

  PPCUIC uic;
diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
index bf02a71c6d..cdd4e0cb4c 100644
--- a/hw/ppc/ppc405_boards.c
+++ b/hw/ppc/ppc405_boards.c
@@ -271,22 +271,12 @@ static void boot_from_kernel(MachineState *machine, 
PowerPCCPU *cpu)
  static void ppc405_init(MachineState *machine)
  {
  Ppc405MachineState *ppc405 = PPC405_MACHINE(machine);
-MachineClass *mc = MACHINE_GET_CLASS(machine);
  const char *kernel_filename = machine->kernel_filename;
  MemoryRegion *sysmem = get_system_memory();
  CPUPPCState *env;
  
-if (machine->ram_size != mc->default_ram_size) {

-char *sz = size_to_str(mc->default_ram_size);
-error_report("Invalid RAM size, should be %s", sz);
-g_free(sz);
-exit(EXIT_FAILURE);
-}
-
  object_initialize_child(OBJECT(machine), "soc", &ppc405->soc,
  TYPE_PPC405_SOC);
-object_property_set_uint(OBJECT(&ppc405->soc), "ram-size",
- machine->ram_size, &error_fatal);
  object_property_set_link(OBJECT(&ppc405->soc), "dram",
   OBJECT(machine->ram), &error_abort);
  object_property_set_uint(OBJECT(&ppc405->soc), "sys-clk", ,
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index bcbf35bc14..e1c7188e61 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -1073,15 +1073,9 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
 qdev_get_gpio_in(DEVICE(&s->cpu), PPC40x_INPUT_CINT));
  
  /* SDRAM controller */

-/* XXX 405EP has no ECC interrupt */
-s->ram_banks[0].base = 0;
-s->ram_banks[0].size = s->ram_size;
-memory_region_init_alias(&s->ram_banks[0].ram, OBJECT(s),
- "ppc405.sdram0", s->dram_mr,
- s->ram_banks[0].base, s->ram_banks[0].size);
-
+/* XXX 405EP has no ECC interrupt */
  ppc4xx_sdram_init(env, qdev_get_gpio_in(DEVICE(&s->uic), 17), 1,
-  s->ram_banks);
+  s->dram_mr);
  
  /* External bus controller */

  if (!ppc4xx_dcr_realize(PPC4xx_DCR_DEVICE(&s->ebc), &s->cpu, errp)) {
@@ -1159,7 +1153,6 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
  static Property ppc405_soc_properties[] = {
  DEFINE_PROP_LINK("dram", Ppc405SoCState, dram_mr, TYPE_MEMORY_REGION,
   MemoryRegion *),
-DEFINE_PROP_UINT64("ram-size", Ppc405SoCState, ram_size, 0),
  DEFINE_PROP_END_OF_LIST(),
  };
  
diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c

index 2bd5e41140..9b456f1819 100644
--- a/hw/ppc/ppc440_bamboo.c
+++ b/hw/ppc/ppc440_bamboo.c
@@ -50,10 +50,6 @@
  
  #define PPC440EP_SDRAM_NR_BANKS 4
  
-static const ram_addr_t ppc440ep_sdram_bank_sizes[] = {

-256 * MiB, 128 * MiB, 64 * MiB, 32 * MiB, 16 * MiB, 8 * MiB, 4 * MiB, 0
-};
-
  static hwaddr entry;
  
  static int bamboo_load_device_tree(hwaddr addr,

@@ -168,8 +164,6 @@ static void bamboo_init(MachineState *machine)
  unsigned int pci_irq_nrs[4] = { 28, 27, 26, 25 };
  MemoryRegion *address_space_mem = get_system_memory();
  MemoryRegion *isa = g_new(MemoryRegion, 1);
-Ppc4xxSdramBank *ram_banks = g_new0(Ppc4xxSdramBank,
-PPC440EP_SDRAM_NR_BANKS);
  PCIBus *pcibus;
  PowerPCCPU *cpu;
  CPUPPCState *env;
@@ -204,11 +198,9 @@ static void bamboo_init(MachineState *machine)
 qdev_get_gpio_in(DEVICE(cpu), PPC40x_INPUT_CINT));
  
  

Re: [PATCH v3 07/20] ppc4xx_sdram: QOM'ify

2022-09-14 Thread Cédric Le Goater

On 9/13/22 21:52, BALATON Zoltan wrote:

Change the ppc4xx_sdram model to a QOM class derived from the
PPC4xx-dcr-device and name it ppc4xx-sdram-ddr. This is mostly
modelling the DDR SDRAM controller found in the 440EP (used on the
bamboo board) but also backward compatible with the older DDR
controllers on some 405 SoCs so we also use it for those now. This
likely does not cause problems for guests we run as the new features
are just not accessed but to model 405 SoC accurately some features
may have to be disabled or the model split between 440 and older.

Newer SoCs (regardless of their PPC core, e.g. 405EX) may have an
updated DDR2 SDRAM controller implemented by the ppc440_sdram model
(only partially, enough for the 460EX on the sam460ex) that is not yet
QOM'ified in this patch. That is intended to become ppc4xx-sdram-ddr2
when QOM'ified later.

Signed-off-by: BALATON Zoltan 
Reviewed-by: Cédric Le Goater 
---
  hw/ppc/ppc405.h |  3 +-
  hw/ppc/ppc405_uc.c  | 22 +
  hw/ppc/ppc440_bamboo.c  | 10 +++--
  hw/ppc/ppc4xx_devs.c| 99 ++---
  include/hw/ppc/ppc4xx.h | 27 +--
  5 files changed, 98 insertions(+), 63 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index ad54dff542..9a4312691e 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -167,8 +167,6 @@ struct Ppc405SoCState {
  DeviceState parent_obj;
  
  /* Public */

-MemoryRegion *dram_mr;
-
  PowerPCCPU cpu;
  PPCUIC uic;
  Ppc405CpcState cpc;
@@ -182,6 +180,7 @@ struct Ppc405SoCState {
  Ppc405PobState pob;
  Ppc4xxPlbState plb;
  Ppc4xxMalState mal;
+Ppc4xxSdramDdrState sdram;
  };
  
  #endif /* PPC405_H */

diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index e1c7188e61..c973cfb04e 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -1016,6 +1016,9 @@ static void ppc405_soc_instance_init(Object *obj)
  object_initialize_child(obj, "plb", &s->plb, TYPE_PPC4xx_PLB);
  
  object_initialize_child(obj, "mal", &s->mal, TYPE_PPC4xx_MAL);

+
+object_initialize_child(obj, "sdram", &s->sdram, TYPE_PPC4xx_SDRAM_DDR);
+object_property_add_alias(obj, "dram", OBJECT(&s->sdram), "dram");
  }
  
  static void ppc405_reset(void *opaque)

@@ -1073,9 +1076,17 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
 qdev_get_gpio_in(DEVICE(&s->cpu), PPC40x_INPUT_CINT));
  
  /* SDRAM controller */

+/*
+ * We use the 440 DDR SDRAM controller which has more regs and features
+ * but it's compatible enough for now
+ */
+object_property_set_int(OBJECT(&s->sdram), "nbanks", 2, &error_abort);
+if (!ppc4xx_dcr_realize(PPC4xx_DCR_DEVICE(&s->sdram), &s->cpu, errp)) {
+return;
+}
  /* XXX 405EP has no ECC interrupt */
-ppc4xx_sdram_init(env, qdev_get_gpio_in(DEVICE(&s->uic), 17), 1,
-  s->dram_mr);
+sysbus_connect_irq(SYS_BUS_DEVICE(&s->sdram), 0,
+   qdev_get_gpio_in(DEVICE(&s->uic), 17));
  
  /* External bus controller */

  if (!ppc4xx_dcr_realize(PPC4xx_DCR_DEVICE(&s->ebc), &s->cpu, errp)) {
@@ -1150,12 +1161,6 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
  /* Uses UIC IRQs 9, 15, 17 */
  }
  
-static Property ppc405_soc_properties[] = {

-DEFINE_PROP_LINK("dram", Ppc405SoCState, dram_mr, TYPE_MEMORY_REGION,
- MemoryRegion *),
-DEFINE_PROP_END_OF_LIST(),
-};
-
  static void ppc405_soc_class_init(ObjectClass *oc, void *data)
  {
  DeviceClass *dc = DEVICE_CLASS(oc);
@@ -1163,7 +1168,6 @@ static void ppc405_soc_class_init(ObjectClass *oc, void 
*data)
  dc->realize = ppc405_soc_realize;
  /* Reason: only works as part of a ppc405 board/machine */
  dc->user_creatable = false;
-device_class_set_props(dc, ppc405_soc_properties);
  }
  
  static const TypeInfo ppc405_types[] = {

diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c
index 9b456f1819..6052d3a2e0 100644
--- a/hw/ppc/ppc440_bamboo.c
+++ b/hw/ppc/ppc440_bamboo.c
@@ -48,8 +48,6 @@
  #define PPC440EP_PCI_IO 0xe800
  #define PPC440EP_PCI_IOLEN  0x0001
  
-#define PPC440EP_SDRAM_NR_BANKS 4

-
  static hwaddr entry;
  
  static int bamboo_load_device_tree(hwaddr addr,

@@ -198,9 +196,13 @@ static void bamboo_init(MachineState *machine)
 qdev_get_gpio_in(DEVICE(cpu), PPC40x_INPUT_CINT));
  
  /* SDRAM controller */

+dev = qdev_new(TYPE_PPC4xx_SDRAM_DDR);
+object_property_set_link(OBJECT(dev), "dram", OBJECT(machine->ram),
+ &error_abort);
+ppc4xx_dcr_realize(PPC4xx_DCR_DEVICE(dev), cpu, &error_fatal);
+object_unref(OBJECT(dev));
  /* XXX 440EP's ECC interrupts are on UIC1, but we've only created UIC0. */
-ppc4xx_sdram_init(env, qdev_get_gpio_in(uicdev, 14),
-  PPC440EP_SDRAM_NR_BANKS, machine->ram);
+sysbus_connect_irq(SYS_BUS_DEV

Re: [PATCH v3 12/20] ppc440_sdram: Rename local variable for readibility

2022-09-14 Thread Cédric Le Goater

On 9/13/22 21:52, BALATON Zoltan wrote:

Rename local sdram variable in ppc440_sdram_init to s for readibility.

Signed-off-by: BALATON Zoltan 




Reviewed-by: Cédric Le Goater 

Thanks,

C.



---
  hw/ppc/ppc440_uc.c | 36 ++--
  1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c
index b3f56c49b5..d8a7947196 100644
--- a/hw/ppc/ppc440_uc.c
+++ b/hw/ppc/ppc440_uc.c
@@ -729,40 +729,40 @@ static void sdram_reset(void *opaque)
  void ppc440_sdram_init(CPUPPCState *env, int nbanks,
 Ppc4xxSdramBank *ram_banks)
  {
-ppc440_sdram_t *sdram;
+ppc440_sdram_t *s;
  int i;
  
-sdram = g_malloc0(sizeof(*sdram));

-sdram->nbanks = nbanks;
+s = g_malloc0(sizeof(*s));
+s->nbanks = nbanks;
  for (i = 0; i < nbanks; i++) {
-sdram->bank[i].ram = ram_banks[i].ram;
-sdram->bank[i].base = ram_banks[i].base;
-sdram->bank[i].size = ram_banks[i].size;
+s->bank[i].ram = ram_banks[i].ram;
+s->bank[i].base = ram_banks[i].base;
+s->bank[i].size = ram_banks[i].size;
  }
-qemu_register_reset(&sdram_reset, sdram);
+qemu_register_reset(&sdram_reset, s);
  ppc_dcr_register(env, SDRAM0_CFGADDR,
- sdram, &dcr_read_sdram, &dcr_write_sdram);
+ s, &dcr_read_sdram, &dcr_write_sdram);
  ppc_dcr_register(env, SDRAM0_CFGDATA,
- sdram, &dcr_read_sdram, &dcr_write_sdram);
+ s, &dcr_read_sdram, &dcr_write_sdram);
  
  ppc_dcr_register(env, SDRAM_R0BAS,

- sdram, &dcr_read_sdram, &dcr_write_sdram);
+ s, &dcr_read_sdram, &dcr_write_sdram);
  ppc_dcr_register(env, SDRAM_R1BAS,
- sdram, &dcr_read_sdram, &dcr_write_sdram);
+ s, &dcr_read_sdram, &dcr_write_sdram);
  ppc_dcr_register(env, SDRAM_R2BAS,
- sdram, &dcr_read_sdram, &dcr_write_sdram);
+ s, &dcr_read_sdram, &dcr_write_sdram);
  ppc_dcr_register(env, SDRAM_R3BAS,
- sdram, &dcr_read_sdram, &dcr_write_sdram);
+ s, &dcr_read_sdram, &dcr_write_sdram);
  ppc_dcr_register(env, SDRAM_CONF1HB,
- sdram, &dcr_read_sdram, &dcr_write_sdram);
+ s, &dcr_read_sdram, &dcr_write_sdram);
  ppc_dcr_register(env, SDRAM_PLBADDULL,
- sdram, &dcr_read_sdram, &dcr_write_sdram);
+ s, &dcr_read_sdram, &dcr_write_sdram);
  ppc_dcr_register(env, SDRAM_CONF1LL,
- sdram, &dcr_read_sdram, &dcr_write_sdram);
+ s, &dcr_read_sdram, &dcr_write_sdram);
  ppc_dcr_register(env, SDRAM_CONFPATHB,
- sdram, &dcr_read_sdram, &dcr_write_sdram);
+ s, &dcr_read_sdram, &dcr_write_sdram);
  ppc_dcr_register(env, SDRAM_PLBADDUHB,
- sdram, &dcr_read_sdram, &dcr_write_sdram);
+ s, &dcr_read_sdram, &dcr_write_sdram);
  }
  
  /*/





Re: [PATCH v3 10/20] ppc440_sdram: Implement enable bit in the DDR2 SDRAM

2022-09-14 Thread Cédric Le Goater

On 9/13/22 21:52, BALATON Zoltan wrote:

To allow removing the do_init hack we need to improve the DDR2 SDRAM
controller model to handle the enable/disable bit that it ignored so
far.

Signed-off-by: BALATON Zoltan 



Please consider adding a define instead.

Thanks,

C.



---
v2: replace 0x0800 with BIT(27)

  hw/ppc/ppc440_uc.c | 34 --
  1 file changed, 32 insertions(+), 2 deletions(-)

diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c
index 01184e717b..3c442eaecc 100644
--- a/hw/ppc/ppc440_uc.c
+++ b/hw/ppc/ppc440_uc.c
@@ -23,6 +23,7 @@
  #include "sysemu/reset.h"
  #include "ppc440.h"
  #include "qom/object.h"
+#include "trace.h"
  
  /*/

  /* L2 Cache as SRAM */
@@ -484,6 +485,7 @@ void ppc4xx_sdr_init(CPUPPCState *env)
  /* SDRAM controller */
  typedef struct ppc440_sdram_t {
  uint32_t addr;
+uint32_t mcopt2;
  int nbanks;
  Ppc4xxSdramBank bank[4];
  } ppc440_sdram_t;
@@ -581,12 +583,15 @@ static void sdram_set_bcr(ppc440_sdram_t *sdram, int i,
  {
  if (sdram->bank[i].bcr & 1) {
  /* First unmap RAM if enabled */
+trace_ppc4xx_sdram_unmap(sdram_base(sdram->bank[i].bcr),
+ sdram_size(sdram->bank[i].bcr));
  sdram_bank_unmap(&sdram->bank[i]);
  }
  sdram->bank[i].bcr = bcr & 0xffe0ffc1;
  sdram->bank[i].base = sdram_base(bcr);
  sdram->bank[i].size = sdram_size(bcr);
  if (enabled && (bcr & 1)) {
+trace_ppc4xx_sdram_map(sdram_base(bcr), sdram_size(bcr));
  sdram_bank_map(&sdram->bank[i]);
  }
  }
@@ -596,7 +601,7 @@ static void sdram_map_bcr(ppc440_sdram_t *sdram)
  int i;
  
  for (i = 0; i < sdram->nbanks; i++) {

-if (sdram->bank[i].size != 0) {
+if (sdram->bank[i].size) {
  sdram_set_bcr(sdram, i, sdram_bcr(sdram->bank[i].base,
sdram->bank[i].size), 1);
  } else {
@@ -605,6 +610,17 @@ static void sdram_map_bcr(ppc440_sdram_t *sdram)
  }
  }
  
+static void sdram_unmap_bcr(ppc440_sdram_t *sdram)

+{
+int i;
+
+for (i = 0; i < sdram->nbanks; i++) {
+if (sdram->bank[i].size) {
+sdram_set_bcr(sdram, i, sdram->bank[i].bcr & ~1, 0);
+}
+}
+}
+
  static uint32_t dcr_read_sdram(void *opaque, int dcrn)
  {
  ppc440_sdram_t *sdram = opaque;
@@ -636,7 +652,7 @@ static uint32_t dcr_read_sdram(void *opaque, int dcrn)
  ret = 0x8000;
  break;
  case 0x21: /* SDRAM_MCOPT2 */
-ret = 0x0800;
+ret = sdram->mcopt2;
  break;
  case 0x40: /* SDRAM_MB0CF */
  ret = 0x8001;
@@ -680,6 +696,19 @@ static void dcr_write_sdram(void *opaque, int dcrn, 
uint32_t val)
  switch (sdram->addr) {
  case 0x00: /* B0CR */
  break;
+case 0x21: /* SDRAM_MCOPT2 */
+if (!(sdram->mcopt2 & BIT(27)) && (val & BIT(27))) {
+trace_ppc4xx_sdram_enable("enable");
+/* validate all RAM mappings */
+sdram_map_bcr(sdram);
+sdram->mcopt2 |= BIT(27);
+} else if ((sdram->mcopt2 & BIT(27)) && !(val & BIT(27))) {
+trace_ppc4xx_sdram_enable("disable");
+/* invalidate all RAM mappings */
+sdram_unmap_bcr(sdram);
+sdram->mcopt2 &= ~BIT(27);
+}
+break;
  default:
  break;
  }
@@ -694,6 +723,7 @@ static void sdram_reset(void *opaque)
  ppc440_sdram_t *sdram = opaque;
  
  sdram->addr = 0;

+sdram->mcopt2 = BIT(27);
  }
  
  void ppc440_sdram_init(CPUPPCState *env, int nbanks,





Re: [PATCH v3 09/20] ppc440_sdram: Split off map/unmap of sdram banks for later reuse

2022-09-14 Thread Cédric Le Goater

On 9/13/22 21:52, BALATON Zoltan wrote:

Signed-off-by: BALATON Zoltan 
---
  hw/ppc/ppc440_uc.c | 31 +++
  1 file changed, 19 insertions(+), 12 deletions(-)

diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c
index 5db59d1190..01184e717b 100644
--- a/hw/ppc/ppc440_uc.c
+++ b/hw/ppc/ppc440_uc.c
@@ -561,26 +561,33 @@ static uint64_t sdram_size(uint32_t bcr)
  return size;
  }
  
+static void sdram_bank_map(Ppc4xxSdramBank *bank)

+{
+memory_region_init(&bank->container, NULL, "sdram-container", bank->size);


This init belongs to the realize routine.

It is a oneliner. I think you can do it now without risks.

Thanks,

C.


+memory_region_add_subregion(&bank->container, 0, &bank->ram);
+memory_region_add_subregion(get_system_memory(), bank->base,
+&bank->container);
+}
+
+static void sdram_bank_unmap(Ppc4xxSdramBank *bank)
+{
+memory_region_del_subregion(get_system_memory(), &bank->container);
+memory_region_del_subregion(&bank->container, &bank->ram);
+object_unparent(OBJECT(&bank->container));
+}
+
  static void sdram_set_bcr(ppc440_sdram_t *sdram, int i,
uint32_t bcr, int enabled)
  {
  if (sdram->bank[i].bcr & 1) {
  /* First unmap RAM if enabled */
-memory_region_del_subregion(get_system_memory(),
-&sdram->bank[i].container);
-memory_region_del_subregion(&sdram->bank[i].container,
-&sdram->bank[i].ram);
-object_unparent(OBJECT(&sdram->bank[i].container));
+sdram_bank_unmap(&sdram->bank[i]);
  }
  sdram->bank[i].bcr = bcr & 0xffe0ffc1;
+sdram->bank[i].base = sdram_base(bcr);
+sdram->bank[i].size = sdram_size(bcr);
  if (enabled && (bcr & 1)) {
-memory_region_init(&sdram->bank[i].container, NULL, "sdram-container",
-   sdram_size(bcr));
-memory_region_add_subregion(&sdram->bank[i].container, 0,
-&sdram->bank[i].ram);
-memory_region_add_subregion(get_system_memory(),
-sdram_base(bcr),
-&sdram->bank[i].container);
+sdram_bank_map(&sdram->bank[i]);
  }
  }
  





Re: [PATCH v3 00/20] ppc4xx_sdram QOMify and clean ups

2022-09-14 Thread Cédric Le Goater

On 9/13/22 21:52, BALATON Zoltan wrote:

This is the end of the QOMify series started by Cédric. This series
handles the SDRAM controller models to clean them up, QOMify and unify
them and at least partially clean up the mess that has accumulated
around these in the past. This includes the not yet merged patches
from the last series and new ones that change the DDR2 version used by
sam460ex.



I made comments on the first ~10 patches. Let's try to agree on these
first. We will see the remaining ones in a second patchset.

Thanks,

C.




v3: Fix patches that got squashed during rebase
v2: address some review comments and try to avoid compile problem with
gcc 12.2 (untested)

BALATON Zoltan (20):
   ppc440_bamboo: Remove unnecessary memsets
   ppc4xx: Introduce Ppc4xxSdramBank struct
   ppc4xx_sdram: Get rid of the init RAM hack
   ppc4xx: Use Ppc4xxSdramBank in ppc4xx_sdram_banks()
   ppc440_bamboo: Add missing 4 MiB valid memory size
   ppc4xx_sdram: Move size check to ppc4xx_sdram_init()
   ppc4xx_sdram: QOM'ify
   ppc4xx_sdram: Drop extra zeros for readability
   ppc440_sdram: Split off map/unmap of sdram banks for later reuse
   ppc440_sdram: Implement enable bit in the DDR2 SDRAM
   ppc440_sdram: Get rid of the init RAM hack
   ppc440_sdram: Rename local variable for readibility
   ppc4xx_sdram: Rename functions to prevent name clashes
   ppc440_sdram: Move RAM size check to ppc440_sdram_init
   ppc440_sdram: QOM'ify
   ppc4xx_sdram: Move ppc4xx DDR and DDR2 SDRAM controller models
 together
   ppc4xx_sdram: Use hwaddr for memory bank size
   ppc4xx_sdram: Rename local state variable for brevity
   ppc4xx_sdram: Generalise bank setup
   ppc4xx_sdram: Convert DDR SDRAM controller to new bank handling

  hw/ppc/meson.build  |   3 +-
  hw/ppc/ppc405.h |   8 +-
  hw/ppc/ppc405_boards.c  |  22 +-
  hw/ppc/ppc405_uc.c  |  33 +-
  hw/ppc/ppc440.h |   4 -
  hw/ppc/ppc440_bamboo.c  |  29 +-
  hw/ppc/ppc440_uc.c  | 267 +--
  hw/ppc/ppc4xx_devs.c| 413 ---
  hw/ppc/ppc4xx_sdram.c   | 723 
  hw/ppc/sam460ex.c   |  48 +--
  hw/ppc/trace-events |   1 +
  include/hw/ppc/ppc4xx.h |  66 +++-
  12 files changed, 847 insertions(+), 770 deletions(-)
  create mode 100644 hw/ppc/ppc4xx_sdram.c






[PATCH] bochs-display: Modify mismatched return value

2022-09-14 Thread jianchunfu
Modify the return value of unsigned int to 0.

Signed-off-by: jianchunfu 
---
 hw/display/bochs-display.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/display/bochs-display.c b/hw/display/bochs-display.c
index 8ed734b195..3bd22b4ea7 100644
--- a/hw/display/bochs-display.c
+++ b/hw/display/bochs-display.c
@@ -83,7 +83,7 @@ static uint64_t bochs_display_vbe_read(void *ptr, hwaddr addr,
 }
 
 if (index >= ARRAY_SIZE(s->vbe_regs)) {
-return -1;
+return 0;
 }
 return s->vbe_regs[index];
 }
-- 
2.18.4






Re: [PATCH 49/51] io/channel-watch: Fix socket watch on Windows

2022-09-14 Thread Bin Meng
On Wed, Sep 7, 2022 at 1:07 PM Bin Meng  wrote:
>
> Hi Clément,
>
> On Tue, Sep 6, 2022 at 8:06 PM Clément Chigot  wrote:
> >
> > > > > I checked your patch, what you did seems to be something one would
> > > > > naturally write, but what is currently in the QEMU sources seems to be
> > > > > written intentionally.
> > > > >
> > > > > +Paolo Bonzini , you are the one who implemented the socket watch on
> > > > > Windows. Could you please help analyze this issue?
> > > > >
> > > > > > to avoid WSAEnumNetworkEvents for the master GSource which only has
> > > > > > G_IO_HUP (or for any GSource having only that).
> > > > > > As I said above, the current code doesn't do anything with it 
> > > > > > anyway.
> > > > > > So, IMO, it's safe to do so.
> > > > > >
> > > > > > I'll send you my patch attached. I was planning to send it in the 
> > > > > > following
> > > > > > weeks anyway. I was just waiting to be sure everything looks fine 
> > > > > > on our
> > > > > > CI. Feel free to test and modify it if needed.
> > > > >
> > > > > I tested your patch. Unfortunately there is still one test case
> > > > > (migration-test.exe) throwing up the "Broken pipe" message.
> > > >
> > > > I must say I didn't fully test it against qemu testsuite yet. Maybe 
> > > > there are
> > > > some refinements to be done. "Broken pipe" might be linked to the 
> > > > missing
> > > > G_IO_HUP support.
> > > >
> > > > > Can you test my patch instead to see if your gdb issue can be fixed?
> > > >
> > > > Yeah sure. I'll try to do it this afternoon.
> >
> > I can't explain how mad at me I am... I'm pretty sure your patch was the 
> > first
> > thing I've tried when I encountered this issue. But it wasn't working
> > or IIRC the
> > issue went away but that was because the polling was actually disabled 
> > (looping
> > indefinitely)...I'm suspecting that I already had changed the CreateEvent 
> > for
> > WSACreateEvent which forces you to handle the reset.
> > Finally, I end up struggling reworking the whole check function...
> > But yeah, your patch does work fine on my gdb issues too.
>
> Good to know this patch works for you too.
>
> > And I guess the events are reset when recv() is being called because of the
> > auto-reset feature set up by CreateEvent().
> > IIUC, what Marc-André means by busy loop is the polling being looping
> > indefinitely as I encountered. I can ensure that this patch doesn't do that.
> > It can be easily checked by setting the env variable G_MAIN_POLL_DEBUG.
> > It'll show what g_poll is doing and it's normally always available on
> > Windows.
> >
> > Anyway, we'll wait for Paolo to see if he remembers why he had to call
> > WSAEnumNetworkEvents. Otherwize, let's go for your patch. Mine might
> > be a good start to improve the whole polling on Windows but if it doesn't
> > work in your case, it then needs some refinements.
> >
>
> Yeah, this issue bugged me quite a lot. If we want to reset the event
> in qio_channel_socket_source_check(), we will have to do the following
> to make sure qtests are happy.
>
> diff --git a/io/channel-watch.c b/io/channel-watch.c
> index 43d38494f7..f1e1650b81 100644
> --- a/io/channel-watch.c
> +++ b/io/channel-watch.c
> @@ -124,8 +124,6 @@ qio_channel_socket_source_check(GSource *source)
> return 0;
> }
> - WSAEnumNetworkEvents(ssource->socket, ssource->ioc->event, &ev);
> -
> FD_ZERO(&rfds);
> FD_ZERO(&wfds);
> FD_ZERO(&xfds);
> @@ -153,6 +151,10 @@ qio_channel_socket_source_check(GSource *source)
> ssource->revents |= G_IO_PRI;
> }
> + if (ssource->revents) {
> + WSAEnumNetworkEvents(ssource->socket, ssource->ioc->event, &ev);
> + }
> +
> return ssource->revents;
> }
>
> Removing "if (ssource->revents)" won't work.
>
> It seems to me that resetting the event twice (one time with the
> master Gsource, and the other time with the child GSource) causes some
> bizarre behavior. But MSDN [1] says
>
> "Resetting an event that is already reset has no effect."
>
> [1] 
> https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-resetevent
>

Paolo, any comments about this issue?

Regards,
Bin



Re: [PATCH] hw/xen: set pci Atomic Ops requests for passthrough device

2022-09-14 Thread Paul Durrant

On 13/09/2022 04:02, Ji, Ruili wrote:

[AMD Official Use Only - General]


Hi Paul,

Could you help to review this patch?



LGTM. You can add my R-b to it.

  Paul


Thanks

*From:* Ji, Ruili
*Sent:* 2022年9月7日 9:04
*To:* 'Paul Durrant' ; 'qemu-devel@nongnu.org' 

*Cc:* Liu, Aaron ; 'xen-de...@lists.xenproject.org' 

*Subject:* RE: [PATCH] hw/xen: set pci Atomic Ops requests for 
passthrough device


FYI

*From:* Ji, Ruili
*Sent:* 2022年9月6日 15:40
*To:* qemu-devel@nongnu.org 
*Cc:* Liu, Aaron mailto:aaron@amd.com>>
*Subject:* [PATCH] hw/xen: set pci Atomic Ops requests for passthrough 
device


 From c54e0714a1e1cac7dc416bd843b9ec7162bcfc47 Mon Sep 17 00:00:00 2001

From: Ruili Ji ruili...@amd.com 

Date: Tue, 6 Sep 2022 14:09:41 +0800

Subject: [PATCH] hw/xen: set pci Atomic Ops requests for passthrough device

Make guest os access pci device control 2 reg for passthrough device

as struct XenPTRegInfo described in the file hw/xen/xen_pt.h.

/* reg read only field mask (ON:RO/ROS, OFF:other) */

uint32_t ro_mask;

/* reg emulate field mask (ON:emu, OFF:passthrough) */

uint32_t emu_mask;

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1196 



Signed-off-by: aaron@amd.com 

Signed-off-by: ruili...@amd.com 

---

hw/xen/xen_pt_config_init.c | 4 ++--

1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c

index c5c4e943a8..adc565a00a 100644

--- a/hw/xen/xen_pt_config_init.c

+++ b/hw/xen/xen_pt_config_init.c

@@ -985,8 +985,8 @@ static XenPTRegInfo xen_pt_emu_reg_pcie[] = {

  .offset = 0x28,

  .size   = 2,

  .init_val   = 0x,

-    .ro_mask    = 0xFFE0,

-    .emu_mask   = 0x,

+    .ro_mask    = 0xFFA0,

+    .emu_mask   = 0xFFBF,

  .init   = xen_pt_devctrl2_reg_init,

  .u.w.read   = xen_pt_word_reg_read,

  .u.w.write  = xen_pt_word_reg_write,

--

2.34.1






Re: [PATCH] chardev: fix segfault in finalize

2022-09-14 Thread Maksim Davydov
+ vsementsov@- pbonzini@   26.08.2022, 11:21, "Marc-André Lureau" :Hi  On Thu, Aug 25, 2022 at 9:02 PM Maksim Davydov  wrote:If finalize chardev-msmouse or chardev-wctable is called immediately afterinit it cases QEMU to crash with segfault. This happens because ofQTAILQ_REMOVE in qemu_input_handler_unregister tries to dereferenceNULL pointer.For instance, this error can be reproduced via `qom-list-properties`command.Signed-off-by: Maksim Davydov  Reviewed-by: Marc-André Lureau  --- chardev/msmouse.c  | 4 +++- chardev/wctablet.c | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-)diff --git a/chardev/msmouse.c b/chardev/msmouse.cindex eb9231dcdb..2cc1b16561 100644--- a/chardev/msmouse.c+++ b/chardev/msmouse.c@@ -146,7 +146,9 @@ static void char_msmouse_finalize(Object *obj) {     MouseChardev *mouse = MOUSE_CHARDEV(obj);-    qemu_input_handler_unregister(mouse->hs);+    if (mouse->hs) {+        qemu_input_handler_unregister(mouse->hs);+    } } static QemuInputHandler msmouse_handler = {diff --git a/chardev/wctablet.c b/chardev/wctablet.cindex e8b292c43c..43bdf6b608 100644--- a/chardev/wctablet.c+++ b/chardev/wctablet.c@@ -319,7 +319,9 @@ static void wctablet_chr_finalize(Object *obj) {     TabletChardev *tablet = WCTABLET_CHARDEV(obj);-    qemu_input_handler_unregister(tablet->hs);+    if (tablet->hs) {+        qemu_input_handler_unregister(tablet->hs);+    } } static void wctablet_chr_open(Chardev *chr,--2.25.1 --Marc-André LureauThanks for reviewing -- Best regards,Maksim Davydov 

[PATCH 1/3] target/riscv: Set the CPU resetvec directly

2022-09-14 Thread Alistair Francis via
Instead of using our properties to set a config value which then might
be used to set the resetvec (depending on your timing), let's instead
just set the resetvec directly in the env struct.

This allows us to set the reset vec from the command line with:
-global driver=riscv.hart_array,property=resetvec,value=0x2400

Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h |  3 +--
 target/riscv/cpu.c | 13 +++--
 target/riscv/machine.c |  6 +++---
 3 files changed, 7 insertions(+), 15 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 06751e1e3e..22344a620b 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -190,7 +190,7 @@ struct CPUArchState {
 /* This contains QEMU specific information about the virt state. */
 target_ulong virt;
 target_ulong geilen;
-target_ulong resetvec;
+uint64_t resetvec;
 
 target_ulong mhartid;
 /*
@@ -474,7 +474,6 @@ struct RISCVCPUConfig {
 bool pmp;
 bool epmp;
 bool debug;
-uint64_t resetvec;
 
 bool short_isa_string;
 };
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index aee14a239a..b29c88b9f0 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -228,13 +228,6 @@ static void set_vext_version(CPURISCVState *env, int 
vext_ver)
 env->vext_ver = vext_ver;
 }
 
-static void set_resetvec(CPURISCVState *env, target_ulong resetvec)
-{
-#ifndef CONFIG_USER_ONLY
-env->resetvec = resetvec;
-#endif
-}
-
 static void riscv_any_cpu_init(Object *obj)
 {
 CPURISCVState *env = &RISCV_CPU(obj)->env;
@@ -336,7 +329,6 @@ static void rv32_imafcu_nommu_cpu_init(Object *obj)
 
 set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVC | RVU);
 set_priv_version(env, PRIV_VERSION_1_10_0);
-set_resetvec(env, DEFAULT_RSTVEC);
 cpu->cfg.mmu = false;
 }
 #endif
@@ -676,7 +668,6 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 riscv_set_feature(env, RISCV_FEATURE_DEBUG);
 }
 
-set_resetvec(env, cpu->cfg.resetvec);
 
 #ifndef CONFIG_USER_ONLY
 if (cpu->cfg.ext_sstc) {
@@ -1079,7 +1070,9 @@ static Property riscv_cpu_properties[] = {
 DEFINE_PROP_UINT64("marchid", RISCVCPU, cfg.marchid, RISCV_CPU_MARCHID),
 DEFINE_PROP_UINT64("mimpid", RISCVCPU, cfg.mimpid, RISCV_CPU_MIMPID),
 
-DEFINE_PROP_UINT64("resetvec", RISCVCPU, cfg.resetvec, DEFAULT_RSTVEC),
+#ifndef CONFIG_USER_ONLY
+DEFINE_PROP_UINT64("resetvec", RISCVCPU, env.resetvec, DEFAULT_RSTVEC),
+#endif
 
 DEFINE_PROP_BOOL("short-isa-string", RISCVCPU, cfg.short_isa_string, 
false),
 
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index 41098f6ad0..c4e6b3bba4 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -308,8 +308,8 @@ static const VMStateDescription vmstate_pmu_ctr_state = {
 
 const VMStateDescription vmstate_riscv_cpu = {
 .name = "cpu",
-.version_id = 4,
-.minimum_version_id = 4,
+.version_id = 5,
+.minimum_version_id = 5,
 .post_load = riscv_cpu_post_load,
 .fields = (VMStateField[]) {
 VMSTATE_UINTTL_ARRAY(env.gpr, RISCVCPU, 32),
@@ -331,7 +331,7 @@ const VMStateDescription vmstate_riscv_cpu = {
 VMSTATE_UINT32(env.features, RISCVCPU),
 VMSTATE_UINTTL(env.priv, RISCVCPU),
 VMSTATE_UINTTL(env.virt, RISCVCPU),
-VMSTATE_UINTTL(env.resetvec, RISCVCPU),
+VMSTATE_UINT64(env.resetvec, RISCVCPU),
 VMSTATE_UINTTL(env.mhartid, RISCVCPU),
 VMSTATE_UINT64(env.mstatus, RISCVCPU),
 VMSTATE_UINT64(env.mip, RISCVCPU),
-- 
2.37.2




[PATCH 2/3] hw/riscv: opentitan: Fixup resetvec

2022-09-14 Thread Alistair Francis via
The resetvec for the OpenTitan machine ended up being set to an out of
date value, so let's fix that and bump it to the correct start address
(after the boot ROM)

Fixes: bf8803c64d75 "hw/riscv: opentitan: bump opentitan version"
Signed-off-by: Alistair Francis 
---
 hw/riscv/opentitan.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
index af13dbe3b1..45c92c9bbc 100644
--- a/hw/riscv/opentitan.c
+++ b/hw/riscv/opentitan.c
@@ -142,7 +142,7 @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, 
Error **errp)
 &error_abort);
 object_property_set_int(OBJECT(&s->cpus), "num-harts", ms->smp.cpus,
 &error_abort);
-object_property_set_int(OBJECT(&s->cpus), "resetvec", 0x2490,
+object_property_set_int(OBJECT(&s->cpus), "resetvec", 0x2400,
 &error_abort);
 sysbus_realize(SYS_BUS_DEVICE(&s->cpus), &error_fatal);
 
-- 
2.37.2




[PATCH 0/3] hw/riscv: opentitan: Fixup resetvec issues

2022-09-14 Thread Alistair Francis via
The OpenTitan resetvec is dynamic on QEMU as we don't run the full boot
ROM flow. This series makes it more configurguable from the command line
and fixes the default.

Alistair Francis (3):
  target/riscv: Set the CPU resetvec directly
  hw/riscv: opentitan: Fixup resetvec
  hw/riscv: opentitan: Expose the resetvec as a SoC property

 include/hw/riscv/opentitan.h |  2 ++
 target/riscv/cpu.h   |  3 +--
 hw/riscv/opentitan.c |  8 +++-
 target/riscv/cpu.c   | 13 +++--
 target/riscv/machine.c   |  6 +++---
 5 files changed, 16 insertions(+), 16 deletions(-)

-- 
2.37.2




[PATCH 3/3] hw/riscv: opentitan: Expose the resetvec as a SoC property

2022-09-14 Thread Alistair Francis via
On the OpenTitan hardware the resetvec is fixed at the start of ROM. In
QEMU we don't run the ROM code and instead just jump to the next stage.
This means we need to be a little more flexible about what the resetvec
is.

This patch allows us to set the resetvec from the command line with
something like this:
-global driver=riscv.lowrisc.ibex.soc,property=resetvec,value=0x2400

This way as the next stage changes we can update the resetvec.

Signed-off-by: Alistair Francis 
---
 include/hw/riscv/opentitan.h | 2 ++
 hw/riscv/opentitan.c | 8 +++-
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/include/hw/riscv/opentitan.h b/include/hw/riscv/opentitan.h
index 26d960f288..6665cd5794 100644
--- a/include/hw/riscv/opentitan.h
+++ b/include/hw/riscv/opentitan.h
@@ -46,6 +46,8 @@ struct LowRISCIbexSoCState {
 IbexTimerState timer;
 IbexSPIHostState spi_host[OPENTITAN_NUM_SPI_HOSTS];
 
+uint32_t resetvec;
+
 MemoryRegion flash_mem;
 MemoryRegion rom;
 MemoryRegion flash_alias;
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
index 45c92c9bbc..be7ff1eea0 100644
--- a/hw/riscv/opentitan.c
+++ b/hw/riscv/opentitan.c
@@ -142,7 +142,7 @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, 
Error **errp)
 &error_abort);
 object_property_set_int(OBJECT(&s->cpus), "num-harts", ms->smp.cpus,
 &error_abort);
-object_property_set_int(OBJECT(&s->cpus), "resetvec", 0x2400,
+object_property_set_int(OBJECT(&s->cpus), "resetvec", s->resetvec,
 &error_abort);
 sysbus_realize(SYS_BUS_DEVICE(&s->cpus), &error_fatal);
 
@@ -297,10 +297,16 @@ static void lowrisc_ibex_soc_realize(DeviceState 
*dev_soc, Error **errp)
 memmap[IBEX_DEV_PERI].base, memmap[IBEX_DEV_PERI].size);
 }
 
+static Property lowrisc_ibex_soc_props[] = {
+DEFINE_PROP_UINT32("resetvec", LowRISCIbexSoCState, resetvec, 0x2400),
+DEFINE_PROP_END_OF_LIST()
+};
+
 static void lowrisc_ibex_soc_class_init(ObjectClass *oc, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(oc);
 
+device_class_set_props(dc, lowrisc_ibex_soc_props);
 dc->realize = lowrisc_ibex_soc_realize;
 /* Reason: Uses serial_hds in realize function, thus can't be used twice */
 dc->user_creatable = false;
-- 
2.37.2




RE: [PATCH] hw/xen: set pci Atomic Ops requests for passthrough device

2022-09-14 Thread Ji, Ruili
[AMD Official Use Only - General]

Hi Paul,

Thank you!
But how could we merge this patch ?

Ruili
-Original Message-
From: Paul Durrant 
Sent: 2022年9月14日 17:08
To: Ji, Ruili ; qemu-devel@nongnu.org
Cc: Liu, Aaron ; xen-de...@lists.xenproject.org
Subject: Re: [PATCH] hw/xen: set pci Atomic Ops requests for passthrough device

Caution: This message originated from an External Source. Use proper caution 
when opening attachments, clicking links, or responding.


On 13/09/2022 04:02, Ji, Ruili wrote:
> [AMD Official Use Only - General]
>
>
> Hi Paul,
>
> Could you help to review this patch?
>

LGTM. You can add my R-b to it.

   Paul

> Thanks
>
> *From:* Ji, Ruili
> *Sent:* 2022年9月7日 9:04
> *To:* 'Paul Durrant' ; 'qemu-devel@nongnu.org'
> 
> *Cc:* Liu, Aaron ; 'xen-de...@lists.xenproject.org'
> 
> *Subject:* RE: [PATCH] hw/xen: set pci Atomic Ops requests for
> passthrough device
>
> FYI
>
> *From:* Ji, Ruili
> *Sent:* 2022年9月6日 15:40
> *To:* qemu-devel@nongnu.org 
> *Cc:* Liu, Aaron mailto:aaron@amd.com>>
> *Subject:* [PATCH] hw/xen: set pci Atomic Ops requests for passthrough
> device
>
>  From c54e0714a1e1cac7dc416bd843b9ec7162bcfc47 Mon Sep 17 00:00:00
> 2001
>
> From: Ruili Ji ruili...@amd.com 
>
> Date: Tue, 6 Sep 2022 14:09:41 +0800
>
> Subject: [PATCH] hw/xen: set pci Atomic Ops requests for passthrough
> device
>
> Make guest os access pci device control 2 reg for passthrough device
>
> as struct XenPTRegInfo described in the file hw/xen/xen_pt.h.
>
> /* reg read only field mask (ON:RO/ROS, OFF:other) */
>
> uint32_t ro_mask;
>
> /* reg emulate field mask (ON:emu, OFF:passthrough) */
>
> uint32_t emu_mask;
>
> Resolves:
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgitl
> ab.com%2Fqemu-project%2Fqemu%2F-%2Fissues%2F1196&data=05%7C01%7CRu
> ili.Ji%40amd.com%7Ca5e2c22a81544feb6bb408da96309702%7C3dd8961fe4884e60
> 8e11a82d994e183d%7C0%7C0%7C637987432689748212%7CUnknown%7CTWFpbGZsb3d8
> eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3
> 000%7C%7C%7C&sdata=Jg8588FWkIZzmSEyt50TYCbck2NuoVJdm7ZP0Z%2FtFGc%3
> D&reserved=0
>  lab.com%2Fqemu-project%2Fqemu%2F-%2Fissues%2F1196&data=05%7C01%7CR
> uili.Ji%40amd.com%7Ca5e2c22a81544feb6bb408da96309702%7C3dd8961fe4884e6
> 08e11a82d994e183d%7C0%7C0%7C637987432689748212%7CUnknown%7CTWFpbGZsb3d
> 8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C
> 3000%7C%7C%7C&sdata=Jg8588FWkIZzmSEyt50TYCbck2NuoVJdm7ZP0Z%2FtFGc%
> 3D&reserved=0>
>
> Signed-off-by: aaron@amd.com 
>
> Signed-off-by: ruili...@amd.com 
>
> ---
>
> hw/xen/xen_pt_config_init.c | 4 ++--
>
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c
>
> index c5c4e943a8..adc565a00a 100644
>
> --- a/hw/xen/xen_pt_config_init.c
>
> +++ b/hw/xen/xen_pt_config_init.c
>
> @@ -985,8 +985,8 @@ static XenPTRegInfo xen_pt_emu_reg_pcie[] = {
>
>   .offset = 0x28,
>
>   .size   = 2,
>
>   .init_val   = 0x,
>
> -.ro_mask= 0xFFE0,
>
> -.emu_mask   = 0x,
>
> +.ro_mask= 0xFFA0,
>
> +.emu_mask   = 0xFFBF,
>
>   .init   = xen_pt_devctrl2_reg_init,
>
>   .u.w.read   = xen_pt_word_reg_read,
>
>   .u.w.write  = xen_pt_word_reg_write,
>
> --
>
> 2.34.1
>




[PATCH] target/arm: Fix alignment for VLD4.32

2022-09-14 Thread Clément Chigot
When requested, the alignment for VLD4.32 is 8 and not 16.

See ARM documentation about VLD4 encoding:
ebytes = 1 << UInt(size);
if size == '10' then
alignment = if a == '0' then 1 else 8;
else
alignment = if a == '0' then 1 else 4*ebytes;

Signed-off-by: Clément Chigot 
---
 target/arm/translate-neon.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
index 321c17e2c7..4016339d46 100644
--- a/target/arm/translate-neon.c
+++ b/target/arm/translate-neon.c
@@ -584,7 +584,11 @@ static bool trans_VLD_all_lanes(DisasContext *s, 
arg_VLD_all_lanes *a)
 case 3:
 return false;
 case 4:
-align = pow2_align(size + 2);
+if (size == 2) {
+align = pow2_align(3);
+} else {
+align = pow2_align(size + 2);
+}
 break;
 default:
 g_assert_not_reached();
-- 
2.25.1




[PATCH v2 2/4] python/qmp: increase read buffer size

2022-09-14 Thread Maksim Davydov
After modification of "query-machines" command the buffer size should be
more than 452kB to contain output with compat-props.

Signed-off-by: Maksim Davydov 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 python/qemu/qmp/qmp_client.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/python/qemu/qmp/qmp_client.py b/python/qemu/qmp/qmp_client.py
index 5dcda04a75..659fe4d98c 100644
--- a/python/qemu/qmp/qmp_client.py
+++ b/python/qemu/qmp/qmp_client.py
@@ -197,8 +197,8 @@ async def run(self, address='/tmp/qemu.socket'):
 #: Logger object used for debugging messages.
 logger = logging.getLogger(__name__)
 
-# Read buffer limit; large enough to accept query-qmp-schema
-_limit = (256 * 1024)
+# Read buffer limit; large enough to accept query-machines
+_limit = (512 * 1024)
 
 # Type alias for pending execute() result items
 _PendingT = Union[Message, ExecInterruptedError]
-- 
2.25.1




[PATCH v2 0/4] compare machine type compat_props

2022-09-14 Thread Maksim Davydov
v2 -> v1:
* fix script code style and descriptions
* reorder patches

v1 -> previous iteration:
* new default value print concept
* QEMU python library is used to collect qmp data
* remove auxiliary patches (that was used to fix ->get sematics)
* print compat_props in the correct order
* delete `absract` field to reduce output JSON size

Maksim Davydov (4):
  qom: add devault value
  python/qmp: increase read buffer size
  qmp: add dump machine type compatible properties
  scripts: add script to compare compatible properties

 hw/core/machine-qmp-cmds.c|  22 +-
 python/qemu/qmp/qmp_client.py |   4 +-
 qapi/machine.json |  54 -
 qom/qom-qmp-cmds.c|   2 +
 scripts/compare_mt.py | 374 ++
 tests/qtest/fuzz/qos_fuzz.c   |   2 +-
 6 files changed, 452 insertions(+), 6 deletions(-)
 create mode 100755 scripts/compare_mt.py

-- 
2.25.1




[PATCH v2 4/4] scripts: add script to compare compatible properties

2022-09-14 Thread Maksim Davydov
This script run QEMU to obtain compat_props of machines and default
values of different types and produce appropriate table. This table
can be used to compare machine types to choose the most suitable
machine. Also table in json or csv format should be used to check that
new machine doesn't affect previous ones via comparisin tables with and
without new machine.
Default values of properties are needed to fill "holes" in the table (one
machine has these properties and another not).

Notes:
* some init values from the devices can't be available like properties
from virtio-9p when configure has --disable-virtfs. This situations will
be seen in the table as "unavailable driver".
* Default values can be get can be obtained in an unobvious way, like
x86 features. If the script doesn't know how to get property default value
to compare one machine with another it fills "holes" with "unavailable
method". This is done because script uses whitelist model to get default
values of different types. It means that the method that can't be applied
to a new type that can crash this script. It is better to get an
"unavailable driver" when creating a new machine with new compatible
properties than to break this script. So it turns out a more stable and
generic script.
* If the default value can't be obtained because this property doesn't
exist or because this property can't have default value, appropriate
"hole" will be filled by "unknown property" or "no default value"
* If the property is applied to the abstract class, the script collects
default values from all child classes (set of default values)

Example:

./scripts/compare_mt.py --mt pc-q35-3.1 pc-q35-2.12

╒╤═══╤═══╕
││  pc-q35-2.12  │  pc-q35-3.1   │
╞╪═══╪═══╡
│EPYC-IBPB-x86_64-cpu-xlevel │  0x800a   │  2147483678   │
├┼───┼───┤
│   EPYC-x86_64-cpu-xlevel   │  0x800a   │  2147483678   │
├┼───┼───┤
│ Skylake-Server-IBRS-x86_64-cpu-pku │ False │ True  │
├┼───┼───┤
│   Skylake-Server-x86_64-cpu-pku│ False │ True  │
├┼───┼───┤
│ VGA-global-vmstate │ True  │ False │
├┼───┼───┤
│ cirrus-vga-global-vmstate  │ True  │ False │
├┼───┼───┤
│hda-audio-use-timer │ False │ True  │
├┼───┼───┤
│  migration-decompress-error-check  │ False │ True  │
├┼───┼───┤
│   qxl-vga-global-vmstate   │ True  │ False │
├┼───┼───┤
│ vmware-svga-global-vmstate │ True  │ False │
├┼───┼───┤
│  x86_64-cpu-legacy-cache   │ True  │ [True, False] │
├┼───┼───┤
│ x86_64-cpu-topoext │ False │ [True, False] │
├┼───┼───┤
│   x86_64-cpu-x-hv-synic-kvm-only   │ True  │ False │
╘╧═══╧═══╛

Signed-off-by: Maksim Davydov 
---
 scripts/compare_mt.py | 374 ++
 1 file changed, 374 insertions(+)
 create mode 100755 scripts/compare_mt.py

diff --git a/scripts/compare_mt.py b/scripts/compare_mt.py
new file mode 100755
index 00..1df5e6c4f4
--- /dev/null
+++ b/scripts/compare_mt.py
@@ -0,0 +1,374 @@
+#!/usr/bin/env python3
+#
+# Script to compare machine type compatible properties (include/hw/boards.h).
+# compat_props are applied to the driver during initialization to change
+# default values, for instance, to maintain compatibility.
+# This script constructs table with machines and values of their compat_props
+# to compare and to find places for improvements or places with bugs. If
+# during the comparision, some machine type doesn't have a property (it is in
+# the comparision table because another machine type has it), then the
+# appropriate method will be used to obtain the default value of this driver
+# property via qmp command (e.g. query-cpu-model-expansion for x86_64-cpu).
+# These methods are defined below in propery_methods.
+#
+# Copyright (c) Yandex Technologies LLC, 2022
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU 

[PATCH v2 1/4] qom: add devault value

2022-09-14 Thread Maksim Davydov
qmp_qom_list_properties can print default values if they are available
as qmp_device_list_properties does, because both of them use the
ObjectPropertyInfo structure with default_value field. This can be useful
when working with "not device" types.

Signed-off-by: Maksim Davydov 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 qom/qom-qmp-cmds.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/qom/qom-qmp-cmds.c b/qom/qom-qmp-cmds.c
index 2e63a4c184..1d7867dc19 100644
--- a/qom/qom-qmp-cmds.c
+++ b/qom/qom-qmp-cmds.c
@@ -217,6 +217,8 @@ ObjectPropertyInfoList *qmp_qom_list_properties(const char 
*typename,
 info->type = g_strdup(prop->type);
 info->has_description = !!prop->description;
 info->description = g_strdup(prop->description);
+info->default_value = qobject_ref(prop->defval);
+info->has_default_value = !!info->default_value;
 
 QAPI_LIST_PREPEND(prop_list, info);
 }
-- 
2.25.1




[PATCH v2 3/4] qmp: add dump machine type compatible properties

2022-09-14 Thread Maksim Davydov
To control that creating new machine type doesn't affect the previous
types (their compat_props) and to check complex compat_props inheritance
we need qmp command to print machine type compatible properties.
This patch adds the ability to get list of all the compat_props of the
corresponding supported machines for their comparison via new optional
argument of "query-machines" command.

Signed-off-by: Maksim Davydov 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
 hw/core/machine-qmp-cmds.c  | 22 ++-
 qapi/machine.json   | 54 +++--
 tests/qtest/fuzz/qos_fuzz.c |  2 +-
 3 files changed, 74 insertions(+), 4 deletions(-)

diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c
index 4f4ab30f8c..a6fc387439 100644
--- a/hw/core/machine-qmp-cmds.c
+++ b/hw/core/machine-qmp-cmds.c
@@ -74,7 +74,8 @@ CpuInfoFastList *qmp_query_cpus_fast(Error **errp)
 return head;
 }
 
-MachineInfoList *qmp_query_machines(Error **errp)
+MachineInfoList *qmp_query_machines(bool has_compat_props, bool compat_props,
+Error **errp)
 {
 GSList *el, *machines = object_class_get_list(TYPE_MACHINE, false);
 MachineInfoList *mach_list = NULL;
@@ -107,6 +108,25 @@ MachineInfoList *qmp_query_machines(Error **errp)
 info->default_ram_id = g_strdup(mc->default_ram_id);
 info->has_default_ram_id = true;
 }
+if (compat_props && mc->compat_props) {
+int i;
+info->compat_props = NULL;
+CompatPropertyList **tail = &(info->compat_props);
+info->has_compat_props = true;
+
+for (i = 0; i < mc->compat_props->len; i++) {
+GlobalProperty *mt_prop = g_ptr_array_index(mc->compat_props,
+i);
+CompatProperty *prop;
+
+prop = g_malloc0(sizeof(*prop));
+prop->driver = g_strdup(mt_prop->driver);
+prop->property = g_strdup(mt_prop->property);
+prop->value = g_strdup(mt_prop->value);
+
+QAPI_LIST_APPEND(tail, prop);
+}
+}
 
 QAPI_LIST_PREPEND(mach_list, info);
 }
diff --git a/qapi/machine.json b/qapi/machine.json
index 6afd1936b0..b5477224a8 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -127,6 +127,25 @@
 ##
 { 'command': 'query-cpus-fast', 'returns': [ 'CpuInfoFast' ] }
 
+##
+# @CompatProperty:
+#
+# Machine type compatible property. It's based on GlobalProperty and created
+# for machine type compat properties (see scripts)
+#
+# @driver: name of the driver that has GlobalProperty
+#
+# @property: global property name
+#
+# @value: global property value
+#
+# Since: 7.2
+##
+{ 'struct': 'CompatProperty',
+  'data': { 'driver': 'str',
+'property': 'str',
+'value': 'str' } }
+
 ##
 # @MachineInfo:
 #
@@ -155,6 +174,9 @@
 #
 # @default-ram-id: the default ID of initial RAM memory backend (since 5.2)
 #
+# @compat-props: List of compatible properties that defines machine type
+#(since 7.2)
+#
 # Since: 1.2
 ##
 { 'struct': 'MachineInfo',
@@ -162,18 +184,46 @@
 '*is-default': 'bool', 'cpu-max': 'int',
 'hotpluggable-cpus': 'bool',  'numa-mem-supported': 'bool',
 'deprecated': 'bool', '*default-cpu-type': 'str',
-'*default-ram-id': 'str' } }
+'*default-ram-id': 'str', '*compat-props': ['CompatProperty'] } }
 
 ##
 # @query-machines:
 #
 # Return a list of supported machines
 #
+# @compat-props: if true return will contain information about machine type
+#compatible properties (since 7.2)
+#
 # Returns: a list of MachineInfo
 #
 # Since: 1.2
+#
+# Example:
+#
+# -> { "execute": "query-machines", "arguments": { "compat-props": true } }
+# <- { "return": [
+#  {
+#  "hotpluggable-cpus": true,
+#  "name": "pc-q35-6.2",
+#  "compat-props": [
+#  {
+#  "driver": "virtio-mem",
+#  "property": "unplugged-inaccessible",
+#  "value": "off"
+#   }
+#   ],
+#   "numa-mem-supported": false,
+#   "default-cpu-type": "qemu64-x86_64-cpu",
+#   "cpu-max": 288,
+#   "deprecated": false,
+#   "default-ram-id": "pc.ram"
+#   },
+#   ...
+#}
 ##
-{ 'command': 'query-machines', 'returns': ['MachineInfo'] }
+{ 'command': 'query-machines',
+  'data': { '*compat-props': 'bool' },
+  'returns': ['MachineInfo'] }
 
 ##
 # @CurrentMachineParams:
diff --git a/tests/qtest/fuzz/qos_fuzz.c b/tests/qtest/fuzz/qos_fuzz.c
index c856d3d500..f0c9ed4c4b 100644
--- a/tests/qtest/fuzz/qos_fuzz.c
+++ b/tests/qtest/fuzz/qos_fuzz.c
@@ -46,7 +46,7 @@ static void qos_set_machines_devices_available(void)
 MachineInfoList *mach_info;
 ObjectTypeInf

[PATCH 1/1] s390x/tcg: Fix opcode for lzrf

2022-09-14 Thread Christian Borntraeger
Fix the opcode for Load and Zero Rightmost Byte (32).

Cc: qemu-sta...@nongnu.org
Reported-by: Nathan Chancellor 
Tested-by: Nathan Chancellor 
Signed-off-by: Christian Borntraeger 
---
 target/s390x/tcg/insn-data.def | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/s390x/tcg/insn-data.def b/target/s390x/tcg/insn-data.def
index 6d2cfe5fa2b7..6382ceabfcfa 100644
--- a/target/s390x/tcg/insn-data.def
+++ b/target/s390x/tcg/insn-data.def
@@ -466,7 +466,7 @@
 C(0xe39f, LAT, RXY_a, LAT, 0, m2_32u, r1, 0, lat, 0)
 C(0xe385, LGAT,RXY_a, LAT, 0, a2, r1, 0, lgat, 0)
 /* LOAD AND ZERO RIGHTMOST BYTE */
-C(0xe3eb, LZRF,RXY_a, LZRB, 0, m2_32u, new, r1_32, lzrb, 0)
+C(0xe33b, LZRF,RXY_a, LZRB, 0, m2_32u, new, r1_32, lzrb, 0)
 C(0xe32a, LZRG,RXY_a, LZRB, 0, m2_64, r1, 0, lzrb, 0)
 /* LOAD LOGICAL AND ZERO RIGHTMOST BYTE */
 C(0xe33a, LLZRGF,  RXY_a, LZRB, 0, m2_32u, r1, 0, lzrb, 0)
-- 
2.37.1




Re: [PATCH 2/3] vdpa: load vlan configuration at NIC startup

2022-09-14 Thread Eugenio Perez Martin
On Wed, Sep 14, 2022 at 4:20 AM Jason Wang  wrote:
>
> On Fri, Sep 9, 2022 at 4:02 PM Eugenio Perez Martin  
> wrote:
> >
> > On Fri, Sep 9, 2022 at 8:40 AM Jason Wang  wrote:
> > >
> > > On Fri, Sep 9, 2022 at 2:38 PM Jason Wang  wrote:
> > > >
> > > > On Wed, Sep 7, 2022 at 12:36 AM Eugenio Pérez  
> > > > wrote:
> > > > >
> > > > > To have enabled vlans at device startup may happen in the destination 
> > > > > of
> > > > > a live migration, so this configuration must be restored.
> > > > >
> > > > > At this moment the code is not accessible, since SVQ refuses to start 
> > > > > if
> > > > > vlan feature is exposed by the device.
> > > > >
> > > > > Signed-off-by: Eugenio Pérez 
> > > > > ---
> > > > >  net/vhost-vdpa.c | 46 --
> > > > >  1 file changed, 44 insertions(+), 2 deletions(-)
> > > > >
> > > > > diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
> > > > > index 4bc3fd01a8..ecbfd08eb9 100644
> > > > > --- a/net/vhost-vdpa.c
> > > > > +++ b/net/vhost-vdpa.c
> > > > > @@ -100,6 +100,8 @@ static const uint64_t vdpa_svq_device_features =
> > > > >  BIT_ULL(VIRTIO_NET_F_RSC_EXT) |
> > > > >  BIT_ULL(VIRTIO_NET_F_STANDBY);
> > > > >
> > > > > +#define MAX_VLAN(1 << 12)   /* Per 802.1Q definition */
> > > > > +
> > > > >  VHostNetState *vhost_vdpa_get_vhost_net(NetClientState *nc)
> > > > >  {
> > > > >  VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
> > > > > @@ -423,6 +425,47 @@ static int vhost_vdpa_net_load_mq(VhostVDPAState 
> > > > > *s,
> > > > >  return *s->status != VIRTIO_NET_OK;
> > > > >  }
> > > > >
> > > > > +static int vhost_vdpa_net_load_single_vlan(VhostVDPAState *s,
> > > > > +   const VirtIONet *n,
> > > > > +   uint16_t vid)
> > > > > +{
> > > > > +ssize_t dev_written = vhost_vdpa_net_load_cmd(s, 
> > > > > VIRTIO_NET_CTRL_VLAN,
> > > > > +  
> > > > > VIRTIO_NET_CTRL_VLAN_ADD,
> > > > > +  &vid, sizeof(vid));
> > > > > +if (unlikely(dev_written < 0)) {
> > > > > +return dev_written;
> > > > > +}
> > > > > +
> > > > > +if (unlikely(*s->status != VIRTIO_NET_OK)) {
> > > > > +return -EINVAL;
> > > > > +}
> > > > > +
> > > > > +return 0;
> > > > > +}
> > > > > +
> > > > > +static int vhost_vdpa_net_load_vlan(VhostVDPAState *s,
> > > > > +const VirtIONet *n)
> > > > > +{
> > > > > +uint64_t features = n->parent_obj.guest_features;
> > > > > +
> > > > > +if (!(features & BIT_ULL(VIRTIO_NET_F_CTRL_VLAN))) {
> > > > > +return 0;
> > > > > +}
> > > > > +
> > > > > +for (int i = 0; i < MAX_VLAN >> 5; i++) {
> > > > > +for (int j = 0; n->vlans[i] && j <= 0x1f; j++) {
> > > > > +if (n->vlans[i] & (1U << j)) {
> > > > > +int r = vhost_vdpa_net_load_single_vlan(s, n, (i << 
> > > > > 5) + j);
> > > >
> > > > This seems to cause a lot of latency if the driver has a lot of vlans.
> > > >
> > > > I wonder if it's simply to let all vlan traffic go by disabling
> > > > CTRL_VLAN feature at vDPA layer.
> > >
> >
> > The guest will not be able to recover that vlan configuration.
>
> Spec said it's best effort and we actually don't do this for
> vhost-net/user for years and manage to survive.
>

If that is accepted I'm ok to do it that way.

> >
> > > Another idea is to extend the spec to allow us to accept a bitmap of
> > > the vlan ids via a single command, then we will be fine.
> > >
> >
> > I'm not sure if adding more ways to configure something is the answer,
> > but I'd be ok to implement it.
> >
> > Another idea is to allow the sending of many CVQ commands in parallel.
> > It shouldn't be very hard to achieve using exposed buffers as ring
> > buffers, and it will short down the start of the devices with many
> > features.
>
> In the extreme case, what if guests decide to filter all of the vlans?
> It means we need MAX_VLAN commands which may exceeds the size of the
> control virtqueue.
>

The buffers should be used in a circular manner: If not every vlan /
cmd could be sent, we should wait for previous buffers completion and
keep sending.

This would speed up not only vlan initialization but all NIC
configuration loading.

> Thanks
>
> >
> > Thanks!
> >
> > > Thanks
> > >
> > > >
> > > > Thanks
> > > >
> > > > > +if (unlikely(r != 0)) {
> > > > > +return r;
> > > > > +}
> > > > > +}
> > > > > +}
> > > > > +}
> > > > > +
> > > > > +return 0;
> > > > > +}
> > > > > +
> > > > >  static int vhost_vdpa_net_load(NetClientState *nc)
> > > > >  {
> > > > >  VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
> > > > > @@ -445,8 +488,7 @@ static int vhost_vdpa_net_load(NetClientState *nc)
> > > > >  if (unlikely(r)) {
> > > > >  r

Re: [PATCH 2/3] vdpa: load vlan configuration at NIC startup

2022-09-14 Thread Eugenio Perez Martin
On Fri, Sep 9, 2022 at 10:38 AM Michael S. Tsirkin  wrote:
>
> On Fri, Sep 09, 2022 at 10:01:16AM +0200, Eugenio Perez Martin wrote:
> > On Fri, Sep 9, 2022 at 8:40 AM Jason Wang  wrote:
> > >
> > > On Fri, Sep 9, 2022 at 2:38 PM Jason Wang  wrote:
> > > >
> > > > On Wed, Sep 7, 2022 at 12:36 AM Eugenio Pérez  
> > > > wrote:
> > > > >
> > > > > To have enabled vlans at device startup may happen in the destination 
> > > > > of
> > > > > a live migration, so this configuration must be restored.
> > > > >
> > > > > At this moment the code is not accessible, since SVQ refuses to start 
> > > > > if
> > > > > vlan feature is exposed by the device.
> > > > >
> > > > > Signed-off-by: Eugenio Pérez 
> > > > > ---
> > > > >  net/vhost-vdpa.c | 46 --
> > > > >  1 file changed, 44 insertions(+), 2 deletions(-)
> > > > >
> > > > > diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
> > > > > index 4bc3fd01a8..ecbfd08eb9 100644
> > > > > --- a/net/vhost-vdpa.c
> > > > > +++ b/net/vhost-vdpa.c
> > > > > @@ -100,6 +100,8 @@ static const uint64_t vdpa_svq_device_features =
> > > > >  BIT_ULL(VIRTIO_NET_F_RSC_EXT) |
> > > > >  BIT_ULL(VIRTIO_NET_F_STANDBY);
> > > > >
> > > > > +#define MAX_VLAN(1 << 12)   /* Per 802.1Q definition */
> > > > > +
> > > > >  VHostNetState *vhost_vdpa_get_vhost_net(NetClientState *nc)
> > > > >  {
> > > > >  VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
> > > > > @@ -423,6 +425,47 @@ static int vhost_vdpa_net_load_mq(VhostVDPAState 
> > > > > *s,
> > > > >  return *s->status != VIRTIO_NET_OK;
> > > > >  }
> > > > >
> > > > > +static int vhost_vdpa_net_load_single_vlan(VhostVDPAState *s,
> > > > > +   const VirtIONet *n,
> > > > > +   uint16_t vid)
> > > > > +{
> > > > > +ssize_t dev_written = vhost_vdpa_net_load_cmd(s, 
> > > > > VIRTIO_NET_CTRL_VLAN,
> > > > > +  
> > > > > VIRTIO_NET_CTRL_VLAN_ADD,
> > > > > +  &vid, sizeof(vid));
> > > > > +if (unlikely(dev_written < 0)) {
> > > > > +return dev_written;
> > > > > +}
> > > > > +
> > > > > +if (unlikely(*s->status != VIRTIO_NET_OK)) {
> > > > > +return -EINVAL;
> > > > > +}
> > > > > +
> > > > > +return 0;
> > > > > +}
> > > > > +
> > > > > +static int vhost_vdpa_net_load_vlan(VhostVDPAState *s,
> > > > > +const VirtIONet *n)
> > > > > +{
> > > > > +uint64_t features = n->parent_obj.guest_features;
> > > > > +
> > > > > +if (!(features & BIT_ULL(VIRTIO_NET_F_CTRL_VLAN))) {
> > > > > +return 0;
> > > > > +}
> > > > > +
> > > > > +for (int i = 0; i < MAX_VLAN >> 5; i++) {
> > > > > +for (int j = 0; n->vlans[i] && j <= 0x1f; j++) {
> > > > > +if (n->vlans[i] & (1U << j)) {
> > > > > +int r = vhost_vdpa_net_load_single_vlan(s, n, (i << 
> > > > > 5) + j);
> > > >
> > > > This seems to cause a lot of latency if the driver has a lot of vlans.
> > > >
> > > > I wonder if it's simply to let all vlan traffic go by disabling
> > > > CTRL_VLAN feature at vDPA layer.
> > >
> >
> > The guest will not be able to recover that vlan configuration.
> >
> > > Another idea is to extend the spec to allow us to accept a bitmap of
> > > the vlan ids via a single command, then we will be fine.
> > >
> >
> > I'm not sure if adding more ways to configure something is the answer,
> > but I'd be ok to implement it.
> >
> > Another idea is to allow the sending of many CVQ commands in parallel.
> > It shouldn't be very hard to achieve using exposed buffers as ring
> > buffers, and it will short down the start of the devices with many
> > features.
>
> This would seem like a reasonable second step.  A first step would be to
> measure the overhead to make sure there's actually a need to optimize
> this.
>

I totally agree.

The processing time of each command is limited by the device. Taking
this to the extreme, we could achieve almost instantaneous
configuration for vdpa_sim_net, but a new device could take forever to
configure each mac.

So I think it should be considered as an optimization on top too, and
apply only if we see the initialization is slow on any devices.

Thanks!




Re: Question about loading bare metal firmware

2022-09-14 Thread Alistair Francis
On Tue, Sep 13, 2022 at 4:57 PM Clément Chigot  wrote:
>
> > > Hi all,
> > >
> > > I'm wondering if there is an official way to load bare metal software
> > > within qemu emulations.
> > > I've seen a lot of people (including us) using -kernel. However, the
> > > doc seems to imply that the generic loader would be a better approach
> > > (cf [1]). I know that the compatibility with older Qemus is one of the
> > > reasons why -kernel is still highly used. I've also seen that the
> > > reset vector can be initialized automatically by -kernel unlike with
> > > the generic loader (this is the case with RiscV AFAICT).
> > > But is there any kind of official recommendation on that topic ?
> >
> > The recommendation is in the document you linked. For bare metal use the
> > generic loader and make sure you put the blob in the right place so the
> > architectural reset vector will jump to it.
>
> Alright. I should have missed something when I tried with the generic loader.
> Thanks for the inputs and the confirmation that we were doing something wrong 
> !

Just another note that for a few RISC-V machines we load OpenSBI by
default. So if you don't want OpenSBI you should also specify `-bios
none`. You should also be able to just use `-bios ` to load
your bare metal application

Alistair

>
> Thanks,
> Clément
>



Re: [PATCH] i386: Add new CPU model SapphireRapids

2022-09-14 Thread Igor Mammedov
On Thu, 11 Aug 2022 22:57:51 -0700
"Wang, Lei"  wrote:

> The new CPU model mostly inherits features from Icelake-Server, while
> adding new features:
>  - AMX (Advance Matrix eXtensions)
>  - Bus Lock Debug Exception
> and new instructions:
>  - AVX VNNI (Vector Neural Network Instruction):
> - VPDPBUS: Multiply and Add Unsigned and Signed Bytes
> - VPDPBUSDS: Multiply and Add Unsigned and Signed Bytes with Saturation
> - VPDPWSSD: Multiply and Add Signed Word Integers
> - VPDPWSSDS: Multiply and Add Signed Integers with Saturation
>  - FP16: Replicates existing AVX512 computational SP (FP32) instructions
>using FP16 instead of FP32 for ~2X performance gain
>  - SERIALIZE: Provide software with a simple way to force the processor to
>complete all modifications, faster, allowed in all privilege levels and
>not causing an unconditional VM exit
>  - TSX Suspend Load Address Tracking: Allows programmers to choose which
>memory accesses do not need to be tracked in the TSX read set
>  - AVX512_BF16: Vector Neural Network Instructions supporting BFLOAT16
>inputs and conversion instructions from IEEE single precision
> 
> Features may be added in future versions:
>  - CET (virtualization support hasn't been merged)
> Instructions may be added in future versions:
>  - fast zero-length MOVSB (KVM doesn't support yet)
>  - fast short STOSB (KVM doesn't support yet)
>  - fast short CMPSB, SCASB (KVM doesn't support yet)
> 
> Signed-off-by: Wang, Lei 
> Reviewed-by: Robert Hoo 

looks fine to me,

Acked-by: Igor Mammedov 

> ---
>  target/i386/cpu.c | 128 ++
>  target/i386/cpu.h |   4 ++
>  2 files changed, 132 insertions(+)
> 
> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> index 1db1278a59..abb43853d4 100644
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c
> @@ -3467,6 +3467,134 @@ static const X86CPUDefinition builtin_x86_defs[] = {
>  { /* end of list */ }
>  }
>  },
> +{
> +.name = "SapphireRapids",
> +.level = 0x20,
> +.vendor = CPUID_VENDOR_INTEL,
> +.family = 6,
> +.model = 143,
> +.stepping = 4,
> +/*
> + * please keep the ascending order so that we can have a clear view 
> of
> + * bit position of each feature.
> + */
> +.features[FEAT_1_EDX] =
> +CPUID_FP87 | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC |
> +CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC |
> +CPUID_SEP | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV |
> +CPUID_PAT | CPUID_PSE36 | CPUID_CLFLUSH | CPUID_MMX | CPUID_FXSR 
> |
> +CPUID_SSE | CPUID_SSE2,
> +.features[FEAT_1_ECX] =
> +CPUID_EXT_SSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSSE3 |
> +CPUID_EXT_FMA | CPUID_EXT_CX16 | CPUID_EXT_PCID | 
> CPUID_EXT_SSE41 |
> +CPUID_EXT_SSE42 | CPUID_EXT_X2APIC | CPUID_EXT_MOVBE |
> +CPUID_EXT_POPCNT | CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_AES |
> +CPUID_EXT_XSAVE | CPUID_EXT_AVX | CPUID_EXT_F16C | 
> CPUID_EXT_RDRAND,
> +.features[FEAT_8000_0001_EDX] =
> +CPUID_EXT2_SYSCALL | CPUID_EXT2_NX | CPUID_EXT2_PDPE1GB |
> +CPUID_EXT2_RDTSCP | CPUID_EXT2_LM,
> +.features[FEAT_8000_0001_ECX] =
> +CPUID_EXT3_LAHF_LM | CPUID_EXT3_ABM | CPUID_EXT3_3DNOWPREFETCH,
> +.features[FEAT_8000_0008_EBX] =
> +CPUID_8000_0008_EBX_WBNOINVD,
> +.features[FEAT_7_0_EBX] =
> +CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_HLE |
> +CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 |
> +CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID | CPUID_7_0_EBX_RTM |
> +CPUID_7_0_EBX_AVX512F | CPUID_7_0_EBX_AVX512DQ |
> +CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX | CPUID_7_0_EBX_SMAP |
> +CPUID_7_0_EBX_AVX512IFMA | CPUID_7_0_EBX_CLFLUSHOPT |
> +CPUID_7_0_EBX_CLWB | CPUID_7_0_EBX_AVX512CD | 
> CPUID_7_0_EBX_SHA_NI |
> +CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512VL,
> +.features[FEAT_7_0_ECX] =
> +CPUID_7_0_ECX_AVX512_VBMI | CPUID_7_0_ECX_UMIP | 
> CPUID_7_0_ECX_PKU |
> +CPUID_7_0_ECX_AVX512_VBMI2 | CPUID_7_0_ECX_GFNI |
> +CPUID_7_0_ECX_VAES | CPUID_7_0_ECX_VPCLMULQDQ |
> +CPUID_7_0_ECX_AVX512VNNI | CPUID_7_0_ECX_AVX512BITALG |
> +CPUID_7_0_ECX_AVX512_VPOPCNTDQ | CPUID_7_0_ECX_LA57 |
> +CPUID_7_0_ECX_RDPID | CPUID_7_0_ECX_BUS_LOCK_DETECT,
> +.features[FEAT_7_0_EDX] =
> +CPUID_7_0_EDX_FSRM | CPUID_7_0_EDX_SERIALIZE |
> +CPUID_7_0_EDX_TSX_LDTRK | CPUID_7_0_EDX_AMX_BF16 |
> +CPUID_7_0_EDX_AVX512_FP16 | CPUID_7_0_EDX_AMX_TILE |
> +CPUID_7_0_EDX_AMX_INT8 | CPUID_7_0_EDX_SPEC_CTRL |
> +CPUID_7_0_EDX_ARCH_CAPABILITIES | CPUID

Re: [PATCH 2/3] vdpa: load vlan configuration at NIC startup

2022-09-14 Thread Si-Wei Liu




On 9/14/2022 3:20 AM, Jason Wang wrote:

On Fri, Sep 9, 2022 at 4:02 PM Eugenio Perez Martin  wrote:

On Fri, Sep 9, 2022 at 8:40 AM Jason Wang  wrote:

On Fri, Sep 9, 2022 at 2:38 PM Jason Wang  wrote:

On Wed, Sep 7, 2022 at 12:36 AM Eugenio Pérez  wrote:

To have enabled vlans at device startup may happen in the destination of
a live migration, so this configuration must be restored.

At this moment the code is not accessible, since SVQ refuses to start if
vlan feature is exposed by the device.

Signed-off-by: Eugenio Pérez 
---
  net/vhost-vdpa.c | 46 --
  1 file changed, 44 insertions(+), 2 deletions(-)

diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index 4bc3fd01a8..ecbfd08eb9 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -100,6 +100,8 @@ static const uint64_t vdpa_svq_device_features =
  BIT_ULL(VIRTIO_NET_F_RSC_EXT) |
  BIT_ULL(VIRTIO_NET_F_STANDBY);

+#define MAX_VLAN(1 << 12)   /* Per 802.1Q definition */
+
  VHostNetState *vhost_vdpa_get_vhost_net(NetClientState *nc)
  {
  VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
@@ -423,6 +425,47 @@ static int vhost_vdpa_net_load_mq(VhostVDPAState *s,
  return *s->status != VIRTIO_NET_OK;
  }

+static int vhost_vdpa_net_load_single_vlan(VhostVDPAState *s,
+   const VirtIONet *n,
+   uint16_t vid)
+{
+ssize_t dev_written = vhost_vdpa_net_load_cmd(s, VIRTIO_NET_CTRL_VLAN,
+  VIRTIO_NET_CTRL_VLAN_ADD,
+  &vid, sizeof(vid));
+if (unlikely(dev_written < 0)) {
+return dev_written;
+}
+
+if (unlikely(*s->status != VIRTIO_NET_OK)) {
+return -EINVAL;
+}
+
+return 0;
+}
+
+static int vhost_vdpa_net_load_vlan(VhostVDPAState *s,
+const VirtIONet *n)
+{
+uint64_t features = n->parent_obj.guest_features;
+
+if (!(features & BIT_ULL(VIRTIO_NET_F_CTRL_VLAN))) {
+return 0;
+}
+
+for (int i = 0; i < MAX_VLAN >> 5; i++) {
+for (int j = 0; n->vlans[i] && j <= 0x1f; j++) {
+if (n->vlans[i] & (1U << j)) {
+int r = vhost_vdpa_net_load_single_vlan(s, n, (i << 5) + j);

This seems to cause a lot of latency if the driver has a lot of vlans.

I wonder if it's simply to let all vlan traffic go by disabling
CTRL_VLAN feature at vDPA layer.

The guest will not be able to recover that vlan configuration.

Spec said it's best effort and we actually don't do this for
vhost-net/user for years and manage to survive.

I thought there's a border line between best effort and do nothing. ;-)

I think that the reason this could survive is really software 
implementation specific - say if the backend doesn't start with VLAN 
filtering disabled (meaning allow all VLAN traffic to pass) then it 
would become a problem. This won't be a problem for almost PF NICs but 
may be problematic for vDPA e.g. VF backed VDPAs.



Another idea is to extend the spec to allow us to accept a bitmap of
the vlan ids via a single command, then we will be fine.


I'm not sure if adding more ways to configure something is the answer,
but I'd be ok to implement it.

Another idea is to allow the sending of many CVQ commands in parallel.
It shouldn't be very hard to achieve using exposed buffers as ring
buffers, and it will short down the start of the devices with many
features.

In the extreme case, what if guests decide to filter all of the vlans?
It means we need MAX_VLAN commands which may exceeds the size of the
control virtqueue.
Indeed, that's a case where a single flat device state blob would be 
more efficient for hardware drivers to apply than individual control 
command messages do.


-Siwei


Thanks


Thanks!


Thanks


Thanks


+if (unlikely(r != 0)) {
+return r;
+}
+}
+}
+}
+
+return 0;
+}
+
  static int vhost_vdpa_net_load(NetClientState *nc)
  {
  VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
@@ -445,8 +488,7 @@ static int vhost_vdpa_net_load(NetClientState *nc)
  if (unlikely(r)) {
  return r;
  }
-
-return 0;
+return vhost_vdpa_net_load_vlan(s, n);
  }

  static NetClientInfo net_vhost_vdpa_cvq_info = {
--
2.31.1






[PATCH v4 05/21] ppc440_bamboo: Add missing 4 MiB valid memory size

2022-09-14 Thread BALATON Zoltan
Signed-off-by: BALATON Zoltan 
Reviewed-by: Cédric Le Goater 
---
 hw/ppc/ppc440_bamboo.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c
index 2aac8a3fe9..2bd5e41140 100644
--- a/hw/ppc/ppc440_bamboo.c
+++ b/hw/ppc/ppc440_bamboo.c
@@ -51,7 +51,7 @@
 #define PPC440EP_SDRAM_NR_BANKS 4
 
 static const ram_addr_t ppc440ep_sdram_bank_sizes[] = {
-256 * MiB, 128 * MiB, 64 * MiB, 32 * MiB, 16 * MiB, 8 * MiB, 0
+256 * MiB, 128 * MiB, 64 * MiB, 32 * MiB, 16 * MiB, 8 * MiB, 4 * MiB, 0
 };
 
 static hwaddr entry;
-- 
2.30.4




[PATCH v4 01/21] ppc440_bamboo: Remove unnecessary memsets

2022-09-14 Thread BALATON Zoltan
In ppc4xx_sdram_init() the struct is allocated with g_new0() so no
need to clear its elements. In the bamboo machine init memset can be
replaced with array initialiser which is shorter.

Signed-off-by: BALATON Zoltan 
---
 hw/ppc/ppc440_bamboo.c | 6 ++
 hw/ppc/ppc4xx_devs.c   | 8 ++--
 2 files changed, 4 insertions(+), 10 deletions(-)

diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c
index ea945a1c99..5ec82fa8c2 100644
--- a/hw/ppc/ppc440_bamboo.c
+++ b/hw/ppc/ppc440_bamboo.c
@@ -169,8 +169,8 @@ static void bamboo_init(MachineState *machine)
 MemoryRegion *address_space_mem = get_system_memory();
 MemoryRegion *isa = g_new(MemoryRegion, 1);
 MemoryRegion *ram_memories = g_new(MemoryRegion, PPC440EP_SDRAM_NR_BANKS);
-hwaddr ram_bases[PPC440EP_SDRAM_NR_BANKS];
-hwaddr ram_sizes[PPC440EP_SDRAM_NR_BANKS];
+hwaddr ram_bases[PPC440EP_SDRAM_NR_BANKS] = {0};
+hwaddr ram_sizes[PPC440EP_SDRAM_NR_BANKS] = {0};
 PCIBus *pcibus;
 PowerPCCPU *cpu;
 CPUPPCState *env;
@@ -205,8 +205,6 @@ static void bamboo_init(MachineState *machine)
qdev_get_gpio_in(DEVICE(cpu), PPC40x_INPUT_CINT));
 
 /* SDRAM controller */
-memset(ram_bases, 0, sizeof(ram_bases));
-memset(ram_sizes, 0, sizeof(ram_sizes));
 ppc4xx_sdram_banks(machine->ram, PPC440EP_SDRAM_NR_BANKS, ram_memories,
ram_bases, ram_sizes, ppc440ep_sdram_bank_sizes);
 /* XXX 440EP's ECC interrupts are on UIC1, but we've only created UIC0. */
diff --git a/hw/ppc/ppc4xx_devs.c b/hw/ppc/ppc4xx_devs.c
index ce38ae65e6..b4cd10f735 100644
--- a/hw/ppc/ppc4xx_devs.c
+++ b/hw/ppc/ppc4xx_devs.c
@@ -363,12 +363,8 @@ void ppc4xx_sdram_init(CPUPPCState *env, qemu_irq irq, int 
nbanks,
 sdram->irq = irq;
 sdram->nbanks = nbanks;
 sdram->ram_memories = ram_memories;
-memset(sdram->ram_bases, 0, 4 * sizeof(hwaddr));
-memcpy(sdram->ram_bases, ram_bases,
-   nbanks * sizeof(hwaddr));
-memset(sdram->ram_sizes, 0, 4 * sizeof(hwaddr));
-memcpy(sdram->ram_sizes, ram_sizes,
-   nbanks * sizeof(hwaddr));
+memcpy(sdram->ram_bases, ram_bases, nbanks * sizeof(hwaddr));
+memcpy(sdram->ram_sizes, ram_sizes, nbanks * sizeof(hwaddr));
 qemu_register_reset(&sdram_reset, sdram);
 ppc_dcr_register(env, SDRAM0_CFGADDR,
  sdram, &dcr_read_sdram, &dcr_write_sdram);
-- 
2.30.4




[PATCH v4 00/21] ppc4xx_sdram QOMify and clean ups

2022-09-14 Thread BALATON Zoltan
This is the end of the QOMify series started by Cédric. This series
handles the SDRAM controller models to clean them up, QOMify and unify
them and at least partially clean up the mess that has accumulated
around these in the past. This includes the not yet merged patches
from the last series and new ones that change the DDR2 version used by
sam460ex.

v4: address more revies comments
v3: Fix patches that got squashed during rebase
v2: address some review comments and try to avoid compile problem with
gcc 12.2 (untested)

BALATON Zoltan (21):
  ppc440_bamboo: Remove unnecessary memsets
  ppc4xx: Introduce Ppc4xxSdramBank struct
  ppc4xx_sdram: Get rid of the init RAM hack
  ppc4xx: Use Ppc4xxSdramBank in ppc4xx_sdram_banks()
  ppc440_bamboo: Add missing 4 MiB valid memory size
  ppc4xx_sdram: Move size check to ppc4xx_sdram_init()
  ppc4xx_sdram: QOM'ify
  ppc4xx_sdram: Drop extra zeros for readability
  ppc440_sdram: Split off map/unmap of sdram banks for later reuse
  ppc440_sdram: Implement enable bit in the DDR2 SDRAM
  ppc440_sdram: Get rid of the init RAM hack
  ppc440_sdram: Rename local variable for readability
  ppc4xx_sdram: Rename functions to prevent name clashes
  ppc440_sdram: Move RAM size check to ppc440_sdram_init
  ppc440_sdram: QOM'ify
  ppc4xx_sdram: Move ppc4xx DDR and DDR2 SDRAM controller models
together
  ppc4xx_sdram: Use hwaddr for memory bank size
  ppc4xx_sdram: Rename local state variable for brevity
  ppc4xx_sdram: Generalise bank setup
  ppc4xx_sdram: Convert DDR SDRAM controller to new bank handling
  ppc4xx_sdram: Add errp parameter to ppc4xx_sdram_banks()

 hw/ppc/meson.build  |   3 +-
 hw/ppc/ppc405.h |   8 +-
 hw/ppc/ppc405_boards.c  |  22 +-
 hw/ppc/ppc405_uc.c  |  33 +-
 hw/ppc/ppc440.h |   4 -
 hw/ppc/ppc440_bamboo.c  |  29 +-
 hw/ppc/ppc440_uc.c  | 267 +--
 hw/ppc/ppc4xx_devs.c| 413 --
 hw/ppc/ppc4xx_sdram.c   | 737 
 hw/ppc/sam460ex.c   |  48 +--
 hw/ppc/trace-events |   1 +
 include/hw/ppc/ppc4xx.h |  66 +++-
 12 files changed, 861 insertions(+), 770 deletions(-)
 create mode 100644 hw/ppc/ppc4xx_sdram.c

-- 
2.30.4




[PATCH v4 04/21] ppc4xx: Use Ppc4xxSdramBank in ppc4xx_sdram_banks()

2022-09-14 Thread BALATON Zoltan
Change ppc4xx_sdram_banks() to take one Ppc4xxSdramBank array instead
of the separate arrays and adjust ppc4xx_sdram_init() and
ppc440_sdram_init() accordingly as well as machines using these.

Signed-off-by: BALATON Zoltan 
Reviewed-by: Cédric Le Goater 
---
v2: Use pointer for ram_banks in the prototype of the init funcs as
an array of struct seems to confuse gcc 12.2.1 and provoke a warning

 hw/ppc/ppc405.h |  4 +---
 hw/ppc/ppc405_uc.c  | 10 +-
 hw/ppc/ppc440.h |  5 ++---
 hw/ppc/ppc440_bamboo.c  | 15 ++-
 hw/ppc/ppc440_uc.c  |  9 -
 hw/ppc/ppc4xx_devs.c| 21 +
 hw/ppc/sam460ex.c   | 15 +--
 include/hw/ppc/ppc4xx.h |  9 +++--
 8 files changed, 35 insertions(+), 53 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index 756865621b..ca0972b88b 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -167,9 +167,7 @@ struct Ppc405SoCState {
 DeviceState parent_obj;
 
 /* Public */
-MemoryRegion ram_banks[2];
-hwaddr ram_bases[2], ram_sizes[2];
-
+Ppc4xxSdramBank ram_banks[2];
 MemoryRegion *dram_mr;
 hwaddr ram_size;
 
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index 1e02347e57..bcbf35bc14 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -1074,14 +1074,14 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
 
 /* SDRAM controller */
 /* XXX 405EP has no ECC interrupt */
-s->ram_bases[0] = 0;
-s->ram_sizes[0] = s->ram_size;
-memory_region_init_alias(&s->ram_banks[0], OBJECT(s),
+s->ram_banks[0].base = 0;
+s->ram_banks[0].size = s->ram_size;
+memory_region_init_alias(&s->ram_banks[0].ram, OBJECT(s),
  "ppc405.sdram0", s->dram_mr,
- s->ram_bases[0], s->ram_sizes[0]);
+ s->ram_banks[0].base, s->ram_banks[0].size);
 
 ppc4xx_sdram_init(env, qdev_get_gpio_in(DEVICE(&s->uic), 17), 1,
-  s->ram_banks, s->ram_bases, s->ram_sizes);
+  s->ram_banks);
 
 /* External bus controller */
 if (!ppc4xx_dcr_realize(PPC4xx_DCR_DEVICE(&s->ebc), &s->cpu, errp)) {
diff --git a/hw/ppc/ppc440.h b/hw/ppc/ppc440.h
index 7cef936125..e6c905b7d6 100644
--- a/hw/ppc/ppc440.h
+++ b/hw/ppc/ppc440.h
@@ -11,14 +11,13 @@
 #ifndef PPC440_H
 #define PPC440_H
 
-#include "hw/ppc/ppc.h"
+#include "hw/ppc/ppc4xx.h"
 
 void ppc4xx_l2sram_init(CPUPPCState *env);
 void ppc4xx_cpr_init(CPUPPCState *env);
 void ppc4xx_sdr_init(CPUPPCState *env);
 void ppc440_sdram_init(CPUPPCState *env, int nbanks,
-   MemoryRegion *ram_memories,
-   hwaddr *ram_bases, hwaddr *ram_sizes,
+   Ppc4xxSdramBank *ram_banks,
int do_init);
 void ppc4xx_ahb_init(CPUPPCState *env);
 void ppc4xx_dma_init(CPUPPCState *env, int dcr_base);
diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c
index e3412c4fcd..2aac8a3fe9 100644
--- a/hw/ppc/ppc440_bamboo.c
+++ b/hw/ppc/ppc440_bamboo.c
@@ -168,9 +168,8 @@ static void bamboo_init(MachineState *machine)
 unsigned int pci_irq_nrs[4] = { 28, 27, 26, 25 };
 MemoryRegion *address_space_mem = get_system_memory();
 MemoryRegion *isa = g_new(MemoryRegion, 1);
-MemoryRegion *ram_memories = g_new(MemoryRegion, PPC440EP_SDRAM_NR_BANKS);
-hwaddr ram_bases[PPC440EP_SDRAM_NR_BANKS] = {0};
-hwaddr ram_sizes[PPC440EP_SDRAM_NR_BANKS] = {0};
+Ppc4xxSdramBank *ram_banks = g_new0(Ppc4xxSdramBank,
+PPC440EP_SDRAM_NR_BANKS);
 PCIBus *pcibus;
 PowerPCCPU *cpu;
 CPUPPCState *env;
@@ -205,13 +204,11 @@ static void bamboo_init(MachineState *machine)
qdev_get_gpio_in(DEVICE(cpu), PPC40x_INPUT_CINT));
 
 /* SDRAM controller */
-ppc4xx_sdram_banks(machine->ram, PPC440EP_SDRAM_NR_BANKS, ram_memories,
-   ram_bases, ram_sizes, ppc440ep_sdram_bank_sizes);
+ppc4xx_sdram_banks(machine->ram, PPC440EP_SDRAM_NR_BANKS, ram_banks,
+   ppc440ep_sdram_bank_sizes);
 /* XXX 440EP's ECC interrupts are on UIC1, but we've only created UIC0. */
-ppc4xx_sdram_init(env,
-  qdev_get_gpio_in(uicdev, 14),
-  PPC440EP_SDRAM_NR_BANKS, ram_memories,
-  ram_bases, ram_sizes);
+ppc4xx_sdram_init(env, qdev_get_gpio_in(uicdev, 14),
+  PPC440EP_SDRAM_NR_BANKS, ram_banks);
 /* Enable SDRAM memory regions, this should be done by the firmware */
 if (ppc_dcr_write(env->dcr_env, SDRAM0_CFGADDR, 0x20) ||
 ppc_dcr_write(env->dcr_env, SDRAM0_CFGDATA, 0x8000)) {
diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c
index 6ab0ad7985..5db59d1190 100644
--- a/hw/ppc/ppc440_uc.c
+++ b/hw/ppc/ppc440_uc.c
@@ -690,8 +690,7 @@ static void sdram_reset(void *opaque)
 }
 
 void ppc440_sdram_init(CPUPPCState *env, int nbanks,

[PATCH v4 07/21] ppc4xx_sdram: QOM'ify

2022-09-14 Thread BALATON Zoltan
Change the ppc4xx_sdram model to a QOM class derived from the
PPC4xx-dcr-device and name it ppc4xx-sdram-ddr. This is mostly
modelling the DDR SDRAM controller found in the 440EP (used on the
bamboo board) but also backward compatible with the older DDR
controllers on some 405 SoCs so we also use it for those now. This
likely does not cause problems for guests we run as the new features
are just not accessed but to model 405 SoC accurately some features
may have to be disabled or the model split between 440 and older.

Newer SoCs (regardless of their PPC core, e.g. 405EX) may have an
updated DDR2 SDRAM controller implemented by the ppc440_sdram model
(only partially, enough for the 460EX on the sam460ex) that is not yet
QOM'ified in this patch. That is intended to become ppc4xx-sdram-ddr2
when QOM'ified later.

Signed-off-by: BALATON Zoltan 
Reviewed-by: Cédric Le Goater 
---
 hw/ppc/ppc405.h |  3 +-
 hw/ppc/ppc405_uc.c  | 22 +
 hw/ppc/ppc440_bamboo.c  | 10 +++--
 hw/ppc/ppc4xx_devs.c| 99 ++---
 include/hw/ppc/ppc4xx.h | 27 +--
 5 files changed, 98 insertions(+), 63 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index ad54dff542..9a4312691e 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -167,8 +167,6 @@ struct Ppc405SoCState {
 DeviceState parent_obj;
 
 /* Public */
-MemoryRegion *dram_mr;
-
 PowerPCCPU cpu;
 PPCUIC uic;
 Ppc405CpcState cpc;
@@ -182,6 +180,7 @@ struct Ppc405SoCState {
 Ppc405PobState pob;
 Ppc4xxPlbState plb;
 Ppc4xxMalState mal;
+Ppc4xxSdramDdrState sdram;
 };
 
 #endif /* PPC405_H */
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index e1c7188e61..c973cfb04e 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -1016,6 +1016,9 @@ static void ppc405_soc_instance_init(Object *obj)
 object_initialize_child(obj, "plb", &s->plb, TYPE_PPC4xx_PLB);
 
 object_initialize_child(obj, "mal", &s->mal, TYPE_PPC4xx_MAL);
+
+object_initialize_child(obj, "sdram", &s->sdram, TYPE_PPC4xx_SDRAM_DDR);
+object_property_add_alias(obj, "dram", OBJECT(&s->sdram), "dram");
 }
 
 static void ppc405_reset(void *opaque)
@@ -1073,9 +1076,17 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
qdev_get_gpio_in(DEVICE(&s->cpu), PPC40x_INPUT_CINT));
 
 /* SDRAM controller */
+/*
+ * We use the 440 DDR SDRAM controller which has more regs and features
+ * but it's compatible enough for now
+ */
+object_property_set_int(OBJECT(&s->sdram), "nbanks", 2, &error_abort);
+if (!ppc4xx_dcr_realize(PPC4xx_DCR_DEVICE(&s->sdram), &s->cpu, errp)) {
+return;
+}
 /* XXX 405EP has no ECC interrupt */
-ppc4xx_sdram_init(env, qdev_get_gpio_in(DEVICE(&s->uic), 17), 1,
-  s->dram_mr);
+sysbus_connect_irq(SYS_BUS_DEVICE(&s->sdram), 0,
+   qdev_get_gpio_in(DEVICE(&s->uic), 17));
 
 /* External bus controller */
 if (!ppc4xx_dcr_realize(PPC4xx_DCR_DEVICE(&s->ebc), &s->cpu, errp)) {
@@ -1150,12 +1161,6 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
 /* Uses UIC IRQs 9, 15, 17 */
 }
 
-static Property ppc405_soc_properties[] = {
-DEFINE_PROP_LINK("dram", Ppc405SoCState, dram_mr, TYPE_MEMORY_REGION,
- MemoryRegion *),
-DEFINE_PROP_END_OF_LIST(),
-};
-
 static void ppc405_soc_class_init(ObjectClass *oc, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(oc);
@@ -1163,7 +1168,6 @@ static void ppc405_soc_class_init(ObjectClass *oc, void 
*data)
 dc->realize = ppc405_soc_realize;
 /* Reason: only works as part of a ppc405 board/machine */
 dc->user_creatable = false;
-device_class_set_props(dc, ppc405_soc_properties);
 }
 
 static const TypeInfo ppc405_types[] = {
diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c
index 9b456f1819..6052d3a2e0 100644
--- a/hw/ppc/ppc440_bamboo.c
+++ b/hw/ppc/ppc440_bamboo.c
@@ -48,8 +48,6 @@
 #define PPC440EP_PCI_IO 0xe800
 #define PPC440EP_PCI_IOLEN  0x0001
 
-#define PPC440EP_SDRAM_NR_BANKS 4
-
 static hwaddr entry;
 
 static int bamboo_load_device_tree(hwaddr addr,
@@ -198,9 +196,13 @@ static void bamboo_init(MachineState *machine)
qdev_get_gpio_in(DEVICE(cpu), PPC40x_INPUT_CINT));
 
 /* SDRAM controller */
+dev = qdev_new(TYPE_PPC4xx_SDRAM_DDR);
+object_property_set_link(OBJECT(dev), "dram", OBJECT(machine->ram),
+ &error_abort);
+ppc4xx_dcr_realize(PPC4xx_DCR_DEVICE(dev), cpu, &error_fatal);
+object_unref(OBJECT(dev));
 /* XXX 440EP's ECC interrupts are on UIC1, but we've only created UIC0. */
-ppc4xx_sdram_init(env, qdev_get_gpio_in(uicdev, 14),
-  PPC440EP_SDRAM_NR_BANKS, machine->ram);
+sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, qdev_get_gpio_in(uicdev, 14));
 /* Enable SDRAM memory regions, this should be done by th

[PATCH v4 03/21] ppc4xx_sdram: Get rid of the init RAM hack

2022-09-14 Thread BALATON Zoltan
The do_init parameter of ppc4xx_sdram_init() is used to map memory
regions that is normally done by the firmware by programming the SDRAM
controller. This is needed when booting a kernel directly from -kernel
without a firmware. Do this from board code accessing normal SDRAM
controller registers the same way as firmware would do, so we can get
rid of this hack.

Signed-off-by: BALATON Zoltan 
---
v2: Fix ref405ep boot with -kernel and U-Boot

 hw/ppc/ppc405.h |  1 -
 hw/ppc/ppc405_boards.c  | 12 ++--
 hw/ppc/ppc405_uc.c  |  4 +---
 hw/ppc/ppc440_bamboo.c  |  8 +++-
 hw/ppc/ppc440_uc.c  |  2 --
 hw/ppc/ppc4xx_devs.c| 11 +--
 include/hw/ppc/ppc4xx.h |  8 ++--
 7 files changed, 25 insertions(+), 21 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index 1e558c7831..756865621b 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -169,7 +169,6 @@ struct Ppc405SoCState {
 /* Public */
 MemoryRegion ram_banks[2];
 hwaddr ram_bases[2], ram_sizes[2];
-bool do_dram_init;
 
 MemoryRegion *dram_mr;
 hwaddr ram_size;
diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
index 083f12b23e..bf02a71c6d 100644
--- a/hw/ppc/ppc405_boards.c
+++ b/hw/ppc/ppc405_boards.c
@@ -274,6 +274,7 @@ static void ppc405_init(MachineState *machine)
 MachineClass *mc = MACHINE_GET_CLASS(machine);
 const char *kernel_filename = machine->kernel_filename;
 MemoryRegion *sysmem = get_system_memory();
+CPUPPCState *env;
 
 if (machine->ram_size != mc->default_ram_size) {
 char *sz = size_to_str(mc->default_ram_size);
@@ -288,12 +289,19 @@ static void ppc405_init(MachineState *machine)
  machine->ram_size, &error_fatal);
 object_property_set_link(OBJECT(&ppc405->soc), "dram",
  OBJECT(machine->ram), &error_abort);
-object_property_set_bool(OBJECT(&ppc405->soc), "dram-init",
- kernel_filename != NULL, &error_abort);
 object_property_set_uint(OBJECT(&ppc405->soc), "sys-clk", ,
  &error_abort);
 qdev_realize(DEVICE(&ppc405->soc), NULL, &error_fatal);
 
+/* Enable SDRAM memory regions */
+/* FIXME This shouldn't be needed with firmware but we lack SPD data */
+env = &ppc405->soc.cpu.env;
+if (ppc_dcr_write(env->dcr_env, SDRAM0_CFGADDR, 0x20) ||
+ppc_dcr_write(env->dcr_env, SDRAM0_CFGDATA, 0x8000)) {
+error_report("Could not enable memory regions");
+exit(1);
+}
+
 /* allocate and load BIOS */
 if (machine->firmware) {
 MemoryRegion *bios = g_new(MemoryRegion, 1);
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index 2ca42fdef6..1e02347e57 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -1081,8 +1081,7 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
  s->ram_bases[0], s->ram_sizes[0]);
 
 ppc4xx_sdram_init(env, qdev_get_gpio_in(DEVICE(&s->uic), 17), 1,
-  s->ram_banks, s->ram_bases, s->ram_sizes,
-  s->do_dram_init);
+  s->ram_banks, s->ram_bases, s->ram_sizes);
 
 /* External bus controller */
 if (!ppc4xx_dcr_realize(PPC4xx_DCR_DEVICE(&s->ebc), &s->cpu, errp)) {
@@ -1160,7 +1159,6 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
 static Property ppc405_soc_properties[] = {
 DEFINE_PROP_LINK("dram", Ppc405SoCState, dram_mr, TYPE_MEMORY_REGION,
  MemoryRegion *),
-DEFINE_PROP_BOOL("dram-init", Ppc405SoCState, do_dram_init, 0),
 DEFINE_PROP_UINT64("ram-size", Ppc405SoCState, ram_size, 0),
 DEFINE_PROP_END_OF_LIST(),
 };
diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c
index 5ec82fa8c2..e3412c4fcd 100644
--- a/hw/ppc/ppc440_bamboo.c
+++ b/hw/ppc/ppc440_bamboo.c
@@ -211,7 +211,13 @@ static void bamboo_init(MachineState *machine)
 ppc4xx_sdram_init(env,
   qdev_get_gpio_in(uicdev, 14),
   PPC440EP_SDRAM_NR_BANKS, ram_memories,
-  ram_bases, ram_sizes, 1);
+  ram_bases, ram_sizes);
+/* Enable SDRAM memory regions, this should be done by the firmware */
+if (ppc_dcr_write(env->dcr_env, SDRAM0_CFGADDR, 0x20) ||
+ppc_dcr_write(env->dcr_env, SDRAM0_CFGDATA, 0x8000)) {
+error_report("couldn't enable memory regions");
+exit(1);
+}
 
 /* PCI */
 dev = sysbus_create_varargs(TYPE_PPC4xx_PCI_HOST_BRIDGE,
diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c
index db4e29..6ab0ad7985 100644
--- a/hw/ppc/ppc440_uc.c
+++ b/hw/ppc/ppc440_uc.c
@@ -489,8 +489,6 @@ typedef struct ppc440_sdram_t {
 } ppc440_sdram_t;
 
 enum {
-SDRAM0_CFGADDR = 0x10,
-SDRAM0_CFGDATA,
 SDRAM_R0BAS = 0x40,
 SDRAM_R1BAS,
 SDRAM_R2BAS,
diff --git a/hw/ppc/ppc4xx_devs.c b/hw/ppc/ppc4xx_devs.c
index 1226ec4aa9..936d6f77fe 100644
--- a/hw/p

[PATCH v4 02/21] ppc4xx: Introduce Ppc4xxSdramBank struct

2022-09-14 Thread BALATON Zoltan
Instead of storing sdram bank parameters in unrelated arrays put them
in a struct so it's clear they belong to the same bank and simplify
the state struct using this bank type.

Signed-off-by: BALATON Zoltan 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/ppc/ppc440_uc.c  | 49 +-
 hw/ppc/ppc4xx_devs.c| 59 -
 include/hw/ppc/ppc4xx.h |  8 ++
 3 files changed, 61 insertions(+), 55 deletions(-)

diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c
index 53e981ddf4..db4e29 100644
--- a/hw/ppc/ppc440_uc.c
+++ b/hw/ppc/ppc440_uc.c
@@ -16,7 +16,7 @@
 #include "qemu/module.h"
 #include "hw/irq.h"
 #include "exec/memory.h"
-#include "hw/ppc/ppc.h"
+#include "hw/ppc/ppc4xx.h"
 #include "hw/qdev-properties.h"
 #include "hw/pci/pci.h"
 #include "sysemu/block-backend.h"
@@ -485,11 +485,7 @@ void ppc4xx_sdr_init(CPUPPCState *env)
 typedef struct ppc440_sdram_t {
 uint32_t addr;
 int nbanks;
-MemoryRegion containers[4]; /* used for clipping */
-MemoryRegion *ram_memories;
-hwaddr ram_bases[4];
-hwaddr ram_sizes[4];
-uint32_t bcr[4];
+Ppc4xxSdramBank bank[4];
 } ppc440_sdram_t;
 
 enum {
@@ -570,23 +566,23 @@ static uint64_t sdram_size(uint32_t bcr)
 static void sdram_set_bcr(ppc440_sdram_t *sdram, int i,
   uint32_t bcr, int enabled)
 {
-if (sdram->bcr[i] & 1) {
+if (sdram->bank[i].bcr & 1) {
 /* First unmap RAM if enabled */
 memory_region_del_subregion(get_system_memory(),
-&sdram->containers[i]);
-memory_region_del_subregion(&sdram->containers[i],
-&sdram->ram_memories[i]);
-object_unparent(OBJECT(&sdram->containers[i]));
+&sdram->bank[i].container);
+memory_region_del_subregion(&sdram->bank[i].container,
+&sdram->bank[i].ram);
+object_unparent(OBJECT(&sdram->bank[i].container));
 }
-sdram->bcr[i] = bcr & 0xffe0ffc1;
+sdram->bank[i].bcr = bcr & 0xffe0ffc1;
 if (enabled && (bcr & 1)) {
-memory_region_init(&sdram->containers[i], NULL, "sdram-containers",
+memory_region_init(&sdram->bank[i].container, NULL, "sdram-container",
sdram_size(bcr));
-memory_region_add_subregion(&sdram->containers[i], 0,
-&sdram->ram_memories[i]);
+memory_region_add_subregion(&sdram->bank[i].container, 0,
+&sdram->bank[i].ram);
 memory_region_add_subregion(get_system_memory(),
 sdram_base(bcr),
-&sdram->containers[i]);
+&sdram->bank[i].container);
 }
 }
 
@@ -595,9 +591,9 @@ static void sdram_map_bcr(ppc440_sdram_t *sdram)
 int i;
 
 for (i = 0; i < sdram->nbanks; i++) {
-if (sdram->ram_sizes[i] != 0) {
-sdram_set_bcr(sdram, i, sdram_bcr(sdram->ram_bases[i],
-  sdram->ram_sizes[i]), 1);
+if (sdram->bank[i].size != 0) {
+sdram_set_bcr(sdram, i, sdram_bcr(sdram->bank[i].base,
+  sdram->bank[i].size), 1);
 } else {
 sdram_set_bcr(sdram, i, 0, 0);
 }
@@ -614,9 +610,9 @@ static uint32_t dcr_read_sdram(void *opaque, int dcrn)
 case SDRAM_R1BAS:
 case SDRAM_R2BAS:
 case SDRAM_R3BAS:
-if (sdram->ram_sizes[dcrn - SDRAM_R0BAS]) {
-ret = sdram_bcr(sdram->ram_bases[dcrn - SDRAM_R0BAS],
-sdram->ram_sizes[dcrn - SDRAM_R0BAS]);
+if (sdram->bank[dcrn - SDRAM_R0BAS].size) {
+ret = sdram_bcr(sdram->bank[dcrn - SDRAM_R0BAS].base,
+sdram->bank[dcrn - SDRAM_R0BAS].size);
 }
 break;
 case SDRAM_CONF1HB:
@@ -701,12 +697,15 @@ void ppc440_sdram_init(CPUPPCState *env, int nbanks,
int do_init)
 {
 ppc440_sdram_t *sdram;
+int i;
 
 sdram = g_malloc0(sizeof(*sdram));
 sdram->nbanks = nbanks;
-sdram->ram_memories = ram_memories;
-memcpy(sdram->ram_bases, ram_bases, nbanks * sizeof(hwaddr));
-memcpy(sdram->ram_sizes, ram_sizes, nbanks * sizeof(hwaddr));
+for (i = 0; i < nbanks; i++) {
+sdram->bank[i].ram = ram_memories[i];
+sdram->bank[i].base = ram_bases[i];
+sdram->bank[i].size = ram_sizes[i];
+}
 qemu_register_reset(&sdram_reset, sdram);
 ppc_dcr_register(env, SDRAM0_CFGADDR,
  sdram, &dcr_read_sdram, &dcr_write_sdram);
diff --git a/hw/ppc/ppc4xx_devs.c b/hw/ppc/ppc4xx_devs.c
index b4cd10f735..1226ec4aa9 100644
--- a/hw/ppc/ppc4xx_devs.c
+++ b/hw/ppc/ppc4xx_devs.c
@@ -42,10 +42,7 @@ typedef struct ppc4xx_sdram_t ppc4xx_sdram_t;
 struct ppc4xx_sdram_t {
 uint32_t addr;
 

[PATCH v4 08/21] ppc4xx_sdram: Drop extra zeros for readability

2022-09-14 Thread BALATON Zoltan
Constants that are written zero padded for no good reason are hard to
read, it's easier to see what is meant if it's just 0 or 1 instead.

Signed-off-by: BALATON Zoltan 
---
 hw/ppc/ppc4xx_devs.c | 40 
 1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/hw/ppc/ppc4xx_devs.c b/hw/ppc/ppc4xx_devs.c
index 375834a52b..bfe7b2d3a6 100644
--- a/hw/ppc/ppc4xx_devs.c
+++ b/hw/ppc/ppc4xx_devs.c
@@ -49,31 +49,31 @@ static uint32_t sdram_ddr_bcr(hwaddr ram_base, hwaddr 
ram_size)
 
 switch (ram_size) {
 case 4 * MiB:
-bcr = 0x;
+bcr = 0;
 break;
 case 8 * MiB:
-bcr = 0x0002;
+bcr = 0x2;
 break;
 case 16 * MiB:
-bcr = 0x0004;
+bcr = 0x4;
 break;
 case 32 * MiB:
-bcr = 0x0006;
+bcr = 0x6;
 break;
 case 64 * MiB:
-bcr = 0x0008;
+bcr = 0x8;
 break;
 case 128 * MiB:
-bcr = 0x000A;
+bcr = 0xA;
 break;
 case 256 * MiB:
-bcr = 0x000C;
+bcr = 0xC;
 break;
 default:
 qemu_log_mask(LOG_GUEST_ERROR,
   "%s: invalid RAM size 0x%" HWADDR_PRIx "\n", __func__,
   ram_size);
-return 0x;
+return 0;
 }
 bcr |= ram_base & 0xFF80;
 bcr |= 1;
@@ -104,7 +104,7 @@ static target_ulong sdram_size(uint32_t bcr)
 static void sdram_set_bcr(Ppc4xxSdramDdrState *sdram, int i,
   uint32_t bcr, int enabled)
 {
-if (sdram->bank[i].bcr & 0x0001) {
+if (sdram->bank[i].bcr & 1) {
 /* Unmap RAM */
 trace_ppc4xx_sdram_unmap(sdram_base(sdram->bank[i].bcr),
  sdram_size(sdram->bank[i].bcr));
@@ -115,7 +115,7 @@ static void sdram_set_bcr(Ppc4xxSdramDdrState *sdram, int i,
 object_unparent(OBJECT(&sdram->bank[i].container));
 }
 sdram->bank[i].bcr = bcr & 0xFFDEE001;
-if (enabled && (bcr & 0x0001)) {
+if (enabled && (bcr & 1)) {
 trace_ppc4xx_sdram_map(sdram_base(bcr), sdram_size(bcr));
 memory_region_init(&sdram->bank[i].container, NULL, "sdram-container",
sdram_size(bcr));
@@ -136,7 +136,7 @@ static void sdram_map_bcr(Ppc4xxSdramDdrState *sdram)
 sdram_set_bcr(sdram, i, sdram_ddr_bcr(sdram->bank[i].base,
   sdram->bank[i].size), 1);
 } else {
-sdram_set_bcr(sdram, i, 0x, 0);
+sdram_set_bcr(sdram, i, 0, 0);
 }
 }
 }
@@ -213,7 +213,7 @@ static uint32_t sdram_ddr_dcr_read(void *opaque, int dcrn)
 break;
 default:
 /* Avoid gcc warning */
-ret = 0x;
+ret = 0;
 break;
 }
 
@@ -306,18 +306,18 @@ static void ppc4xx_sdram_ddr_reset(DeviceState *dev)
 {
 Ppc4xxSdramDdrState *sdram = PPC4xx_SDRAM_DDR(dev);
 
-sdram->addr = 0x;
-sdram->bear = 0x;
-sdram->besr0 = 0x; /* No error */
-sdram->besr1 = 0x; /* No error */
-sdram->cfg = 0x;
-sdram->ecccfg = 0x; /* No ECC */
-sdram->eccesr = 0x; /* No error */
+sdram->addr = 0;
+sdram->bear = 0;
+sdram->besr0 = 0; /* No error */
+sdram->besr1 = 0; /* No error */
+sdram->cfg = 0;
+sdram->ecccfg = 0; /* No ECC */
+sdram->eccesr = 0; /* No error */
 sdram->pmit = 0x07C0;
 sdram->rtr = 0x05F0;
 sdram->tr = 0x00854009;
 /* We pre-initialize RAM banks */
-sdram->status = 0x;
+sdram->status = 0;
 sdram->cfg = 0x0080;
 }
 
-- 
2.30.4




[PATCH v4 06/21] ppc4xx_sdram: Move size check to ppc4xx_sdram_init()

2022-09-14 Thread BALATON Zoltan
Instead of checking if memory size is valid in board code move this
check to ppc4xx_sdram_init() as this is a restriction imposed by the
SDRAM controller.

Signed-off-by: BALATON Zoltan 
---
 hw/ppc/ppc405.h |  2 --
 hw/ppc/ppc405_boards.c  | 10 --
 hw/ppc/ppc405_uc.c  | 11 ++-
 hw/ppc/ppc440_bamboo.c  | 10 +-
 hw/ppc/ppc4xx_devs.c| 14 ++
 include/hw/ppc/ppc4xx.h |  2 +-
 6 files changed, 10 insertions(+), 39 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index ca0972b88b..ad54dff542 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -167,9 +167,7 @@ struct Ppc405SoCState {
 DeviceState parent_obj;
 
 /* Public */
-Ppc4xxSdramBank ram_banks[2];
 MemoryRegion *dram_mr;
-hwaddr ram_size;
 
 PowerPCCPU cpu;
 PPCUIC uic;
diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
index bf02a71c6d..cdd4e0cb4c 100644
--- a/hw/ppc/ppc405_boards.c
+++ b/hw/ppc/ppc405_boards.c
@@ -271,22 +271,12 @@ static void boot_from_kernel(MachineState *machine, 
PowerPCCPU *cpu)
 static void ppc405_init(MachineState *machine)
 {
 Ppc405MachineState *ppc405 = PPC405_MACHINE(machine);
-MachineClass *mc = MACHINE_GET_CLASS(machine);
 const char *kernel_filename = machine->kernel_filename;
 MemoryRegion *sysmem = get_system_memory();
 CPUPPCState *env;
 
-if (machine->ram_size != mc->default_ram_size) {
-char *sz = size_to_str(mc->default_ram_size);
-error_report("Invalid RAM size, should be %s", sz);
-g_free(sz);
-exit(EXIT_FAILURE);
-}
-
 object_initialize_child(OBJECT(machine), "soc", &ppc405->soc,
 TYPE_PPC405_SOC);
-object_property_set_uint(OBJECT(&ppc405->soc), "ram-size",
- machine->ram_size, &error_fatal);
 object_property_set_link(OBJECT(&ppc405->soc), "dram",
  OBJECT(machine->ram), &error_abort);
 object_property_set_uint(OBJECT(&ppc405->soc), "sys-clk", ,
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index bcbf35bc14..e1c7188e61 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -1073,15 +1073,9 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
qdev_get_gpio_in(DEVICE(&s->cpu), PPC40x_INPUT_CINT));
 
 /* SDRAM controller */
-/* XXX 405EP has no ECC interrupt */
-s->ram_banks[0].base = 0;
-s->ram_banks[0].size = s->ram_size;
-memory_region_init_alias(&s->ram_banks[0].ram, OBJECT(s),
- "ppc405.sdram0", s->dram_mr,
- s->ram_banks[0].base, s->ram_banks[0].size);
-
+/* XXX 405EP has no ECC interrupt */
 ppc4xx_sdram_init(env, qdev_get_gpio_in(DEVICE(&s->uic), 17), 1,
-  s->ram_banks);
+  s->dram_mr);
 
 /* External bus controller */
 if (!ppc4xx_dcr_realize(PPC4xx_DCR_DEVICE(&s->ebc), &s->cpu, errp)) {
@@ -1159,7 +1153,6 @@ static void ppc405_soc_realize(DeviceState *dev, Error 
**errp)
 static Property ppc405_soc_properties[] = {
 DEFINE_PROP_LINK("dram", Ppc405SoCState, dram_mr, TYPE_MEMORY_REGION,
  MemoryRegion *),
-DEFINE_PROP_UINT64("ram-size", Ppc405SoCState, ram_size, 0),
 DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c
index 2bd5e41140..9b456f1819 100644
--- a/hw/ppc/ppc440_bamboo.c
+++ b/hw/ppc/ppc440_bamboo.c
@@ -50,10 +50,6 @@
 
 #define PPC440EP_SDRAM_NR_BANKS 4
 
-static const ram_addr_t ppc440ep_sdram_bank_sizes[] = {
-256 * MiB, 128 * MiB, 64 * MiB, 32 * MiB, 16 * MiB, 8 * MiB, 4 * MiB, 0
-};
-
 static hwaddr entry;
 
 static int bamboo_load_device_tree(hwaddr addr,
@@ -168,8 +164,6 @@ static void bamboo_init(MachineState *machine)
 unsigned int pci_irq_nrs[4] = { 28, 27, 26, 25 };
 MemoryRegion *address_space_mem = get_system_memory();
 MemoryRegion *isa = g_new(MemoryRegion, 1);
-Ppc4xxSdramBank *ram_banks = g_new0(Ppc4xxSdramBank,
-PPC440EP_SDRAM_NR_BANKS);
 PCIBus *pcibus;
 PowerPCCPU *cpu;
 CPUPPCState *env;
@@ -204,11 +198,9 @@ static void bamboo_init(MachineState *machine)
qdev_get_gpio_in(DEVICE(cpu), PPC40x_INPUT_CINT));
 
 /* SDRAM controller */
-ppc4xx_sdram_banks(machine->ram, PPC440EP_SDRAM_NR_BANKS, ram_banks,
-   ppc440ep_sdram_bank_sizes);
 /* XXX 440EP's ECC interrupts are on UIC1, but we've only created UIC0. */
 ppc4xx_sdram_init(env, qdev_get_gpio_in(uicdev, 14),
-  PPC440EP_SDRAM_NR_BANKS, ram_banks);
+  PPC440EP_SDRAM_NR_BANKS, machine->ram);
 /* Enable SDRAM memory regions, this should be done by the firmware */
 if (ppc_dcr_write(env->dcr_env, SDRAM0_CFGADDR, 0x20) ||
 ppc_dcr_write(env->dcr_env, SDRAM0_CFGDATA, 0x8000)) {
diff --git a/hw/ppc/ppc4xx_devs.c b/hw/ppc/ppc4

[PATCH v4 17/21] ppc4xx_sdram: Use hwaddr for memory bank size

2022-09-14 Thread BALATON Zoltan
This resolves the target_ulong dependency that's clearly wrong and was
also noted in a fixme comment.

Signed-off-by: BALATON Zoltan 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/ppc/ppc4xx_sdram.c | 14 --
 1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/hw/ppc/ppc4xx_sdram.c b/hw/ppc/ppc4xx_sdram.c
index 39c27fa7d3..a6b80281b3 100644
--- a/hw/ppc/ppc4xx_sdram.c
+++ b/hw/ppc/ppc4xx_sdram.c
@@ -34,7 +34,6 @@
 #include "qapi/error.h"
 #include "qemu/log.h"
 #include "exec/address-spaces.h" /* get_system_memory() */
-#include "exec/cpu-defs.h" /* target_ulong */
 #include "hw/irq.h"
 #include "hw/qdev-properties.h"
 #include "qapi/error.h"
@@ -122,11 +121,6 @@ static void sdram_bank_unmap(Ppc4xxSdramBank *bank)
 
 /*/
 /* DDR SDRAM controller */
-/*
- * XXX: TOFIX: some patches have made this code become inconsistent:
- *  there are type inconsistencies, mixing hwaddr, target_ulong
- *  and uint32_t
- */
 static uint32_t sdram_ddr_bcr(hwaddr ram_base, hwaddr ram_size)
 {
 uint32_t bcr;
@@ -170,9 +164,9 @@ static inline hwaddr sdram_ddr_base(uint32_t bcr)
 return bcr & 0xFF80;
 }
 
-static target_ulong sdram_ddr_size(uint32_t bcr)
+static hwaddr sdram_ddr_size(uint32_t bcr)
 {
-target_ulong size;
+hwaddr size;
 int sh;
 
 sh = (bcr >> 17) & 0x7;
@@ -513,9 +507,9 @@ static inline hwaddr sdram_ddr2_base(uint32_t bcr)
 return (bcr & 0xffe0) << 2;
 }
 
-static uint64_t sdram_ddr2_size(uint32_t bcr)
+static hwaddr sdram_ddr2_size(uint32_t bcr)
 {
-uint64_t size;
+hwaddr size;
 int sh;
 
 sh = 1024 - ((bcr >> 6) & 0x3ff);
-- 
2.30.4




[PATCH v4 11/21] ppc440_sdram: Get rid of the init RAM hack

2022-09-14 Thread BALATON Zoltan
Remove the do_init parameter of ppc440_sdram_init and enable SDRAM
controller from the board via DCR access instead. Firmware does this
so it may not be needed when booting firmware only with -kernel but we
enable it unconditionally to preserve previous behaviour.

Signed-off-by: BALATON Zoltan 
---
 hw/ppc/ppc440.h| 3 +--
 hw/ppc/ppc440_uc.c | 8 ++--
 hw/ppc/sam460ex.c  | 8 +++-
 3 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/hw/ppc/ppc440.h b/hw/ppc/ppc440.h
index e6c905b7d6..01d76b8000 100644
--- a/hw/ppc/ppc440.h
+++ b/hw/ppc/ppc440.h
@@ -17,8 +17,7 @@ void ppc4xx_l2sram_init(CPUPPCState *env);
 void ppc4xx_cpr_init(CPUPPCState *env);
 void ppc4xx_sdr_init(CPUPPCState *env);
 void ppc440_sdram_init(CPUPPCState *env, int nbanks,
-   Ppc4xxSdramBank *ram_banks,
-   int do_init);
+   Ppc4xxSdramBank *ram_banks);
 void ppc4xx_ahb_init(CPUPPCState *env);
 void ppc4xx_dma_init(CPUPPCState *env, int dcr_base);
 void ppc460ex_pcie_init(CPUPPCState *env);
diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c
index aa09534abb..9d011ae0cb 100644
--- a/hw/ppc/ppc440_uc.c
+++ b/hw/ppc/ppc440_uc.c
@@ -727,12 +727,11 @@ static void sdram_reset(void *opaque)
 ppc440_sdram_t *sdram = opaque;
 
 sdram->addr = 0;
-sdram->mcopt2 = SDRAM_DDR2_MCOPT2_DCEN;
+sdram->mcopt2 = 0;
 }
 
 void ppc440_sdram_init(CPUPPCState *env, int nbanks,
-   Ppc4xxSdramBank *ram_banks,
-   int do_init)
+   Ppc4xxSdramBank *ram_banks)
 {
 ppc440_sdram_t *sdram;
 int i;
@@ -749,9 +748,6 @@ void ppc440_sdram_init(CPUPPCState *env, int nbanks,
  sdram, &dcr_read_sdram, &dcr_write_sdram);
 ppc_dcr_register(env, SDRAM0_CFGDATA,
  sdram, &dcr_read_sdram, &dcr_write_sdram);
-if (do_init) {
-sdram_map_bcr(sdram);
-}
 
 ppc_dcr_register(env, SDRAM_R0BAS,
  sdram, &dcr_read_sdram, &dcr_write_sdram);
diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c
index f4c2a693fb..dac329d482 100644
--- a/hw/ppc/sam460ex.c
+++ b/hw/ppc/sam460ex.c
@@ -345,7 +345,13 @@ static void sam460ex_init(MachineState *machine)
 ppc4xx_sdram_banks(machine->ram, 1, ram_banks, ppc460ex_sdram_bank_sizes);
 
 /* FIXME: does 460EX have ECC interrupts? */
-ppc440_sdram_init(env, 1, ram_banks, 1);
+ppc440_sdram_init(env, 1, ram_banks);
+/* Enable SDRAM memory regions as we may boot without firmware */
+if (ppc_dcr_write(env->dcr_env, SDRAM0_CFGADDR, 0x21) ||
+ppc_dcr_write(env->dcr_env, SDRAM0_CFGDATA, 0x0800)) {
+error_report("Couldn't enable memory regions");
+exit(1);
+}
 
 /* IIC controllers and devices */
 dev = sysbus_create_simple(TYPE_PPC4xx_I2C, 0x4ef600700,
-- 
2.30.4




[PATCH v4 09/21] ppc440_sdram: Split off map/unmap of sdram banks for later reuse

2022-09-14 Thread BALATON Zoltan
Signed-off-by: BALATON Zoltan 
---
 hw/ppc/ppc440_uc.c | 31 +++
 1 file changed, 19 insertions(+), 12 deletions(-)

diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c
index 5db59d1190..01184e717b 100644
--- a/hw/ppc/ppc440_uc.c
+++ b/hw/ppc/ppc440_uc.c
@@ -561,26 +561,33 @@ static uint64_t sdram_size(uint32_t bcr)
 return size;
 }
 
+static void sdram_bank_map(Ppc4xxSdramBank *bank)
+{
+memory_region_init(&bank->container, NULL, "sdram-container", bank->size);
+memory_region_add_subregion(&bank->container, 0, &bank->ram);
+memory_region_add_subregion(get_system_memory(), bank->base,
+&bank->container);
+}
+
+static void sdram_bank_unmap(Ppc4xxSdramBank *bank)
+{
+memory_region_del_subregion(get_system_memory(), &bank->container);
+memory_region_del_subregion(&bank->container, &bank->ram);
+object_unparent(OBJECT(&bank->container));
+}
+
 static void sdram_set_bcr(ppc440_sdram_t *sdram, int i,
   uint32_t bcr, int enabled)
 {
 if (sdram->bank[i].bcr & 1) {
 /* First unmap RAM if enabled */
-memory_region_del_subregion(get_system_memory(),
-&sdram->bank[i].container);
-memory_region_del_subregion(&sdram->bank[i].container,
-&sdram->bank[i].ram);
-object_unparent(OBJECT(&sdram->bank[i].container));
+sdram_bank_unmap(&sdram->bank[i]);
 }
 sdram->bank[i].bcr = bcr & 0xffe0ffc1;
+sdram->bank[i].base = sdram_base(bcr);
+sdram->bank[i].size = sdram_size(bcr);
 if (enabled && (bcr & 1)) {
-memory_region_init(&sdram->bank[i].container, NULL, "sdram-container",
-   sdram_size(bcr));
-memory_region_add_subregion(&sdram->bank[i].container, 0,
-&sdram->bank[i].ram);
-memory_region_add_subregion(get_system_memory(),
-sdram_base(bcr),
-&sdram->bank[i].container);
+sdram_bank_map(&sdram->bank[i]);
 }
 }
 
-- 
2.30.4




[PATCH v4 15/21] ppc440_sdram: QOM'ify

2022-09-14 Thread BALATON Zoltan
Change the ppc440_sdram model to a QOM class derived from the
PPC4xx-dcr-device and name it ppc4xx-sdram-ddr2. This is mostly
modelling the DDR2 SDRAM controller found in the 460EX (used on the
sam460ex board). Newer SoCs (regardless of their PPC core, e.g. 405EX)
may have this controller but we only emulate enough of it for the
sam460ex u-boot firmware.

Signed-off-by: BALATON Zoltan 
Reviewed-by: Cédric Le Goater 
---
 hw/ppc/ppc440.h |   2 -
 hw/ppc/ppc440_uc.c  | 115 +---
 hw/ppc/sam460ex.c   |   7 ++-
 include/hw/ppc/ppc4xx.h |  14 +
 4 files changed, 91 insertions(+), 47 deletions(-)

diff --git a/hw/ppc/ppc440.h b/hw/ppc/ppc440.h
index 29f6f14ed7..7c24db8504 100644
--- a/hw/ppc/ppc440.h
+++ b/hw/ppc/ppc440.h
@@ -16,8 +16,6 @@
 void ppc4xx_l2sram_init(CPUPPCState *env);
 void ppc4xx_cpr_init(CPUPPCState *env);
 void ppc4xx_sdr_init(CPUPPCState *env);
-void ppc440_sdram_init(CPUPPCState *env, int nbanks,
-   MemoryRegion *ram);
 void ppc4xx_ahb_init(CPUPPCState *env);
 void ppc4xx_dma_init(CPUPPCState *env, int dcr_base);
 void ppc460ex_pcie_init(CPUPPCState *env);
diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c
index bd2a489557..3c118e8860 100644
--- a/hw/ppc/ppc440_uc.c
+++ b/hw/ppc/ppc440_uc.c
@@ -483,13 +483,6 @@ void ppc4xx_sdr_init(CPUPPCState *env)
 
 /*/
 /* SDRAM controller */
-typedef struct ppc440_sdram_t {
-uint32_t addr;
-uint32_t mcopt2;
-int nbanks; /* Banks to use from the 4, e.g. when board has less slots */
-Ppc4xxSdramBank bank[4];
-} ppc440_sdram_t;
-
 enum {
 SDRAM_R0BAS = 0x40,
 SDRAM_R1BAS,
@@ -578,7 +571,7 @@ static void sdram_bank_unmap(Ppc4xxSdramBank *bank)
 object_unparent(OBJECT(&bank->container));
 }
 
-static void sdram_ddr2_set_bcr(ppc440_sdram_t *sdram, int i,
+static void sdram_ddr2_set_bcr(Ppc4xxSdramDdr2State *sdram, int i,
uint32_t bcr, int enabled)
 {
 if (sdram->bank[i].bcr & 1) {
@@ -596,7 +589,7 @@ static void sdram_ddr2_set_bcr(ppc440_sdram_t *sdram, int i,
 }
 }
 
-static void sdram_ddr2_map_bcr(ppc440_sdram_t *sdram)
+static void sdram_ddr2_map_bcr(Ppc4xxSdramDdr2State *sdram)
 {
 int i;
 
@@ -611,7 +604,7 @@ static void sdram_ddr2_map_bcr(ppc440_sdram_t *sdram)
 }
 }
 
-static void sdram_ddr2_unmap_bcr(ppc440_sdram_t *sdram)
+static void sdram_ddr2_unmap_bcr(Ppc4xxSdramDdr2State *sdram)
 {
 int i;
 
@@ -624,7 +617,7 @@ static void sdram_ddr2_unmap_bcr(ppc440_sdram_t *sdram)
 
 static uint32_t sdram_ddr2_dcr_read(void *opaque, int dcrn)
 {
-ppc440_sdram_t *sdram = opaque;
+Ppc4xxSdramDdr2State *sdram = opaque;
 uint32_t ret = 0;
 
 switch (dcrn) {
@@ -679,7 +672,7 @@ static uint32_t sdram_ddr2_dcr_read(void *opaque, int dcrn)
 
 static void sdram_ddr2_dcr_write(void *opaque, int dcrn, uint32_t val)
 {
-ppc440_sdram_t *sdram = opaque;
+Ppc4xxSdramDdr2State *sdram = opaque;
 
 switch (dcrn) {
 case SDRAM_R0BAS:
@@ -723,52 +716,86 @@ static void sdram_ddr2_dcr_write(void *opaque, int dcrn, 
uint32_t val)
 }
 }
 
-static void sdram_ddr2_reset(void *opaque)
+static void ppc4xx_sdram_ddr2_reset(DeviceState *dev)
 {
-ppc440_sdram_t *sdram = opaque;
+Ppc4xxSdramDdr2State *sdram = PPC4xx_SDRAM_DDR2(dev);
 
 sdram->addr = 0;
 sdram->mcopt2 = 0;
 }
 
-void ppc440_sdram_init(CPUPPCState *env, int nbanks,
-   MemoryRegion *ram)
+static void ppc4xx_sdram_ddr2_realize(DeviceState *dev, Error **errp)
 {
-ppc440_sdram_t *s;
+Ppc4xxSdramDdr2State *s = PPC4xx_SDRAM_DDR2(dev);
+Ppc4xxDcrDeviceState *dcr = PPC4xx_DCR_DEVICE(dev);
 const ram_addr_t valid_bank_sizes[] = {
 4 * GiB, 2 * GiB, 1 * GiB, 512 * MiB, 256 * MiB, 128 * MiB, 64 * MiB,
 32 * MiB, 16 * MiB, 8 * MiB, 0
 };
 
-s = g_malloc0(sizeof(*s));
-s->nbanks = nbanks;
-ppc4xx_sdram_banks(ram, s->nbanks, s->bank, valid_bank_sizes);
-qemu_register_reset(&sdram_ddr2_reset, s);
-ppc_dcr_register(env, SDRAM0_CFGADDR,
- s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
-ppc_dcr_register(env, SDRAM0_CFGDATA,
- s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
-
-ppc_dcr_register(env, SDRAM_R0BAS,
- s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
-ppc_dcr_register(env, SDRAM_R1BAS,
- s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
-ppc_dcr_register(env, SDRAM_R2BAS,
- s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
-ppc_dcr_register(env, SDRAM_R3BAS,
- s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
-ppc_dcr_register(env, SDRAM_CONF1HB,
- s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
-ppc_dcr_register(env, SDRAM_PLBADDULL,
- s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
-ppc_

[PATCH v4 14/21] ppc440_sdram: Move RAM size check to ppc440_sdram_init

2022-09-14 Thread BALATON Zoltan
Move the check for valid memory sizes from board to sdram controller
init. Board now only checks for additional restrictions imposed by
firmware then sdram init checks for valid sizes for SoC.

Signed-off-by: BALATON Zoltan 
---
 hw/ppc/ppc440.h|  4 ++--
 hw/ppc/ppc440_uc.c | 15 +++
 hw/ppc/sam460ex.c  | 32 +---
 3 files changed, 26 insertions(+), 25 deletions(-)

diff --git a/hw/ppc/ppc440.h b/hw/ppc/ppc440.h
index 01d76b8000..29f6f14ed7 100644
--- a/hw/ppc/ppc440.h
+++ b/hw/ppc/ppc440.h
@@ -11,13 +11,13 @@
 #ifndef PPC440_H
 #define PPC440_H
 
-#include "hw/ppc/ppc4xx.h"
+#include "hw/ppc/ppc.h"
 
 void ppc4xx_l2sram_init(CPUPPCState *env);
 void ppc4xx_cpr_init(CPUPPCState *env);
 void ppc4xx_sdr_init(CPUPPCState *env);
 void ppc440_sdram_init(CPUPPCState *env, int nbanks,
-   Ppc4xxSdramBank *ram_banks);
+   MemoryRegion *ram);
 void ppc4xx_ahb_init(CPUPPCState *env);
 void ppc4xx_dma_init(CPUPPCState *env, int dcr_base);
 void ppc460ex_pcie_init(CPUPPCState *env);
diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c
index fa313f979d..bd2a489557 100644
--- a/hw/ppc/ppc440_uc.c
+++ b/hw/ppc/ppc440_uc.c
@@ -486,7 +486,7 @@ void ppc4xx_sdr_init(CPUPPCState *env)
 typedef struct ppc440_sdram_t {
 uint32_t addr;
 uint32_t mcopt2;
-int nbanks;
+int nbanks; /* Banks to use from the 4, e.g. when board has less slots */
 Ppc4xxSdramBank bank[4];
 } ppc440_sdram_t;
 
@@ -732,18 +732,17 @@ static void sdram_ddr2_reset(void *opaque)
 }
 
 void ppc440_sdram_init(CPUPPCState *env, int nbanks,
-   Ppc4xxSdramBank *ram_banks)
+   MemoryRegion *ram)
 {
 ppc440_sdram_t *s;
-int i;
+const ram_addr_t valid_bank_sizes[] = {
+4 * GiB, 2 * GiB, 1 * GiB, 512 * MiB, 256 * MiB, 128 * MiB, 64 * MiB,
+32 * MiB, 16 * MiB, 8 * MiB, 0
+};
 
 s = g_malloc0(sizeof(*s));
 s->nbanks = nbanks;
-for (i = 0; i < nbanks; i++) {
-s->bank[i].ram = ram_banks[i].ram;
-s->bank[i].base = ram_banks[i].base;
-s->bank[i].size = ram_banks[i].size;
-}
+ppc4xx_sdram_banks(ram, s->nbanks, s->bank, valid_bank_sizes);
 qemu_register_reset(&sdram_ddr2_reset, s);
 ppc_dcr_register(env, SDRAM0_CFGADDR,
  s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write);
diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c
index dac329d482..9b850808a3 100644
--- a/hw/ppc/sam460ex.c
+++ b/hw/ppc/sam460ex.c
@@ -74,13 +74,6 @@
 #define EBC_FREQ 11500
 #define UART_FREQ 11059200
 
-/* The SoC could also handle 4 GiB but firmware does not work with that. */
-/* Maybe it overflows a signed 32 bit number somewhere? */
-static const ram_addr_t ppc460ex_sdram_bank_sizes[] = {
-2 * GiB, 1 * GiB, 512 * MiB, 256 * MiB, 128 * MiB, 64 * MiB,
-32 * MiB, 0
-};
-
 struct boot_info {
 uint32_t dt_base;
 uint32_t dt_size;
@@ -273,7 +266,6 @@ static void sam460ex_init(MachineState *machine)
 {
 MemoryRegion *address_space_mem = get_system_memory();
 MemoryRegion *isa = g_new(MemoryRegion, 1);
-Ppc4xxSdramBank *ram_banks = g_new0(Ppc4xxSdramBank, 1);
 MemoryRegion *l2cache_ram = g_new(MemoryRegion, 1);
 DeviceState *uic[4];
 int i;
@@ -340,12 +332,22 @@ static void sam460ex_init(MachineState *machine)
 }
 
 /* SDRAM controller */
-/* put all RAM on first bank because board has one slot
- * and firmware only checks that */
-ppc4xx_sdram_banks(machine->ram, 1, ram_banks, ppc460ex_sdram_bank_sizes);
-
+/* The SoC could also handle 4 GiB but firmware does not work with that. */
+if (machine->ram_size > 2 * GiB) {
+error_report("Memory over 2 GiB is not supported");
+exit(1);
+}
+/* Firmware needs at least 64 MiB */
+if (machine->ram_size < 64 * MiB) {
+error_report("Memory below 64 MiB is not supported");
+exit(1);
+}
+/*
+ * Put all RAM on first bank because board has one slot
+ * and firmware only checks that
+ */
+ppc440_sdram_init(env, 1, machine->ram);
 /* FIXME: does 460EX have ECC interrupts? */
-ppc440_sdram_init(env, 1, ram_banks);
 /* Enable SDRAM memory regions as we may boot without firmware */
 if (ppc_dcr_write(env->dcr_env, SDRAM0_CFGADDR, 0x21) ||
 ppc_dcr_write(env->dcr_env, SDRAM0_CFGDATA, 0x0800)) {
@@ -358,8 +360,8 @@ static void sam460ex_init(MachineState *machine)
qdev_get_gpio_in(uic[0], 2));
 i2c = PPC4xx_I2C(dev)->bus;
 /* SPD EEPROM on RAM module */
-spd_data = spd_data_generate(ram_banks->size < 128 * MiB ? DDR : DDR2,
- ram_banks->size);
+spd_data = spd_data_generate(machine->ram_size < 128 * MiB ? DDR : DDR2,
+ machine->ram_size);
 spd_data[20] = 4; /* SO-DIMM module */
 smbus_eeprom_init_one(i2c, 0x50, spd_data);
 /* RTC */
-- 
2.30.4




[PATCH v4 19/21] ppc4xx_sdram: Generalise bank setup

2022-09-14 Thread BALATON Zoltan
Currently only base and size are set on initial bank creation and bcr
value is computed on mapping the region. Set bcr at init so the bcr
encoding method becomes local to the controller model and mapping and
unmapping can operate on the bank so it can be shared between
different controller models. This patch converts the DDR2 controller.

Signed-off-by: BALATON Zoltan 
---
 hw/ppc/ppc4xx_sdram.c | 93 ++-
 hw/ppc/trace-events   |  1 +
 2 files changed, 48 insertions(+), 46 deletions(-)

diff --git a/hw/ppc/ppc4xx_sdram.c b/hw/ppc/ppc4xx_sdram.c
index 611dc7594b..c0cc7f6735 100644
--- a/hw/ppc/ppc4xx_sdram.c
+++ b/hw/ppc/ppc4xx_sdram.c
@@ -106,6 +106,7 @@ static void ppc4xx_sdram_banks(MemoryRegion *ram, int 
nr_banks,
 
 static void sdram_bank_map(Ppc4xxSdramBank *bank)
 {
+trace_ppc4xx_sdram_map(bank->base, bank->size);
 memory_region_init(&bank->container, NULL, "sdram-container", bank->size);
 memory_region_add_subregion(&bank->container, 0, &bank->ram);
 memory_region_add_subregion(get_system_memory(), bank->base,
@@ -114,11 +115,26 @@ static void sdram_bank_map(Ppc4xxSdramBank *bank)
 
 static void sdram_bank_unmap(Ppc4xxSdramBank *bank)
 {
+trace_ppc4xx_sdram_unmap(bank->base, bank->size);
 memory_region_del_subregion(get_system_memory(), &bank->container);
 memory_region_del_subregion(&bank->container, &bank->ram);
 object_unparent(OBJECT(&bank->container));
 }
 
+static void sdram_bank_set_bcr(Ppc4xxSdramBank *bank, uint32_t bcr,
+   hwaddr base, hwaddr size, int enabled)
+{
+if (memory_region_is_mapped(&bank->container)) {
+sdram_bank_unmap(bank);
+}
+bank->bcr = bcr;
+bank->base = base;
+bank->size = size;
+if (enabled && (bcr & 1)) {
+sdram_bank_map(bank);
+}
+}
+
 /*/
 /* DDR SDRAM controller */
 static uint32_t sdram_ddr_bcr(hwaddr ram_base, hwaddr ram_size)
@@ -445,6 +461,8 @@ static void ppc4xx_sdram_ddr_class_init(ObjectClass *oc, 
void *data)
 
 /*/
 /* DDR2 SDRAM controller */
+#define SDRAM_DDR2_BCR_MASK 0xffe0ffc1
+
 enum {
 SDRAM_R0BAS = 0x40,
 SDRAM_R1BAS,
@@ -518,50 +536,6 @@ static hwaddr sdram_ddr2_size(uint32_t bcr)
 return size;
 }
 
-static void sdram_ddr2_set_bcr(Ppc4xxSdramDdr2State *sdram, int i,
-   uint32_t bcr, int enabled)
-{
-if (sdram->bank[i].bcr & 1) {
-/* First unmap RAM if enabled */
-trace_ppc4xx_sdram_unmap(sdram_ddr2_base(sdram->bank[i].bcr),
- sdram_ddr2_size(sdram->bank[i].bcr));
-sdram_bank_unmap(&sdram->bank[i]);
-}
-sdram->bank[i].bcr = bcr & 0xffe0ffc1;
-sdram->bank[i].base = sdram_ddr2_base(bcr);
-sdram->bank[i].size = sdram_ddr2_size(bcr);
-if (enabled && (bcr & 1)) {
-trace_ppc4xx_sdram_map(sdram_ddr2_base(bcr), sdram_ddr2_size(bcr));
-sdram_bank_map(&sdram->bank[i]);
-}
-}
-
-static void sdram_ddr2_map_bcr(Ppc4xxSdramDdr2State *sdram)
-{
-int i;
-
-for (i = 0; i < sdram->nbanks; i++) {
-if (sdram->bank[i].size) {
-sdram_ddr2_set_bcr(sdram, i,
-   sdram_ddr2_bcr(sdram->bank[i].base,
-  sdram->bank[i].size), 1);
-} else {
-sdram_ddr2_set_bcr(sdram, i, 0, 0);
-}
-}
-}
-
-static void sdram_ddr2_unmap_bcr(Ppc4xxSdramDdr2State *sdram)
-{
-int i;
-
-for (i = 0; i < sdram->nbanks; i++) {
-if (sdram->bank[i].size) {
-sdram_ddr2_set_bcr(sdram, i, sdram->bank[i].bcr & ~1, 0);
-}
-}
-}
-
 static uint32_t sdram_ddr2_dcr_read(void *opaque, int dcrn)
 {
 Ppc4xxSdramDdr2State *s = opaque;
@@ -620,6 +594,7 @@ static uint32_t sdram_ddr2_dcr_read(void *opaque, int dcrn)
 static void sdram_ddr2_dcr_write(void *opaque, int dcrn, uint32_t val)
 {
 Ppc4xxSdramDdr2State *s = opaque;
+int i;
 
 switch (dcrn) {
 case SDRAM_R0BAS:
@@ -644,13 +619,25 @@ static void sdram_ddr2_dcr_write(void *opaque, int dcrn, 
uint32_t val)
 (val & SDRAM_DDR2_MCOPT2_DCEN)) {
 trace_ppc4xx_sdram_enable("enable");
 /* validate all RAM mappings */
-sdram_ddr2_map_bcr(s);
+for (i = 0; i < s->nbanks; i++) {
+if (s->bank[i].size) {
+sdram_bank_set_bcr(&s->bank[i], s->bank[i].bcr,
+   s->bank[i].base, s->bank[i].size,
+   1);
+}
+}
 s->mcopt2 |= SDRAM_DDR2_MCOPT2_DCEN;
 } else if ((s->mcopt2 & SDRAM_DDR2_MCOPT2_DCEN) &&
!(val & SDRAM_DDR2_MCOPT2_DCEN)) {
 trace_ppc4xx_sdram_enable("disab

[PATCH v4 20/21] ppc4xx_sdram: Convert DDR SDRAM controller to new bank handling

2022-09-14 Thread BALATON Zoltan
Use the generic bank handling introduced in previous patch in the DDR
SDRAM controller too. This also fixes previously broken region unmap
due to sdram_ddr_unmap_bcr() ignoring container region so it crashed
with an assert when the guest tried to disable the controller.

Signed-off-by: BALATON Zoltan 
---
 hw/ppc/ppc4xx_sdram.c | 98 ---
 1 file changed, 37 insertions(+), 61 deletions(-)

diff --git a/hw/ppc/ppc4xx_sdram.c b/hw/ppc/ppc4xx_sdram.c
index c0cc7f6735..05d0c8f004 100644
--- a/hw/ppc/ppc4xx_sdram.c
+++ b/hw/ppc/ppc4xx_sdram.c
@@ -137,6 +137,8 @@ static void sdram_bank_set_bcr(Ppc4xxSdramBank *bank, 
uint32_t bcr,
 
 /*/
 /* DDR SDRAM controller */
+#define SDRAM_DDR_BCR_MASK 0xFFDEE001
+
 static uint32_t sdram_ddr_bcr(hwaddr ram_base, hwaddr ram_size)
 {
 uint32_t bcr;
@@ -195,58 +197,6 @@ static hwaddr sdram_ddr_size(uint32_t bcr)
 return size;
 }
 
-static void sdram_ddr_set_bcr(Ppc4xxSdramDdrState *sdram, int i,
-  uint32_t bcr, int enabled)
-{
-if (sdram->bank[i].bcr & 1) {
-/* Unmap RAM */
-trace_ppc4xx_sdram_unmap(sdram_ddr_base(sdram->bank[i].bcr),
- sdram_ddr_size(sdram->bank[i].bcr));
-memory_region_del_subregion(get_system_memory(),
-&sdram->bank[i].container);
-memory_region_del_subregion(&sdram->bank[i].container,
-&sdram->bank[i].ram);
-object_unparent(OBJECT(&sdram->bank[i].container));
-}
-sdram->bank[i].bcr = bcr & 0xFFDEE001;
-if (enabled && (bcr & 1)) {
-trace_ppc4xx_sdram_map(sdram_ddr_base(bcr), sdram_ddr_size(bcr));
-memory_region_init(&sdram->bank[i].container, NULL, "sdram-container",
-   sdram_ddr_size(bcr));
-memory_region_add_subregion(&sdram->bank[i].container, 0,
-&sdram->bank[i].ram);
-memory_region_add_subregion(get_system_memory(),
-sdram_ddr_base(bcr),
-&sdram->bank[i].container);
-}
-}
-
-static void sdram_ddr_map_bcr(Ppc4xxSdramDdrState *sdram)
-{
-int i;
-
-for (i = 0; i < sdram->nbanks; i++) {
-if (sdram->bank[i].size != 0) {
-sdram_ddr_set_bcr(sdram, i, sdram_ddr_bcr(sdram->bank[i].base,
-  sdram->bank[i].size), 1);
-} else {
-sdram_ddr_set_bcr(sdram, i, 0, 0);
-}
-}
-}
-
-static void sdram_ddr_unmap_bcr(Ppc4xxSdramDdrState *sdram)
-{
-int i;
-
-for (i = 0; i < sdram->nbanks; i++) {
-trace_ppc4xx_sdram_unmap(sdram_ddr_base(sdram->bank[i].bcr),
- sdram_ddr_size(sdram->bank[i].bcr));
-memory_region_del_subregion(get_system_memory(),
-&sdram->bank[i].ram);
-}
-}
-
 static uint32_t sdram_ddr_dcr_read(void *opaque, int dcrn)
 {
 Ppc4xxSdramDdrState *s = opaque;
@@ -317,6 +267,7 @@ static uint32_t sdram_ddr_dcr_read(void *opaque, int dcrn)
 static void sdram_ddr_dcr_write(void *opaque, int dcrn, uint32_t val)
 {
 Ppc4xxSdramDdrState *s = opaque;
+int i;
 
 switch (dcrn) {
 case SDRAM0_CFGADDR:
@@ -338,12 +289,24 @@ static void sdram_ddr_dcr_write(void *opaque, int dcrn, 
uint32_t val)
 if (!(s->cfg & 0x8000) && (val & 0x8000)) {
 trace_ppc4xx_sdram_enable("enable");
 /* validate all RAM mappings */
-sdram_ddr_map_bcr(s);
+for (i = 0; i < s->nbanks; i++) {
+if (s->bank[i].size) {
+sdram_bank_set_bcr(&s->bank[i], s->bank[i].bcr,
+   s->bank[i].base, s->bank[i].size,
+   1);
+}
+}
 s->status &= ~0x8000;
 } else if ((s->cfg & 0x8000) && !(val & 0x8000)) {
 trace_ppc4xx_sdram_enable("disable");
 /* invalidate all RAM mappings */
-sdram_ddr_unmap_bcr(s);
+for (i = 0; i < s->nbanks; i++) {
+if (s->bank[i].size) {
+sdram_bank_set_bcr(&s->bank[i], s->bank[i].bcr,
+   s->bank[i].base, s->bank[i].size,
+   0);
+}
+}
 s->status |= 0x8000;
 }
 if (!(s->cfg & 0x4000) && (val & 0x4000)) {
@@ -363,16 +326,16 @@ static void sdram_ddr_dcr_write(void *opaque, int dcrn, 
uint32_t val)
 s->pmit = (val & 0xF800) | 0x07C0;
 break;
 case 0x40: /* SDRAM_B0CR */
-sdram_ddr_set_bcr(s, 0, val, s->cf

[PATCH v4 10/21] ppc440_sdram: Implement enable bit in the DDR2 SDRAM

2022-09-14 Thread BALATON Zoltan
To allow removing the do_init hack we need to improve the DDR2 SDRAM
controller model to handle the enable/disable bit that it ignored so
far.

Signed-off-by: BALATON Zoltan 
---
v4: Add define for enable bit
v2: replace 0x0800 with BIT(27)

 hw/ppc/ppc440_uc.c | 38 --
 1 file changed, 36 insertions(+), 2 deletions(-)

diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c
index 01184e717b..aa09534abb 100644
--- a/hw/ppc/ppc440_uc.c
+++ b/hw/ppc/ppc440_uc.c
@@ -23,6 +23,7 @@
 #include "sysemu/reset.h"
 #include "ppc440.h"
 #include "qom/object.h"
+#include "trace.h"
 
 /*/
 /* L2 Cache as SRAM */
@@ -484,6 +485,7 @@ void ppc4xx_sdr_init(CPUPPCState *env)
 /* SDRAM controller */
 typedef struct ppc440_sdram_t {
 uint32_t addr;
+uint32_t mcopt2;
 int nbanks;
 Ppc4xxSdramBank bank[4];
 } ppc440_sdram_t;
@@ -581,12 +583,15 @@ static void sdram_set_bcr(ppc440_sdram_t *sdram, int i,
 {
 if (sdram->bank[i].bcr & 1) {
 /* First unmap RAM if enabled */
+trace_ppc4xx_sdram_unmap(sdram_base(sdram->bank[i].bcr),
+ sdram_size(sdram->bank[i].bcr));
 sdram_bank_unmap(&sdram->bank[i]);
 }
 sdram->bank[i].bcr = bcr & 0xffe0ffc1;
 sdram->bank[i].base = sdram_base(bcr);
 sdram->bank[i].size = sdram_size(bcr);
 if (enabled && (bcr & 1)) {
+trace_ppc4xx_sdram_map(sdram_base(bcr), sdram_size(bcr));
 sdram_bank_map(&sdram->bank[i]);
 }
 }
@@ -596,7 +601,7 @@ static void sdram_map_bcr(ppc440_sdram_t *sdram)
 int i;
 
 for (i = 0; i < sdram->nbanks; i++) {
-if (sdram->bank[i].size != 0) {
+if (sdram->bank[i].size) {
 sdram_set_bcr(sdram, i, sdram_bcr(sdram->bank[i].base,
   sdram->bank[i].size), 1);
 } else {
@@ -605,6 +610,17 @@ static void sdram_map_bcr(ppc440_sdram_t *sdram)
 }
 }
 
+static void sdram_unmap_bcr(ppc440_sdram_t *sdram)
+{
+int i;
+
+for (i = 0; i < sdram->nbanks; i++) {
+if (sdram->bank[i].size) {
+sdram_set_bcr(sdram, i, sdram->bank[i].bcr & ~1, 0);
+}
+}
+}
+
 static uint32_t dcr_read_sdram(void *opaque, int dcrn)
 {
 ppc440_sdram_t *sdram = opaque;
@@ -636,7 +652,7 @@ static uint32_t dcr_read_sdram(void *opaque, int dcrn)
 ret = 0x8000;
 break;
 case 0x21: /* SDRAM_MCOPT2 */
-ret = 0x0800;
+ret = sdram->mcopt2;
 break;
 case 0x40: /* SDRAM_MB0CF */
 ret = 0x8001;
@@ -658,6 +674,8 @@ static uint32_t dcr_read_sdram(void *opaque, int dcrn)
 return ret;
 }
 
+#define SDRAM_DDR2_MCOPT2_DCEN BIT(27)
+
 static void dcr_write_sdram(void *opaque, int dcrn, uint32_t val)
 {
 ppc440_sdram_t *sdram = opaque;
@@ -680,6 +698,21 @@ static void dcr_write_sdram(void *opaque, int dcrn, 
uint32_t val)
 switch (sdram->addr) {
 case 0x00: /* B0CR */
 break;
+case 0x21: /* SDRAM_MCOPT2 */
+if (!(sdram->mcopt2 & SDRAM_DDR2_MCOPT2_DCEN) &&
+(val & SDRAM_DDR2_MCOPT2_DCEN)) {
+trace_ppc4xx_sdram_enable("enable");
+/* validate all RAM mappings */
+sdram_map_bcr(sdram);
+sdram->mcopt2 |= SDRAM_DDR2_MCOPT2_DCEN;
+} else if ((sdram->mcopt2 & SDRAM_DDR2_MCOPT2_DCEN) &&
+   !(val & SDRAM_DDR2_MCOPT2_DCEN)) {
+trace_ppc4xx_sdram_enable("disable");
+/* invalidate all RAM mappings */
+sdram_unmap_bcr(sdram);
+sdram->mcopt2 &= ~SDRAM_DDR2_MCOPT2_DCEN;
+}
+break;
 default:
 break;
 }
@@ -694,6 +727,7 @@ static void sdram_reset(void *opaque)
 ppc440_sdram_t *sdram = opaque;
 
 sdram->addr = 0;
+sdram->mcopt2 = SDRAM_DDR2_MCOPT2_DCEN;
 }
 
 void ppc440_sdram_init(CPUPPCState *env, int nbanks,
-- 
2.30.4




Re: [PATCH 1/1] s390x/tcg: Fix opcode for lzrf

2022-09-14 Thread Cornelia Huck
On Wed, Sep 14 2022, Christian Borntraeger  wrote:

> Fix the opcode for Load and Zero Rightmost Byte (32).

Fixes: c2a5c1d718ea ("target/s390x: Implement load-and-zero-rightmost-byte 
insns")

>
> Cc: qemu-sta...@nongnu.org
> Reported-by: Nathan Chancellor 
> Tested-by: Nathan Chancellor 
> Signed-off-by: Christian Borntraeger 
> ---
>  target/s390x/tcg/insn-data.def | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Reviewed-by: Cornelia Huck 




[PATCH v4 18/21] ppc4xx_sdram: Rename local state variable for brevity

2022-09-14 Thread BALATON Zoltan
Rename the sdram local state variable to s in dcr read/write functions
and reset methods for better readability and to match realize methods.
Other places not converted will be changed or removed in subsequent
patches.

Signed-off-by: BALATON Zoltan 
---
 hw/ppc/ppc4xx_sdram.c | 158 +-
 1 file changed, 79 insertions(+), 79 deletions(-)

diff --git a/hw/ppc/ppc4xx_sdram.c b/hw/ppc/ppc4xx_sdram.c
index a6b80281b3..611dc7594b 100644
--- a/hw/ppc/ppc4xx_sdram.c
+++ b/hw/ppc/ppc4xx_sdram.c
@@ -233,56 +233,56 @@ static void sdram_ddr_unmap_bcr(Ppc4xxSdramDdrState 
*sdram)
 
 static uint32_t sdram_ddr_dcr_read(void *opaque, int dcrn)
 {
-Ppc4xxSdramDdrState *sdram = opaque;
+Ppc4xxSdramDdrState *s = opaque;
 uint32_t ret;
 
 switch (dcrn) {
 case SDRAM0_CFGADDR:
-ret = sdram->addr;
+ret = s->addr;
 break;
 case SDRAM0_CFGDATA:
-switch (sdram->addr) {
+switch (s->addr) {
 case 0x00: /* SDRAM_BESR0 */
-ret = sdram->besr0;
+ret = s->besr0;
 break;
 case 0x08: /* SDRAM_BESR1 */
-ret = sdram->besr1;
+ret = s->besr1;
 break;
 case 0x10: /* SDRAM_BEAR */
-ret = sdram->bear;
+ret = s->bear;
 break;
 case 0x20: /* SDRAM_CFG */
-ret = sdram->cfg;
+ret = s->cfg;
 break;
 case 0x24: /* SDRAM_STATUS */
-ret = sdram->status;
+ret = s->status;
 break;
 case 0x30: /* SDRAM_RTR */
-ret = sdram->rtr;
+ret = s->rtr;
 break;
 case 0x34: /* SDRAM_PMIT */
-ret = sdram->pmit;
+ret = s->pmit;
 break;
 case 0x40: /* SDRAM_B0CR */
-ret = sdram->bank[0].bcr;
+ret = s->bank[0].bcr;
 break;
 case 0x44: /* SDRAM_B1CR */
-ret = sdram->bank[1].bcr;
+ret = s->bank[1].bcr;
 break;
 case 0x48: /* SDRAM_B2CR */
-ret = sdram->bank[2].bcr;
+ret = s->bank[2].bcr;
 break;
 case 0x4C: /* SDRAM_B3CR */
-ret = sdram->bank[3].bcr;
+ret = s->bank[3].bcr;
 break;
 case 0x80: /* SDRAM_TR */
 ret = -1; /* ? */
 break;
 case 0x94: /* SDRAM_ECCCFG */
-ret = sdram->ecccfg;
+ret = s->ecccfg;
 break;
 case 0x98: /* SDRAM_ECCESR */
-ret = sdram->eccesr;
+ret = s->eccesr;
 break;
 default: /* Error */
 ret = -1;
@@ -300,78 +300,78 @@ static uint32_t sdram_ddr_dcr_read(void *opaque, int dcrn)
 
 static void sdram_ddr_dcr_write(void *opaque, int dcrn, uint32_t val)
 {
-Ppc4xxSdramDdrState *sdram = opaque;
+Ppc4xxSdramDdrState *s = opaque;
 
 switch (dcrn) {
 case SDRAM0_CFGADDR:
-sdram->addr = val;
+s->addr = val;
 break;
 case SDRAM0_CFGDATA:
-switch (sdram->addr) {
+switch (s->addr) {
 case 0x00: /* SDRAM_BESR0 */
-sdram->besr0 &= ~val;
+s->besr0 &= ~val;
 break;
 case 0x08: /* SDRAM_BESR1 */
-sdram->besr1 &= ~val;
+s->besr1 &= ~val;
 break;
 case 0x10: /* SDRAM_BEAR */
-sdram->bear = val;
+s->bear = val;
 break;
 case 0x20: /* SDRAM_CFG */
 val &= 0xFFE0;
-if (!(sdram->cfg & 0x8000) && (val & 0x8000)) {
+if (!(s->cfg & 0x8000) && (val & 0x8000)) {
 trace_ppc4xx_sdram_enable("enable");
 /* validate all RAM mappings */
-sdram_ddr_map_bcr(sdram);
-sdram->status &= ~0x8000;
-} else if ((sdram->cfg & 0x8000) && !(val & 0x8000)) {
+sdram_ddr_map_bcr(s);
+s->status &= ~0x8000;
+} else if ((s->cfg & 0x8000) && !(val & 0x8000)) {
 trace_ppc4xx_sdram_enable("disable");
 /* invalidate all RAM mappings */
-sdram_ddr_unmap_bcr(sdram);
-sdram->status |= 0x8000;
+sdram_ddr_unmap_bcr(s);
+s->status |= 0x8000;
 }
-if (!(sdram->cfg & 0x4000) && (val & 0x4000)) {
-sdram->status |= 0x4000;
-} else if ((sdram->cfg & 0x4000) && !(val & 0x4000)) {
-sdram->status &= ~0x4000;
+if (!(s->cfg & 0x4000) && (val & 0x4000)) {
+s->status |= 0x4000;
+} else if ((s->cfg & 0x4000) && !(val & 0x4000)) {
+s->status &= ~0x4000;
 }
-sdram->cfg = val;
+s->cfg = val;
 break;
   

[PATCH v4 21/21] ppc4xx_sdram: Add errp parameter to ppc4xx_sdram_banks()

2022-09-14 Thread BALATON Zoltan
Do not exit from ppc4xx_sdram_banks() but report error via an errp
parameter instead.

Signed-off-by: BALATON Zoltan 
---
 hw/ppc/ppc4xx_sdram.c | 28 +++-
 1 file changed, 19 insertions(+), 9 deletions(-)

diff --git a/hw/ppc/ppc4xx_sdram.c b/hw/ppc/ppc4xx_sdram.c
index 05d0c8f004..23f406f4e3 100644
--- a/hw/ppc/ppc4xx_sdram.c
+++ b/hw/ppc/ppc4xx_sdram.c
@@ -53,10 +53,12 @@
  * must be one of a small set of sizes. The number of banks and the supported
  * sizes varies by SoC.
  */
-static void ppc4xx_sdram_banks(MemoryRegion *ram, int nr_banks,
+static bool ppc4xx_sdram_banks(MemoryRegion *ram, int nr_banks,
Ppc4xxSdramBank ram_banks[],
-   const ram_addr_t sdram_bank_sizes[])
+   const ram_addr_t sdram_bank_sizes[],
+   Error **errp)
 {
+ERRP_GUARD();
 ram_addr_t size_left = memory_region_size(ram);
 ram_addr_t base = 0;
 ram_addr_t bank_size;
@@ -94,14 +96,16 @@ static void ppc4xx_sdram_banks(MemoryRegion *ram, int 
nr_banks,
sdram_bank_sizes[i] / MiB,
sdram_bank_sizes[i + 1] ? ", " : "");
 }
-error_report("at most %d bank%s of %s MiB each supported",
- nr_banks, nr_banks == 1 ? "" : "s", s->str);
-error_printf("Possible valid RAM size: %" PRIi64 " MiB\n",
-used_size ? used_size / MiB : sdram_bank_sizes[i - 1] / MiB);
+error_setg(errp, "Invalid SDRAM banks");
+error_append_hint(errp, "at most %d bank%s of %s MiB each supported\n",
+  nr_banks, nr_banks == 1 ? "" : "s", s->str);
+error_append_hint(errp, "Possible valid RAM size: %" PRIi64 " MiB\n",
+  used_size ? used_size / MiB : sdram_bank_sizes[i - 1] / MiB);
 
 g_string_free(s, true);
-exit(EXIT_FAILURE);
+return false;
 }
+return true;
 }
 
 static void sdram_bank_map(Ppc4xxSdramBank *bank)
@@ -395,7 +399,10 @@ static void ppc4xx_sdram_ddr_realize(DeviceState *dev, 
Error **errp)
 error_setg(errp, "Missing dram memory region");
 return;
 }
-ppc4xx_sdram_banks(s->dram_mr, s->nbanks, s->bank, valid_bank_sizes);
+if (!ppc4xx_sdram_banks(s->dram_mr, s->nbanks, s->bank,
+valid_bank_sizes, errp)) {
+return;
+}
 for (i = 0; i < s->nbanks; i++) {
 if (s->bank[i].size) {
 s->bank[i].bcr = sdram_ddr_bcr(s->bank[i].base, s->bank[i].size);
@@ -652,7 +659,10 @@ static void ppc4xx_sdram_ddr2_realize(DeviceState *dev, 
Error **errp)
 error_setg(errp, "Missing dram memory region");
 return;
 }
-ppc4xx_sdram_banks(s->dram_mr, s->nbanks, s->bank, valid_bank_sizes);
+if (!ppc4xx_sdram_banks(s->dram_mr, s->nbanks, s->bank,
+valid_bank_sizes, errp)) {
+return;
+}
 for (i = 0; i < s->nbanks; i++) {
 if (s->bank[i].size) {
 s->bank[i].bcr = sdram_ddr2_bcr(s->bank[i].base, s->bank[i].size);
-- 
2.30.4




[PATCH v4 12/21] ppc440_sdram: Rename local variable for readability

2022-09-14 Thread BALATON Zoltan
Rename local sdram variable in ppc440_sdram_init to s for readability.

Signed-off-by: BALATON Zoltan 
Reviewed-by: Cédric Le Goater 
---
 hw/ppc/ppc440_uc.c | 36 ++--
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c
index 9d011ae0cb..c316893944 100644
--- a/hw/ppc/ppc440_uc.c
+++ b/hw/ppc/ppc440_uc.c
@@ -733,40 +733,40 @@ static void sdram_reset(void *opaque)
 void ppc440_sdram_init(CPUPPCState *env, int nbanks,
Ppc4xxSdramBank *ram_banks)
 {
-ppc440_sdram_t *sdram;
+ppc440_sdram_t *s;
 int i;
 
-sdram = g_malloc0(sizeof(*sdram));
-sdram->nbanks = nbanks;
+s = g_malloc0(sizeof(*s));
+s->nbanks = nbanks;
 for (i = 0; i < nbanks; i++) {
-sdram->bank[i].ram = ram_banks[i].ram;
-sdram->bank[i].base = ram_banks[i].base;
-sdram->bank[i].size = ram_banks[i].size;
+s->bank[i].ram = ram_banks[i].ram;
+s->bank[i].base = ram_banks[i].base;
+s->bank[i].size = ram_banks[i].size;
 }
-qemu_register_reset(&sdram_reset, sdram);
+qemu_register_reset(&sdram_reset, s);
 ppc_dcr_register(env, SDRAM0_CFGADDR,
- sdram, &dcr_read_sdram, &dcr_write_sdram);
+ s, &dcr_read_sdram, &dcr_write_sdram);
 ppc_dcr_register(env, SDRAM0_CFGDATA,
- sdram, &dcr_read_sdram, &dcr_write_sdram);
+ s, &dcr_read_sdram, &dcr_write_sdram);
 
 ppc_dcr_register(env, SDRAM_R0BAS,
- sdram, &dcr_read_sdram, &dcr_write_sdram);
+ s, &dcr_read_sdram, &dcr_write_sdram);
 ppc_dcr_register(env, SDRAM_R1BAS,
- sdram, &dcr_read_sdram, &dcr_write_sdram);
+ s, &dcr_read_sdram, &dcr_write_sdram);
 ppc_dcr_register(env, SDRAM_R2BAS,
- sdram, &dcr_read_sdram, &dcr_write_sdram);
+ s, &dcr_read_sdram, &dcr_write_sdram);
 ppc_dcr_register(env, SDRAM_R3BAS,
- sdram, &dcr_read_sdram, &dcr_write_sdram);
+ s, &dcr_read_sdram, &dcr_write_sdram);
 ppc_dcr_register(env, SDRAM_CONF1HB,
- sdram, &dcr_read_sdram, &dcr_write_sdram);
+ s, &dcr_read_sdram, &dcr_write_sdram);
 ppc_dcr_register(env, SDRAM_PLBADDULL,
- sdram, &dcr_read_sdram, &dcr_write_sdram);
+ s, &dcr_read_sdram, &dcr_write_sdram);
 ppc_dcr_register(env, SDRAM_CONF1LL,
- sdram, &dcr_read_sdram, &dcr_write_sdram);
+ s, &dcr_read_sdram, &dcr_write_sdram);
 ppc_dcr_register(env, SDRAM_CONFPATHB,
- sdram, &dcr_read_sdram, &dcr_write_sdram);
+ s, &dcr_read_sdram, &dcr_write_sdram);
 ppc_dcr_register(env, SDRAM_PLBADDUHB,
- sdram, &dcr_read_sdram, &dcr_write_sdram);
+ s, &dcr_read_sdram, &dcr_write_sdram);
 }
 
 /*/
-- 
2.30.4




Re: [PATCH v3 06/20] ppc4xx_sdram: Move size check to ppc4xx_sdram_init()

2022-09-14 Thread BALATON Zoltan

On Wed, 14 Sep 2022, Cédric Le Goater wrote:

On 9/13/22 21:52, BALATON Zoltan wrote:

Instead of checking if memory size is valid in board code move this
check to ppc4xx_sdram_init() as this is a restriction imposed by the
SDRAM controller.



So, we are relying on ppc4xx_sdram_banks() to check the RAM size
and report the error. The problem is the exit.

You also need to change the prototypes of some routine to take an
"Error **errp" parameter as realize routines do.

   qdev_realize(DEVICE(&ppc405->soc), NULL, &error_fatal);
   ppc405_soc_realize(DeviceState *dev, Error **errp)
ppc4xx_sdram_init()
 ppc4xx_sdram_banks()

at least, ppc4xx_sdram_banks() should be changed. The next patch
doing the QOMification takes care of ppc4xx_sdram_init()


I thought about changing ppc4xx_sdram_banks to use Error but did not do it 
first because of how the message is formatted. I had to look up docs on 
how to do this with Error, added a patch in v4 to do this conversion.


Regards,
BALATON Zoltan


Thanks,

C.





Signed-off-by: BALATON Zoltan 
---
  hw/ppc/ppc405.h |  2 --
  hw/ppc/ppc405_boards.c  | 10 --
  hw/ppc/ppc405_uc.c  | 11 ++-
  hw/ppc/ppc440_bamboo.c  | 10 +-
  hw/ppc/ppc4xx_devs.c| 14 ++
  include/hw/ppc/ppc4xx.h |  2 +-
  6 files changed, 10 insertions(+), 39 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index ca0972b88b..ad54dff542 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -167,9 +167,7 @@ struct Ppc405SoCState {
  DeviceState parent_obj;
/* Public */
-Ppc4xxSdramBank ram_banks[2];
  MemoryRegion *dram_mr;
-hwaddr ram_size;
PowerPCCPU cpu;
  PPCUIC uic;
diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
index bf02a71c6d..cdd4e0cb4c 100644
--- a/hw/ppc/ppc405_boards.c
+++ b/hw/ppc/ppc405_boards.c
@@ -271,22 +271,12 @@ static void boot_from_kernel(MachineState *machine, 
PowerPCCPU *cpu)

  static void ppc405_init(MachineState *machine)
  {
  Ppc405MachineState *ppc405 = PPC405_MACHINE(machine);
-MachineClass *mc = MACHINE_GET_CLASS(machine);
  const char *kernel_filename = machine->kernel_filename;
  MemoryRegion *sysmem = get_system_memory();
  CPUPPCState *env;
  -if (machine->ram_size != mc->default_ram_size) {
-char *sz = size_to_str(mc->default_ram_size);
-error_report("Invalid RAM size, should be %s", sz);
-g_free(sz);
-exit(EXIT_FAILURE);
-}
-
  object_initialize_child(OBJECT(machine), "soc", &ppc405->soc,
  TYPE_PPC405_SOC);
-object_property_set_uint(OBJECT(&ppc405->soc), "ram-size",
- machine->ram_size, &error_fatal);
  object_property_set_link(OBJECT(&ppc405->soc), "dram",
   OBJECT(machine->ram), &error_abort);
  object_property_set_uint(OBJECT(&ppc405->soc), "sys-clk", ,
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index bcbf35bc14..e1c7188e61 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -1073,15 +1073,9 @@ static void ppc405_soc_realize(DeviceState *dev, 
Error **errp)
 qdev_get_gpio_in(DEVICE(&s->cpu), 
PPC40x_INPUT_CINT));

/* SDRAM controller */
-/* XXX 405EP has no ECC interrupt */
-s->ram_banks[0].base = 0;
-s->ram_banks[0].size = s->ram_size;
-memory_region_init_alias(&s->ram_banks[0].ram, OBJECT(s),
- "ppc405.sdram0", s->dram_mr,
- s->ram_banks[0].base, s->ram_banks[0].size);
-
+/* XXX 405EP has no ECC interrupt */
  ppc4xx_sdram_init(env, qdev_get_gpio_in(DEVICE(&s->uic), 17), 1,
-  s->ram_banks);
+  s->dram_mr);
/* External bus controller */
  if (!ppc4xx_dcr_realize(PPC4xx_DCR_DEVICE(&s->ebc), &s->cpu, errp)) {
@@ -1159,7 +1153,6 @@ static void ppc405_soc_realize(DeviceState *dev, 
Error **errp)

  static Property ppc405_soc_properties[] = {
  DEFINE_PROP_LINK("dram", Ppc405SoCState, dram_mr, TYPE_MEMORY_REGION,
   MemoryRegion *),
-DEFINE_PROP_UINT64("ram-size", Ppc405SoCState, ram_size, 0),
  DEFINE_PROP_END_OF_LIST(),
  };
  diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c
index 2bd5e41140..9b456f1819 100644
--- a/hw/ppc/ppc440_bamboo.c
+++ b/hw/ppc/ppc440_bamboo.c
@@ -50,10 +50,6 @@
#define PPC440EP_SDRAM_NR_BANKS 4
  -static const ram_addr_t ppc440ep_sdram_bank_sizes[] = {
-256 * MiB, 128 * MiB, 64 * MiB, 32 * MiB, 16 * MiB, 8 * MiB, 4 * MiB, 
0

-};
-
  static hwaddr entry;
static int bamboo_load_device_tree(hwaddr addr,
@@ -168,8 +164,6 @@ static void bamboo_init(MachineState *machine)
  unsigned int pci_irq_nrs[4] = { 28, 27, 26, 25 };
  MemoryRegion *address_space_mem = get_system_memory();
  MemoryRegion *isa = g_new(MemoryRegion, 1);
-Ppc4xxSdramBank *ram_banks = g_new0(Ppc4xxSdramBank,
- 

[PATCH v4 13/21] ppc4xx_sdram: Rename functions to prevent name clashes

2022-09-14 Thread BALATON Zoltan
Rename functions to avoid name clashes when moving the DDR2 controller
model currently called ppc440_sdram to ppc4xx_devs. This also more
clearly shows which function belongs to which model.

Signed-off-by: BALATON Zoltan 
---
 hw/ppc/ppc440_uc.c   | 69 ++--
 hw/ppc/ppc4xx_devs.c | 44 ++--
 2 files changed, 57 insertions(+), 56 deletions(-)

diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c
index c316893944..fa313f979d 100644
--- a/hw/ppc/ppc440_uc.c
+++ b/hw/ppc/ppc440_uc.c
@@ -502,7 +502,7 @@ enum {
 SDRAM_PLBADDUHB = 0x50,
 };
 
-static uint32_t sdram_bcr(hwaddr ram_base, hwaddr ram_size)
+static uint32_t sdram_ddr2_bcr(hwaddr ram_base, hwaddr ram_size)
 {
 uint32_t bcr;
 
@@ -547,12 +547,12 @@ static uint32_t sdram_bcr(hwaddr ram_base, hwaddr 
ram_size)
 return bcr;
 }
 
-static inline hwaddr sdram_base(uint32_t bcr)
+static inline hwaddr sdram_ddr2_base(uint32_t bcr)
 {
 return (bcr & 0xffe0) << 2;
 }
 
-static uint64_t sdram_size(uint32_t bcr)
+static uint64_t sdram_ddr2_size(uint32_t bcr)
 {
 uint64_t size;
 int sh;
@@ -578,50 +578,51 @@ static void sdram_bank_unmap(Ppc4xxSdramBank *bank)
 object_unparent(OBJECT(&bank->container));
 }
 
-static void sdram_set_bcr(ppc440_sdram_t *sdram, int i,
-  uint32_t bcr, int enabled)
+static void sdram_ddr2_set_bcr(ppc440_sdram_t *sdram, int i,
+   uint32_t bcr, int enabled)
 {
 if (sdram->bank[i].bcr & 1) {
 /* First unmap RAM if enabled */
-trace_ppc4xx_sdram_unmap(sdram_base(sdram->bank[i].bcr),
- sdram_size(sdram->bank[i].bcr));
+trace_ppc4xx_sdram_unmap(sdram_ddr2_base(sdram->bank[i].bcr),
+ sdram_ddr2_size(sdram->bank[i].bcr));
 sdram_bank_unmap(&sdram->bank[i]);
 }
 sdram->bank[i].bcr = bcr & 0xffe0ffc1;
-sdram->bank[i].base = sdram_base(bcr);
-sdram->bank[i].size = sdram_size(bcr);
+sdram->bank[i].base = sdram_ddr2_base(bcr);
+sdram->bank[i].size = sdram_ddr2_size(bcr);
 if (enabled && (bcr & 1)) {
-trace_ppc4xx_sdram_map(sdram_base(bcr), sdram_size(bcr));
+trace_ppc4xx_sdram_map(sdram_ddr2_base(bcr), sdram_ddr2_size(bcr));
 sdram_bank_map(&sdram->bank[i]);
 }
 }
 
-static void sdram_map_bcr(ppc440_sdram_t *sdram)
+static void sdram_ddr2_map_bcr(ppc440_sdram_t *sdram)
 {
 int i;
 
 for (i = 0; i < sdram->nbanks; i++) {
 if (sdram->bank[i].size) {
-sdram_set_bcr(sdram, i, sdram_bcr(sdram->bank[i].base,
+sdram_ddr2_set_bcr(sdram, i,
+   sdram_ddr2_bcr(sdram->bank[i].base,
   sdram->bank[i].size), 1);
 } else {
-sdram_set_bcr(sdram, i, 0, 0);
+sdram_ddr2_set_bcr(sdram, i, 0, 0);
 }
 }
 }
 
-static void sdram_unmap_bcr(ppc440_sdram_t *sdram)
+static void sdram_ddr2_unmap_bcr(ppc440_sdram_t *sdram)
 {
 int i;
 
 for (i = 0; i < sdram->nbanks; i++) {
 if (sdram->bank[i].size) {
-sdram_set_bcr(sdram, i, sdram->bank[i].bcr & ~1, 0);
+sdram_ddr2_set_bcr(sdram, i, sdram->bank[i].bcr & ~1, 0);
 }
 }
 }
 
-static uint32_t dcr_read_sdram(void *opaque, int dcrn)
+static uint32_t sdram_ddr2_dcr_read(void *opaque, int dcrn)
 {
 ppc440_sdram_t *sdram = opaque;
 uint32_t ret = 0;
@@ -632,8 +633,8 @@ static uint32_t dcr_read_sdram(void *opaque, int dcrn)
 case SDRAM_R2BAS:
 case SDRAM_R3BAS:
 if (sdram->bank[dcrn - SDRAM_R0BAS].size) {
-ret = sdram_bcr(sdram->bank[dcrn - SDRAM_R0BAS].base,
-sdram->bank[dcrn - SDRAM_R0BAS].size);
+ret = sdram_ddr2_bcr(sdram->bank[dcrn - SDRAM_R0BAS].base,
+ sdram->bank[dcrn - SDRAM_R0BAS].size);
 }
 break;
 case SDRAM_CONF1HB:
@@ -676,7 +677,7 @@ static uint32_t dcr_read_sdram(void *opaque, int dcrn)
 
 #define SDRAM_DDR2_MCOPT2_DCEN BIT(27)
 
-static void dcr_write_sdram(void *opaque, int dcrn, uint32_t val)
+static void sdram_ddr2_dcr_write(void *opaque, int dcrn, uint32_t val)
 {
 ppc440_sdram_t *sdram = opaque;
 
@@ -703,13 +704,13 @@ static void dcr_write_sdram(void *opaque, int dcrn, 
uint32_t val)
 (val & SDRAM_DDR2_MCOPT2_DCEN)) {
 trace_ppc4xx_sdram_enable("enable");
 /* validate all RAM mappings */
-sdram_map_bcr(sdram);
+sdram_ddr2_map_bcr(sdram);
 sdram->mcopt2 |= SDRAM_DDR2_MCOPT2_DCEN;
 } else if ((sdram->mcopt2 & SDRAM_DDR2_MCOPT2_DCEN) &&
!(val & SDRAM_DDR2_MCOPT2_DCEN)) {
 trace_ppc4xx_sdram_enable("disable");
 /* invalidate all RAM mappings */
-sdram_unmap_bcr(sdram);
+sdram_ddr2_unmap_bcr(sdram

[PULL 04/20] target/arm: Sort KVM reads of AArch32 ID registers into encoding order

2022-09-14 Thread Richard Henderson
From: Peter Maydell 

The code that reads the AArch32 ID registers from KVM in
kvm_arm_get_host_cpu_features() does so almost but not quite in
encoding order.  Move the read of ID_PFR2 down so it's really in
encoding order.

Signed-off-by: Peter Maydell 
Reviewed-by: Richard Henderson 
Message-Id: <20220819110052.2942289-3-peter.mayd...@linaro.org>
Signed-off-by: Richard Henderson 
---
 target/arm/kvm64.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
index 9b9dd46d78..84c4c85f40 100644
--- a/target/arm/kvm64.c
+++ b/target/arm/kvm64.c
@@ -608,8 +608,6 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
   ARM64_SYS_REG(3, 0, 0, 1, 0));
 err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_pfr1,
   ARM64_SYS_REG(3, 0, 0, 1, 1));
-err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_pfr2,
-  ARM64_SYS_REG(3, 0, 0, 3, 4));
 err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_dfr0,
   ARM64_SYS_REG(3, 0, 0, 1, 2));
 err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr0,
@@ -643,6 +641,8 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
   ARM64_SYS_REG(3, 0, 0, 3, 1));
 err |= read_sys_reg32(fdarray[2], &ahcf->isar.mvfr2,
   ARM64_SYS_REG(3, 0, 0, 3, 2));
+err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_pfr2,
+  ARM64_SYS_REG(3, 0, 0, 3, 4));
 
 /*
  * DBGDIDR is a bit complicated because the kernel doesn't
-- 
2.34.1




Re: [PATCH v3 03/20] ppc4xx_sdram: Get rid of the init RAM hack

2022-09-14 Thread BALATON Zoltan

On Wed, 14 Sep 2022, Cédric Le Goater wrote:

On 9/13/22 21:52, BALATON Zoltan wrote:

The do_init parameter of ppc4xx_sdram_init() is used to map memory
regions that is normally done by the firmware by programming the SDRAM
controller. This is needed when booting a kernel directly from -kernel
without a firmware. Do this from board code accesing normal SDRAM


accessing


Fixed, also two ofhers in another patch you haven't noticed.


controller registers the same way as firmware would do, so we can get
rid of this hack.

Signed-off-by: BALATON Zoltan 
---
v2: Fix ref405ep boot with -kernel and U-Boot

  hw/ppc/ppc405.h |  1 -
  hw/ppc/ppc405_boards.c  | 12 ++--
  hw/ppc/ppc405_uc.c  |  4 +---
  hw/ppc/ppc440_bamboo.c  |  8 +++-
  hw/ppc/ppc440_uc.c  |  2 --
  hw/ppc/ppc4xx_devs.c| 11 +--
  include/hw/ppc/ppc4xx.h |  8 ++--
  7 files changed, 25 insertions(+), 21 deletions(-)

diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index 1e558c7831..756865621b 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -169,7 +169,6 @@ struct Ppc405SoCState {
  /* Public */
  MemoryRegion ram_banks[2];
  hwaddr ram_bases[2], ram_sizes[2];
-bool do_dram_init;
MemoryRegion *dram_mr;
  hwaddr ram_size;
diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
index 083f12b23e..bf02a71c6d 100644
--- a/hw/ppc/ppc405_boards.c
+++ b/hw/ppc/ppc405_boards.c
@@ -274,6 +274,7 @@ static void ppc405_init(MachineState *machine)
  MachineClass *mc = MACHINE_GET_CLASS(machine);
  const char *kernel_filename = machine->kernel_filename;
  MemoryRegion *sysmem = get_system_memory();
+CPUPPCState *env;
if (machine->ram_size != mc->default_ram_size) {
  char *sz = size_to_str(mc->default_ram_size);
@@ -288,12 +289,19 @@ static void ppc405_init(MachineState *machine)
   machine->ram_size, &error_fatal);
  object_property_set_link(OBJECT(&ppc405->soc), "dram",
   OBJECT(machine->ram), &error_abort);
-object_property_set_bool(OBJECT(&ppc405->soc), "dram-init",
- kernel_filename != NULL, &error_abort);
  object_property_set_uint(OBJECT(&ppc405->soc), "sys-clk", ,
   &error_abort);
  qdev_realize(DEVICE(&ppc405->soc), NULL, &error_fatal);
  +/* Enable SDRAM memory regions */
+/* FIXME This shouldn't be needed with firmware but we lack SPD data 
*/


what do you mean ?


U-Boot detects the available RAM by reading the SPD info of the RAM 
modules but that probably also needs i2c emulation. See sam460ex.



+env = &ppc405->soc.cpu.env;
+if (ppc_dcr_write(env->dcr_env, SDRAM0_CFGADDR, 0x20) ||
+ppc_dcr_write(env->dcr_env, SDRAM0_CFGDATA, 0x8000)) {



I am not in favor of these ppc_drc_write calls and this is still a hack.


It's not. Normally this is done by firmware to enable memory controller 
but the board code has to do it if not using firmware (e.g. booting with 
-kernel) the same way it provides bootinfo or device tree mods the 
firmware would normally do or in this case maybe the emulation is 
incomplete so the part of firmware that configures the SDRAM controller 
does not run.



The "dram-init" property is a cleaner solution. It takes care of doing the
pre-mapping of RAM banks in the realize routine of the sdram model (when
available).


I disagree, the hardware does not have such feature, it proviesd DCRs as 
the way to configure it. Adding a special property for it deviates from 
hardware and clutters qtree. Doing it like this patch is cleaner IMO.


Regards,
BALATON Zoltan



C.


+error_report("Could not enable memory regions");
+exit(1);
+}
+
  /* allocate and load BIOS */
  if (machine->firmware) {
  MemoryRegion *bios = g_new(MemoryRegion, 1);
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index 2ca42fdef6..1e02347e57 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -1081,8 +1081,7 @@ static void ppc405_soc_realize(DeviceState *dev, 
Error **errp)

   s->ram_bases[0], s->ram_sizes[0]);
ppc4xx_sdram_init(env, qdev_get_gpio_in(DEVICE(&s->uic), 17), 1,
-  s->ram_banks, s->ram_bases, s->ram_sizes,
-  s->do_dram_init);
+  s->ram_banks, s->ram_bases, s->ram_sizes);
/* External bus controller */
  if (!ppc4xx_dcr_realize(PPC4xx_DCR_DEVICE(&s->ebc), &s->cpu, errp)) {
@@ -1160,7 +1159,6 @@ static void ppc405_soc_realize(DeviceState *dev, 
Error **errp)

  static Property ppc405_soc_properties[] = {
  DEFINE_PROP_LINK("dram", Ppc405SoCState, dram_mr, TYPE_MEMORY_REGION,
   MemoryRegion *),
-DEFINE_PROP_BOOL("dram-init", Ppc405SoCState, do_dram_init, 0),
  DEFINE_PROP_UINT64("ram-size", Ppc405SoCState, ram_size, 0),
  DEFINE_PROP_END_OF_LIST(),
  };
diff --git a/hw/ppc/ppc440_bamboo

[PATCH v4 16/21] ppc4xx_sdram: Move ppc4xx DDR and DDR2 SDRAM controller models together

2022-09-14 Thread BALATON Zoltan
Move the PPC4xx DDR and DDR2 SDRAM contrller models into a new file
called ppc4xx_sdram to separate from other device models and put them
in one place allowing sharing some code between them.

Signed-off-by: BALATON Zoltan 
---
 hw/ppc/meson.build  |   3 +-
 hw/ppc/ppc440_uc.c  | 325 -
 hw/ppc/ppc4xx_devs.c| 403 -
 hw/ppc/ppc4xx_sdram.c   | 756 
 include/hw/ppc/ppc4xx.h |  34 +-
 5 files changed, 775 insertions(+), 746 deletions(-)
 create mode 100644 hw/ppc/ppc4xx_sdram.c

diff --git a/hw/ppc/meson.build b/hw/ppc/meson.build
index 62801923f3..74720dd1e1 100644
--- a/hw/ppc/meson.build
+++ b/hw/ppc/meson.build
@@ -59,8 +59,9 @@ ppc_ss.add(when: 'CONFIG_PPC440', if_true: files(
   'ppc440_bamboo.c',
   'ppc440_pcix.c', 'ppc440_uc.c'))
 ppc_ss.add(when: 'CONFIG_PPC4XX', if_true: files(
+  'ppc4xx_devs.c',
   'ppc4xx_pci.c',
-  'ppc4xx_devs.c'))
+  'ppc4xx_sdram.c'))
 ppc_ss.add(when: 'CONFIG_SAM460EX', if_true: files('sam460ex.c'))
 # PReP
 ppc_ss.add(when: 'CONFIG_PREP', if_true: files('prep.c'))
diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c
index 3c118e8860..651263926e 100644
--- a/hw/ppc/ppc440_uc.c
+++ b/hw/ppc/ppc440_uc.c
@@ -10,20 +10,14 @@
 
 #include "qemu/osdep.h"
 #include "qemu/units.h"
-#include "qemu/error-report.h"
 #include "qapi/error.h"
 #include "qemu/log.h"
-#include "qemu/module.h"
 #include "hw/irq.h"
-#include "exec/memory.h"
 #include "hw/ppc/ppc4xx.h"
 #include "hw/qdev-properties.h"
 #include "hw/pci/pci.h"
-#include "sysemu/block-backend.h"
 #include "sysemu/reset.h"
 #include "ppc440.h"
-#include "qom/object.h"
-#include "trace.h"
 
 /*/
 /* L2 Cache as SRAM */
@@ -379,10 +373,6 @@ enum {
 PESDR1_RSTSTA = 0x365,
 };
 
-#define SDR0_DDR0_DDRM_ENCODE(n)  unsigned long)(n)) & 0x03) << 29)
-#define SDR0_DDR0_DDRM_DDR1   0x2000
-#define SDR0_DDR0_DDRM_DDR2   0x4000
-
 static uint32_t dcr_read_sdr(void *opaque, int dcrn)
 {
 ppc4xx_sdr_t *sdr = opaque;
@@ -481,321 +471,6 @@ void ppc4xx_sdr_init(CPUPPCState *env)
  sdr, &dcr_read_sdr, &dcr_write_sdr);
 }
 
-/*/
-/* SDRAM controller */
-enum {
-SDRAM_R0BAS = 0x40,
-SDRAM_R1BAS,
-SDRAM_R2BAS,
-SDRAM_R3BAS,
-SDRAM_CONF1HB = 0x45,
-SDRAM_PLBADDULL = 0x4a,
-SDRAM_CONF1LL = 0x4b,
-SDRAM_CONFPATHB = 0x4f,
-SDRAM_PLBADDUHB = 0x50,
-};
-
-static uint32_t sdram_ddr2_bcr(hwaddr ram_base, hwaddr ram_size)
-{
-uint32_t bcr;
-
-switch (ram_size) {
-case (8 * MiB):
-bcr = 0xffc0;
-break;
-case (16 * MiB):
-bcr = 0xff80;
-break;
-case (32 * MiB):
-bcr = 0xff00;
-break;
-case (64 * MiB):
-bcr = 0xfe00;
-break;
-case (128 * MiB):
-bcr = 0xfc00;
-break;
-case (256 * MiB):
-bcr = 0xf800;
-break;
-case (512 * MiB):
-bcr = 0xf000;
-break;
-case (1 * GiB):
-bcr = 0xe000;
-break;
-case (2 * GiB):
-bcr = 0xc000;
-break;
-case (4 * GiB):
-bcr = 0x8000;
-break;
-default:
-error_report("invalid RAM size " TARGET_FMT_plx, ram_size);
-return 0;
-}
-bcr |= ram_base >> 2 & 0xffe0;
-bcr |= 1;
-
-return bcr;
-}
-
-static inline hwaddr sdram_ddr2_base(uint32_t bcr)
-{
-return (bcr & 0xffe0) << 2;
-}
-
-static uint64_t sdram_ddr2_size(uint32_t bcr)
-{
-uint64_t size;
-int sh;
-
-sh = 1024 - ((bcr >> 6) & 0x3ff);
-size = 8 * MiB * sh;
-
-return size;
-}
-
-static void sdram_bank_map(Ppc4xxSdramBank *bank)
-{
-memory_region_init(&bank->container, NULL, "sdram-container", bank->size);
-memory_region_add_subregion(&bank->container, 0, &bank->ram);
-memory_region_add_subregion(get_system_memory(), bank->base,
-&bank->container);
-}
-
-static void sdram_bank_unmap(Ppc4xxSdramBank *bank)
-{
-memory_region_del_subregion(get_system_memory(), &bank->container);
-memory_region_del_subregion(&bank->container, &bank->ram);
-object_unparent(OBJECT(&bank->container));
-}
-
-static void sdram_ddr2_set_bcr(Ppc4xxSdramDdr2State *sdram, int i,
-   uint32_t bcr, int enabled)
-{
-if (sdram->bank[i].bcr & 1) {
-/* First unmap RAM if enabled */
-trace_ppc4xx_sdram_unmap(sdram_ddr2_base(sdram->bank[i].bcr),
- sdram_ddr2_size(sdram->bank[i].bcr));
-sdram_bank_unmap(&sdram->bank[i]);
-}
-sdram->bank[i].bcr = bcr & 0xffe0ffc1;
-sdram->bank[i].base = sdram_ddr2_base(bcr);
-sdram->bank[i].size = sdram_ddr2_size(bcr);
-if (enabled && (bcr & 1)) {
-trace_ppc4xx_sdram_map(sdram_ddr2_base(bcr), sdram_ddr2_size(bcr));
-sdram_bank_map(&

Re: [PATCH v3 09/20] ppc440_sdram: Split off map/unmap of sdram banks for later reuse

2022-09-14 Thread BALATON Zoltan

On Wed, 14 Sep 2022, Cédric Le Goater wrote:

On 9/13/22 21:52, BALATON Zoltan wrote:

Signed-off-by: BALATON Zoltan 
---
  hw/ppc/ppc440_uc.c | 31 +++
  1 file changed, 19 insertions(+), 12 deletions(-)

diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c
index 5db59d1190..01184e717b 100644
--- a/hw/ppc/ppc440_uc.c
+++ b/hw/ppc/ppc440_uc.c
@@ -561,26 +561,33 @@ static uint64_t sdram_size(uint32_t bcr)
  return size;
  }
  +static void sdram_bank_map(Ppc4xxSdramBank *bank)
+{
+memory_region_init(&bank->container, NULL, "sdram-container", 
bank->size);


This init belongs to the realize routine.

It is a oneliner. I think you can do it now without risks.


Not in this patch for sure as this is just moving this out from the write 
callback here. What you suggest is a separate clean up that could be 
considered as a followup after this series. I'm not sure which way is best 
as one could argue that we don't need this container region and could just 
create the ram region alias with the right size and offset but that may 
need to store more info or understand the register values better. Since I 
may not understand it completely I chose to not break it more and just 
leave it as it is for now. You could think about changing it afterwards 
separately.


Regards,
BALATON Zoltan


Thanks,

C.


+memory_region_add_subregion(&bank->container, 0, &bank->ram);
+memory_region_add_subregion(get_system_memory(), bank->base,
+&bank->container);
+}
+
+static void sdram_bank_unmap(Ppc4xxSdramBank *bank)
+{
+memory_region_del_subregion(get_system_memory(), &bank->container);
+memory_region_del_subregion(&bank->container, &bank->ram);
+object_unparent(OBJECT(&bank->container));
+}
+
  static void sdram_set_bcr(ppc440_sdram_t *sdram, int i,
uint32_t bcr, int enabled)
  {
  if (sdram->bank[i].bcr & 1) {
  /* First unmap RAM if enabled */
-memory_region_del_subregion(get_system_memory(),
-&sdram->bank[i].container);
-memory_region_del_subregion(&sdram->bank[i].container,
-&sdram->bank[i].ram);
-object_unparent(OBJECT(&sdram->bank[i].container));
+sdram_bank_unmap(&sdram->bank[i]);
  }
  sdram->bank[i].bcr = bcr & 0xffe0ffc1;
+sdram->bank[i].base = sdram_base(bcr);
+sdram->bank[i].size = sdram_size(bcr);
  if (enabled && (bcr & 1)) {
-memory_region_init(&sdram->bank[i].container, NULL, 
"sdram-container",

-   sdram_size(bcr));
-memory_region_add_subregion(&sdram->bank[i].container, 0,
-&sdram->bank[i].ram);
-memory_region_add_subregion(get_system_memory(),
-sdram_base(bcr),
-&sdram->bank[i].container);
+sdram_bank_map(&sdram->bank[i]);
  }
  }






[PULL 10/20] target/arm: Correct value returned by pmu_counter_mask()

2022-09-14 Thread Richard Henderson
From: Peter Maydell 

pmu_counter_mask() accidentally returns a value with bits [63:32]
set, because the expression it returns is evaluated as a signed value
that gets sign-extended to 64 bits.  Force the whole expression to be
evaluated with 64-bit arithmetic with ULL suffixes.

The main effect of this bug was that a guest could write to the bits
in the high half of registers like PMCNTENSET_EL0 that are supposed
to be RES0.

Signed-off-by: Peter Maydell 
Reviewed-by: Richard Henderson 
Message-Id: <20220822132358.3524971-3-peter.mayd...@linaro.org>
Signed-off-by: Richard Henderson 
---
 target/arm/internals.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/arm/internals.h b/target/arm/internals.h
index b8fefdff67..83526166de 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -1296,7 +1296,7 @@ static inline uint32_t pmu_num_counters(CPUARMState *env)
 /* Bits allowed to be set/cleared for PMCNTEN* and PMINTEN* */
 static inline uint64_t pmu_counter_mask(CPUARMState *env)
 {
-  return (1 << 31) | ((1 << pmu_num_counters(env)) - 1);
+  return (1ULL << 31) | ((1ULL << pmu_num_counters(env)) - 1);
 }
 
 #ifdef TARGET_AARCH64
-- 
2.34.1




[PULL 16/20] target/arm: Implement FEAT_PMUv3p5 cycle counter disable bits

2022-09-14 Thread Richard Henderson
From: Peter Maydell 

FEAT_PMUv3p5 introduces new bits which disable the cycle
counter from counting:
 * MDCR_EL2.HCCD disables the counter when in EL2
 * MDCR_EL3.SCCD disables the counter when Secure

Add the code to support these bits.

(Note that there is a third documented counter-disable
bit, MDCR_EL3.MCCD, which disables the counter when in
EL3. This is not present until FEAT_PMUv3p7, so is
out of scope for now.)

Signed-off-by: Peter Maydell 
Reviewed-by: Richard Henderson 
Message-Id: <20220822132358.3524971-9-peter.mayd...@linaro.org>
Signed-off-by: Richard Henderson 
---
 target/arm/cpu.h| 20 
 target/arm/helper.c | 21 +
 2 files changed, 37 insertions(+), 4 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index d86e51992a..41e74df104 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1334,6 +1334,8 @@ FIELD(CPTR_EL3, TTA, 20, 1)
 FIELD(CPTR_EL3, TAM, 30, 1)
 FIELD(CPTR_EL3, TCPAC, 31, 1)
 
+#define MDCR_SCCD (1U << 23)  /* MDCR_EL3 */
+#define MDCR_HCCD (1U << 23)  /* MDCR_EL2 */
 #define MDCR_EPMAD(1U << 21)
 #define MDCR_EDAD (1U << 20)
 #define MDCR_SPME (1U << 17)  /* MDCR_EL3 */
@@ -3726,6 +3728,13 @@ static inline bool isar_feature_aa32_pmuv3p4(const 
ARMISARegisters *id)
 FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) != 0xf;
 }
 
+static inline bool isar_feature_aa32_pmuv3p5(const ARMISARegisters *id)
+{
+/* 0xf means "non-standard IMPDEF PMU" */
+return FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) >= 6 &&
+FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) != 0xf;
+}
+
 static inline bool isar_feature_aa32_hpd(const ARMISARegisters *id)
 {
 return FIELD_EX32(id->id_mmfr4, ID_MMFR4, HPDS) != 0;
@@ -4050,6 +4059,12 @@ static inline bool isar_feature_aa64_pmuv3p4(const 
ARMISARegisters *id)
 FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
 }
 
+static inline bool isar_feature_aa64_pmuv3p5(const ARMISARegisters *id)
+{
+return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 6 &&
+FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
+}
+
 static inline bool isar_feature_aa64_rcpc_8_3(const ARMISARegisters *id)
 {
 return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, LRCPC) != 0;
@@ -4223,6 +4238,11 @@ static inline bool isar_feature_any_pmuv3p4(const 
ARMISARegisters *id)
 return isar_feature_aa64_pmuv3p4(id) || isar_feature_aa32_pmuv3p4(id);
 }
 
+static inline bool isar_feature_any_pmuv3p5(const ARMISARegisters *id)
+{
+return isar_feature_aa64_pmuv3p5(id) || isar_feature_aa32_pmuv3p5(id);
+}
+
 static inline bool isar_feature_any_ccidx(const ARMISARegisters *id)
 {
 return isar_feature_aa64_ccidx(id) || isar_feature_aa32_ccidx(id);
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 987ac19fe8..0d1f23de09 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -1084,8 +1084,8 @@ static CPAccessResult pmreg_access_ccntr(CPUARMState *env,
  * We use these to decide whether we need to wrap a write to MDCR_EL2
  * or MDCR_EL3 in pmu_op_start()/pmu_op_finish() calls.
  */
-#define MDCR_EL2_PMU_ENABLE_BITS (MDCR_HPME | MDCR_HPMD | MDCR_HPMN)
-#define MDCR_EL3_PMU_ENABLE_BITS (MDCR_SPME)
+#define MDCR_EL2_PMU_ENABLE_BITS (MDCR_HPME | MDCR_HPMD | MDCR_HPMN | 
MDCR_HCCD)
+#define MDCR_EL3_PMU_ENABLE_BITS (MDCR_SPME | MDCR_SCCD)
 
 /* Returns true if the counter (pass 31 for PMCCNTR) should count events using
  * the current EL, security state, and register configuration.
@@ -1120,8 +1120,21 @@ static bool pmu_counter_enabled(CPUARMState *env, 
uint8_t counter)
 prohibited = prohibited || !(env->cp15.mdcr_el3 & MDCR_SPME);
 }
 
-if (prohibited && counter == 31) {
-prohibited = env->cp15.c9_pmcr & PMCRDP;
+if (counter == 31) {
+/*
+ * The cycle counter defaults to running. PMCR.DP says "disable
+ * the cycle counter when event counting is prohibited".
+ * Some MDCR bits disable the cycle counter specifically.
+ */
+prohibited = prohibited && env->cp15.c9_pmcr & PMCRDP;
+if (cpu_isar_feature(any_pmuv3p5, env_archcpu(env))) {
+if (secure) {
+prohibited = prohibited || (env->cp15.mdcr_el3 & MDCR_SCCD);
+}
+if (el == 2) {
+prohibited = prohibited || (mdcr_el2 & MDCR_HCCD);
+}
+}
 }
 
 if (counter == 31) {
-- 
2.34.1




[PULL 01/20] target/arm: Add cortex-a35

2022-09-14 Thread Richard Henderson
From: Hao Wu 

Add cortex A35 core and enable it for virt board.

Signed-off-by: Hao Wu 
Reviewed-by: Joe Komlodi 
Reviewed-by: Peter Maydell 
Message-Id: <20220819002015.1663247-1-wuhao...@google.com>
Signed-off-by: Richard Henderson 
---
 docs/system/arm/virt.rst |  1 +
 hw/arm/virt.c|  1 +
 target/arm/cpu64.c   | 80 
 3 files changed, 82 insertions(+)

diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst
index 3b6ba69a9a..20442ea2c1 100644
--- a/docs/system/arm/virt.rst
+++ b/docs/system/arm/virt.rst
@@ -52,6 +52,7 @@ Supported guest CPU types:
 
 - ``cortex-a7`` (32-bit)
 - ``cortex-a15`` (32-bit; the default)
+- ``cortex-a35`` (64-bit)
 - ``cortex-a53`` (64-bit)
 - ``cortex-a57`` (64-bit)
 - ``cortex-a72`` (64-bit)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 1a6480fd2a..0961e053e5 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -199,6 +199,7 @@ static const int a15irqmap[] = {
 static const char *valid_cpus[] = {
 ARM_CPU_TYPE_NAME("cortex-a7"),
 ARM_CPU_TYPE_NAME("cortex-a15"),
+ARM_CPU_TYPE_NAME("cortex-a35"),
 ARM_CPU_TYPE_NAME("cortex-a53"),
 ARM_CPU_TYPE_NAME("cortex-a57"),
 ARM_CPU_TYPE_NAME("cortex-a72"),
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 78e27f778a..9d1ea32057 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -36,6 +36,85 @@
 #include "hw/qdev-properties.h"
 #include "internals.h"
 
+static void aarch64_a35_initfn(Object *obj)
+{
+ARMCPU *cpu = ARM_CPU(obj);
+
+cpu->dtb_compatible = "arm,cortex-a35";
+set_feature(&cpu->env, ARM_FEATURE_V8);
+set_feature(&cpu->env, ARM_FEATURE_NEON);
+set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
+set_feature(&cpu->env, ARM_FEATURE_AARCH64);
+set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
+set_feature(&cpu->env, ARM_FEATURE_EL2);
+set_feature(&cpu->env, ARM_FEATURE_EL3);
+set_feature(&cpu->env, ARM_FEATURE_PMU);
+
+/* From B2.2 AArch64 identification registers. */
+cpu->midr = 0x411fd040;
+cpu->revidr = 0;
+cpu->ctr = 0x84448004;
+cpu->isar.id_pfr0 = 0x0131;
+cpu->isar.id_pfr1 = 0x00011011;
+cpu->isar.id_dfr0 = 0x03010066;
+cpu->id_afr0 = 0;
+cpu->isar.id_mmfr0 = 0x10201105;
+cpu->isar.id_mmfr1 = 0x4000;
+cpu->isar.id_mmfr2 = 0x0126;
+cpu->isar.id_mmfr3 = 0x02102211;
+cpu->isar.id_isar0 = 0x02101110;
+cpu->isar.id_isar1 = 0x13112111;
+cpu->isar.id_isar2 = 0x21232042;
+cpu->isar.id_isar3 = 0x01112131;
+cpu->isar.id_isar4 = 0x00011142;
+cpu->isar.id_isar5 = 0x00011121;
+cpu->isar.id_aa64pfr0 = 0x;
+cpu->isar.id_aa64pfr1 = 0;
+cpu->isar.id_aa64dfr0 = 0x10305106;
+cpu->isar.id_aa64dfr1 = 0;
+cpu->isar.id_aa64isar0 = 0x00011120;
+cpu->isar.id_aa64isar1 = 0;
+cpu->isar.id_aa64mmfr0 = 0x00101122;
+cpu->isar.id_aa64mmfr1 = 0;
+cpu->clidr = 0x0a200023;
+cpu->dcz_blocksize = 4;
+
+/* From B2.4 AArch64 Virtual Memory control registers */
+cpu->reset_sctlr = 0x00c50838;
+
+/* From B2.10 AArch64 performance monitor registers */
+cpu->isar.reset_pmcr_el0 = 0x410a3000;
+
+/* From B2.29 Cache ID registers */
+cpu->ccsidr[0] = 0x700fe01a; /* 32KB L1 dcache */
+cpu->ccsidr[1] = 0x201fe00a; /* 32KB L1 icache */
+cpu->ccsidr[2] = 0x703fe03a; /* 512KB L2 cache */
+
+/* From B3.5 VGIC Type register */
+cpu->gic_num_lrs = 4;
+cpu->gic_vpribits = 5;
+cpu->gic_vprebits = 5;
+cpu->gic_pribits = 5;
+
+/* From C6.4 Debug ID Register */
+cpu->isar.dbgdidr = 0x3516d000;
+/* From C6.5 Debug Device ID Register */
+cpu->isar.dbgdevid = 0x00110f13;
+/* From C6.6 Debug Device ID Register 1 */
+cpu->isar.dbgdevid1 = 0x2;
+
+/* From Cortex-A35 SIMD and Floating-point Support r1p0 */
+/* From 3.2 AArch32 register summary */
+cpu->reset_fpsid = 0x41034043;
+
+/* From 2.2 AArch64 register summary */
+cpu->isar.mvfr0 = 0x10110222;
+cpu->isar.mvfr1 = 0x1211;
+cpu->isar.mvfr2 = 0x0043;
+
+/* These values are the same with A53/A57/A72. */
+define_cortex_a72_a57_a53_cp_reginfo(cpu);
+}
 
 static void aarch64_a57_initfn(Object *obj)
 {
@@ -1158,6 +1237,7 @@ static void aarch64_a64fx_initfn(Object *obj)
 }
 
 static const ARMCPUInfo aarch64_cpus[] = {
+{ .name = "cortex-a35", .initfn = aarch64_a35_initfn },
 { .name = "cortex-a57", .initfn = aarch64_a57_initfn },
 { .name = "cortex-a53", .initfn = aarch64_a53_initfn },
 { .name = "cortex-a72", .initfn = aarch64_a72_initfn },
-- 
2.34.1




[PULL 00/20] target-arm.next patch queue

2022-09-14 Thread Richard Henderson
A collection of arm-related patches that I collected while
Peter was on holiday.  There are some still outstanding that
I didn't feel comfortable collecting, such as cortex-r52.


r~


The following changes since commit 79dfa177ae348bb5ab5f97c0915359b13d6186e2:

  Merge tag 'pull-qapi-2022-09-07' of git://repo.or.cz/qemu/armbru into staging 
(2022-09-07 13:13:30 -0400)

are available in the Git repository at:

  https://gitlab.com/rth7680/qemu.git tags/pull-arm-20220914

for you to fetch changes up to 761c532ab1ebe9d345c9afe4fb9c2c4b26c58582:

  target/arm: Make boards pass base address to armv7m_load_kernel() (2022-09-14 
11:19:40 +0100)


Add cortex-a35.
Fix bcm2835 framebuffer for rpi firmware.
Add FEAT_ETS.
Add FEAT_PMUv3p5.
Cleanups to armv7m_load_kernel.


Enrik Berkhan (1):
  hw/arm/bcm2835_property: Add support for 
RPI_FIRMWARE_FRAMEBUFFER_GET_NUM_DISPLAYS

Hao Wu (1):
  target/arm: Add cortex-a35

Peter Maydell (18):
  target/arm: Make cpregs 0, c0, c{3-15}, {0-7} correctly RAZ in v8
  target/arm: Sort KVM reads of AArch32 ID registers into encoding order
  target/arm: Implement ID_MMFR5
  target/arm: Implement ID_DFR1
  target/arm: Advertise FEAT_ETS for '-cpu max'
  target/arm: Add missing space in comment
  target/arm: Don't corrupt high half of PMOVSR when cycle counter overflows
  target/arm: Correct value returned by pmu_counter_mask()
  target/arm: Don't mishandle count when enabling or disabling PMU counters
  target/arm: Ignore PMCR.D when PMCR.LC is set
  target/arm: Honour MDCR_EL2.HPMD in Secure EL2
  target/arm: Detect overflow when calculating next PMU interrupt
  target/arm: Rename pmu_8_n feature test functions
  target/arm: Implement FEAT_PMUv3p5 cycle counter disable bits
  target/arm: Support 64-bit event counters for FEAT_PMUv3p5
  target/arm: Report FEAT_PMUv3p5 for TCG '-cpu max'
  target/arm: Remove useless TARGET_BIG_ENDIAN check in armv7m_load_kernel()
  target/arm: Make boards pass base address to armv7m_load_kernel()

 docs/system/arm/emulation.rst |   2 +
 docs/system/arm/virt.rst  |   1 +
 include/hw/arm/boot.h |   5 +-
 target/arm/cpu.h  |  39 --
 target/arm/internals.h|   5 +-
 hw/arm/armv7m.c   |  14 +--
 hw/arm/aspeed.c   |   1 +
 hw/arm/microbit.c |   2 +-
 hw/arm/mps2-tz.c  |   2 +-
 hw/arm/mps2.c |   2 +-
 hw/arm/msf2-som.c |   2 +-
 hw/arm/musca.c|   3 +-
 hw/arm/netduino2.c|   2 +-
 hw/arm/netduinoplus2.c|   2 +-
 hw/arm/stellaris.c|   2 +-
 hw/arm/stm32vldiscovery.c |   2 +-
 hw/arm/virt.c |   1 +
 hw/misc/bcm2835_property.c|   4 +
 target/arm/cpu64.c|  83 -
 target/arm/cpu_tcg.c  |   8 +-
 target/arm/helper.c   | 267 ++
 target/arm/kvm64.c|   8 +-
 22 files changed, 374 insertions(+), 83 deletions(-)



[PULL 03/20] target/arm: Make cpregs 0, c0, c{3-15}, {0-7} correctly RAZ in v8

2022-09-14 Thread Richard Henderson
From: Peter Maydell 

In the AArch32 ID register scheme, coprocessor registers with
encoding cp15, 0, c0, c{0-7}, {0-7} are all in the space covered by
what in v6 and v7 was called the "CPUID scheme", and are supposed to
RAZ if they're not allocated to a specific ID register.  For our
pre-v8 CPUs we get this right, because the regdefs in
id_pre_v8_midr_cp_reginfo[] cover these RAZ requirements.  However
for v8 we failed to put in the necessary patterns to cover this, so
we end up UNDEFing on everything we didn't have an ID register for.
This is a problem because in Armv8 some encodings in 0, c0, c3, {0-7}
are now being used for new ID registers, and guests might thus start
trying to read them.  (We already have one of these: ID_PFR2.)

For v8 CPUs, we already have regdefs for 0, c0, c{0-2}, {0-7} (that
is, the space is completely allocated with no reserved spaces).  Add
entries to v8_idregs[] covering 0, c0, c3, {0-7}:
 * c3, {0-2} is the reserved AArch32 space corresponding to the
   AArch64 MVFR[012]_EL1
 * c3, {3,5,6,7} are reserved RAZ for both AArch32 and AArch64
   (in fact some of these are given defined meanings in Armv8.6,
   but we don't implement them yet)
 * c3, 4 is ID_PFR2 (already defined)

We then programmatically add RAZ patterns for AArch32 for
0, c0, c{4..15}, {0-7}:
 * c4-c7 are unused, and not shared with AArch64 (these
   are the encodings corresponding to where the AArch64
   specific ID registers live in the system register space)
 * c8-c15 weren't required to RAZ in v6/v7, but v8 extends
   the AArch32 reserved-should-RAZ space to cover these;
   the equivalent area of the AArch64 sysreg space is not
   defined as must-RAZ

Note that the architecture allows some registers in this space
to return an UNKNOWN value; we always return 0.

Signed-off-by: Peter Maydell 
Reviewed-by: Richard Henderson 
Message-Id: <20220819110052.2942289-2-peter.mayd...@linaro.org>
Signed-off-by: Richard Henderson 
---
 target/arm/helper.c | 65 +
 1 file changed, 60 insertions(+), 5 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index d7bc467a2a..c171770b03 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -7345,11 +7345,16 @@ void register_cp_regs_for_features(ARMCPU *cpu)
 define_arm_cp_regs(cpu, not_v7_cp_reginfo);
 }
 if (arm_feature(env, ARM_FEATURE_V8)) {
-/* AArch64 ID registers, which all have impdef reset values.
+/*
+ * v8 ID registers, which all have impdef reset values.
  * Note that within the ID register ranges the unused slots
  * must all RAZ, not UNDEF; future architecture versions may
  * define new registers here.
+ * ID registers which are AArch64 views of the AArch32 ID registers
+ * which already existed in v6 and v7 are handled elsewhere,
+ * in v6_idregs[].
  */
+int i;
 ARMCPRegInfo v8_idregs[] = {
 /*
  * ID_AA64PFR0_EL1 is not a plain ARM_CP_CONST in system
@@ -7539,7 +7544,34 @@ void register_cp_regs_for_features(ARMCPU *cpu)
   .access = PL1_R, .type = ARM_CP_CONST,
   .accessfn = access_aa64_tid3,
   .resetvalue = cpu->isar.mvfr2 },
-{ .name = "MVFR3_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
+/*
+ * "0, c0, c3, {0,1,2}" are the encodings corresponding to
+ * AArch64 MVFR[012]_EL1. Define the STATE_AA32 encoding
+ * as RAZ, since it is in the "reserved for future ID
+ * registers, RAZ" part of the AArch32 encoding space.
+ */
+{ .name = "RES_0_C0_C3_0", .state = ARM_CP_STATE_AA32,
+  .cp = 15, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 0,
+  .access = PL1_R, .type = ARM_CP_CONST,
+  .accessfn = access_aa64_tid3,
+  .resetvalue = 0 },
+{ .name = "RES_0_C0_C3_1", .state = ARM_CP_STATE_AA32,
+  .cp = 15, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 1,
+  .access = PL1_R, .type = ARM_CP_CONST,
+  .accessfn = access_aa64_tid3,
+  .resetvalue = 0 },
+{ .name = "RES_0_C0_C3_2", .state = ARM_CP_STATE_AA32,
+  .cp = 15, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 2,
+  .access = PL1_R, .type = ARM_CP_CONST,
+  .accessfn = access_aa64_tid3,
+  .resetvalue = 0 },
+/*
+ * Other encodings in "0, c0, c3, ..." are STATE_BOTH because
+ * they're also RAZ for AArch64, and in v8 are gradually
+ * being filled with AArch64-view-of-AArch32-ID-register
+ * for new ID registers.
+ */
+{ .name = "RES_0_C0_C3_3", .state = ARM_CP_STATE_BOTH,
   .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 3,
   .access = PL1_R, .type = ARM_CP_CONST,
   .accessfn = access_aa64_tid3,
@@ -7549,17 +7581,17 @@ 

[PULL 17/20] target/arm: Support 64-bit event counters for FEAT_PMUv3p5

2022-09-14 Thread Richard Henderson
From: Peter Maydell 

With FEAT_PMUv3p5, the event counters are now 64 bit, rather than 32
bit.  (Previously, only the cycle counter could be 64 bit, and other
event counters were always 32 bits).  For any given event counter,
whether the overflow event is noted for overflow from bit 31 or from
bit 63 is controlled by a combination of PMCR.LP, MDCR_EL2.HLP and
MDCR_EL2.HPMN.

Implement the 64-bit event counter handling.  We choose to make our
counters always 64 bits, and mask out the top 32 bits on read or
write of PMXEVCNTR for CPUs which don't have FEAT_PMUv3p5.

(Note that the changes to pmenvcntr_op_start() and
pmenvcntr_op_finish() bring their logic closer into line with that of
pmccntr_op_start() and pmccntr_op_finish(), which already had to cope
with the overflow being either at 32 or 64 bits.)

Signed-off-by: Peter Maydell 
Reviewed-by: Richard Henderson 
Message-Id: <20220822132358.3524971-10-peter.mayd...@linaro.org>
Signed-off-by: Richard Henderson 
---
 target/arm/cpu.h   |  1 +
 target/arm/internals.h |  3 +-
 target/arm/helper.c| 62 --
 3 files changed, 57 insertions(+), 9 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 41e74df104..33cdbc0143 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1334,6 +1334,7 @@ FIELD(CPTR_EL3, TTA, 20, 1)
 FIELD(CPTR_EL3, TAM, 30, 1)
 FIELD(CPTR_EL3, TCPAC, 31, 1)
 
+#define MDCR_HLP  (1U << 26)  /* MDCR_EL2 */
 #define MDCR_SCCD (1U << 23)  /* MDCR_EL3 */
 #define MDCR_HCCD (1U << 23)  /* MDCR_EL2 */
 #define MDCR_EPMAD(1U << 21)
diff --git a/target/arm/internals.h b/target/arm/internals.h
index 83526166de..bf60cd5f84 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -1256,6 +1256,7 @@ enum MVEECIState {
 /* Definitions for the PMU registers */
 #define PMCRN_MASK  0xf800
 #define PMCRN_SHIFT 11
+#define PMCRLP  0x80
 #define PMCRLC  0x40
 #define PMCRDP  0x20
 #define PMCRX   0x10
@@ -1267,7 +1268,7 @@ enum MVEECIState {
  * Mask of PMCR bits writable by guest (not including WO bits like C, P,
  * which can be written as 1 to trigger behaviour but which stay RAZ).
  */
-#define PMCR_WRITABLE_MASK (PMCRLC | PMCRDP | PMCRX | PMCRD | PMCRE)
+#define PMCR_WRITABLE_MASK (PMCRLP | PMCRLC | PMCRDP | PMCRX | PMCRD | PMCRE)
 
 #define PMXEVTYPER_P  0x8000
 #define PMXEVTYPER_U  0x4000
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 0d1f23de09..1a57d2e1d6 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -1084,7 +1084,8 @@ static CPAccessResult pmreg_access_ccntr(CPUARMState *env,
  * We use these to decide whether we need to wrap a write to MDCR_EL2
  * or MDCR_EL3 in pmu_op_start()/pmu_op_finish() calls.
  */
-#define MDCR_EL2_PMU_ENABLE_BITS (MDCR_HPME | MDCR_HPMD | MDCR_HPMN | 
MDCR_HCCD)
+#define MDCR_EL2_PMU_ENABLE_BITS \
+(MDCR_HPME | MDCR_HPMD | MDCR_HPMN | MDCR_HCCD | MDCR_HLP)
 #define MDCR_EL3_PMU_ENABLE_BITS (MDCR_SPME | MDCR_SCCD)
 
 /* Returns true if the counter (pass 31 for PMCCNTR) should count events using
@@ -1193,6 +1194,32 @@ static bool pmccntr_clockdiv_enabled(CPUARMState *env)
 return (env->cp15.c9_pmcr & (PMCRD | PMCRLC)) == PMCRD;
 }
 
+static bool pmevcntr_is_64_bit(CPUARMState *env, int counter)
+{
+/* Return true if the specified event counter is configured to be 64 bit */
+
+/* This isn't intended to be used with the cycle counter */
+assert(counter < 31);
+
+if (!cpu_isar_feature(any_pmuv3p5, env_archcpu(env))) {
+return false;
+}
+
+if (arm_feature(env, ARM_FEATURE_EL2)) {
+/*
+ * MDCR_EL2.HLP still applies even when EL2 is disabled in the
+ * current security state, so we don't use arm_mdcr_el2_eff() here.
+ */
+bool hlp = env->cp15.mdcr_el2 & MDCR_HLP;
+int hpmn = env->cp15.mdcr_el2 & MDCR_HPMN;
+
+if (hpmn != 0 && counter >= hpmn) {
+return hlp;
+}
+}
+return env->cp15.c9_pmcr & PMCRLP;
+}
+
 /*
  * Ensure c15_ccnt is the guest-visible count so that operations such as
  * enabling/disabling the counter or filtering, modifying the count itself,
@@ -1269,9 +1296,11 @@ static void pmevcntr_op_start(CPUARMState *env, uint8_t 
counter)
 }
 
 if (pmu_counter_enabled(env, counter)) {
-uint32_t new_pmevcntr = count - env->cp15.c14_pmevcntr_delta[counter];
+uint64_t new_pmevcntr = count - env->cp15.c14_pmevcntr_delta[counter];
+uint64_t overflow_mask = pmevcntr_is_64_bit(env, counter) ?
+1ULL << 63 : 1ULL << 31;
 
-if (env->cp15.c14_pmevcntr[counter] & ~new_pmevcntr & INT32_MIN) {
+if (env->cp15.c14_pmevcntr[counter] & ~new_pmevcntr & overflow_mask) {
 env->cp15.c9_pmovsr |= (1 << counter);
 pmu_update_irq(env);
 }
@@ -1286,9 +1315,13 @@ static void pmevcntr_op_finish(CPUARMState *env, uint8_t 
counter)
 #ifndef CONFIG_USER_ONLY
 uint16_t event = env->cp15.c14_pmevtyp

[PULL 06/20] target/arm: Implement ID_DFR1

2022-09-14 Thread Richard Henderson
From: Peter Maydell 

In Armv8.6, a new AArch32 ID register ID_DFR1 is defined; implement
it. We don't have any CPUs with features that they need to advertise
here yet, but plumbing in the ID register gives it the right name
when debugging and will help in future when we do add a CPU that
has non-zero ID_DFR1 fields.

Signed-off-by: Peter Maydell 
Reviewed-by: Richard Henderson 
Message-Id: <20220819110052.2942289-5-peter.mayd...@linaro.org>
Signed-off-by: Richard Henderson 
---
 target/arm/cpu.h| 1 +
 target/arm/helper.c | 4 ++--
 target/arm/kvm64.c  | 2 ++
 3 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index fcc5927587..fa24ce9f96 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -983,6 +983,7 @@ struct ArchCPU {
 uint32_t mvfr1;
 uint32_t mvfr2;
 uint32_t id_dfr0;
+uint32_t id_dfr1;
 uint32_t dbgdidr;
 uint32_t dbgdevid;
 uint32_t dbgdevid1;
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 0737851925..7ff03f1a4b 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -7581,11 +7581,11 @@ void register_cp_regs_for_features(ARMCPU *cpu)
   .access = PL1_R, .type = ARM_CP_CONST,
   .accessfn = access_aa64_tid3,
   .resetvalue = cpu->isar.id_pfr2 },
-{ .name = "RES_0_C0_C3_5", .state = ARM_CP_STATE_BOTH,
+{ .name = "ID_DFR1", .state = ARM_CP_STATE_BOTH,
   .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 5,
   .access = PL1_R, .type = ARM_CP_CONST,
   .accessfn = access_aa64_tid3,
-  .resetvalue = 0 },
+  .resetvalue = cpu->isar.id_dfr1 },
 { .name = "ID_MMFR5", .state = ARM_CP_STATE_BOTH,
   .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 6,
   .access = PL1_R, .type = ARM_CP_CONST,
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
index 2d737c443e..1197253d12 100644
--- a/target/arm/kvm64.c
+++ b/target/arm/kvm64.c
@@ -643,6 +643,8 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
   ARM64_SYS_REG(3, 0, 0, 3, 2));
 err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_pfr2,
   ARM64_SYS_REG(3, 0, 0, 3, 4));
+err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_dfr1,
+  ARM64_SYS_REG(3, 0, 0, 3, 5));
 err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr5,
   ARM64_SYS_REG(3, 0, 0, 3, 6));
 
-- 
2.34.1




[PULL 11/20] target/arm: Don't mishandle count when enabling or disabling PMU counters

2022-09-14 Thread Richard Henderson
From: Peter Maydell 

The PMU cycle and event counter infrastructure design requires that
operations on the PMU register fields are wrapped in pmu_op_start()
and pmu_op_finish() calls (or their more specific pmmcntr and
pmevcntr equivalents).  This includes any changes to registers which
affect whether the counter should be enabled or disabled, but we
forgot to do this.

The effect of this bug is that in sequences like:
 * disable the cycle counter (PMCCNTR) using the PMCNTEN register
 * write a value such as 0xf000 to the PMCCNTR
 * restart the counter by writing to PMCNTEN
the value written to the cycle counter is corrupted, and it starts
counting from the wrong place. (Essentially, we fail to record that
the QEMU_CLOCK_VIRTUAL timestamp when the counter should be considered
to have started counting is the point when PMCNTEN is written to enable
the counter.)

Add the necessary bracketing calls, so that updates to the various
registers which affect whether the PMU is counting are handled
correctly.

Signed-off-by: Peter Maydell 
Reviewed-by: Richard Henderson 
Message-Id: <20220822132358.3524971-4-peter.mayd...@linaro.org>
Signed-off-by: Richard Henderson 
---
 target/arm/helper.c | 45 +
 1 file changed, 45 insertions(+)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index e4824e01b8..a348c7407d 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -1079,6 +1079,14 @@ static CPAccessResult pmreg_access_ccntr(CPUARMState 
*env,
 return pmreg_access(env, ri, isread);
 }
 
+/*
+ * Bits in MDCR_EL2 and MDCR_EL3 which pmu_counter_enabled() looks at.
+ * We use these to decide whether we need to wrap a write to MDCR_EL2
+ * or MDCR_EL3 in pmu_op_start()/pmu_op_finish() calls.
+ */
+#define MDCR_EL2_PMU_ENABLE_BITS (MDCR_HPME | MDCR_HPMD | MDCR_HPMN)
+#define MDCR_EL3_PMU_ENABLE_BITS (MDCR_SPME)
+
 /* Returns true if the counter (pass 31 for PMCCNTR) should count events using
  * the current EL, security state, and register configuration.
  */
@@ -1432,15 +1440,19 @@ static uint64_t pmccfiltr_read_a32(CPUARMState *env, 
const ARMCPRegInfo *ri)
 static void pmcntenset_write(CPUARMState *env, const ARMCPRegInfo *ri,
 uint64_t value)
 {
+pmu_op_start(env);
 value &= pmu_counter_mask(env);
 env->cp15.c9_pmcnten |= value;
+pmu_op_finish(env);
 }
 
 static void pmcntenclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
  uint64_t value)
 {
+pmu_op_start(env);
 value &= pmu_counter_mask(env);
 env->cp15.c9_pmcnten &= ~value;
+pmu_op_finish(env);
 }
 
 static void pmovsr_write(CPUARMState *env, const ARMCPRegInfo *ri,
@@ -4681,7 +4693,39 @@ static void sctlr_write(CPUARMState *env, const 
ARMCPRegInfo *ri,
 static void sdcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t value)
 {
+/*
+ * Some MDCR_EL3 bits affect whether PMU counters are running:
+ * if we are trying to change any of those then we must
+ * bracket this update with PMU start/finish calls.
+ */
+bool pmu_op = (env->cp15.mdcr_el3 ^ value) & MDCR_EL3_PMU_ENABLE_BITS;
+
+if (pmu_op) {
+pmu_op_start(env);
+}
 env->cp15.mdcr_el3 = value & SDCR_VALID_MASK;
+if (pmu_op) {
+pmu_op_finish(env);
+}
+}
+
+static void mdcr_el2_write(CPUARMState *env, const ARMCPRegInfo *ri,
+   uint64_t value)
+{
+/*
+ * Some MDCR_EL2 bits affect whether PMU counters are running:
+ * if we are trying to change any of those then we must
+ * bracket this update with PMU start/finish calls.
+ */
+bool pmu_op = (env->cp15.mdcr_el2 ^ value) & MDCR_EL2_PMU_ENABLE_BITS;
+
+if (pmu_op) {
+pmu_op_start(env);
+}
+env->cp15.mdcr_el2 = value;
+if (pmu_op) {
+pmu_op_finish(env);
+}
 }
 
 static const ARMCPRegInfo v8_cp_reginfo[] = {
@@ -7724,6 +7768,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
 ARMCPRegInfo mdcr_el2 = {
 .name = "MDCR_EL2", .state = ARM_CP_STATE_BOTH,
 .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 1,
+.writefn = mdcr_el2_write,
 .access = PL2_RW, .resetvalue = pmu_num_counters(env),
 .fieldoffset = offsetof(CPUARMState, cp15.mdcr_el2),
 };
-- 
2.34.1




[PULL 02/20] hw/arm/bcm2835_property: Add support for RPI_FIRMWARE_FRAMEBUFFER_GET_NUM_DISPLAYS

2022-09-14 Thread Richard Henderson
From: Enrik Berkhan 

In more recent Raspbian OS Linux kernels, the fb driver gives up
immediately if RPI_FIRMWARE_FRAMEBUFFER_GET_NUM_DISPLAYS fails or no
displays are reported.

This change simply always reports one display. It makes bcm2835_fb work
again with these more recent kernels.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Enrik Berkhan 
Message-Id: <20220812143519.59134-1-enrik.berk...@inka.de>
Signed-off-by: Richard Henderson 
---
 hw/misc/bcm2835_property.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/hw/misc/bcm2835_property.c b/hw/misc/bcm2835_property.c
index e94e951057..890ae7bae5 100644
--- a/hw/misc/bcm2835_property.c
+++ b/hw/misc/bcm2835_property.c
@@ -270,6 +270,10 @@ static void 
bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
 stl_le_phys(&s->dma_as, value + 12, 0);
 resplen = 4;
 break;
+case 0x00040013: /* Get number of displays */
+stl_le_phys(&s->dma_as, value + 12, 1);
+resplen = 4;
+break;
 
 case 0x00060001: /* Get DMA channels */
 /* channels 2-5 */
-- 
2.34.1




[PULL 13/20] target/arm: Honour MDCR_EL2.HPMD in Secure EL2

2022-09-14 Thread Richard Henderson
From: Peter Maydell 

The logic in pmu_counter_enabled() for handling the 'prohibit event
counting' bits MDCR_EL2.HPMD and MDCR_EL3.SPME is written in a way
that assumes that EL2 is never Secure.  This used to be true, but the
architecture now permits Secure EL2, and QEMU can emulate this.

Refactor the prohibit logic so that we effectively OR together
the various prohibit bits when they apply, rather than trying to
construct an if-else ladder where any particular state of the CPU
ends up in exactly one branch of the ladder.

This fixes the Secure EL2 case and also is a better structure for
adding the PMUv8.5 bits MDCR_EL2.HCCD and MDCR_EL3.SCCD.

Signed-off-by: Peter Maydell 
Reviewed-by: Richard Henderson 
Message-Id: <20220822132358.3524971-6-peter.mayd...@linaro.org>
Signed-off-by: Richard Henderson 
---
 target/arm/helper.c | 17 +++--
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index f1b20de16d..b792694df0 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -1094,7 +1094,7 @@ static bool pmu_counter_enabled(CPUARMState *env, uint8_t 
counter)
 {
 uint64_t filter;
 bool e, p, u, nsk, nsu, nsh, m;
-bool enabled, prohibited, filtered;
+bool enabled, prohibited = false, filtered;
 bool secure = arm_is_secure(env);
 int el = arm_current_el(env);
 uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);
@@ -1112,15 +1112,12 @@ static bool pmu_counter_enabled(CPUARMState *env, 
uint8_t counter)
 }
 enabled = e && (env->cp15.c9_pmcnten & (1 << counter));
 
-if (!secure) {
-if (el == 2 && (counter < hpmn || counter == 31)) {
-prohibited = mdcr_el2 & MDCR_HPMD;
-} else {
-prohibited = false;
-}
-} else {
-prohibited = arm_feature(env, ARM_FEATURE_EL3) &&
-   !(env->cp15.mdcr_el3 & MDCR_SPME);
+/* Is event counting prohibited? */
+if (el == 2 && (counter < hpmn || counter == 31)) {
+prohibited = mdcr_el2 & MDCR_HPMD;
+}
+if (secure) {
+prohibited = prohibited || !(env->cp15.mdcr_el3 & MDCR_SPME);
 }
 
 if (prohibited && counter == 31) {
-- 
2.34.1




[PULL 09/20] target/arm: Don't corrupt high half of PMOVSR when cycle counter overflows

2022-09-14 Thread Richard Henderson
From: Peter Maydell 

When the cycle counter overflows, we are intended to set bit 31 in PMOVSR
to indicate this. However a missing ULL suffix means that we end up
setting all of bits 63-31. Fix the bug.

Signed-off-by: Peter Maydell 
Reviewed-by: Richard Henderson 
Message-Id: <20220822132358.3524971-2-peter.mayd...@linaro.org>
Signed-off-by: Richard Henderson 
---
 target/arm/helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 7ff03f1a4b..e4824e01b8 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -1186,7 +1186,7 @@ static void pmccntr_op_start(CPUARMState *env)
 uint64_t overflow_mask = env->cp15.c9_pmcr & PMCRLC ? \
  1ull << 63 : 1ull << 31;
 if (env->cp15.c15_ccnt & ~new_pmccntr & overflow_mask) {
-env->cp15.c9_pmovsr |= (1 << 31);
+env->cp15.c9_pmovsr |= (1ULL << 31);
 pmu_update_irq(env);
 }
 
-- 
2.34.1




[PULL 05/20] target/arm: Implement ID_MMFR5

2022-09-14 Thread Richard Henderson
From: Peter Maydell 

In Armv8.6 a new AArch32 ID register ID_MMFR5 is defined.
Implement this; we want to be able to use it to report to
the guest that we implement FEAT_ETS.

Signed-off-by: Peter Maydell 
Reviewed-by: Richard Henderson 
Message-Id: <20220819110052.2942289-4-peter.mayd...@linaro.org>
Signed-off-by: Richard Henderson 
---
 target/arm/cpu.h| 1 +
 target/arm/helper.c | 4 ++--
 target/arm/kvm64.c  | 2 ++
 3 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 5168e3d837..fcc5927587 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -975,6 +975,7 @@ struct ArchCPU {
 uint32_t id_mmfr2;
 uint32_t id_mmfr3;
 uint32_t id_mmfr4;
+uint32_t id_mmfr5;
 uint32_t id_pfr0;
 uint32_t id_pfr1;
 uint32_t id_pfr2;
diff --git a/target/arm/helper.c b/target/arm/helper.c
index c171770b03..0737851925 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -7586,11 +7586,11 @@ void register_cp_regs_for_features(ARMCPU *cpu)
   .access = PL1_R, .type = ARM_CP_CONST,
   .accessfn = access_aa64_tid3,
   .resetvalue = 0 },
-{ .name = "RES_0_C0_C3_6", .state = ARM_CP_STATE_BOTH,
+{ .name = "ID_MMFR5", .state = ARM_CP_STATE_BOTH,
   .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 6,
   .access = PL1_R, .type = ARM_CP_CONST,
   .accessfn = access_aa64_tid3,
-  .resetvalue = 0 },
+  .resetvalue = cpu->isar.id_mmfr5 },
 { .name = "RES_0_C0_C3_7", .state = ARM_CP_STATE_BOTH,
   .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 7,
   .access = PL1_R, .type = ARM_CP_CONST,
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
index 84c4c85f40..2d737c443e 100644
--- a/target/arm/kvm64.c
+++ b/target/arm/kvm64.c
@@ -643,6 +643,8 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
   ARM64_SYS_REG(3, 0, 0, 3, 2));
 err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_pfr2,
   ARM64_SYS_REG(3, 0, 0, 3, 4));
+err |= read_sys_reg32(fdarray[2], &ahcf->isar.id_mmfr5,
+  ARM64_SYS_REG(3, 0, 0, 3, 6));
 
 /*
  * DBGDIDR is a bit complicated because the kernel doesn't
-- 
2.34.1




[PULL 07/20] target/arm: Advertise FEAT_ETS for '-cpu max'

2022-09-14 Thread Richard Henderson
From: Peter Maydell 

The architectural feature FEAT_ETS (Enhanced Translation
Synchronization) is a set of tightened guarantees about memory
ordering involving translation table walks:

 * if memory access RW1 is ordered-before memory access RW2 then it
   is also ordered-before any translation table walk generated by RW2
   that generates a translation fault, address size fault or access
   fault

 * TLB maintenance on non-exec-permission translations is guaranteed
   complete after a DSB (ie it does not need the context
   synchronization event that you have to have if you don’t have
   FEAT_ETS)

For QEMU’s implementation we don’t reorder translation table walk
accesses, and we guarantee to finish the TLB maintenance as soon as
the TLB op is done (the tlb_flush functions will complete at the end
of the TLB, and TLB ops always end the TB because they’re sysreg
writes).

So we’re already compliant and all we need to do is say so in the ID
registers for the 'max' CPU.

Signed-off-by: Peter Maydell 
Reviewed-by: Richard Henderson 
Message-Id: <20220819110052.2942289-6-peter.mayd...@linaro.org>
Signed-off-by: Richard Henderson 
---
 docs/system/arm/emulation.rst | 1 +
 target/arm/cpu64.c| 1 +
 target/arm/cpu_tcg.c  | 4 
 3 files changed, 6 insertions(+)

diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
index 8e494c8bea..811358fd0a 100644
--- a/docs/system/arm/emulation.rst
+++ b/docs/system/arm/emulation.rst
@@ -24,6 +24,7 @@ the following architecture extensions:
 - FEAT_Debugv8p4 (Debug changes for v8.4)
 - FEAT_DotProd (Advanced SIMD dot product instructions)
 - FEAT_DoubleFault (Double Fault Extension)
+- FEAT_ETS (Enhanced Translation Synchronization)
 - FEAT_FCMA (Floating-point complex number instructions)
 - FEAT_FHM (Floating-point half-precision multiplication instructions)
 - FEAT_FP16 (Half-precision floating-point data processing)
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 9d1ea32057..3ac5e197a7 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -1122,6 +1122,7 @@ static void aarch64_max_initfn(Object *obj)
 t = FIELD_DP64(t, ID_AA64MMFR1, LO, 1);   /* FEAT_LOR */
 t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 2);  /* FEAT_PAN2 */
 t = FIELD_DP64(t, ID_AA64MMFR1, XNX, 1);  /* FEAT_XNX */
+t = FIELD_DP64(t, ID_AA64MMFR1, ETS, 1);  /* FEAT_ETS */
 t = FIELD_DP64(t, ID_AA64MMFR1, HCX, 1);  /* FEAT_HCX */
 cpu->isar.id_aa64mmfr1 = t;
 
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
index 3099b38e32..f63f8cdd95 100644
--- a/target/arm/cpu_tcg.c
+++ b/target/arm/cpu_tcg.c
@@ -67,6 +67,10 @@ void aa32_max_features(ARMCPU *cpu)
 t = FIELD_DP32(t, ID_MMFR4, XNX, 1);  /* FEAT_XNX*/
 cpu->isar.id_mmfr4 = t;
 
+t = cpu->isar.id_mmfr5;
+t = FIELD_DP32(t, ID_MMFR5, ETS, 1);  /* FEAT_ETS */
+cpu->isar.id_mmfr5 = t;
+
 t = cpu->isar.id_pfr0;
 t = FIELD_DP32(t, ID_PFR0, CSV2, 2);  /* FEAT_CVS2 */
 t = FIELD_DP32(t, ID_PFR0, DIT, 1);   /* FEAT_DIT */
-- 
2.34.1




[PULL 08/20] target/arm: Add missing space in comment

2022-09-14 Thread Richard Henderson
From: Peter Maydell 

Fix a missing space before a comment terminator.

Signed-off-by: Peter Maydell 
Reviewed-by: Richard Henderson 
Message-Id: <20220819110052.2942289-7-peter.mayd...@linaro.org>
Signed-off-by: Richard Henderson 
---
 target/arm/cpu_tcg.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
index f63f8cdd95..b714c61d94 100644
--- a/target/arm/cpu_tcg.c
+++ b/target/arm/cpu_tcg.c
@@ -64,7 +64,7 @@ void aa32_max_features(ARMCPU *cpu)
 t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* FEAT_AA32HPD */
 t = FIELD_DP32(t, ID_MMFR4, AC2, 1);  /* ACTLR2, HACTLR2 */
 t = FIELD_DP32(t, ID_MMFR4, CNP, 1);  /* FEAT_TTCNP */
-t = FIELD_DP32(t, ID_MMFR4, XNX, 1);  /* FEAT_XNX*/
+t = FIELD_DP32(t, ID_MMFR4, XNX, 1);  /* FEAT_XNX */
 cpu->isar.id_mmfr4 = t;
 
 t = cpu->isar.id_mmfr5;
-- 
2.34.1




Re: [PATCH v3 00/20] ppc4xx_sdram QOMify and clean ups

2022-09-14 Thread BALATON Zoltan

On Wed, 14 Sep 2022, Cédric Le Goater wrote:

On 9/13/22 21:52, BALATON Zoltan wrote:

This is the end of the QOMify series started by Cédric. This series
handles the SDRAM controller models to clean them up, QOMify and unify
them and at least partially clean up the mess that has accumulated
around these in the past. This includes the not yet merged patches
from the last series and new ones that change the DDR2 version used by
sam460ex.



I made comments on the first ~10 patches. Let's try to agree on these
first. We will see the remaining ones in a second patchset.


Patch 10 does not make much sense without 11 and the final unificatoin of 
the two controllers is the real goal here so please try to review further 
patches too.


Regards,
BALATON Zoltan


Thanks,

C.




v3: Fix patches that got squashed during rebase
v2: address some review comments and try to avoid compile problem with
gcc 12.2 (untested)

BALATON Zoltan (20):
   ppc440_bamboo: Remove unnecessary memsets
   ppc4xx: Introduce Ppc4xxSdramBank struct
   ppc4xx_sdram: Get rid of the init RAM hack
   ppc4xx: Use Ppc4xxSdramBank in ppc4xx_sdram_banks()
   ppc440_bamboo: Add missing 4 MiB valid memory size
   ppc4xx_sdram: Move size check to ppc4xx_sdram_init()
   ppc4xx_sdram: QOM'ify
   ppc4xx_sdram: Drop extra zeros for readability
   ppc440_sdram: Split off map/unmap of sdram banks for later reuse
   ppc440_sdram: Implement enable bit in the DDR2 SDRAM
   ppc440_sdram: Get rid of the init RAM hack
   ppc440_sdram: Rename local variable for readibility
   ppc4xx_sdram: Rename functions to prevent name clashes
   ppc440_sdram: Move RAM size check to ppc440_sdram_init
   ppc440_sdram: QOM'ify
   ppc4xx_sdram: Move ppc4xx DDR and DDR2 SDRAM controller models
 together
   ppc4xx_sdram: Use hwaddr for memory bank size
   ppc4xx_sdram: Rename local state variable for brevity
   ppc4xx_sdram: Generalise bank setup
   ppc4xx_sdram: Convert DDR SDRAM controller to new bank handling

  hw/ppc/meson.build  |   3 +-
  hw/ppc/ppc405.h |   8 +-
  hw/ppc/ppc405_boards.c  |  22 +-
  hw/ppc/ppc405_uc.c  |  33 +-
  hw/ppc/ppc440.h |   4 -
  hw/ppc/ppc440_bamboo.c  |  29 +-
  hw/ppc/ppc440_uc.c  | 267 +--
  hw/ppc/ppc4xx_devs.c| 413 ---
  hw/ppc/ppc4xx_sdram.c   | 723 
  hw/ppc/sam460ex.c   |  48 +--
  hw/ppc/trace-events |   1 +
  include/hw/ppc/ppc4xx.h |  66 +++-
  12 files changed, 847 insertions(+), 770 deletions(-)
  create mode 100644 hw/ppc/ppc4xx_sdram.c






[PULL 18/20] target/arm: Report FEAT_PMUv3p5 for TCG '-cpu max'

2022-09-14 Thread Richard Henderson
From: Peter Maydell 

Update the ID registers for TCG's '-cpu max' to report a FEAT_PMUv3p5
compliant PMU.

Signed-off-by: Peter Maydell 
Reviewed-by: Richard Henderson 
Message-Id: <20220822132358.3524971-11-peter.mayd...@linaro.org>
Signed-off-by: Richard Henderson 
---
 docs/system/arm/emulation.rst | 1 +
 target/arm/cpu64.c| 2 +-
 target/arm/cpu_tcg.c  | 2 +-
 3 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
index 811358fd0a..be7bbffe59 100644
--- a/docs/system/arm/emulation.rst
+++ b/docs/system/arm/emulation.rst
@@ -53,6 +53,7 @@ the following architecture extensions:
 - FEAT_PMULL (PMULL, PMULL2 instructions)
 - FEAT_PMUv3p1 (PMU Extensions v3.1)
 - FEAT_PMUv3p4 (PMU Extensions v3.4)
+- FEAT_PMUv3p5 (PMU Extensions v3.5)
 - FEAT_RAS (Reliability, availability, and serviceability)
 - FEAT_RASv1p1 (RAS Extension v1.1)
 - FEAT_RDM (Advanced SIMD rounding double multiply accumulate instructions)
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 3ac5e197a7..e6314e86d2 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -1152,7 +1152,7 @@ static void aarch64_max_initfn(Object *obj)
 
 t = cpu->isar.id_aa64dfr0;
 t = FIELD_DP64(t, ID_AA64DFR0, DEBUGVER, 9);  /* FEAT_Debugv8p4 */
-t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 5);/* FEAT_PMUv3p4 */
+t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 6);/* FEAT_PMUv3p5 */
 cpu->isar.id_aa64dfr0 = t;
 
 t = cpu->isar.id_aa64smfr0;
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
index b714c61d94..98b5ba2160 100644
--- a/target/arm/cpu_tcg.c
+++ b/target/arm/cpu_tcg.c
@@ -85,7 +85,7 @@ void aa32_max_features(ARMCPU *cpu)
 t = cpu->isar.id_dfr0;
 t = FIELD_DP32(t, ID_DFR0, COPDBG, 9);/* FEAT_Debugv8p4 */
 t = FIELD_DP32(t, ID_DFR0, COPSDBG, 9);   /* FEAT_Debugv8p4 */
-t = FIELD_DP32(t, ID_DFR0, PERFMON, 5);   /* FEAT_PMUv3p4 */
+t = FIELD_DP32(t, ID_DFR0, PERFMON, 6);   /* FEAT_PMUv3p5 */
 cpu->isar.id_dfr0 = t;
 }
 
-- 
2.34.1




[PULL 12/20] target/arm: Ignore PMCR.D when PMCR.LC is set

2022-09-14 Thread Richard Henderson
From: Peter Maydell 

The architecture requires that if PMCR.LC is set (for a 64-bit cycle
counter) then PMCR.D (which enables the clock divider so the counter
ticks every 64 cycles rather than every cycle) should be ignored.  We
were always honouring PMCR.D; fix the bug so we correctly ignore it
in this situation.

Signed-off-by: Peter Maydell 
Reviewed-by: Richard Henderson 
Message-Id: <20220822132358.3524971-5-peter.mayd...@linaro.org>
Signed-off-by: Richard Henderson 
---
 target/arm/helper.c | 17 +
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index a348c7407d..f1b20de16d 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -1172,6 +1172,17 @@ static void pmu_update_irq(CPUARMState *env)
 (env->cp15.c9_pminten & env->cp15.c9_pmovsr));
 }
 
+static bool pmccntr_clockdiv_enabled(CPUARMState *env)
+{
+/*
+ * Return true if the clock divider is enabled and the cycle counter
+ * is supposed to tick only once every 64 clock cycles. This is
+ * controlled by PMCR.D, but if PMCR.LC is set to enable the long
+ * (64-bit) cycle counter PMCR.D has no effect.
+ */
+return (env->cp15.c9_pmcr & (PMCRD | PMCRLC)) == PMCRD;
+}
+
 /*
  * Ensure c15_ccnt is the guest-visible count so that operations such as
  * enabling/disabling the counter or filtering, modifying the count itself,
@@ -1184,8 +1195,7 @@ static void pmccntr_op_start(CPUARMState *env)
 
 if (pmu_counter_enabled(env, 31)) {
 uint64_t eff_cycles = cycles;
-if (env->cp15.c9_pmcr & PMCRD) {
-/* Increment once every 64 processor clock cycles */
+if (pmccntr_clockdiv_enabled(env)) {
 eff_cycles /= 64;
 }
 
@@ -1228,8 +1238,7 @@ static void pmccntr_op_finish(CPUARMState *env)
 #endif
 
 uint64_t prev_cycles = env->cp15.c15_ccnt_delta;
-if (env->cp15.c9_pmcr & PMCRD) {
-/* Increment once every 64 processor clock cycles */
+if (pmccntr_clockdiv_enabled(env)) {
 prev_cycles /= 64;
 }
 env->cp15.c15_ccnt_delta = prev_cycles - env->cp15.c15_ccnt;
-- 
2.34.1




[PULL 19/20] target/arm: Remove useless TARGET_BIG_ENDIAN check in armv7m_load_kernel()

2022-09-14 Thread Richard Henderson
From: Peter Maydell 

Arm system emulation targets always have TARGET_BIG_ENDIAN clear, so
there is no need to have handling in armv7m_load_kernel() for the
case when it is defined.  Remove the unnecessary code.

Side notes:
 * our M-profile implementation is always little-endian (that is, it
   makes the IMPDEF choice that the read-only AIRCR.ENDIANNESS is 0)
 * if we did want to handle big-endian ELF files here we should do it
   the way that hw/arm/boot.c:arm_load_elf() does, by looking at the
   ELF header to see what endianness the file itself is

Signed-off-by: Peter Maydell 
Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20220823160417.3858216-2-peter.mayd...@linaro.org>
Signed-off-by: Richard Henderson 
---
 hw/arm/armv7m.c | 9 +
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
index 990861ee5e..fa4c2c735d 100644
--- a/hw/arm/armv7m.c
+++ b/hw/arm/armv7m.c
@@ -572,17 +572,10 @@ void armv7m_load_kernel(ARMCPU *cpu, const char 
*kernel_filename, int mem_size)
 {
 ssize_t image_size;
 uint64_t entry;
-int big_endian;
 AddressSpace *as;
 int asidx;
 CPUState *cs = CPU(cpu);
 
-#if TARGET_BIG_ENDIAN
-big_endian = 1;
-#else
-big_endian = 0;
-#endif
-
 if (arm_feature(&cpu->env, ARM_FEATURE_EL3)) {
 asidx = ARMASIdx_S;
 } else {
@@ -593,7 +586,7 @@ void armv7m_load_kernel(ARMCPU *cpu, const char 
*kernel_filename, int mem_size)
 if (kernel_filename) {
 image_size = load_elf_as(kernel_filename, NULL, NULL, NULL,
  &entry, NULL, NULL,
- NULL, big_endian, EM_ARM, 1, 0, as);
+ NULL, 0, EM_ARM, 1, 0, as);
 if (image_size < 0) {
 image_size = load_image_targphys_as(kernel_filename, 0,
 mem_size, as);
-- 
2.34.1




[PULL 14/20] target/arm: Detect overflow when calculating next PMU interrupt

2022-09-14 Thread Richard Henderson
From: Peter Maydell 

In pmccntr_op_finish() and pmevcntr_op_finish() we calculate the next
point at which we will get an overflow and need to fire the PMU
interrupt or set the overflow flag.  We do this by calculating the
number of nanoseconds to the overflow event and then adding it to
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL).  However, we don't check
whether that signed addition overflows, which can happen if the next
PMU interrupt would happen massively far in the future (250 years or
more).

Since QEMU assumes that "when the QEMU_CLOCK_VIRTUAL rolls over" is
"never", the sensible behaviour in this situation is simply to not
try to set the timer if it would be beyond that point.  Detect the
overflow, and skip setting the timer in that case.

Signed-off-by: Peter Maydell 
Reviewed-by: Richard Henderson 
Message-Id: <20220822132358.3524971-7-peter.mayd...@linaro.org>
Signed-off-by: Richard Henderson 
---
 target/arm/helper.c | 22 ++
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index b792694df0..11a7a57710 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -1227,10 +1227,13 @@ static void pmccntr_op_finish(CPUARMState *env)
 int64_t overflow_in = cycles_ns_per(remaining_cycles);
 
 if (overflow_in > 0) {
-int64_t overflow_at = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
-overflow_in;
-ARMCPU *cpu = env_archcpu(env);
-timer_mod_anticipate_ns(cpu->pmu_timer, overflow_at);
+int64_t overflow_at;
+
+if (!sadd64_overflow(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
+ overflow_in, &overflow_at)) {
+ARMCPU *cpu = env_archcpu(env);
+timer_mod_anticipate_ns(cpu->pmu_timer, overflow_at);
+}
 }
 #endif
 
@@ -1275,10 +1278,13 @@ static void pmevcntr_op_finish(CPUARMState *env, 
uint8_t counter)
 int64_t overflow_in = pm_events[event_idx].ns_per_count(delta);
 
 if (overflow_in > 0) {
-int64_t overflow_at = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
-overflow_in;
-ARMCPU *cpu = env_archcpu(env);
-timer_mod_anticipate_ns(cpu->pmu_timer, overflow_at);
+int64_t overflow_at;
+
+if (!sadd64_overflow(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
+ overflow_in, &overflow_at)) {
+ARMCPU *cpu = env_archcpu(env);
+timer_mod_anticipate_ns(cpu->pmu_timer, overflow_at);
+}
 }
 #endif
 
-- 
2.34.1




[PATCH] target/arm: Do alignment check when translation disabled

2022-09-14 Thread Richard Henderson
If translation is disabled, the default memory type is Device,
which requires alignment checking.  Document, but defer, the
more general case of per-page alignment checking.

Reported-by: Idan Horowitz 
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1204
Signed-off-by: Richard Henderson 
---
 target/arm/helper.c | 38 --
 1 file changed, 36 insertions(+), 2 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index d7bc467a2a..79609443aa 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -10713,6 +10713,39 @@ ARMMMUIdx arm_mmu_idx(CPUARMState *env)
 return arm_mmu_idx_el(env, arm_current_el(env));
 }
 
+/*
+ * Return true if memory alignment should be enforced.
+ */
+static bool aprofile_require_alignment(CPUARMState *env, int el, uint64_t 
sctlr)
+{
+/* Check the alignment enable bit. */
+if (sctlr & SCTLR_A) {
+return true;
+}
+
+/*
+ * If translation is disabled, then the default memory type
+ * may be Device(-nGnRnE) instead of Normal, which requires that
+ * alignment be enforced.
+ *
+ * TODO: The more general case is translation enabled, with a per-page
+ * check of the memory type as assigned via MAIR_ELx and the PTE.
+ * We could arrange for a bit in MemTxAttrs to enforce alignment
+ * via forced use of the softmmu slow path.  Given that such pages
+ * are intended for MMIO, where the slow path is required anyhow,
+ * this should not result in extra overhead.
+ */
+if (sctlr & SCTLR_M) {
+/* Translation enabled: memory type in PTE via MAIR_ELx. */
+return false;
+}
+if (el < 2 && (arm_hcr_el2_eff(env) & (HCR_DC | HCR_VM))) {
+/* Stage 2 translation enabled: memory type in PTE. */
+return false;
+}
+return true;
+}
+
 static CPUARMTBFlags rebuild_hflags_common(CPUARMState *env, int fp_el,
ARMMMUIdx mmu_idx,
CPUARMTBFlags flags)
@@ -10777,8 +10810,9 @@ static CPUARMTBFlags rebuild_hflags_a32(CPUARMState 
*env, int fp_el,
 {
 CPUARMTBFlags flags = {};
 int el = arm_current_el(env);
+uint64_t sctlr = arm_sctlr(env, el);
 
-if (arm_sctlr(env, el) & SCTLR_A) {
+if (aprofile_require_alignment(env, el, sctlr)) {
 DP_TBFLAG_ANY(flags, ALIGN_MEM, 1);
 }
 
@@ -10871,7 +10905,7 @@ static CPUARMTBFlags rebuild_hflags_a64(CPUARMState 
*env, int el, int fp_el,
 
 sctlr = regime_sctlr(env, stage1);
 
-if (sctlr & SCTLR_A) {
+if (aprofile_require_alignment(env, el, sctlr)) {
 DP_TBFLAG_ANY(flags, ALIGN_MEM, 1);
 }
 
-- 
2.34.1




[PATCH v2 3/4] scripts/ci/setup: spice-server only on x86 aarch64

2022-09-14 Thread Lucas Mateus Castro(alqotel)
From: "Lucas Mateus Castro (alqotel)" 

Changed build-environment.yml to only install spice-server on x86_64 and
aarch64 as this package is only available on those architectures.

Signed-off-by: Lucas Mateus Castro (alqotel) 
---
 scripts/ci/setup/build-environment.yml | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/scripts/ci/setup/build-environment.yml 
b/scripts/ci/setup/build-environment.yml
index 7535228685..43cf8c759f 100644
--- a/scripts/ci/setup/build-environment.yml
+++ b/scripts/ci/setup/build-environment.yml
@@ -160,7 +160,6 @@
   - python36
   - rdma-core-devel
   - spice-glib-devel
-  - spice-server
   - systemtap-sdt-devel
   - tar
   - zlib-devel
@@ -168,3 +167,14 @@
   when:
 - ansible_facts['distribution_file_variety'] == 'RedHat'
 - ansible_facts['distribution_version'] == '8'
+
+- name: Install packages only available on x86 and aarch64
+  dnf:
+# Spice server not available in ppc64le
+name:
+  - spice-server
+state: present
+  when:
+- ansible_facts['distribution_file_variety'] == 'RedHat'
+- ansible_facts['distribution_version'] == '8'
+- ansible_facts['architecture'] == 'aarch64' or 
ansible_facts['architecture'] == 'x86_64'
-- 
2.31.1




[PULL 15/20] target/arm: Rename pmu_8_n feature test functions

2022-09-14 Thread Richard Henderson
From: Peter Maydell 

Our feature test functions that check the PMU version are named
isar_feature_{aa32,aa64,any}_pmu_8_{1,4}.  This doesn't match the
current Arm ARM official feature names, which are FEAT_PMUv3p1 and
FEAT_PMUv3p4.  Rename these functions to _pmuv3p1 and _pmuv3p4.

This commit was created with:
  sed -i -e 's/pmu_8_/pmuv3p/g' target/arm/*.[ch]

Signed-off-by: Peter Maydell 
Reviewed-by: Richard Henderson 
Message-Id: <20220822132358.3524971-8-peter.mayd...@linaro.org>
Signed-off-by: Richard Henderson 
---
 target/arm/cpu.h| 16 
 target/arm/helper.c | 18 +-
 2 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index fa24ce9f96..d86e51992a 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -3712,14 +3712,14 @@ static inline bool isar_feature_aa32_ats1e1(const 
ARMISARegisters *id)
 return FIELD_EX32(id->id_mmfr3, ID_MMFR3, PAN) >= 2;
 }
 
-static inline bool isar_feature_aa32_pmu_8_1(const ARMISARegisters *id)
+static inline bool isar_feature_aa32_pmuv3p1(const ARMISARegisters *id)
 {
 /* 0xf means "non-standard IMPDEF PMU" */
 return FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) >= 4 &&
 FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) != 0xf;
 }
 
-static inline bool isar_feature_aa32_pmu_8_4(const ARMISARegisters *id)
+static inline bool isar_feature_aa32_pmuv3p4(const ARMISARegisters *id)
 {
 /* 0xf means "non-standard IMPDEF PMU" */
 return FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) >= 5 &&
@@ -4038,13 +4038,13 @@ static inline bool isar_feature_aa64_sme(const 
ARMISARegisters *id)
 return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, SME) != 0;
 }
 
-static inline bool isar_feature_aa64_pmu_8_1(const ARMISARegisters *id)
+static inline bool isar_feature_aa64_pmuv3p1(const ARMISARegisters *id)
 {
 return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 4 &&
 FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
 }
 
-static inline bool isar_feature_aa64_pmu_8_4(const ARMISARegisters *id)
+static inline bool isar_feature_aa64_pmuv3p4(const ARMISARegisters *id)
 {
 return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 5 &&
 FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
@@ -4213,14 +4213,14 @@ static inline bool isar_feature_any_predinv(const 
ARMISARegisters *id)
 return isar_feature_aa64_predinv(id) || isar_feature_aa32_predinv(id);
 }
 
-static inline bool isar_feature_any_pmu_8_1(const ARMISARegisters *id)
+static inline bool isar_feature_any_pmuv3p1(const ARMISARegisters *id)
 {
-return isar_feature_aa64_pmu_8_1(id) || isar_feature_aa32_pmu_8_1(id);
+return isar_feature_aa64_pmuv3p1(id) || isar_feature_aa32_pmuv3p1(id);
 }
 
-static inline bool isar_feature_any_pmu_8_4(const ARMISARegisters *id)
+static inline bool isar_feature_any_pmuv3p4(const ARMISARegisters *id)
 {
-return isar_feature_aa64_pmu_8_4(id) || isar_feature_aa32_pmu_8_4(id);
+return isar_feature_aa64_pmuv3p4(id) || isar_feature_aa32_pmuv3p4(id);
 }
 
 static inline bool isar_feature_any_ccidx(const ARMISARegisters *id)
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 11a7a57710..987ac19fe8 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -879,16 +879,16 @@ static int64_t instructions_ns_per(uint64_t icount)
 }
 #endif
 
-static bool pmu_8_1_events_supported(CPUARMState *env)
+static bool pmuv3p1_events_supported(CPUARMState *env)
 {
 /* For events which are supported in any v8.1 PMU */
-return cpu_isar_feature(any_pmu_8_1, env_archcpu(env));
+return cpu_isar_feature(any_pmuv3p1, env_archcpu(env));
 }
 
-static bool pmu_8_4_events_supported(CPUARMState *env)
+static bool pmuv3p4_events_supported(CPUARMState *env)
 {
 /* For events which are supported in any v8.1 PMU */
-return cpu_isar_feature(any_pmu_8_4, env_archcpu(env));
+return cpu_isar_feature(any_pmuv3p4, env_archcpu(env));
 }
 
 static uint64_t zero_event_get_count(CPUARMState *env)
@@ -922,17 +922,17 @@ static const pm_event pm_events[] = {
 },
 #endif
 { .number = 0x023, /* STALL_FRONTEND */
-  .supported = pmu_8_1_events_supported,
+  .supported = pmuv3p1_events_supported,
   .get_count = zero_event_get_count,
   .ns_per_count = zero_event_ns_per,
 },
 { .number = 0x024, /* STALL_BACKEND */
-  .supported = pmu_8_1_events_supported,
+  .supported = pmuv3p1_events_supported,
   .get_count = zero_event_get_count,
   .ns_per_count = zero_event_ns_per,
 },
 { .number = 0x03c, /* STALL */
-  .supported = pmu_8_4_events_supported,
+  .supported = pmuv3p4_events_supported,
   .get_count = zero_event_get_count,
   .ns_per_count = zero_event_ns_per,
 },
@@ -6400,7 +6400,7 @@ static void define_pmu_regs(ARMCPU *cpu)
 g_free(pmevtyper_name);
 g_free(pmevtyper_el0_name);
 }
-if (cpu_isar_feature(aa32_pmu_8_1, cpu)) {
+if (cpu_isar_feature(aa32_pmuv3p1, cp

[PATCH v2] e1000e: set RX desc status with DD flag in a separate operation

2022-09-14 Thread Ding Hui
Like commit 034d00d48581 ("e1000: set RX descriptor status in
a separate operation"), there is also same issue in e1000e, which
would cause lost packets or stop sending packets to VM with DPDK.

Do similar fix in e1000e.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/402
Signed-off-by: Ding Hui 
---
 hw/net/e1000e_core.c | 53 +++-
 1 file changed, 52 insertions(+), 1 deletion(-)

---
v2: use uint8_t/uint32_t directly instead of typeof

diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
index 208e3e0d79..a570b366b2 100644
--- a/hw/net/e1000e_core.c
+++ b/hw/net/e1000e_core.c
@@ -1364,6 +1364,57 @@ struct NetRxPkt *pkt, const E1000E_RSSInfo *rss_info,
 }
 }
 
+static inline void
+e1000e_pci_dma_write_rx_desc(E1000ECore *core, dma_addr_t addr,
+ uint8_t *desc, dma_addr_t len)
+{
+PCIDevice *dev = core->owner;
+
+if (e1000e_rx_use_legacy_descriptor(core)) {
+struct e1000_rx_desc *d = (struct e1000_rx_desc *) desc;
+size_t offset = offsetof(struct e1000_rx_desc, status);
+uint8_t status = d->status;
+
+d->status &= ~E1000_RXD_STAT_DD;
+pci_dma_write(dev, addr, desc, len);
+
+if (status & E1000_RXD_STAT_DD) {
+d->status = status;
+pci_dma_write(dev, addr + offset, &status, sizeof(status));
+}
+} else {
+if (core->mac[RCTL] & E1000_RCTL_DTYP_PS) {
+union e1000_rx_desc_packet_split *d =
+(union e1000_rx_desc_packet_split *) desc;
+size_t offset = offsetof(union e1000_rx_desc_packet_split,
+wb.middle.status_error);
+uint32_t status = d->wb.middle.status_error;
+
+d->wb.middle.status_error &= ~E1000_RXD_STAT_DD;
+pci_dma_write(dev, addr, desc, len);
+
+if (status & E1000_RXD_STAT_DD) {
+d->wb.middle.status_error = status;
+pci_dma_write(dev, addr + offset, &status, sizeof(status));
+}
+} else {
+union e1000_rx_desc_extended *d =
+(union e1000_rx_desc_extended *) desc;
+size_t offset = offsetof(union e1000_rx_desc_extended,
+wb.upper.status_error);
+uint32_t status = d->wb.upper.status_error;
+
+d->wb.upper.status_error &= ~E1000_RXD_STAT_DD;
+pci_dma_write(dev, addr, desc, len);
+
+if (status & E1000_RXD_STAT_DD) {
+d->wb.upper.status_error = status;
+pci_dma_write(dev, addr + offset, &status, sizeof(status));
+}
+}
+}
+}
+
 typedef struct e1000e_ba_state_st {
 uint16_t written[MAX_PS_BUFFERS];
 uint8_t cur_idx;
@@ -1600,7 +1651,7 @@ e1000e_write_packet_to_guest(E1000ECore *core, struct 
NetRxPkt *pkt,
 
 e1000e_write_rx_descr(core, desc, is_last ? core->rx_pkt : NULL,
rss_info, do_ps ? ps_hdr_len : 0, &bastate.written);
-pci_dma_write(d, base, &desc, core->rx_desc_len);
+e1000e_pci_dma_write_rx_desc(core, base, desc, core->rx_desc_len);
 
 e1000e_ring_advance(core, rxi,
 core->rx_desc_len / E1000_MIN_RX_DESC_LEN);
-- 
2.17.1




Re: [PATCH v11 10/21] block/mirror.c: use of job helpers in drivers

2022-09-14 Thread Vladimir Sementsov-Ogievskiy

On 8/26/22 16:20, Emanuele Giuseppe Esposito wrote:

Once job lock is used and aiocontext is removed, mirror has
to perform job operations under the same critical section,
Note: at this stage, job_{lock/unlock} and job lock guard macros
are*nop*.

Signed-off-by: Emanuele Giuseppe Esposito


Reviewed-by: Vladimir Sementsov-Ogievskiy 

--
Best regards,
Vladimir



[PULL 20/20] target/arm: Make boards pass base address to armv7m_load_kernel()

2022-09-14 Thread Richard Henderson
From: Peter Maydell 

Currently armv7m_load_kernel() takes the size of the block of memory
where it should load the initial guest image, but assumes that it
should always load it at address 0.  This happens to be true of all
our M-profile boards at the moment, but it isn't guaranteed to always
be so: M-profile CPUs can be configured (via init-svtor and
init-nsvtor, which match equivalent hardware configuration signals)
to have the initial vector table at any address, not just zero.  (For
instance the Teeny board has the boot ROM at address 0x0200_.)

Add a base address argument to armv7m_load_kernel(), so that
callers now pass in both base address and size. All the current
callers pass 0, so this is not a behaviour change.

Signed-off-by: Peter Maydell 
Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20220823160417.3858216-3-peter.mayd...@linaro.org>
Signed-off-by: Richard Henderson 
---
 include/hw/arm/boot.h | 5 -
 hw/arm/armv7m.c   | 5 +++--
 hw/arm/aspeed.c   | 1 +
 hw/arm/microbit.c | 2 +-
 hw/arm/mps2-tz.c  | 2 +-
 hw/arm/mps2.c | 2 +-
 hw/arm/msf2-som.c | 2 +-
 hw/arm/musca.c| 3 ++-
 hw/arm/netduino2.c| 2 +-
 hw/arm/netduinoplus2.c| 2 +-
 hw/arm/stellaris.c| 2 +-
 hw/arm/stm32vldiscovery.c | 2 +-
 12 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/include/hw/arm/boot.h b/include/hw/arm/boot.h
index c7ebae156e..f18cc3064f 100644
--- a/include/hw/arm/boot.h
+++ b/include/hw/arm/boot.h
@@ -25,13 +25,16 @@ typedef enum {
  * armv7m_load_kernel:
  * @cpu: CPU
  * @kernel_filename: file to load
+ * @mem_base: base address to load image at (should be where the
+ *CPU expects to find its vector table on reset)
  * @mem_size: mem_size: maximum image size to load
  *
  * Load the guest image for an ARMv7M system. This must be called by
  * any ARMv7M board. (This is necessary to ensure that the CPU resets
  * correctly on system reset, as well as for kernel loading.)
  */
-void armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename, int 
mem_size);
+void armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename,
+hwaddr mem_base, int mem_size);
 
 /* arm_boot.c */
 struct arm_boot_info {
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
index fa4c2c735d..50a9507c0b 100644
--- a/hw/arm/armv7m.c
+++ b/hw/arm/armv7m.c
@@ -568,7 +568,8 @@ static void armv7m_reset(void *opaque)
 cpu_reset(CPU(cpu));
 }
 
-void armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename, int mem_size)
+void armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename,
+hwaddr mem_base, int mem_size)
 {
 ssize_t image_size;
 uint64_t entry;
@@ -588,7 +589,7 @@ void armv7m_load_kernel(ARMCPU *cpu, const char 
*kernel_filename, int mem_size)
  &entry, NULL, NULL,
  NULL, 0, EM_ARM, 1, 0, as);
 if (image_size < 0) {
-image_size = load_image_targphys_as(kernel_filename, 0,
+image_size = load_image_targphys_as(kernel_filename, mem_base,
 mem_size, as);
 }
 if (image_size < 0) {
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index b3bbe06f8f..bc3ecdb619 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -1430,6 +1430,7 @@ static void aspeed_minibmc_machine_init(MachineState 
*machine)
 
 armv7m_load_kernel(ARM_CPU(first_cpu),
machine->kernel_filename,
+   0,
AST1030_INTERNAL_FLASH_SIZE);
 }
 
diff --git a/hw/arm/microbit.c b/hw/arm/microbit.c
index e9494334ce..50df362088 100644
--- a/hw/arm/microbit.c
+++ b/hw/arm/microbit.c
@@ -57,7 +57,7 @@ static void microbit_init(MachineState *machine)
 mr, -1);
 
 armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
-   s->nrf51.flash_size);
+   0, s->nrf51.flash_size);
 }
 
 static void microbit_machine_class_init(ObjectClass *oc, void *data)
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
index 4017392bf5..394192b9b2 100644
--- a/hw/arm/mps2-tz.c
+++ b/hw/arm/mps2-tz.c
@@ -1197,7 +1197,7 @@ static void mps2tz_common_init(MachineState *machine)
 }
 
 armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
-   boot_ram_size(mms));
+   0, boot_ram_size(mms));
 }
 
 static void mps2_tz_idau_check(IDAUInterface *ii, uint32_t address,
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
index bb76fa6889..a86a994dba 100644
--- a/hw/arm/mps2.c
+++ b/hw/arm/mps2.c
@@ -450,7 +450,7 @@ static void mps2_common_init(MachineState *machine)
   mmc->fpga_type == FPGA_AN511 ? 47 : 13));
 
 armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
-   0x40);
+  

Re: [PATCH] target/arm: Fix alignment for VLD4.32

2022-09-14 Thread Richard Henderson

On 9/14/22 11:50, Clément Chigot wrote:

When requested, the alignment for VLD4.32 is 8 and not 16.

See ARM documentation about VLD4 encoding:
 ebytes = 1 << UInt(size);
 if size == '10' then
 alignment = if a == '0' then 1 else 8;
 else
 alignment = if a == '0' then 1 else 4*ebytes;

Signed-off-by: Clément Chigot 


Reviewed-by: Richard Henderson 

r~


---
  target/arm/translate-neon.c | 6 +-
  1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
index 321c17e2c7..4016339d46 100644
--- a/target/arm/translate-neon.c
+++ b/target/arm/translate-neon.c
@@ -584,7 +584,11 @@ static bool trans_VLD_all_lanes(DisasContext *s, 
arg_VLD_all_lanes *a)
  case 3:
  return false;
  case 4:
-align = pow2_align(size + 2);
+if (size == 2) {
+align = pow2_align(3);
+} else {
+align = pow2_align(size + 2);
+}
  break;
  default:
  g_assert_not_reached();





[PULL 01/11] target/nios2: Use semihosting/syscalls.h

2022-09-14 Thread Richard Henderson
This separates guest file descriptors from host file descriptors,
and utilizes shared infrastructure for integration with gdbstub.

Signed-off-by: Richard Henderson 
---
 target/nios2/nios2-semi.c | 296 +++---
 1 file changed, 50 insertions(+), 246 deletions(-)

diff --git a/target/nios2/nios2-semi.c b/target/nios2/nios2-semi.c
index 55061bb2dc..614fd76695 100644
--- a/target/nios2/nios2-semi.c
+++ b/target/nios2/nios2-semi.c
@@ -24,6 +24,7 @@
 #include "qemu/osdep.h"
 #include "cpu.h"
 #include "exec/gdbstub.h"
+#include "semihosting/syscalls.h"
 #include "semihosting/softmmu-uaccess.h"
 #include "qemu/log.h"
 
@@ -42,67 +43,6 @@
 #define HOSTED_ISATTY 12
 #define HOSTED_SYSTEM 13
 
-static int translate_openflags(int flags)
-{
-int hf;
-
-if (flags & GDB_O_WRONLY) {
-hf = O_WRONLY;
-} else if (flags & GDB_O_RDWR) {
-hf = O_RDWR;
-} else {
-hf = O_RDONLY;
-}
-
-if (flags & GDB_O_APPEND) {
-hf |= O_APPEND;
-}
-if (flags & GDB_O_CREAT) {
-hf |= O_CREAT;
-}
-if (flags & GDB_O_TRUNC) {
-hf |= O_TRUNC;
-}
-if (flags & GDB_O_EXCL) {
-hf |= O_EXCL;
-}
-
-return hf;
-}
-
-static bool translate_stat(CPUNios2State *env, target_ulong addr,
-   struct stat *s)
-{
-struct gdb_stat *p;
-
-p = lock_user(VERIFY_WRITE, addr, sizeof(struct gdb_stat), 0);
-
-if (!p) {
-return false;
-}
-p->gdb_st_dev = cpu_to_be32(s->st_dev);
-p->gdb_st_ino = cpu_to_be32(s->st_ino);
-p->gdb_st_mode = cpu_to_be32(s->st_mode);
-p->gdb_st_nlink = cpu_to_be32(s->st_nlink);
-p->gdb_st_uid = cpu_to_be32(s->st_uid);
-p->gdb_st_gid = cpu_to_be32(s->st_gid);
-p->gdb_st_rdev = cpu_to_be32(s->st_rdev);
-p->gdb_st_size = cpu_to_be64(s->st_size);
-#ifdef _WIN32
-/* Windows stat is missing some fields.  */
-p->gdb_st_blksize = 0;
-p->gdb_st_blocks = 0;
-#else
-p->gdb_st_blksize = cpu_to_be64(s->st_blksize);
-p->gdb_st_blocks = cpu_to_be64(s->st_blocks);
-#endif
-p->gdb_st_atime = cpu_to_be32(s->st_atime);
-p->gdb_st_mtime = cpu_to_be32(s->st_mtime);
-p->gdb_st_ctime = cpu_to_be32(s->st_ctime);
-unlock_user(p, addr, sizeof(struct gdb_stat));
-return true;
-}
-
 static void nios2_semi_u32_cb(CPUState *cs, uint64_t ret, int err)
 {
 Nios2CPU *cpu = NIOS2_CPU(cs);
@@ -142,22 +82,22 @@ static void nios2_semi_u64_cb(CPUState *cs, uint64_t ret, 
int err)
  */
 #define GET_ARG(n) do { \
 if (get_user_ual(arg ## n, args + (n) * 4)) {   \
-result = -1;\
-errno = EFAULT; \
 goto failed;\
 }   \
 } while (0)
 
+#define GET_ARG64(n) do {   \
+if (get_user_ual(arg ## n, args + (n) * 4)) {   \
+goto failed64;  \
+}   \
+} while (0)
+
 void do_nios2_semihosting(CPUNios2State *env)
 {
 CPUState *cs = env_cpu(env);
 int nr;
 uint32_t args;
 target_ulong arg0, arg1, arg2, arg3;
-void *p;
-void *q;
-uint32_t len;
-uint32_t result;
 
 nr = env->regs[R_ARG0];
 args = env->regs[R_ARG1];
@@ -165,234 +105,98 @@ void do_nios2_semihosting(CPUNios2State *env)
 case HOSTED_EXIT:
 gdb_exit(env->regs[R_ARG0]);
 exit(env->regs[R_ARG0]);
+
 case HOSTED_OPEN:
 GET_ARG(0);
 GET_ARG(1);
 GET_ARG(2);
 GET_ARG(3);
-if (use_gdb_syscalls()) {
-gdb_do_syscall(nios2_semi_u32_cb, "open,%s,%x,%x", arg0, (int)arg1,
-   arg2, arg3);
-return;
-} else {
-p = lock_user_string(arg0);
-if (!p) {
-result = -1;
-errno = EFAULT;
-} else {
-result = open(p, translate_openflags(arg2), arg3);
-unlock_user(p, arg0, 0);
-}
-}
+semihost_sys_open(cs, nios2_semi_u32_cb, arg0, arg1, arg2, arg3);
 break;
+
 case HOSTED_CLOSE:
-{
-/* Ignore attempts to close stdin/out/err.  */
-GET_ARG(0);
-int fd = arg0;
-if (fd > 2) {
-if (use_gdb_syscalls()) {
-gdb_do_syscall(nios2_semi_u32_cb, "close,%x", arg0);
-return;
-} else {
-result = close(fd);
-}
-} else {
-result = 0;
-}
-break;
-}
+GET_ARG(0);
+semihost_sys_close(cs, nios2_semi_u32_cb, arg0);
+break;
+
 case HOSTED_READ:
 GET_ARG(0);
 GET_ARG(1);
 GET_ARG(2);
-len = arg2;
-if (use_gdb_s

[PULL 04/11] target/m68k: Convert semihosting errno to gdb remote errno

2022-09-14 Thread Richard Henderson
The semihosting abi used by m68k uses the gdb remote
protocol filesys errnos.

Acked-by: Laurent Vivier 
Signed-off-by: Richard Henderson 
---
 target/m68k/m68k-semi.c | 33 +++--
 1 file changed, 31 insertions(+), 2 deletions(-)

diff --git a/target/m68k/m68k-semi.c b/target/m68k/m68k-semi.c
index 586a801034..87b1314925 100644
--- a/target/m68k/m68k-semi.c
+++ b/target/m68k/m68k-semi.c
@@ -41,6 +41,35 @@
 #define HOSTED_ISATTY 12
 #define HOSTED_SYSTEM 13
 
+static int host_to_gdb_errno(int err)
+{
+#define E(X)  case E##X: return GDB_E##X
+switch (err) {
+E(PERM);
+E(NOENT);
+E(INTR);
+E(BADF);
+E(ACCES);
+E(FAULT);
+E(BUSY);
+E(EXIST);
+E(NODEV);
+E(NOTDIR);
+E(ISDIR);
+E(INVAL);
+E(NFILE);
+E(MFILE);
+E(FBIG);
+E(NOSPC);
+E(SPIPE);
+E(ROFS);
+E(NAMETOOLONG);
+default:
+return GDB_EUNKNOWN;
+}
+#undef E
+}
+
 static void m68k_semi_u32_cb(CPUState *cs, uint64_t ret, int err)
 {
 M68kCPU *cpu = M68K_CPU(cs);
@@ -48,7 +77,7 @@ static void m68k_semi_u32_cb(CPUState *cs, uint64_t ret, int 
err)
 
 target_ulong args = env->dregs[1];
 if (put_user_u32(ret, args) ||
-put_user_u32(err, args + 4)) {
+put_user_u32(host_to_gdb_errno(err), args + 4)) {
 /*
  * The m68k semihosting ABI does not provide any way to report this
  * error to the guest, so the best we can do is log it in qemu.
@@ -67,7 +96,7 @@ static void m68k_semi_u64_cb(CPUState *cs, uint64_t ret, int 
err)
 target_ulong args = env->dregs[1];
 if (put_user_u32(ret >> 32, args) ||
 put_user_u32(ret, args + 4) ||
-put_user_u32(err, args + 8)) {
+put_user_u32(host_to_gdb_errno(err), args + 8)) {
 /* No way to report this via m68k semihosting ABI; just log it */
 qemu_log_mask(LOG_GUEST_ERROR, "m68k-semihosting: return value "
   "discarded because argument block not writable\n");
-- 
2.34.1




[PATCH v2 0/4] Patch series to set up a ppc64le CI

2022-09-14 Thread Lucas Mateus Castro(alqotel)
From: "Lucas Mateus Castro (alqotel)" 

This patch series aim to make easier to set up a compilation and CI
environment on PPC64 and PPC64LE machines.

v2:
This patch series are only patches 2-4 of v1 and an alternative to patch 1
suggested by Daniel.

Lucas Mateus Castro (alqotel) (4):
  scripts/ci/setup: ninja missing from build-environment
  scripts/ci/setup: Fix libxen requirements
  scripts/ci/setup: spice-server only on x86 aarch64
  tests/docker: run script use realpath instead of readlink

 scripts/ci/setup/build-environment.yml | 15 +--
 tests/docker/run   |  2 +-
 2 files changed, 14 insertions(+), 3 deletions(-)

-- 
2.31.1




[PULL 05/11] semihosting: Allow optional use of semihosting from userspace

2022-09-14 Thread Richard Henderson
From: Peter Maydell 

Currently our semihosting implementations generally prohibit use of
semihosting calls in system emulation from the guest userspace.  This
is a very long standing behaviour justified originally "to provide
some semblance of security" (since code with access to the
semihosting ABI can do things like read and write arbitrary files on
the host system).  However, it is sometimes useful to be able to run
trusted guest code which performs semihosting calls from guest
userspace, notably for test code.  Add a command line suboption to
the existing semihosting-config option group so that you can
explicitly opt in to semihosting from guest userspace with
 -semihosting-config userspace=on

(There is no equivalent option for the user-mode emulator, because
there by definition all code runs in userspace and has access to
semihosting already.)

This commit adds the infrastructure for the command line option and
adds a bool 'is_user' parameter to the function
semihosting_userspace_enabled() that target code can use to check
whether it should be permitting the semihosting call for userspace.
It mechanically makes all the callsites pass 'false', so they
continue checking "is semihosting enabled in general".  Subsequent
commits will make each target that implements semihosting honour the
userspace=on option by passing the correct value and removing
whatever "don't do this for userspace" checking they were doing by
hand.

Signed-off-by: Peter Maydell 
Acked-by: Alex Bennée 
Reviewed-by: Alistair Francis 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-Id: <20220822141230.3658237-2-peter.mayd...@linaro.org>
Signed-off-by: Richard Henderson 
---
 include/semihosting/semihost.h | 10 --
 semihosting/config.c   | 10 --
 softmmu/vl.c   |  2 +-
 stubs/semihost.c   |  2 +-
 target/arm/translate-a64.c |  2 +-
 target/arm/translate.c |  6 +++---
 target/m68k/op_helper.c|  2 +-
 target/nios2/translate.c   |  2 +-
 target/xtensa/translate.c  |  6 +++---
 qemu-options.hx| 11 +--
 10 files changed, 36 insertions(+), 17 deletions(-)

diff --git a/include/semihosting/semihost.h b/include/semihosting/semihost.h
index 93a3c21b44..efd2efa25a 100644
--- a/include/semihosting/semihost.h
+++ b/include/semihosting/semihost.h
@@ -27,7 +27,7 @@ typedef enum SemihostingTarget {
 } SemihostingTarget;
 
 #ifdef CONFIG_USER_ONLY
-static inline bool semihosting_enabled(void)
+static inline bool semihosting_enabled(bool is_user)
 {
 return true;
 }
@@ -52,7 +52,13 @@ static inline const char *semihosting_get_cmdline(void)
 return NULL;
 }
 #else /* !CONFIG_USER_ONLY */
-bool semihosting_enabled(void);
+/**
+ * semihosting_enabled:
+ * @is_user: true if guest code is in usermode (i.e. not privileged)
+ *
+ * Return true if guest code is allowed to make semihosting calls.
+ */
+bool semihosting_enabled(bool is_user);
 SemihostingTarget semihosting_get_target(void);
 const char *semihosting_get_arg(int i);
 int semihosting_get_argc(void);
diff --git a/semihosting/config.c b/semihosting/config.c
index e171d4d6bc..89a1759687 100644
--- a/semihosting/config.c
+++ b/semihosting/config.c
@@ -34,6 +34,9 @@ QemuOptsList qemu_semihosting_config_opts = {
 {
 .name = "enable",
 .type = QEMU_OPT_BOOL,
+}, {
+.name = "userspace",
+.type = QEMU_OPT_BOOL,
 }, {
 .name = "target",
 .type = QEMU_OPT_STRING,
@@ -50,6 +53,7 @@ QemuOptsList qemu_semihosting_config_opts = {
 
 typedef struct SemihostingConfig {
 bool enabled;
+bool userspace_enabled;
 SemihostingTarget target;
 char **argv;
 int argc;
@@ -59,9 +63,9 @@ typedef struct SemihostingConfig {
 static SemihostingConfig semihosting;
 static const char *semihost_chardev;
 
-bool semihosting_enabled(void)
+bool semihosting_enabled(bool is_user)
 {
-return semihosting.enabled;
+return semihosting.enabled && (!is_user || semihosting.userspace_enabled);
 }
 
 SemihostingTarget semihosting_get_target(void)
@@ -137,6 +141,8 @@ int qemu_semihosting_config_options(const char *optarg)
 if (opts != NULL) {
 semihosting.enabled = qemu_opt_get_bool(opts, "enable",
 true);
+semihosting.userspace_enabled = qemu_opt_get_bool(opts, "userspace",
+  false);
 const char *target = qemu_opt_get(opts, "target");
 /* setup of chardev is deferred until they are initialised */
 semihost_chardev = qemu_opt_get(opts, "chardev");
diff --git a/softmmu/vl.c b/softmmu/vl.c
index dea4005e47..263f029a8e 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -1822,7 +1822,7 @@ static void qemu_apply_machine_options(QDict *qdict)
 {
 object_set_properties_from_keyval(OBJECT(current_machine), qdict, false, 
&error_fatal);
 
-if 

[PULL 08/11] target/mips: Honour -semihosting-config userspace=on

2022-09-14 Thread Richard Henderson
From: Peter Maydell 

Honour the commandline -semihosting-config userspace=on option,
instead of always permitting userspace semihosting calls in system
emulation mode, by passing the correct value to the is_userspace
argument of semihosting_enabled().

Note that this is a behaviour change: if the user wants to
do semihosting calls from userspace they must now specifically
enable them on the command line.

MIPS semihosting is not implemented for linux-user builds.

Signed-off-by: Peter Maydell 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-Id: <20220822141230.3658237-5-peter.mayd...@linaro.org>
Signed-off-by: Richard Henderson 
---
 target/mips/tcg/translate.c   | 9 +
 target/mips/tcg/micromips_translate.c.inc | 6 +++---
 target/mips/tcg/mips16e_translate.c.inc   | 2 +-
 target/mips/tcg/nanomips_translate.c.inc  | 4 ++--
 4 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
index 0d936e2648..c3f92ea652 100644
--- a/target/mips/tcg/translate.c
+++ b/target/mips/tcg/translate.c
@@ -12082,12 +12082,13 @@ static void gen_cache_operation(DisasContext *ctx, 
uint32_t op, int base,
 tcg_temp_free_i32(t0);
 }
 
-static inline bool is_uhi(int sdbbp_code)
+static inline bool is_uhi(DisasContext *ctx, int sdbbp_code)
 {
 #ifdef CONFIG_USER_ONLY
 return false;
 #else
-return semihosting_enabled() && sdbbp_code == 1;
+bool is_user = (ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM;
+return semihosting_enabled(is_user) && sdbbp_code == 1;
 #endif
 }
 
@@ -13898,7 +13899,7 @@ static void decode_opc_special_r6(CPUMIPSState *env, 
DisasContext *ctx)
 }
 break;
 case R6_OPC_SDBBP:
-if (is_uhi(extract32(ctx->opcode, 6, 20))) {
+if (is_uhi(ctx, extract32(ctx->opcode, 6, 20))) {
 ctx->base.is_jmp = DISAS_SEMIHOST;
 } else {
 if (ctx->hflags & MIPS_HFLAG_SBRI) {
@@ -14310,7 +14311,7 @@ static void decode_opc_special2_legacy(CPUMIPSState 
*env, DisasContext *ctx)
 gen_cl(ctx, op1, rd, rs);
 break;
 case OPC_SDBBP:
-if (is_uhi(extract32(ctx->opcode, 6, 20))) {
+if (is_uhi(ctx, extract32(ctx->opcode, 6, 20))) {
 ctx->base.is_jmp = DISAS_SEMIHOST;
 } else {
 /*
diff --git a/target/mips/tcg/micromips_translate.c.inc 
b/target/mips/tcg/micromips_translate.c.inc
index b2c696f891..632895cc9e 100644
--- a/target/mips/tcg/micromips_translate.c.inc
+++ b/target/mips/tcg/micromips_translate.c.inc
@@ -825,7 +825,7 @@ static void gen_pool16c_insn(DisasContext *ctx)
 generate_exception_break(ctx, extract32(ctx->opcode, 0, 4));
 break;
 case SDBBP16:
-if (is_uhi(extract32(ctx->opcode, 0, 4))) {
+if (is_uhi(ctx, extract32(ctx->opcode, 0, 4))) {
 ctx->base.is_jmp = DISAS_SEMIHOST;
 } else {
 /*
@@ -941,7 +941,7 @@ static void gen_pool16c_r6_insn(DisasContext *ctx)
 break;
 case R6_SDBBP16:
 /* SDBBP16 */
-if (is_uhi(extract32(ctx->opcode, 6, 4))) {
+if (is_uhi(ctx, extract32(ctx->opcode, 6, 4))) {
 ctx->base.is_jmp = DISAS_SEMIHOST;
 } else {
 if (ctx->hflags & MIPS_HFLAG_SBRI) {
@@ -1310,7 +1310,7 @@ static void gen_pool32axf(CPUMIPSState *env, DisasContext 
*ctx, int rt, int rs)
 generate_exception_end(ctx, EXCP_SYSCALL);
 break;
 case SDBBP:
-if (is_uhi(extract32(ctx->opcode, 16, 10))) {
+if (is_uhi(ctx, extract32(ctx->opcode, 16, 10))) {
 ctx->base.is_jmp = DISAS_SEMIHOST;
 } else {
 check_insn(ctx, ISA_MIPS_R1);
diff --git a/target/mips/tcg/mips16e_translate.c.inc 
b/target/mips/tcg/mips16e_translate.c.inc
index 7568933e23..918b15d55c 100644
--- a/target/mips/tcg/mips16e_translate.c.inc
+++ b/target/mips/tcg/mips16e_translate.c.inc
@@ -951,7 +951,7 @@ static int decode_ase_mips16e(CPUMIPSState *env, 
DisasContext *ctx)
 }
 break;
 case RR_SDBBP:
-if (is_uhi(extract32(ctx->opcode, 5, 6))) {
+if (is_uhi(ctx, extract32(ctx->opcode, 5, 6))) {
 ctx->base.is_jmp = DISAS_SEMIHOST;
 } else {
 /*
diff --git a/target/mips/tcg/nanomips_translate.c.inc 
b/target/mips/tcg/nanomips_translate.c.inc
index b3aff22c18..812c111e3c 100644
--- a/target/mips/tcg/nanomips_translate.c.inc
+++ b/target/mips/tcg/nanomips_translate.c.inc
@@ -3694,7 +3694,7 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, 
DisasContext *ctx)
 generate_exception_end(ctx, EXCP_BREAK);
 break;
 case NM_SDBBP:
-if (is_uhi(extract32(ctx->opcode, 0, 19))) {
+if (is_uhi(ctx, extract32(ctx->opcode, 0, 19))) {
 ctx->base.is_jmp = DISAS_SEMIHOST;

[PULL 07/11] target/m68k: Honour -semihosting-config userspace=on

2022-09-14 Thread Richard Henderson
From: Peter Maydell 

Honour the commandline -semihosting-config userspace=on option,
instead of never permitting userspace semihosting calls in system
emulation mode, by passing the correct value to the is_userspace
argument of semihosting_enabled(), instead of manually checking and
always forbidding semihosting if the guest is in userspace.

(Note that target/m68k doesn't support semihosting at all
in the linux-user build.)

Signed-off-by: Peter Maydell 
Reviewed-by: Laurent Vivier 
Reviewed-by: Richard Henderson 
Message-Id: <20220822141230.3658237-4-peter.mayd...@linaro.org>
Signed-off-by: Richard Henderson 
---
 target/m68k/op_helper.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/target/m68k/op_helper.c b/target/m68k/op_helper.c
index 4b3dfec130..a96a034050 100644
--- a/target/m68k/op_helper.c
+++ b/target/m68k/op_helper.c
@@ -203,8 +203,7 @@ static void cf_interrupt_all(CPUM68KState *env, int is_hw)
 cf_rte(env);
 return;
 case EXCP_HALT_INSN:
-if (semihosting_enabled(false)
-&& (env->sr & SR_S) != 0
+if (semihosting_enabled((env->sr & SR_S) == 0)
 && (env->pc & 3) == 0
 && cpu_lduw_code(env, env->pc - 4) == 0x4e71
 && cpu_ldl_code(env, env->pc) == 0x4e7bf000) {
-- 
2.34.1




[PATCH v2 1/4] scripts/ci/setup: ninja missing from build-environment

2022-09-14 Thread Lucas Mateus Castro(alqotel)
From: "Lucas Mateus Castro (alqotel)" 

ninja-build is missing from the RHEL environment, so a system prepared
with that script would still fail to compile QEMU.
Tested on a Fedora 36

Signed-off-by: Lucas Mateus Castro (alqotel) 
---
 scripts/ci/setup/build-environment.yml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/scripts/ci/setup/build-environment.yml 
b/scripts/ci/setup/build-environment.yml
index 232525b91d..6df3e61d94 100644
--- a/scripts/ci/setup/build-environment.yml
+++ b/scripts/ci/setup/build-environment.yml
@@ -150,6 +150,7 @@
   - libepoxy-devel
   - libgcrypt-devel
   - lzo-devel
+  - ninja-build
   - make
   - mesa-libEGL-devel
   - nettle-devel
-- 
2.31.1




Proposal for a fixed ram migration stream format for file-based migrations

2022-09-14 Thread Nikolay Borisov

Hello,

Based on several discussions I've had in the past 2 days and time spent
looking at the migration stream code I came up with the following
proposal for changes to the stream format. Let me recap what we have
right now:


...()

Where  is put only when the current page we are writing
to belongs to a different block than the last written page. My proposal is to
change this format to:

...

Each page belonging to a ramblock would be at a fixed offset in the file. Which 
is going to be
 + page_offset. The size of the region for a particular 
ramblock would be
ramblock::used_length but not the whole range is going to be written, only 
those pages which
have been dirtied. If we assume a 1tb ramblock then we'd make the the region 1 
tb but it will
be sparsely populated. This means that we can have the following layout for the 
memory range:


|---p---ppppp---p|
01tb

Each 'p' signifies an allocated page and '-' is a page which hasn't been 
dirtied ergo its
index in the stream is not touched. This of course would result in having a lot 
of holes, so when
the incoming migration starts parsing the stream it might end up in a situation
where page at offset 0 is read, but then it has to jump some at arbitrary
location for the next page. To avoid resorting to calling into the filesystem 
and dealing with
fiemap's format I also intend to extend the ramblock header format by adding a 
dirty bitmap in
which every bit would signify whether a page has been written or not, the bit's 
position would be
used to index into the allocated space for pages. Simple maths shows that for 
4k pages, 1tb can be
indexed with just 32kbytes of memory. The way the indexing would work is

page = ramblock->offset (this is the offset in the file, not the in-memory 
::ofset field) +
bit's position * target_page_size

That way we can still handle sparsely dirtied memory and have direct mapping in 
the file, this
dirty bitmap would be populated during the course of ram migration and once the 
final page is written,
those in-memory bitmaps would be written into their respective positions in the 
file, needless to say
this would be supported only on seekable channels (for now only file-based 
channels).

Another important thing worth mentioning is I don't intend on incrementing the
format version but rather introducing a new migration capability.

Any thoughts/comments/suggestions, would be highly appreciated.



[PATCH v2 2/4] scripts/ci/setup: Fix libxen requirements

2022-09-14 Thread Lucas Mateus Castro(alqotel)
From: "Lucas Mateus Castro (alqotel)" 

XEN hypervisor is only available in ARM and x86, but the yaml only
checked if the architecture is different from s390x, changed it to
a more accurate test.
Tested this change on a Ubuntu 20.04 ppc64le.

Signed-off-by: Lucas Mateus Castro (alqotel) 
Reviewed-by: Alex Bennée 
---
 scripts/ci/setup/build-environment.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/ci/setup/build-environment.yml 
b/scripts/ci/setup/build-environment.yml
index 6df3e61d94..7535228685 100644
--- a/scripts/ci/setup/build-environment.yml
+++ b/scripts/ci/setup/build-environment.yml
@@ -97,7 +97,7 @@
 state: present
   when:
 - ansible_facts['distribution'] == 'Ubuntu'
-- ansible_facts['architecture'] != 's390x'
+- ansible_facts['architecture'] == 'aarch64' or 
ansible_facts['architecture'] == 'x86_64'
 
 - name: Install basic packages to build QEMU on Ubuntu 20.04
   package:
-- 
2.31.1




[PULL 10/11] target/xtensa: Honour -semihosting-config userspace=on

2022-09-14 Thread Richard Henderson
From: Peter Maydell 

Honour the commandline -semihosting-config userspace=on option,
instead of always permitting userspace semihosting calls in system
emulation mode, by passing the correct value to the is_userspace
argument of semihosting_enabled().

Note that this is a behaviour change: if the user wants to
do semihosting calls from userspace they must now specifically
enable them on the command line.

xtensa semihosting is not implemented for linux-user builds.

Signed-off-by: Peter Maydell 
Acked-by: Max Filippov 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Richard Henderson 
Message-Id: <20220822141230.3658237-7-peter.mayd...@linaro.org>
Signed-off-by: Richard Henderson 
---
 target/xtensa/translate.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c
index afae8a1bea..bdd4690a5c 100644
--- a/target/xtensa/translate.c
+++ b/target/xtensa/translate.c
@@ -2362,13 +2362,14 @@ static uint32_t test_exceptions_simcall(DisasContext 
*dc,
 const OpcodeArg arg[],
 const uint32_t par[])
 {
+bool is_semi = semihosting_enabled(dc->cring != 0);
 #ifdef CONFIG_USER_ONLY
 bool ill = true;
 #else
 /* Between RE.2 and RE.3 simcall opcode's become nop for the hardware. */
-bool ill = dc->config->hw_version <= 250002 && !semihosting_enabled(false);
+bool ill = dc->config->hw_version <= 250002 && !is_semi;
 #endif
-if (ill || !semihosting_enabled(false)) {
+if (ill || !is_semi) {
 qemu_log_mask(LOG_GUEST_ERROR, "SIMCALL but semihosting is 
disabled\n");
 }
 return ill ? XTENSA_OP_ILL : 0;
@@ -2378,7 +2379,7 @@ static void translate_simcall(DisasContext *dc, const 
OpcodeArg arg[],
   const uint32_t par[])
 {
 #ifndef CONFIG_USER_ONLY
-if (semihosting_enabled(false)) {
+if (semihosting_enabled(dc->cring != 0)) {
 gen_helper_simcall(cpu_env);
 }
 #endif
-- 
2.34.1




Re: [PATCH v11 11/21] jobs: group together API calls under the same job lock

2022-09-14 Thread Vladimir Sementsov-Ogievskiy

On 8/26/22 16:20, Emanuele Giuseppe Esposito wrote:

Now that the API offers also _locked() functions, take advantage
of it and give also the caller control to take the lock and call
_locked functions.

This makes sense especially when we have for loops, because it
makes no sense to have:

for(job = job_next(); ...)

where each job_next() takes the lock internally.
Instead we want

JOB_LOCK_GUARD();
for(job = job_next_locked(); ...)

In addition, protect also direct field accesses, by either creating a
new critical section or widening the existing ones.

Note: at this stage, job_{lock/unlock} and job lock guard macros
are *nop*.

Signed-off-by: Emanuele Giuseppe Esposito 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
---
  block.c| 17 ++---
  blockdev.c | 14 ++
  blockjob.c | 35 ++-
  job-qmp.c  |  9 ++---
  job.c  |  7 +--
  monitor/qmp-cmds.c |  7 +--
  qemu-img.c | 17 +++--
  7 files changed, 69 insertions(+), 37 deletions(-)



[..]


diff --git a/job.c b/job.c
index dcd561fd46..e336af0c1c 100644
--- a/job.c
+++ b/job.c


job.c hunks are unrelated in this patch, they should go to patch 05.


@@ -672,7 +672,7 @@ void coroutine_fn job_pause_point(Job *job)
  job_pause_point_locked(job);
  }
  
-void job_yield_locked(Job *job)

+static void job_yield_locked(Job *job)
  {
  assert(job->busy);
  
@@ -1046,11 +1046,14 @@ static void job_completed_txn_abort_locked(Job *job)

  /* Called with job_mutex held, but releases it temporarily */
  static int job_prepare_locked(Job *job)
  {
+int ret;
+
  GLOBAL_STATE_CODE();
  if (job->ret == 0 && job->driver->prepare) {
  job_unlock();
-job->ret = job->driver->prepare(job);
+ret = job->driver->prepare(job);
  job_lock();
+job->ret = ret;
  job_update_rc_locked(job);
  }
  return job->ret;
diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c
index 7314cd813d..81c8fdadf8 100644
--- a/monitor/qmp-cmds.c
+++ b/monitor/qmp-cmds.c
@@ -135,8 +135,11 @@ void qmp_cont(Error **errp)
  blk_iostatus_reset(blk);
  }
  
-for (job = block_job_next(NULL); job; job = block_job_next(job)) {

-block_job_iostatus_reset(job);
+WITH_JOB_LOCK_GUARD() {
+for (job = block_job_next_locked(NULL); job;
+ job = block_job_next_locked(job)) {
+block_job_iostatus_reset_locked(job);
+}
  }
  
  /* Continuing after completed migration. Images have been inactivated to

diff --git a/qemu-img.c b/qemu-img.c
index 7d4b33b3da..c8ae704166 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -912,25 +912,30 @@ static void run_block_job(BlockJob *job, Error **errp)
  int ret = 0;
  
  aio_context_acquire(aio_context);

-job_ref(&job->job);
+job_lock();
+job_ref_locked(&job->job);
  do {
  float progress = 0.0f;
+job_unlock();
  aio_poll(aio_context, true);
  
  progress_get_snapshot(&job->job.progress, &progress_current,

-  &progress_total);
+&progress_total);


broken indentation


  if (progress_total) {
  progress = (float)progress_current / progress_total * 100.f;
  }
  qemu_progress_print(progress, 0);
-} while (!job_is_ready(&job->job) && !job_is_completed(&job->job));
+job_lock();
+} while (!job_is_ready_locked(&job->job) &&
+!job_is_completed_locked(&job->job));


and here

  
-if (!job_is_completed(&job->job)) {

-ret = job_complete_sync(&job->job, errp);
+if (!job_is_completed_locked(&job->job)) {
+ret = job_complete_sync_locked(&job->job, errp);
  } else {
  ret = job->job.ret;
  }
-job_unref(&job->job);
+job_unref_locked(&job->job);
+job_unlock();
  aio_context_release(aio_context);
  
  /* publish completion progress only when success */



--
Best regards,
Vladimir



Re: [PATCH 2/3] vdpa: load vlan configuration at NIC startup

2022-09-14 Thread Eugenio Perez Martin
On Wed, Sep 14, 2022 at 1:33 PM Si-Wei Liu  wrote:
>
>
>
> On 9/14/2022 3:20 AM, Jason Wang wrote:
> > On Fri, Sep 9, 2022 at 4:02 PM Eugenio Perez Martin  
> > wrote:
> >> On Fri, Sep 9, 2022 at 8:40 AM Jason Wang  wrote:
> >>> On Fri, Sep 9, 2022 at 2:38 PM Jason Wang  wrote:
>  On Wed, Sep 7, 2022 at 12:36 AM Eugenio Pérez  
>  wrote:
> > To have enabled vlans at device startup may happen in the destination of
> > a live migration, so this configuration must be restored.
> >
> > At this moment the code is not accessible, since SVQ refuses to start if
> > vlan feature is exposed by the device.
> >
> > Signed-off-by: Eugenio Pérez 
> > ---
> >   net/vhost-vdpa.c | 46 --
> >   1 file changed, 44 insertions(+), 2 deletions(-)
> >
> > diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
> > index 4bc3fd01a8..ecbfd08eb9 100644
> > --- a/net/vhost-vdpa.c
> > +++ b/net/vhost-vdpa.c
> > @@ -100,6 +100,8 @@ static const uint64_t vdpa_svq_device_features =
> >   BIT_ULL(VIRTIO_NET_F_RSC_EXT) |
> >   BIT_ULL(VIRTIO_NET_F_STANDBY);
> >
> > +#define MAX_VLAN(1 << 12)   /* Per 802.1Q definition */
> > +
> >   VHostNetState *vhost_vdpa_get_vhost_net(NetClientState *nc)
> >   {
> >   VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
> > @@ -423,6 +425,47 @@ static int vhost_vdpa_net_load_mq(VhostVDPAState 
> > *s,
> >   return *s->status != VIRTIO_NET_OK;
> >   }
> >
> > +static int vhost_vdpa_net_load_single_vlan(VhostVDPAState *s,
> > +   const VirtIONet *n,
> > +   uint16_t vid)
> > +{
> > +ssize_t dev_written = vhost_vdpa_net_load_cmd(s, 
> > VIRTIO_NET_CTRL_VLAN,
> > +  
> > VIRTIO_NET_CTRL_VLAN_ADD,
> > +  &vid, sizeof(vid));
> > +if (unlikely(dev_written < 0)) {
> > +return dev_written;
> > +}
> > +
> > +if (unlikely(*s->status != VIRTIO_NET_OK)) {
> > +return -EINVAL;
> > +}
> > +
> > +return 0;
> > +}
> > +
> > +static int vhost_vdpa_net_load_vlan(VhostVDPAState *s,
> > +const VirtIONet *n)
> > +{
> > +uint64_t features = n->parent_obj.guest_features;
> > +
> > +if (!(features & BIT_ULL(VIRTIO_NET_F_CTRL_VLAN))) {
> > +return 0;
> > +}
> > +
> > +for (int i = 0; i < MAX_VLAN >> 5; i++) {
> > +for (int j = 0; n->vlans[i] && j <= 0x1f; j++) {
> > +if (n->vlans[i] & (1U << j)) {
> > +int r = vhost_vdpa_net_load_single_vlan(s, n, (i << 5) 
> > + j);
>  This seems to cause a lot of latency if the driver has a lot of vlans.
> 
>  I wonder if it's simply to let all vlan traffic go by disabling
>  CTRL_VLAN feature at vDPA layer.
> >> The guest will not be able to recover that vlan configuration.
> > Spec said it's best effort and we actually don't do this for
> > vhost-net/user for years and manage to survive.
> I thought there's a border line between best effort and do nothing. ;-)
>

I also think it is worth at least trying to migrate it for sure. For
MAC there may be too many entries, but VLAN should be totally
manageable (and the information is already there, the bitmap is
actually being migrated).

> I think that the reason this could survive is really software
> implementation specific - say if the backend doesn't start with VLAN
> filtering disabled (meaning allow all VLAN traffic to pass) then it
> would become a problem. This won't be a problem for almost PF NICs but
> may be problematic for vDPA e.g. VF backed VDPAs.

I'd say the driver would expect all vlan filters to be cleared after a
reset, isn't it? The spec doesn't explicitly say anything about that
as far as I see.

> >
> >>> Another idea is to extend the spec to allow us to accept a bitmap of
> >>> the vlan ids via a single command, then we will be fine.
> >>>
> >> I'm not sure if adding more ways to configure something is the answer,
> >> but I'd be ok to implement it.
> >>
> >> Another idea is to allow the sending of many CVQ commands in parallel.
> >> It shouldn't be very hard to achieve using exposed buffers as ring
> >> buffers, and it will short down the start of the devices with many
> >> features.
> > In the extreme case, what if guests decide to filter all of the vlans?
> > It means we need MAX_VLAN commands which may exceeds the size of the
> > control virtqueue.
> Indeed, that's a case where a single flat device state blob would be
> more efficient for hardware drivers to apply than individual control
> command messages do.
>

If we're going that route, being able to set a bitmap for vlan
filtering 

Re: [PATCH v11 16/21] blockjob: protect iostatus field in BlockJob struct

2022-09-14 Thread Vladimir Sementsov-Ogievskiy

On 8/26/22 16:20, Emanuele Giuseppe Esposito wrote:

iostatus is the only field (together with .job) that needs
protection using the job mutex.

It is set in the main loop (GLOBAL_STATE functions) but read
in I/O code (block_job_error_action).

In order to protect it, change block_job_iostatus_set_err
to block_job_iostatus_set_err_locked(), always called under
job lock.

Signed-off-by: Emanuele Giuseppe Esposito
Reviewed-by: Kevin Wolf


Reviewed-by: Vladimir Sementsov-Ogievskiy 

--
Best regards,
Vladimir



[PATCH v2 4/4] tests/docker: run script use realpath instead of readlink

2022-09-14 Thread Lucas Mateus Castro(alqotel)
From: "Lucas Mateus Castro (alqotel)" 

The alpine docker image only comes with busybox, which doesn't have the
'-e' option on its readlink, so change it to 'realpath' to avoid that
problem.

Suggested-by: Daniel P. Berrangé 
Signed-off-by: Lucas Mateus Castro (alqotel) 
---
 tests/docker/run | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/docker/run b/tests/docker/run
index 421393046b..9eb96129da 100755
--- a/tests/docker/run
+++ b/tests/docker/run
@@ -15,7 +15,7 @@ if test -n "$V"; then
 set -x
 fi
 
-BASE="$(dirname $(readlink -e $0))"
+BASE="$(dirname $(realpath $0))"
 
 # Prepare the environment
 export PATH=/usr/lib/ccache:/usr/lib64/ccache:$PATH
-- 
2.31.1




Re: [PATCH v11 17/21] job.h: categorize JobDriver callbacks that need the AioContext lock

2022-09-14 Thread Vladimir Sementsov-Ogievskiy

On 8/26/22 16:21, Emanuele Giuseppe Esposito wrote:

Some callbacks implementation use bdrv_* APIs that assume the
AioContext lock is held. Make sure this invariant is documented.

Signed-off-by: Emanuele Giuseppe Esposito



Reviewed-by: Vladimir Sementsov-Ogievskiy 

--
Best regards,
Vladimir



[PULL 02/11] target/nios2: Convert semihosting errno to gdb remote errno

2022-09-14 Thread Richard Henderson
The semihosting abi used by nios2 uses the gdb remote
protocol filesys errnos.

Signed-off-by: Richard Henderson 
---
 target/nios2/nios2-semi.c | 33 +++--
 1 file changed, 31 insertions(+), 2 deletions(-)

diff --git a/target/nios2/nios2-semi.c b/target/nios2/nios2-semi.c
index 614fd76695..f76e8588c5 100644
--- a/target/nios2/nios2-semi.c
+++ b/target/nios2/nios2-semi.c
@@ -43,6 +43,35 @@
 #define HOSTED_ISATTY 12
 #define HOSTED_SYSTEM 13
 
+static int host_to_gdb_errno(int err)
+{
+#define E(X)  case E##X: return GDB_E##X
+switch (err) {
+E(PERM);
+E(NOENT);
+E(INTR);
+E(BADF);
+E(ACCES);
+E(FAULT);
+E(BUSY);
+E(EXIST);
+E(NODEV);
+E(NOTDIR);
+E(ISDIR);
+E(INVAL);
+E(NFILE);
+E(MFILE);
+E(FBIG);
+E(NOSPC);
+E(SPIPE);
+E(ROFS);
+E(NAMETOOLONG);
+default:
+return GDB_EUNKNOWN;
+}
+#undef E
+}
+
 static void nios2_semi_u32_cb(CPUState *cs, uint64_t ret, int err)
 {
 Nios2CPU *cpu = NIOS2_CPU(cs);
@@ -50,7 +79,7 @@ static void nios2_semi_u32_cb(CPUState *cs, uint64_t ret, int 
err)
 target_ulong args = env->regs[R_ARG1];
 
 if (put_user_u32(ret, args) ||
-put_user_u32(err, args + 4)) {
+put_user_u32(host_to_gdb_errno(err), args + 4)) {
 /*
  * The nios2 semihosting ABI does not provide any way to report this
  * error to the guest, so the best we can do is log it in qemu.
@@ -69,7 +98,7 @@ static void nios2_semi_u64_cb(CPUState *cs, uint64_t ret, int 
err)
 
 if (put_user_u32(ret >> 32, args) ||
 put_user_u32(ret, args + 4) ||
-put_user_u32(err, args + 8)) {
+put_user_u32(host_to_gdb_errno(err), args + 8)) {
 /* No way to report this via nios2 semihosting ABI; just log it */
 qemu_log_mask(LOG_GUEST_ERROR, "nios2-semihosting: return value "
   "discarded because argument block not writable\n");
-- 
2.34.1




[PULL 00/11] semihosting patch queue

2022-09-14 Thread Richard Henderson
The following changes since commit 79dfa177ae348bb5ab5f97c0915359b13d6186e2:

  Merge tag 'pull-qapi-2022-09-07' of git://repo.or.cz/qemu/armbru into staging 
(2022-09-07 13:13:30 -0400)

are available in the Git repository at:

  https://gitlab.com/rth7680/qemu.git tags/pull-semi-20220914

for you to fetch changes up to 7d7fb11615809839ff858328134c6a0abad27ea4:

  target/riscv: Honour -semihosting-config userspace=on and enable=on 
(2022-09-13 17:18:21 +0100)


Convert m68k to semihosting/syscalls.h.
Convert nios2 to semihosting/syscalls.h.
Allow optional use of semihosting from userspace.


Peter Maydell (7):
  semihosting: Allow optional use of semihosting from userspace
  target/arm: Honour -semihosting-config userspace=on
  target/m68k: Honour -semihosting-config userspace=on
  target/mips: Honour -semihosting-config userspace=on
  target/nios2: Honour -semihosting-config userspace=on
  target/xtensa: Honour -semihosting-config userspace=on
  target/riscv: Honour -semihosting-config userspace=on and enable=on

Richard Henderson (4):
  target/nios2: Use semihosting/syscalls.h
  target/nios2: Convert semihosting errno to gdb remote errno
  target/m68k: Use semihosting/syscalls.h
  target/m68k: Convert semihosting errno to gdb remote errno

 include/semihosting/semihost.h |  10 +-
 semihosting/config.c   |  10 +-
 softmmu/vl.c   |   2 +-
 stubs/semihost.c   |   2 +-
 target/arm/translate-a64.c |  12 +-
 target/arm/translate.c |  16 +-
 target/m68k/m68k-semi.c| 306 ++-
 target/m68k/op_helper.c|   3 +-
 target/mips/tcg/translate.c|   9 +-
 target/nios2/nios2-semi.c  | 321 ++---
 target/nios2/translate.c   |   3 +-
 target/riscv/cpu_helper.c  |   9 +-
 target/riscv/translate.c   |   1 +
 target/xtensa/translate.c  |   7 +-
 target/mips/tcg/micromips_translate.c.inc  |   6 +-
 target/mips/tcg/mips16e_translate.c.inc|   2 +-
 target/mips/tcg/nanomips_translate.c.inc   |   4 +-
 target/riscv/insn_trans/trans_privileged.c.inc |   3 +-
 qemu-options.hx|  11 +-
 19 files changed, 209 insertions(+), 528 deletions(-)



[PULL 09/11] target/nios2: Honour -semihosting-config userspace=on

2022-09-14 Thread Richard Henderson
From: Peter Maydell 

Honour the commandline -semihosting-config userspace=on option,
instead of always permitting userspace semihosting calls in system
emulation mode, by passing the correct value to the is_userspace
argument of semihosting_enabled().

Note that this is a behaviour change: if the user wants to
do semihosting calls from userspace they must now specifically
enable them on the command line.

nios2 semihosting is not implemented for linux-user builds.

Signed-off-by: Peter Maydell 
Reviewed-by: Richard Henderson 
Message-Id: <20220822141230.3658237-6-peter.mayd...@linaro.org>
Signed-off-by: Richard Henderson 
---
 target/nios2/translate.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/target/nios2/translate.c b/target/nios2/translate.c
index ff631a42f6..8dc0a32c6c 100644
--- a/target/nios2/translate.c
+++ b/target/nios2/translate.c
@@ -817,8 +817,9 @@ static void gen_break(DisasContext *dc, uint32_t code, 
uint32_t flags)
 {
 #ifndef CONFIG_USER_ONLY
 /* The semihosting instruction is "break 1".  */
+bool is_user = FIELD_EX32(dc->tb_flags, TBFLAGS, U);
 R_TYPE(instr, code);
-if (semihosting_enabled(false) && instr.imm5 == 1) {
+if (semihosting_enabled(is_user) && instr.imm5 == 1) {
 t_gen_helper_raise_exception(dc, EXCP_SEMIHOST);
 return;
 }
-- 
2.34.1




[PULL 03/11] target/m68k: Use semihosting/syscalls.h

2022-09-14 Thread Richard Henderson
This separates guest file descriptors from host file descriptors,
and utilizes shared infrastructure for integration with gdbstub.

Acked-by: Laurent Vivier 
Signed-off-by: Richard Henderson 
---
 target/m68k/m68k-semi.c | 281 +++-
 1 file changed, 49 insertions(+), 232 deletions(-)

diff --git a/target/m68k/m68k-semi.c b/target/m68k/m68k-semi.c
index d0697ddbd1..586a801034 100644
--- a/target/m68k/m68k-semi.c
+++ b/target/m68k/m68k-semi.c
@@ -21,6 +21,7 @@
 
 #include "cpu.h"
 #include "exec/gdbstub.h"
+#include "semihosting/syscalls.h"
 #include "semihosting/softmmu-uaccess.h"
 #include "hw/boards.h"
 #include "qemu/log.h"
@@ -40,56 +41,6 @@
 #define HOSTED_ISATTY 12
 #define HOSTED_SYSTEM 13
 
-static int translate_openflags(int flags)
-{
-int hf;
-
-if (flags & GDB_O_WRONLY)
-hf = O_WRONLY;
-else if (flags & GDB_O_RDWR)
-hf = O_RDWR;
-else
-hf = O_RDONLY;
-
-if (flags & GDB_O_APPEND) hf |= O_APPEND;
-if (flags & GDB_O_CREAT) hf |= O_CREAT;
-if (flags & GDB_O_TRUNC) hf |= O_TRUNC;
-if (flags & GDB_O_EXCL) hf |= O_EXCL;
-
-return hf;
-}
-
-static void translate_stat(CPUM68KState *env, target_ulong addr, struct stat 
*s)
-{
-struct gdb_stat *p;
-
-p = lock_user(VERIFY_WRITE, addr, sizeof(struct gdb_stat), 0);
-if (!p) {
-/* FIXME - should this return an error code? */
-return;
-}
-p->gdb_st_dev = cpu_to_be32(s->st_dev);
-p->gdb_st_ino = cpu_to_be32(s->st_ino);
-p->gdb_st_mode = cpu_to_be32(s->st_mode);
-p->gdb_st_nlink = cpu_to_be32(s->st_nlink);
-p->gdb_st_uid = cpu_to_be32(s->st_uid);
-p->gdb_st_gid = cpu_to_be32(s->st_gid);
-p->gdb_st_rdev = cpu_to_be32(s->st_rdev);
-p->gdb_st_size = cpu_to_be64(s->st_size);
-#ifdef _WIN32
-/* Windows stat is missing some fields.  */
-p->gdb_st_blksize = 0;
-p->gdb_st_blocks = 0;
-#else
-p->gdb_st_blksize = cpu_to_be64(s->st_blksize);
-p->gdb_st_blocks = cpu_to_be64(s->st_blocks);
-#endif
-p->gdb_st_atime = cpu_to_be32(s->st_atime);
-p->gdb_st_mtime = cpu_to_be32(s->st_mtime);
-p->gdb_st_ctime = cpu_to_be32(s->st_ctime);
-unlock_user(p, addr, sizeof(struct gdb_stat));
-}
-
 static void m68k_semi_u32_cb(CPUState *cs, uint64_t ret, int err)
 {
 M68kCPU *cpu = M68K_CPU(cs);
@@ -129,248 +80,109 @@ static void m68k_semi_u64_cb(CPUState *cs, uint64_t ret, 
int err)
  */
 #define GET_ARG(n) do { \
 if (get_user_ual(arg ## n, args + (n) * 4)) {   \
-result = -1;\
-errno = EFAULT; \
 goto failed;\
 }   \
 } while (0)
 
+#define GET_ARG64(n) do {   \
+if (get_user_ual(arg ## n, args + (n) * 4)) {   \
+goto failed64;  \
+}   \
+} while (0)
+
+
 void do_m68k_semihosting(CPUM68KState *env, int nr)
 {
 CPUState *cs = env_cpu(env);
 uint32_t args;
 target_ulong arg0, arg1, arg2, arg3;
-void *p;
-void *q;
-uint32_t len;
-uint32_t result;
 
 args = env->dregs[1];
 switch (nr) {
 case HOSTED_EXIT:
 gdb_exit(env->dregs[0]);
 exit(env->dregs[0]);
+
 case HOSTED_OPEN:
 GET_ARG(0);
 GET_ARG(1);
 GET_ARG(2);
 GET_ARG(3);
-if (use_gdb_syscalls()) {
-gdb_do_syscall(m68k_semi_u32_cb, "open,%s,%x,%x", arg0, (int)arg1,
-   arg2, arg3);
-return;
-} else {
-p = lock_user_string(arg0);
-if (!p) {
-/* FIXME - check error code? */
-result = -1;
-} else {
-result = open(p, translate_openflags(arg2), arg3);
-unlock_user(p, arg0, 0);
-}
-}
+semihost_sys_open(cs, m68k_semi_u32_cb, arg0, arg1, arg2, arg3);
 break;
+
 case HOSTED_CLOSE:
-{
-/* Ignore attempts to close stdin/out/err.  */
-GET_ARG(0);
-int fd = arg0;
-if (fd > 2) {
-if (use_gdb_syscalls()) {
-gdb_do_syscall(m68k_semi_u32_cb, "close,%x", arg0);
-return;
-} else {
-result = close(fd);
-}
-} else {
-result = 0;
-}
-break;
-}
+GET_ARG(0);
+semihost_sys_close(cs, m68k_semi_u32_cb, arg0);
+break;
+
 case HOSTED_READ:
 GET_ARG(0);
 GET_ARG(1);
 GET_ARG(2);
-len = arg2;
-if (use_gdb_syscalls()) {
-gdb_do_syscall(m68k_semi_u32_cb, "read,%x,%x,%x",
-   arg0, arg1, len);
-return;
-} e

  1   2   >