Re: [PATCH v4 2/2] target/loongarch: Implement lbt registers save/restore function

2024-09-28 Thread maobibo




On 2024/9/23 下午9:02, gaosong wrote:

在 2024/9/10 上午10:24, maobibo 写道:



On 2024/9/9 下午9:13, gaosong wrote:

在 2024/9/9 下午7:52, gaosong 写道:



在 2024/9/4 下午2:18, Bibo Mao 写道:
Six registers scr0 - scr3, eflags and ftop are added in percpu 
vmstate.
And two functions kvm_loongarch_get_lbt/kvm_loongarch_put_lbt are 
added

to save/restore lbt registers.

Signed-off-by: Bibo Mao 
---
  target/loongarch/cpu.h | 12 
  target/loongarch/kvm/kvm.c | 60 
++

  target/loongarch/machine.c | 24 +++
  3 files changed, 96 insertions(+)



Reviewed-by: Song Gao 

Thanks
Song Gao

Hi,  this patch need rebase.

Applying: target/loongarch: Implement lbt registers save/restore 
function
error: sha1 information is lacking or useless 
(target/loongarch/kvm/kvm.c).

error: could not build fake ancestor
Patch failed at 0001 target/loongarch: Implement lbt registers 
save/restore function


Hi Song,

It can apply with the latest qemu version on my side, only that it 
fails to compile since kvm uapi header files need be updated.


LBT patch on qemu side can be skipped here since it depends on LBT 
patch merged on kernel side firstly.



Hi,

The LBT patches already merged on kernel side.
Could you update this series  and add a patch to support gdb LBT feature ?

Hi Song,

QEMU TCG does not support LBT, and kernel does not use LBT and it is 
only saved and restored in kernel mode. gdb can be used to debug user 
app if there is such requirements.


There is no obvious requirement to debug kernel with LBT function, how 
about adding the function if there is such requirement in future.


Regards
Bibo Mao


Thanks.
Song Gao


Regards
Bibo Mao



Thanks.
Song Gao.






Re: [PATCH v4 2/2] target/loongarch: Implement lbt registers save/restore function

2024-09-23 Thread maobibo

Hi Tiezhu,

Does mainline gdb support to dump LBT register now?

Regards
Bibo Mao

On 2024/9/23 下午9:02, gaosong wrote:

在 2024/9/10 上午10:24, maobibo 写道:



On 2024/9/9 下午9:13, gaosong wrote:

在 2024/9/9 下午7:52, gaosong 写道:



在 2024/9/4 下午2:18, Bibo Mao 写道:
Six registers scr0 - scr3, eflags and ftop are added in percpu 
vmstate.
And two functions kvm_loongarch_get_lbt/kvm_loongarch_put_lbt are 
added

to save/restore lbt registers.

Signed-off-by: Bibo Mao 
---
  target/loongarch/cpu.h | 12 
  target/loongarch/kvm/kvm.c | 60 
++

  target/loongarch/machine.c | 24 +++
  3 files changed, 96 insertions(+)



Reviewed-by: Song Gao 

Thanks
Song Gao

Hi,  this patch need rebase.

Applying: target/loongarch: Implement lbt registers save/restore 
function
error: sha1 information is lacking or useless 
(target/loongarch/kvm/kvm.c).

error: could not build fake ancestor
Patch failed at 0001 target/loongarch: Implement lbt registers 
save/restore function


Hi Song,

It can apply with the latest qemu version on my side, only that it 
fails to compile since kvm uapi header files need be updated.


LBT patch on qemu side can be skipped here since it depends on LBT 
patch merged on kernel side firstly.



Hi,

The LBT patches already merged on kernel side.
Could you update this series  and add a patch to support gdb LBT feature ?

Thanks.
Song Gao


Regards
Bibo Mao



Thanks.
Song Gao.








Re: [PATCH v2 1/2] acpi: ged: Add macro for acpi sleep control register

2024-09-17 Thread maobibo




On 2024/9/17 下午3:44, Igor Mammedov wrote:

On Sat, 14 Sep 2024 10:25:45 +0800
maobibo  wrote:


On 2024/9/13 下午8:41, Igor Mammedov wrote:

On Wed, 11 Sep 2024 11:09:21 +0800
Bibo Mao  wrote:
   

Macro definition is added for acpi sleep control register, so that
ged emulation driver can use this, also it can be used in FDT table if
ged is exposed with FDT table.

Signed-off-by: Bibo Mao 
---
   hw/acpi/generic_event_device.c | 6 +++---
   hw/i386/acpi-microvm.c | 2 +-
   hw/loongarch/acpi-build.c  | 2 +-
   include/hw/acpi/generic_event_device.h | 9 +++--
   4 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
index 15b4c3ebbf..94992e6119 100644
--- a/hw/acpi/generic_event_device.c
+++ b/hw/acpi/generic_event_device.c
@@ -201,9 +201,9 @@ static void ged_regs_write(void *opaque, hwaddr addr, 
uint64_t data,
   
   switch (addr) {

   case ACPI_GED_REG_SLEEP_CTL:
-slp_typ = (data >> 2) & 0x07;
-slp_en  = (data >> 5) & 0x01;
-if (slp_en && slp_typ == 5) {
+slp_typ = (data & ACPI_GED_SLP_TYPx_MASK) >> ACPI_GED_SLP_TYPx_POS;

this makes a bit more complex expression once macros are expanded,
but doesn't really helps to clarity.

If I have to touch/share this code, I'd replace magic numbers above
with corresponding simple numeric macro but keep the same expressions.

That sounds reasonable, it is better to keep the same expression such as:
  slp_typ = (data >> ACPI_GED_SLP_TYPx_POS) & ACPI_GED_SLP_TYPx_MASK;

However what about for this sentence?
  slp_en  = (data >> 5) & 0x01;
I think the modification like this is better
  slp_en  = !!(data & ACPI_GED_SLP_EN);


then one has to got and check what ACPI_GED_SLP_EN is
and why it's that specific value.
while keeping it as is would be consistent with slp_typ
line right above it.
But it's stylistic, I don't really care wrt it.
  


   

+slp_en  = !!(data & ACPI_GED_SLP_EN);
+if (slp_en && slp_typ == ACPI_GED_SLP_TYPx_S5) {
   qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
   }
   return;
diff --git a/hw/i386/acpi-microvm.c b/hw/i386/acpi-microvm.c
index 279da6b4aa..1e424076d2 100644
--- a/hw/i386/acpi-microvm.c
+++ b/hw/i386/acpi-microvm.c
@@ -131,7 +131,7 @@ build_dsdt_microvm(GArray *table_data, BIOSLinker *linker,
   /* ACPI 5.0: Table 7-209 System State Package */
   scope = aml_scope("\\");
   pkg = aml_package(4);
-aml_append(pkg, aml_int(ACPI_GED_SLP_TYP_S5));
+aml_append(pkg, aml_int(ACPI_GED_SLP_TYPx_S5));


what's the point of renaming this?

ACPI spec set name with SLP_TYPx. I am ok with both, it seems less
modification is better.


I'd avoid renaming, if one need to reference spec we usually add
a comment about field/value that points to earliest spec where it
was introduced and chapter in it. Also for fields we also add
a comment with _verbatim_ field name from spec, so that one
can copy/past/search it in spec when needed.

Got it, thanks for your detailed explanation.
Will refresh it in the next patch.

Regards
Bibo Mao





Regards
Bibo Mao
   

   aml_append(pkg, aml_int(0)); /* ignored */
   aml_append(pkg, aml_int(0)); /* reserved */
   aml_append(pkg, aml_int(0)); /* reserved */
diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c
index 2638f87434..974519a347 100644
--- a/hw/loongarch/acpi-build.c
+++ b/hw/loongarch/acpi-build.c
@@ -418,7 +418,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, 
MachineState *machine)
   /* System State Package */
   scope = aml_scope("\\");
   pkg = aml_package(4);
-aml_append(pkg, aml_int(ACPI_GED_SLP_TYP_S5));
+aml_append(pkg, aml_int(ACPI_GED_SLP_TYPx_S5));
   aml_append(pkg, aml_int(0)); /* ignored */
   aml_append(pkg, aml_int(0)); /* reserved */
   aml_append(pkg, aml_int(0)); /* reserved */
diff --git a/include/hw/acpi/generic_event_device.h 
b/include/hw/acpi/generic_event_device.h
index 40af3550b5..41741e94ea 100644
--- a/include/hw/acpi/generic_event_device.h
+++ b/include/hw/acpi/generic_event_device.h
@@ -81,8 +81,13 @@ OBJECT_DECLARE_SIMPLE_TYPE(AcpiGedState, ACPI_GED)
   /* ACPI_GED_REG_RESET value for reset*/
   #define ACPI_GED_RESET_VALUE   0x42
   
-/* ACPI_GED_REG_SLEEP_CTL.SLP_TYP value for S5 (aka poweroff) */

-#define ACPI_GED_SLP_TYP_S50x05
+/* [ACPI 5.0+ FADT] Sleep Control Register */
+/* 3-bit field defines the type of hardware sleep state */
+#define ACPI_GED_SLP_TYPx_POS  0x2
+#define ACPI_GED_SLP_TYPx_MASK (0x07 << ACPI_GED_SLP_TYPx_POS)
+#define ACPI_GED_SLP_TYPx_S5   0x05  /* System \_S5 State (Soft Off) */
+/* Write-only, Set this bit causes system to enter SLP_TYPx sleeping state */
+#define ACPI_GED_SLP_EN0x20
   
   #define GED_DEVICE  "GED"

   #define AML_GED_EVT_REG "EREG"
   







Re: [RFC PATCH V2 5/5] hw/loongarch: Add KVM pch msi device support

2024-09-14 Thread maobibo

Hi Xianglai,

I do not find any usage about function kvm_irqchip_commit_routes() in 
your patch-set, do I miss something?


Regards
Bibo Mao

On 2024/9/10 下午8:18, Xianglai Li wrote:

Added pch_msi interrupt controller handling
during kernel emulation of irq chip.

Signed-off-by: Xianglai Li 
---
Cc: Paolo Bonzini 
Cc: Song Gao 
Cc: Jiaxun Yang 
Cc: Huacai Chen 
Cc: "Michael S. Tsirkin" 
Cc: Cornelia Huck 
Cc: k...@vger.kernel.org
Cc: Bibo Mao 
Cc: Xianglai Li 

  hw/intc/loongarch_pch_msi.c | 42 +++--
  hw/loongarch/virt.c | 26 +--
  target/loongarch/kvm/kvm.c  |  1 -
  3 files changed, 46 insertions(+), 23 deletions(-)

diff --git a/hw/intc/loongarch_pch_msi.c b/hw/intc/loongarch_pch_msi.c
index ecf3ed0267..bab6f852f8 100644
--- a/hw/intc/loongarch_pch_msi.c
+++ b/hw/intc/loongarch_pch_msi.c
@@ -2,7 +2,7 @@
  /*
   * QEMU Loongson 7A1000 msi interrupt controller.
   *
- * Copyright (C) 2021 Loongson Technology Corporation Limited
+ * Copyright (C) 2024 Loongson Technology Corporation Limited
   */
  
  #include "qemu/osdep.h"

@@ -14,6 +14,8 @@
  #include "hw/misc/unimp.h"
  #include "migration/vmstate.h"
  #include "trace.h"
+#include "sysemu/kvm.h"
+#include "hw/loongarch/virt.h"
  
  static uint64_t loongarch_msi_mem_read(void *opaque, hwaddr addr, unsigned size)

  {
@@ -26,14 +28,24 @@ static void loongarch_msi_mem_write(void *opaque, hwaddr 
addr,
  LoongArchPCHMSI *s = (LoongArchPCHMSI *)opaque;
  int irq_num;
  
-/*

- * vector number is irq number from upper extioi intc
- * need subtract irq base to get msi vector offset
- */
-irq_num = (val & 0xff) - s->irq_base;
-trace_loongarch_msi_set_irq(irq_num);
-assert(irq_num < s->irq_num);
-qemu_set_irq(s->pch_msi_irq[irq_num], 1);
+MSIMessage msg = {
+.address = addr,
+.data = val,
+};
+
+if (kvm_enabled() && kvm_irqchip_in_kernel()) {
+kvm_irqchip_send_msi(kvm_state, msg);
+} else {
+/*
+ * vector number is irq number from upper extioi intc
+ * need subtract irq base to get msi vector offset
+ */
+irq_num = (val & 0xff) - s->irq_base;
+trace_loongarch_msi_set_irq(irq_num);
+assert(irq_num < s->irq_num);
+
+qemu_set_irq(s->pch_msi_irq[irq_num], 1);
+}
  }
  
  static const MemoryRegionOps loongarch_pch_msi_ops = {

@@ -45,8 +57,16 @@ static const MemoryRegionOps loongarch_pch_msi_ops = {
  static void pch_msi_irq_handler(void *opaque, int irq, int level)
  {
  LoongArchPCHMSI *s = LOONGARCH_PCH_MSI(opaque);
-
-qemu_set_irq(s->pch_msi_irq[irq], level);
+MSIMessage msg = {
+.address = 0,
+.data = irq,
+};
+
+if (kvm_enabled() && kvm_irqchip_in_kernel()) {
+kvm_irqchip_send_msi(kvm_state, msg);
+} else {
+qemu_set_irq(s->pch_msi_irq[irq], level);
+}
  }
  
  static void loongarch_pch_msi_realize(DeviceState *dev, Error **errp)

diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index db0c08899b..b42cf7e5af 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -887,24 +887,28 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
  for (i = 0; i < num; i++) {
  qdev_connect_gpio_out(DEVICE(d), i, qdev_get_gpio_in(extioi, i));
  }
+}
  
-/* Add PCH PIC node */

-fdt_add_pch_pic_node(lvms, &eiointc_phandle, &pch_pic_phandle);
+/* Add PCH PIC node */
+fdt_add_pch_pic_node(lvms, &eiointc_phandle, &pch_pic_phandle);
  
-pch_msi = qdev_new(TYPE_LOONGARCH_PCH_MSI);

-start   =  num;
-num = EXTIOI_IRQS - start;
-qdev_prop_set_uint32(pch_msi, "msi_irq_base", start);
-qdev_prop_set_uint32(pch_msi, "msi_irq_num", num);
-d = SYS_BUS_DEVICE(pch_msi);
-sysbus_realize_and_unref(d, &error_fatal);
-sysbus_mmio_map(d, 0, VIRT_PCH_MSI_ADDR_LOW);
+pch_msi = qdev_new(TYPE_LOONGARCH_PCH_MSI);
+num = VIRT_PCH_PIC_IRQ_NUM;
+start   =  num;
+num = EXTIOI_IRQS - start;
+qdev_prop_set_uint32(pch_msi, "msi_irq_base", start);
+qdev_prop_set_uint32(pch_msi, "msi_irq_num", num);
+d = SYS_BUS_DEVICE(pch_msi);
+sysbus_realize_and_unref(d, &error_fatal);
+
+if (!(kvm_enabled() && kvm_irqchip_in_kernel())) {
+/* Connect pch_msi irqs to extioi */
  for (i = 0; i < num; i++) {
-/* Connect pch_msi irqs to extioi */
  qdev_connect_gpio_out(DEVICE(d), i,
qdev_get_gpio_in(extioi, i + start));
  }
  }
+sysbus_mmio_map(d, 0, VIRT_PCH_MSI_ADDR_LOW);
  
  /* Add PCH MSI node */

  fdt_add_pch_msi_node(lvms, &eiointc_phandle, &pch_msi_phandle);
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
index c07dcfd85f..e1be6a6959 100644
--- a/target/loongarch/kvm/kvm.c
+++ b/target/loongarch/kvm/kvm.c
@@ -719,7 +719,6 @@ int kvm_arch_get_default_type(Machin

Re: [PATCH] target/loongarch: Avoid shifting with bool type variable

2024-09-13 Thread maobibo




On 2024/9/14 上午10:58, Richard Henderson wrote:

On 9/13/24 18:43, Bibo Mao wrote:

Variable env->cf[i] is defined as bool type, it cannot be used with left
shifting operation. 


Not true; it promotes to 'int'.  But that isn't wide enough for the 
value that you're trying to construct.
yeap, you are right. Variable with 'bool' type can be used with left 
shifting and treated as 'int' type.


I will refresh patch in the next version.

Regards
Bibo Mao


There is existing api read_fcc(), it can be used when

dumping fp registers into coredump note segment.

Resolves: Coverity CID 1561133
Signed-off-by: Bibo Mao 


Reviewed-by: Richard Henderson 

r~


---
  target/loongarch/arch_dump.c | 6 +-
  1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/target/loongarch/arch_dump.c b/target/loongarch/arch_dump.c
index 4986db970e..d9e1120333 100644
--- a/target/loongarch/arch_dump.c
+++ b/target/loongarch/arch_dump.c
@@ -97,11 +97,7 @@ static int 
loongarch_write_elf64_fprpreg(WriteCoreDumpFunction f,
  loongarch_note_init(¬e, s, "CORE", 5, NT_PRFPREG, 
sizeof(note.fpu));

  note.fpu.fcsr = cpu_to_dump64(s, env->fcsr0);
-
-    for (i = 0; i < 8; i++) {
-    note.fpu.fcc |= env->cf[i] << (8 * i);
-    }
-    note.fpu.fcc = cpu_to_dump64(s, note.fpu.fcc);
+    note.fpu.fcc = cpu_to_dump64(s, read_fcc(env));
  for (i = 0; i < 32; ++i) {
  note.fpu.fpr[i] = cpu_to_dump64(s, env->fpr[i].vreg.UD[0]);

base-commit: 28ae3179fc52d2e4d870b635c4a412aab99759e7







Re: [PATCH v2 1/2] acpi: ged: Add macro for acpi sleep control register

2024-09-13 Thread maobibo




On 2024/9/13 下午8:41, Igor Mammedov wrote:

On Wed, 11 Sep 2024 11:09:21 +0800
Bibo Mao  wrote:


Macro definition is added for acpi sleep control register, so that
ged emulation driver can use this, also it can be used in FDT table if
ged is exposed with FDT table.

Signed-off-by: Bibo Mao 
---
  hw/acpi/generic_event_device.c | 6 +++---
  hw/i386/acpi-microvm.c | 2 +-
  hw/loongarch/acpi-build.c  | 2 +-
  include/hw/acpi/generic_event_device.h | 9 +++--
  4 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
index 15b4c3ebbf..94992e6119 100644
--- a/hw/acpi/generic_event_device.c
+++ b/hw/acpi/generic_event_device.c
@@ -201,9 +201,9 @@ static void ged_regs_write(void *opaque, hwaddr addr, 
uint64_t data,
  
  switch (addr) {

  case ACPI_GED_REG_SLEEP_CTL:
-slp_typ = (data >> 2) & 0x07;
-slp_en  = (data >> 5) & 0x01;
-if (slp_en && slp_typ == 5) {
+slp_typ = (data & ACPI_GED_SLP_TYPx_MASK) >> ACPI_GED_SLP_TYPx_POS;

this makes a bit more complex expression once macros are expanded,
but doesn't really helps to clarity.

If I have to touch/share this code, I'd replace magic numbers above
with corresponding simple numeric macro but keep the same expressions.

That sounds reasonable, it is better to keep the same expression such as:
slp_typ = (data >> ACPI_GED_SLP_TYPx_POS) & ACPI_GED_SLP_TYPx_MASK;

However what about for this sentence?
slp_en  = (data >> 5) & 0x01;
I think the modification like this is better
slp_en  = !!(data & ACPI_GED_SLP_EN);




+slp_en  = !!(data & ACPI_GED_SLP_EN);
+if (slp_en && slp_typ == ACPI_GED_SLP_TYPx_S5) {
  qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
  }
  return;
diff --git a/hw/i386/acpi-microvm.c b/hw/i386/acpi-microvm.c
index 279da6b4aa..1e424076d2 100644
--- a/hw/i386/acpi-microvm.c
+++ b/hw/i386/acpi-microvm.c
@@ -131,7 +131,7 @@ build_dsdt_microvm(GArray *table_data, BIOSLinker *linker,
  /* ACPI 5.0: Table 7-209 System State Package */
  scope = aml_scope("\\");
  pkg = aml_package(4);
-aml_append(pkg, aml_int(ACPI_GED_SLP_TYP_S5));
+aml_append(pkg, aml_int(ACPI_GED_SLP_TYPx_S5));


what's the point of renaming this?
ACPI spec set name with SLP_TYPx. I am ok with both, it seems less 
modification is better.


Regards
Bibo Mao



  aml_append(pkg, aml_int(0)); /* ignored */
  aml_append(pkg, aml_int(0)); /* reserved */
  aml_append(pkg, aml_int(0)); /* reserved */
diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c
index 2638f87434..974519a347 100644
--- a/hw/loongarch/acpi-build.c
+++ b/hw/loongarch/acpi-build.c
@@ -418,7 +418,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, 
MachineState *machine)
  /* System State Package */
  scope = aml_scope("\\");
  pkg = aml_package(4);
-aml_append(pkg, aml_int(ACPI_GED_SLP_TYP_S5));
+aml_append(pkg, aml_int(ACPI_GED_SLP_TYPx_S5));
  aml_append(pkg, aml_int(0)); /* ignored */
  aml_append(pkg, aml_int(0)); /* reserved */
  aml_append(pkg, aml_int(0)); /* reserved */
diff --git a/include/hw/acpi/generic_event_device.h 
b/include/hw/acpi/generic_event_device.h
index 40af3550b5..41741e94ea 100644
--- a/include/hw/acpi/generic_event_device.h
+++ b/include/hw/acpi/generic_event_device.h
@@ -81,8 +81,13 @@ OBJECT_DECLARE_SIMPLE_TYPE(AcpiGedState, ACPI_GED)
  /* ACPI_GED_REG_RESET value for reset*/
  #define ACPI_GED_RESET_VALUE   0x42
  
-/* ACPI_GED_REG_SLEEP_CTL.SLP_TYP value for S5 (aka poweroff) */

-#define ACPI_GED_SLP_TYP_S50x05
+/* [ACPI 5.0+ FADT] Sleep Control Register */
+/* 3-bit field defines the type of hardware sleep state */
+#define ACPI_GED_SLP_TYPx_POS  0x2
+#define ACPI_GED_SLP_TYPx_MASK (0x07 << ACPI_GED_SLP_TYPx_POS)
+#define ACPI_GED_SLP_TYPx_S5   0x05  /* System \_S5 State (Soft Off) */
+/* Write-only, Set this bit causes system to enter SLP_TYPx sleeping state */
+#define ACPI_GED_SLP_EN0x20
  
  #define GED_DEVICE  "GED"

  #define AML_GED_EVT_REG "EREG"







Re: [PATCH 3/5] include: Add loongarch_pic_common header file

2024-09-13 Thread maobibo




On 2024/9/14 上午1:19, Philippe Mathieu-Daudé wrote:

On 12/9/24 04:35, Bibo Mao wrote:

From: bibo mao 

For header file hw/intc/loongarch_pch_pic.h, add common file
hw/intc/loongarch_pic_common.h and remove duplicated macro definition
in file loongarch_pch_pic.h

Signed-off-by: Bibo Mao 
---
  include/hw/intc/loongarch_pch_pic.h | 36 +
  1 file changed, 6 insertions(+), 30 deletions(-)


Maybe easier to review if moved as first patch, moving definitions
to the new include/hw/intc/loongarch_pic_common.h

Good suggestion, will do in this way.
And thanks for you advice.

Regards
Bibo Mao


diff --git a/include/hw/intc/loongarch_pch_pic.h 
b/include/hw/intc/loongarch_pch_pic.h

index d5437e88f2..c71ee59de2 100644
--- a/include/hw/intc/loongarch_pch_pic.h
+++ b/include/hw/intc/loongarch_pch_pic.h
@@ -5,42 +5,16 @@
   * Copyright (c) 2021 Loongson Technology Corporation Limited
   */
+#ifndef HW_LOONGARCH_PCH_PIC_H
+#define HW_LOONGARCH_PCH_PIC_H
+
  #include "hw/sysbus.h"
+#include "hw/intc/loongarch_pic_common.h"
  #define TYPE_LOONGARCH_PCH_PIC "loongarch_pch_pic"
  #define PCH_PIC_NAME(name) TYPE_LOONGARCH_PCH_PIC#name
  OBJECT_DECLARE_SIMPLE_TYPE(LoongArchPCHPIC, LOONGARCH_PCH_PIC)
-#define PCH_PIC_INT_ID_VAL  0x700UL
-#define PCH_PIC_INT_ID_VER  0x1UL
-
-#define PCH_PIC_INT_ID_LO   0x00
-#define PCH_PIC_INT_ID_HI   0x04
-#define PCH_PIC_INT_MASK_LO 0x20
-#define PCH_PIC_INT_MASK_HI 0x24
-#define PCH_PIC_HTMSI_EN_LO 0x40
-#define PCH_PIC_HTMSI_EN_HI 0x44
-#define PCH_PIC_INT_EDGE_LO 0x60
-#define PCH_PIC_INT_EDGE_HI 0x64
-#define PCH_PIC_INT_CLEAR_LO    0x80
-#define PCH_PIC_INT_CLEAR_HI    0x84
-#define PCH_PIC_AUTO_CTRL0_LO   0xc0
-#define PCH_PIC_AUTO_CTRL0_HI   0xc4
-#define PCH_PIC_AUTO_CTRL1_LO   0xe0
-#define PCH_PIC_AUTO_CTRL1_HI   0xe4
-#define PCH_PIC_ROUTE_ENTRY_OFFSET  0x100
-#define PCH_PIC_ROUTE_ENTRY_END 0x13f
-#define PCH_PIC_HTMSI_VEC_OFFSET    0x200
-#define PCH_PIC_HTMSI_VEC_END   0x23f
-#define PCH_PIC_INT_STATUS_LO   0x3a0
-#define PCH_PIC_INT_STATUS_HI   0x3a4
-#define PCH_PIC_INT_POL_LO  0x3e0
-#define PCH_PIC_INT_POL_HI  0x3e4
-
-#define STATUS_LO_START 0
-#define STATUS_HI_START 0x4
-#define POL_LO_START    0x40
-#define POL_HI_START    0x44
  struct LoongArchPCHPIC {
  SysBusDevice parent_obj;
  qemu_irq parent_irq[64];
@@ -67,3 +41,5 @@ struct LoongArchPCHPIC {
  MemoryRegion iomem8;
  unsigned int irq_num;
  };
+
+#endif /* HW_LOONGARCH_PCH_PIC_H */





Re: [PATCH v4 1/5] hw/loongarch: Rename LOONGARCH_MACHINE with LOONGARCH_VIRT_MACHINE

2024-09-13 Thread maobibo




On 2024/9/13 下午4:02, Markus Armbruster wrote:

Thomas Huth  writes:


On 08/05/2024 05.11, Bibo Mao wrote:

On LoongArch system, there is only virt machine type now, name
LOONGARCH_MACHINE is confused, rename it with LOONGARCH_VIRT_MACHINE.
Machine name about Other real hw boards can be added in future.
Signed-off-by: Bibo Mao 
---

...

diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index c0999878df..6619cb52a9 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c

...

@@ -1208,7 +1208,6 @@ static void loongarch_class_init(ObjectClass *oc, void 
*data)
   MachineClass *mc = MACHINE_CLASS(oc);
   HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
   -mc->desc = "Loongson-3A5000 LS7A1000 machine";
   mc->init = loongarch_init;
   mc->default_ram_size = 1 * GiB;
   mc->default_cpu_type = LOONGARCH_CPU_TYPE_NAME("la464");


  Hi!

I noticed that the machine now does not have any description anymore, which is 
kind of ugly when you list the available machines:

$ ./qemu-system-loongarch64 -M help
Supported machines are:
none empty machine
virt (null) (default)

Could you please come up with a new mc->desc for the virt machine?


Formatting a null pointer with %s is actually a crash bug on some
systems.

Thanks for pointing it out, I will submit a patch to add the description.

Regards
Bibo Ma




Re: [RFC PATCH V2 4/5] hw/loongarch: Add KVM pch pic device support

2024-09-13 Thread maobibo




On 2024/9/10 下午8:18, Xianglai Li wrote:

Added pch_pic interrupt controller for kvm emulation.
The main process is to send the command word for
creating an pch_pic device to the kernel,
Delivers the pch pic interrupt controller configuration
register base address to the kernel.
When the VM is saved, the ioctl obtains the pch_pic
interrupt controller data in the kernel and saves it.
When the VM is recovered, the saved data is sent to the kernel.

Signed-off-by: Xianglai Li 
---
Cc: Paolo Bonzini 
Cc: Song Gao 
Cc: Jiaxun Yang 
Cc: Huacai Chen 
Cc: "Michael S. Tsirkin" 
Cc: Cornelia Huck 
Cc: k...@vger.kernel.org
Cc: Bibo Mao 
Cc: Xianglai Li 

  hw/intc/Kconfig |   3 +
  hw/intc/loongarch_pch_pic.c |  40 ---
  hw/intc/loongarch_pch_pic_kvm.c | 180 
  hw/intc/meson.build |   1 +
  hw/loongarch/Kconfig|   1 +
  hw/loongarch/virt.c |  67 ++--
  6 files changed, 249 insertions(+), 43 deletions(-)
  create mode 100644 hw/intc/loongarch_pch_pic_kvm.c

diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
index df9352d41d..1169926eec 100644
--- a/hw/intc/Kconfig
+++ b/hw/intc/Kconfig
@@ -105,6 +105,9 @@ config LOONGARCH_PCH_PIC
  bool
  select UNIMP
  
+config LOONGARCH_PCH_PIC_KVM

+bool
+
  config LOONGARCH_PCH_MSI
  select MSI_NONBROKEN
  bool
diff --git a/hw/intc/loongarch_pch_pic.c b/hw/intc/loongarch_pch_pic.c
index 2d5e65abff..13934be7d9 100644
--- a/hw/intc/loongarch_pch_pic.c
+++ b/hw/intc/loongarch_pch_pic.c
@@ -16,18 +16,27 @@
  #include "migration/vmstate.h"
  #include "trace.h"
  #include "qapi/error.h"
+#include "sysemu/kvm.h"
  
  static void pch_pic_update_irq(LoongArchPCHPIC *s, uint64_t mask, int level)

  {
  uint64_t val;
  int irq;
+int kvm_irq;
  
  if (level) {

  val = mask & s->intirr & ~s->int_mask;
  if (val) {
  irq = ctz64(val);
  s->intisr |= MAKE_64BIT_MASK(irq, 1);
-qemu_set_irq(s->parent_irq[s->htmsi_vector[irq]], 1);
+if (kvm_enabled() && kvm_irqchip_in_kernel()) {
+kvm_irq = (
+KVM_LOONGARCH_IRQ_TYPE_IOAPIC << KVM_LOONGARCH_IRQ_TYPE_SHIFT)
+| (0 <<  KVM_LOONGARCH_IRQ_VCPU_SHIFT) | s->htmsi_vector[irq];
+kvm_set_irq(kvm_state, kvm_irq, !!level);
+} else {
+qemu_set_irq(s->parent_irq[s->htmsi_vector[irq]], 1);
+}
From my point, modification is unnecessay, since there is separate irq 
handler if irqchip_in_kernel in file hw/intc/loongarch_pch_pic_kvm.c


Also I do not know why there is so such modification with file 
hw/intc/loongarch_pch_pic.c, it is irrelative and not used if 
irqchip_in_kernel is set.


Regards
Bibo Mao


  }
  } else {
  /*
@@ -38,7 +47,14 @@ static void pch_pic_update_irq(LoongArchPCHPIC *s, uint64_t 
mask, int level)
  if (val) {
  irq = ctz64(val);
  s->intisr &= ~MAKE_64BIT_MASK(irq, 1);
-qemu_set_irq(s->parent_irq[s->htmsi_vector[irq]], 0);
+if (kvm_enabled() && kvm_irqchip_in_kernel()) {
+kvm_irq = (
+KVM_LOONGARCH_IRQ_TYPE_IOAPIC << KVM_LOONGARCH_IRQ_TYPE_SHIFT)
+| (0 <<  KVM_LOONGARCH_IRQ_VCPU_SHIFT) | s->htmsi_vector[irq];
+kvm_set_irq(kvm_state, kvm_irq, !!level);
+} else {
+qemu_set_irq(s->parent_irq[s->htmsi_vector[irq]], 0);
+}
  }
  }
  }
@@ -265,18 +281,18 @@ static uint64_t loongarch_pch_pic_readb(void *opaque, 
hwaddr addr,
  {
  LoongArchPCHPIC *s = LOONGARCH_PCH_PIC(opaque);
  uint64_t val = 0;
-uint32_t offset = (addr & 0xfff) + PCH_PIC_ROUTE_ENTRY_OFFSET;
+uint32_t offset = (addr & 0xfff) + PCH_PIC_ROUTE_ENTRY_START;
  int64_t offset_tmp;
  
  switch (offset) {

-case PCH_PIC_HTMSI_VEC_OFFSET ... PCH_PIC_HTMSI_VEC_END:
-offset_tmp = offset - PCH_PIC_HTMSI_VEC_OFFSET;
+case PCH_PIC_HTMSI_VEC_START ... PCH_PIC_HTMSI_VEC_END:
+offset_tmp = offset - PCH_PIC_HTMSI_VEC_START;
  if (offset_tmp >= 0 && offset_tmp < 64) {
  val = s->htmsi_vector[offset_tmp];
  }
  break;
-case PCH_PIC_ROUTE_ENTRY_OFFSET ... PCH_PIC_ROUTE_ENTRY_END:
-offset_tmp = offset - PCH_PIC_ROUTE_ENTRY_OFFSET;
+case PCH_PIC_ROUTE_ENTRY_START ... PCH_PIC_ROUTE_ENTRY_END:
+offset_tmp = offset - PCH_PIC_ROUTE_ENTRY_START;
  if (offset_tmp >= 0 && offset_tmp < 64) {
  val = s->route_entry[offset_tmp];
  }
@@ -294,19 +310,19 @@ static void loongarch_pch_pic_writeb(void *opaque, hwaddr 
addr,
  {
  LoongArchPCHPIC *s = LOONGARCH_PCH_PIC(opaque);
  int32_t offset_tmp;
-uint32_t offset = (addr & 0xfff) + PCH_PIC_ROUTE_ENTRY_OFFSET;
+uint32_t offset = (addr & 0xfff) + PCH_PIC_ROUTE_ENTRY_START;
  
  trace_loongarch_pch_pic_writeb(size, addr, data);
  

Re: [PATCH v2 0/2] Add FDT table support with acpi ged pm register

2024-09-12 Thread maobibo

Song,

On 2024/9/12 下午7:35, gaosong wrote:



在 2024/9/11 上午11:09, Bibo Mao 写道:

ACPI ged is used for power management on LoongArch virt platform, in
general it is parsed from acpi table. However if system boot directly 
from

elf kernel, no UEFI bios is provided and acpi table cannot be used also.

Here acpi ged pm register is exposed with FDT table, it is compatbile
with syscon method in FDT table, only that acpi ged pm register is 
accessed

with 8-bit mode, rather with 32-bit mode.

---
v1 ... v2:
   1. Modify name of macro for acpi ged register from ACPI spec, and 
also add

  comments for macro definition.
---
Bibo Mao (2):
   acpi: ged: Add macro for acpi sleep control register
   hw/loongarch/virt: Add FDT table support with acpi ged pm register





  hw/acpi/generic_event_device.c |  6 ++--
  hw/i386/acpi-microvm.c |  2 +-
  hw/loongarch/acpi-build.c  |  2 +-
  hw/loongarch/virt.c    | 39 ++
  include/hw/acpi/generic_event_device.h |  9 --
  5 files changed, 51 insertions(+), 7 deletions(-)


base-commit: a66f28df650166ae8b50c992eea45e7b247f4143
Reviewed-by: Song Gao 


Applied series to loongarch-next


It is not urgent and it needs approval from other maintainers :)

Regards
Bibo Mao


Thanks
Song Gao







Re: [RFC PATCH V2 3/5] hw/loongarch: Add KVM extioi device support

2024-09-11 Thread maobibo




On 2024/9/10 下午8:18, Xianglai Li wrote:

Added extioi interrupt controller for kvm emulation.
The main process is to send the command word for
creating an extioi device to the kernel.
When the VM is saved, the ioctl obtains the related
data of the extioi interrupt controller in the kernel
and saves it. When the VM is recovered, the saved data
is sent to the kernel.

Signed-off-by: Tianrui Zhao 
Signed-off-by: Xianglai Li 
---
Cc: Paolo Bonzini 
Cc: Song Gao 
Cc: Jiaxun Yang 
Cc: Huacai Chen 
Cc: "Michael S. Tsirkin" 
Cc: Cornelia Huck 
Cc: k...@vger.kernel.org
Cc: Bibo Mao 
Cc: Xianglai Li 

  hw/intc/Kconfig|   3 +
  hw/intc/loongarch_extioi_kvm.c | 250 +
  hw/intc/meson.build|   1 +
  hw/loongarch/Kconfig   |   1 +
  hw/loongarch/virt.c|  51 ---
  5 files changed, 285 insertions(+), 21 deletions(-)
  create mode 100644 hw/intc/loongarch_extioi_kvm.c

diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
index 5201505f23..df9352d41d 100644
--- a/hw/intc/Kconfig
+++ b/hw/intc/Kconfig
@@ -112,3 +112,6 @@ config LOONGARCH_PCH_MSI
  
  config LOONGARCH_EXTIOI

  bool
+
+config LOONGARCH_EXTIOI_KVM
+bool
diff --git a/hw/intc/loongarch_extioi_kvm.c b/hw/intc/loongarch_extioi_kvm.c
new file mode 100644
index 00..139a00ac2a
--- /dev/null
+++ b/hw/intc/loongarch_extioi_kvm.c
@@ -0,0 +1,250 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * LoongArch kvm extioi interrupt support
+ *
+ * Copyright (C) 2024 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "hw/qdev-properties.h"
+#include "qemu/typedefs.h"
+#include "hw/intc/loongarch_extioi.h"
+#include "hw/sysbus.h"
+#include "linux/kvm.h"
+#include "migration/vmstate.h"
+#include "qapi/error.h"
+#include "sysemu/kvm.h"
+
+static void kvm_extioi_access_regs(int fd, uint64_t addr,
+   void *val, bool is_write)
+{
+kvm_device_access(fd, KVM_DEV_LOONGARCH_EXTIOI_GRP_REGS,
+  addr, val, is_write, &error_abort);
+}
+
+static void kvm_extioi_access_sw_status(int fd, uint64_t addr,
+   void *val, bool is_write)
+{
+kvm_device_access(fd, KVM_DEV_LOONGARCH_EXTIOI_GRP_SW_STATUS,
+  addr, val, is_write, &error_abort);
+}
+
+static void kvm_extioi_save_load_sw_status(void *opaque, bool is_write)
+{
+KVMLoongArchExtIOI *s = (KVMLoongArchExtIOI *)opaque;
+KVMLoongArchExtIOIClass *class = KVM_LOONGARCH_EXTIOI_GET_CLASS(s);
+int fd = class->dev_fd;
+int addr;
+
+addr = KVM_DEV_LOONGARCH_EXTIOI_SW_STATUS_NUM_CPU;
+kvm_extioi_access_sw_status(fd, addr, (void *)&s->num_cpu, is_write);
+
+addr = KVM_DEV_LOONGARCH_EXTIOI_SW_STATUS_FEATURE;
+kvm_extioi_access_sw_status(fd, addr, (void *)&s->features, is_write);
+
+addr = KVM_DEV_LOONGARCH_EXTIOI_SW_STATUS_STATE;
+kvm_extioi_access_sw_status(fd, addr, (void *)&s->status, is_write);
+}
+
+static void kvm_extioi_save_load_regs(void *opaque, bool is_write)
+{
+KVMLoongArchExtIOI *s = (KVMLoongArchExtIOI *)opaque;
+KVMLoongArchExtIOIClass *class = KVM_LOONGARCH_EXTIOI_GET_CLASS(s);
+int fd = class->dev_fd;
+int addr, offset, cpuid;
+
+for (addr = EXTIOI_NODETYPE_START; addr < EXTIOI_NODETYPE_END; addr += 4) {
+offset = (addr - EXTIOI_NODETYPE_START) / 4;
+kvm_extioi_access_regs(fd, addr,
+   (void *)&s->nodetype[offset], is_write);
+}
+
+for (addr = EXTIOI_IPMAP_START; addr < EXTIOI_IPMAP_END; addr += 4) {
+offset = (addr - EXTIOI_IPMAP_START) / 4;
+kvm_extioi_access_regs(fd, addr, (void *)&s->ipmap[offset], is_write);
+}
+
+for (addr = EXTIOI_ENABLE_START; addr < EXTIOI_ENABLE_END; addr += 4) {
+offset = (addr - EXTIOI_ENABLE_START) / 4;
+kvm_extioi_access_regs(fd, addr,
+   (void *)&s->enable[offset], is_write);
+}
+
+for (addr = EXTIOI_BOUNCE_START; addr < EXTIOI_BOUNCE_END; addr += 4) {
+offset = (addr - EXTIOI_BOUNCE_START) / 4;
+kvm_extioi_access_regs(fd, addr,
+   (void *)&s->bounce[offset], is_write);
+}
+
+for (addr = EXTIOI_ISR_START; addr < EXTIOI_ISR_END; addr += 4) {
+offset = (addr - EXTIOI_ISR_START) / 4;
+kvm_extioi_access_regs(fd, addr,
+   (void *)&s->isr[offset], is_write);
+}
+
+for (addr = EXTIOI_COREMAP_START; addr < EXTIOI_COREMAP_END; addr += 4) {
+offset = (addr - EXTIOI_COREMAP_START) / 4;
+kvm_extioi_access_regs(fd, addr,
+   (void *)&s->coremap[offset], is_write);
+}
+
+for (cpuid = 0; cpuid < s->num_cpu; cpuid++) {
+for (addr = EXTIOI_COREISR_START;
+ addr < EXTIOI_COREISR_END; addr += 4) {
+offset = (addr - EXTIOI_COREISR_START) / 4;
+addr = (cpuid << 16) | addr;

Re: [PATCH 1/2] acpi: ged: Add macro for acpi ged sleep register

2024-09-10 Thread maobibo




On 2024/9/11 上午1:32, Michael S. Tsirkin wrote:

On Fri, Sep 06, 2024 at 10:19:42AM +0800, Bibo Mao wrote:

Macro definition is added for acpi ged sleep register, so that ged
emulation driver can use this, also it can be used in FDT table if
ged is exposed with FDT table.

Signed-off-by: Bibo Mao 
---
  hw/acpi/generic_event_device.c | 6 +++---
  include/hw/acpi/generic_event_device.h | 3 +++
  2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
index 15b4c3ebbf..10a338877c 100644
--- a/hw/acpi/generic_event_device.c
+++ b/hw/acpi/generic_event_device.c
@@ -201,9 +201,9 @@ static void ged_regs_write(void *opaque, hwaddr addr, 
uint64_t data,
  
  switch (addr) {

  case ACPI_GED_REG_SLEEP_CTL:
-slp_typ = (data >> 2) & 0x07;
-slp_en  = (data >> 5) & 0x01;
-if (slp_en && slp_typ == 5) {
+slp_typ = (data & ACPI_GED_SLP_TYP_MASK) >> ACPI_GED_SLP_TYP_SHIFT;
+slp_en  = !!(data  & ACPI_GED_SLP_ENABLE);
+if (slp_en && slp_typ == ACPI_GED_SLP_TYP_S5) {
  qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
  }
  return;
diff --git a/include/hw/acpi/generic_event_device.h 
b/include/hw/acpi/generic_event_device.h
index 40af3550b5..526fea6efe 100644
--- a/include/hw/acpi/generic_event_device.h
+++ b/include/hw/acpi/generic_event_device.h
@@ -82,7 +82,10 @@ OBJECT_DECLARE_SIMPLE_TYPE(AcpiGedState, ACPI_GED)
  #define ACPI_GED_RESET_VALUE   0x42
  
  /* ACPI_GED_REG_SLEEP_CTL.SLP_TYP value for S5 (aka poweroff) */

+#define ACPI_GED_SLP_TYP_SHIFT 0x02
  #define ACPI_GED_SLP_TYP_S50x05
+#define ACPI_GED_SLP_TYP_MASK  0x1C
+#define ACPI_GED_SLP_ENABLE0x20


The comment is wrong now, isn't it?
Pls document each value, copying name from spec verbatim.

The name comes from linux header files with little modification.
#define ACPI_X_WAKE_STATUS  0x80
#define ACPI_X_SLEEP_TYPE_MASK  0x1C
#define ACPI_X_SLEEP_TYPE_POSITION  0x02
#define ACPI_X_SLEEP_ENABLE 0x20

yeap, it will better if comes from spec verbatim. I will investigate and 
refresh the patch in next version.


Regards
Bibo Mao


  
  #define GED_DEVICE  "GED"

  #define AML_GED_EVT_REG "EREG"
--
2.39.3





Re: [PATCH v4 2/2] target/loongarch: Implement lbt registers save/restore function

2024-09-09 Thread maobibo




On 2024/9/9 下午9:13, gaosong wrote:

在 2024/9/9 下午7:52, gaosong 写道:



在 2024/9/4 下午2:18, Bibo Mao 写道:

Six registers scr0 - scr3, eflags and ftop are added in percpu vmstate.
And two functions kvm_loongarch_get_lbt/kvm_loongarch_put_lbt are added
to save/restore lbt registers.

Signed-off-by: Bibo Mao 
---
  target/loongarch/cpu.h | 12 
  target/loongarch/kvm/kvm.c | 60 ++
  target/loongarch/machine.c | 24 +++
  3 files changed, 96 insertions(+)



Reviewed-by: Song Gao 

Thanks
Song Gao

Hi,  this patch need rebase.

Applying: target/loongarch: Implement lbt registers save/restore function
error: sha1 information is lacking or useless (target/loongarch/kvm/kvm.c).
error: could not build fake ancestor
Patch failed at 0001 target/loongarch: Implement lbt registers 
save/restore function


Hi Song,

It can apply with the latest qemu version on my side, only that it fails 
to compile since kvm uapi header files need be updated.


LBT patch on qemu side can be skipped here since it depends on LBT patch 
merged on kernel side firstly.


Regards
Bibo Mao



Thanks.
Song Gao.






Re: [PATCH v3] hw/loongarch: virt: support up to 4 serial ports

2024-09-08 Thread maobibo




On 2024/9/7 下午10:34, Jason A. Donenfeld wrote:

In order to support additional channels of communication using
`-serial`, add several serial ports, up to the standard 4 generally
supported by the 8250 driver.

Signed-off-by: Jason A. Donenfeld 
---
  hw/loongarch/acpi-build.c  | 23 +++
  hw/loongarch/virt.c| 23 +--
  include/hw/pci-host/ls7a.h |  9 +
  3 files changed, 33 insertions(+), 22 deletions(-)

diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c
index 3912c8d307..459d2b5f84 100644
--- a/hw/loongarch/acpi-build.c
+++ b/hw/loongarch/acpi-build.c
@@ -31,6 +31,7 @@
  
  #include "hw/acpi/generic_event_device.h"

  #include "hw/pci-host/gpex.h"
+#include "sysemu/sysemu.h"
  #include "sysemu/tpm.h"
  #include "hw/platform-bus.h"
  #include "hw/acpi/aml-build.h"
@@ -290,23 +291,27 @@ struct AcpiBuildState {
  MemoryRegion *linker_mr;
  } AcpiBuildState;
  
-static void build_uart_device_aml(Aml *table)

+static void build_uart_device_aml(Aml *table, int index)
  {
  Aml *dev;
  Aml *crs;
  Aml *pkg0, *pkg1, *pkg2;
-uint32_t uart_irq = VIRT_UART_IRQ;
-
-Aml *scope = aml_scope("_SB");
-dev = aml_device("COMA");
+Aml *scope;
+uint32_t uart_irq;
+uint64_t base;
+
+uart_irq = VIRT_UART_IRQ + index;
+base = VIRT_UART_BASE + index * VIRT_UART_SIZE;
+scope = aml_scope("_SB");
+dev = aml_device("COM%d", index);
  aml_append(dev, aml_name_decl("_HID", aml_string("PNP0501")));
-aml_append(dev, aml_name_decl("_UID", aml_int(0)));
+aml_append(dev, aml_name_decl("_UID", aml_int(index)));
  aml_append(dev, aml_name_decl("_CCA", aml_int(1)));
  crs = aml_resource_template();
  aml_append(crs,
  aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED,
   AML_NON_CACHEABLE, AML_READ_WRITE,
- 0, VIRT_UART_BASE, VIRT_UART_BASE + VIRT_UART_SIZE - 
1,
+ 0, base, base + VIRT_UART_SIZE - 1,
   0, VIRT_UART_SIZE));
  aml_append(crs, aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH,
AML_SHARED, &uart_irq, 1));
@@ -439,6 +444,7 @@ static void acpi_dsdt_add_tpm(Aml *scope, 
LoongArchVirtMachineState *vms)
  static void
  build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine)
  {
+int i;
  Aml *dsdt, *scope, *pkg;
  LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(machine);
  AcpiTable table = { .sig = "DSDT", .rev = 1, .oem_id = lvms->oem_id,
@@ -446,7 +452,8 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, 
MachineState *machine)
  
  acpi_table_begin(&table, table_data);

  dsdt = init_aml_allocator();
-build_uart_device_aml(dsdt);
+for (i = VIRT_UART_COUNT; i --> 0;)
+build_uart_device_aml(dsdt, i);
  build_pci_device_aml(dsdt, lvms);
  build_la_ged_aml(dsdt, machine);
  build_flash_aml(dsdt, lvms);
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 4151fc5e0c..b9bd88d3f4 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -319,10 +319,10 @@ static void fdt_add_ged_reset(LoongArchVirtMachineState 
*lvms)
  }
  
  static void fdt_add_uart_node(LoongArchVirtMachineState *lvms,

-  uint32_t *pch_pic_phandle)
+  uint32_t *pch_pic_phandle, hwaddr base,
+  int irq, bool chosen)
  {
  char *nodename;
-hwaddr base = VIRT_UART_BASE;
  hwaddr size = VIRT_UART_SIZE;
  MachineState *ms = MACHINE(lvms);
  
@@ -331,9 +331,9 @@ static void fdt_add_uart_node(LoongArchVirtMachineState *lvms,

  qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "ns16550a");
  qemu_fdt_setprop_cells(ms->fdt, nodename, "reg", 0x0, base, 0x0, size);
  qemu_fdt_setprop_cell(ms->fdt, nodename, "clock-frequency", 1);
-qemu_fdt_setprop_string(ms->fdt, "/chosen", "stdout-path", nodename);
-qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts",
-   VIRT_UART_IRQ - VIRT_GSI_BASE, 0x4);
+if (chosen)
+qemu_fdt_setprop_string(ms->fdt, "/chosen", "stdout-path", nodename);
+qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts", irq, 0x4);
  qemu_fdt_setprop_cell(ms->fdt, nodename, "interrupt-parent",
*pch_pic_phandle);
  g_free(nodename);
@@ -750,11 +750,14 @@ static void virt_devices_init(DeviceState *pch_pic,
  /* Add pcie node */
  fdt_add_pcie_node(lvms, pch_pic_phandle, pch_msi_phandle);
  
-serial_mm_init(get_system_memory(), VIRT_UART_BASE, 0,

-   qdev_get_gpio_in(pch_pic,
-VIRT_UART_IRQ - VIRT_GSI_BASE),
-   115200, serial_hd(0), DEVICE_LITTLE_ENDIAN);
-fdt_add_uart_node(lvms, pch_pic_phandle);
+for (i = VIRT_UART_COUNT; i --> 0;) {
+hwaddr base = VIRT_UART_B

Re: [PATCH v2] hw/loongarch: virt: support up to 4 serial ports

2024-09-06 Thread maobibo

Hi Jason,

It works well with ELF kernel, however it fails to boot with UEFI BIOS. 
Maybe it is problem of UEFI BIOS, can we create UART in reverse order? 
so that it can work well on both ELF kernel and UEFI BIOS.


Also for develops they usually use as earlycon with command line 
-serial stdio --append "... earlycon=uart,mmio,0x1fe001e0", this 
requires to uart with address 0x1fe001e0 as the first serial port.


Just small code base your patch like this:

-for (i = 0; i < VIRT_UART_COUNT; ++i) {
+for (i = VIRT_UART_COUNT - 1; i >= 0; i--) {
 hwaddr base = VIRT_UART_BASE + i * VIRT_UART_SIZE;
 int irq = VIRT_UART_IRQ + i - VIRT_GSI_BASE;
 serial_mm_init(get_system_memory(), base, 0,
qdev_get_gpio_in(pch_pic, irq),
-   115200, serial_hd(VIRT_UART_COUNT - 1 - i),
+   115200, serial_hd(i),
DEVICE_LITTLE_ENDIAN);
-fdt_add_uart_node(lvms, pch_pic_phandle, base, irq, i == 
VIRT_UART_COUNT - 1 - i);

+fdt_add_uart_node(lvms, pch_pic_phandle, base, irq, i == 0);
 }

Regards
Bibo Mao

On 2024/9/6 下午10:31, Jason A. Donenfeld wrote:

In order to support additional channels of communication using
`-serial`, add several serial ports, up to the standard 4 generally
supported by the 8250 driver.

Signed-off-by: Jason A. Donenfeld 
---
As I don't use ACPI, I haven't tested the ACPI part of this, which
Maobibo wrote.

  hw/loongarch/acpi-build.c  | 23 +++
  hw/loongarch/virt.c| 24 ++--
  include/hw/pci-host/ls7a.h |  9 +
  3 files changed, 34 insertions(+), 22 deletions(-)

diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c
index 2638f87434..2750c6e858 100644
--- a/hw/loongarch/acpi-build.c
+++ b/hw/loongarch/acpi-build.c
@@ -31,6 +31,7 @@
  
  #include "hw/acpi/generic_event_device.h"

  #include "hw/pci-host/gpex.h"
+#include "sysemu/sysemu.h"
  #include "sysemu/tpm.h"
  #include "hw/platform-bus.h"
  #include "hw/acpi/aml-build.h"
@@ -252,23 +253,27 @@ struct AcpiBuildState {
  MemoryRegion *linker_mr;
  } AcpiBuildState;
  
-static void build_uart_device_aml(Aml *table)

+static void build_uart_device_aml(Aml *table, int index)
  {
  Aml *dev;
  Aml *crs;
  Aml *pkg0, *pkg1, *pkg2;
-uint32_t uart_irq = VIRT_UART_IRQ;
-
-Aml *scope = aml_scope("_SB");
-dev = aml_device("COMA");
+Aml *scope;
+uint32_t uart_irq;
+uint64_t base;
+
+uart_irq = VIRT_UART_IRQ + index;
+base = VIRT_UART_BASE + index * VIRT_UART_SIZE;
+scope = aml_scope("_SB");
+dev = aml_device("COM%d", VIRT_UART_COUNT - 1 - index);
  aml_append(dev, aml_name_decl("_HID", aml_string("PNP0501")));
-aml_append(dev, aml_name_decl("_UID", aml_int(0)));
+aml_append(dev, aml_name_decl("_UID", aml_int(VIRT_UART_COUNT - 1 - 
index)));
  aml_append(dev, aml_name_decl("_CCA", aml_int(1)));
  crs = aml_resource_template();
  aml_append(crs,
  aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED,
   AML_NON_CACHEABLE, AML_READ_WRITE,
- 0, VIRT_UART_BASE, VIRT_UART_BASE + VIRT_UART_SIZE - 
1,
+ 0, base, base + VIRT_UART_SIZE - 1,
   0, VIRT_UART_SIZE));
  aml_append(crs, aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH,
AML_SHARED, &uart_irq, 1));
@@ -401,6 +406,7 @@ static void acpi_dsdt_add_tpm(Aml *scope, 
LoongArchVirtMachineState *vms)
  static void
  build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine)
  {
+int i;
  Aml *dsdt, *scope, *pkg;
  LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(machine);
  AcpiTable table = { .sig = "DSDT", .rev = 1, .oem_id = lvms->oem_id,
@@ -408,7 +414,8 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, 
MachineState *machine)
  
  acpi_table_begin(&table, table_data);

  dsdt = init_aml_allocator();
-build_uart_device_aml(dsdt);
+for (i = 0; i < VIRT_UART_COUNT; ++i)
+build_uart_device_aml(dsdt, i);
  build_pci_device_aml(dsdt, lvms);
  build_la_ged_aml(dsdt, machine);
  build_flash_aml(dsdt, lvms);
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 4151fc5e0c..6e8608874c 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -319,10 +319,10 @@ static void fdt_add_ged_reset(LoongArchVirtMachineState 
*lvms)
  }
  
  static void fdt_add_uart_node(LoongArchVirtMachineState *lvms,

-  uint32_t *pch_pic_phandle)
+  uint32_t *pch_pic_phandle, hwaddr base,
+  int irq, bool chosen)
  {
  char *noden

Re: LoongArch without CONFIG_ACPI and CONFIG_EFI

2024-09-06 Thread maobibo

Add huacai who is maintainer of Loongarch Linux kernel.

On 2024/9/6 下午10:55, Jason A. Donenfeld wrote:

Hi,

It appears that as of QEMU 9.1, it's possible to boot LoongArch machines
that don't provide EFI or ACPI.

Would you consider removing the `select ACPI` and `select EFI` from the
arch Kconfig, so that kernels built for this minimal QEMU environment
can be a bit leaner and quicker to build?

Jason






Re: [PATCH] hw/loongarch: virt: support up to 4 serial ports

2024-09-06 Thread maobibo




On 2024/9/6 下午12:49, Jason A. Donenfeld wrote:

In order to support additional channels of communication using
`-serial`, add several serial ports, up to the standard 4 generally
supported by the 8250 driver.

Signed-off-by: Jason A. Donenfeld 
---
  hw/loongarch/virt.c| 24 ++--
  include/hw/pci-host/ls7a.h |  9 +
  2 files changed, 19 insertions(+), 14 deletions(-)

diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 4151fc5e0c..155678b684 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -319,10 +319,10 @@ static void fdt_add_ged_reset(LoongArchVirtMachineState 
*lvms)
  }
  
  static void fdt_add_uart_node(LoongArchVirtMachineState *lvms,

-  uint32_t *pch_pic_phandle)
+  uint32_t *pch_pic_phandle, hwaddr base,
+  int irq, bool chosen)
  {
  char *nodename;
-hwaddr base = VIRT_UART_BASE;
  hwaddr size = VIRT_UART_SIZE;
  MachineState *ms = MACHINE(lvms);
  
@@ -331,9 +331,9 @@ static void fdt_add_uart_node(LoongArchVirtMachineState *lvms,

  qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "ns16550a");
  qemu_fdt_setprop_cells(ms->fdt, nodename, "reg", 0x0, base, 0x0, size);
  qemu_fdt_setprop_cell(ms->fdt, nodename, "clock-frequency", 1);
-qemu_fdt_setprop_string(ms->fdt, "/chosen", "stdout-path", nodename);
-qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts",
-   VIRT_UART_IRQ - VIRT_GSI_BASE, 0x4);
+if (chosen)
+qemu_fdt_setprop_string(ms->fdt, "/chosen", "stdout-path", nodename);
+qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts", irq, 0x4);
  qemu_fdt_setprop_cell(ms->fdt, nodename, "interrupt-parent",
*pch_pic_phandle);
  g_free(nodename);
@@ -750,11 +750,15 @@ static void virt_devices_init(DeviceState *pch_pic,
  /* Add pcie node */
  fdt_add_pcie_node(lvms, pch_pic_phandle, pch_msi_phandle);
  
-serial_mm_init(get_system_memory(), VIRT_UART_BASE, 0,

-   qdev_get_gpio_in(pch_pic,
-VIRT_UART_IRQ - VIRT_GSI_BASE),
-   115200, serial_hd(0), DEVICE_LITTLE_ENDIAN);
-fdt_add_uart_node(lvms, pch_pic_phandle);
+for (i = 0; i < VIRT_UART_COUNT; ++i) {

How about adding serial_hd(i) checking here, such as
  for (i = 0; (i < VIRT_UART_COUNT) && serial_hd(i); ++i) {


+hwaddr base = VIRT_UART_BASE + i * VIRT_UART_SIZE;
+int irq = VIRT_UART_IRQ + i - VIRT_GSI_BASE;
+serial_mm_init(get_system_memory(), base, 0,
+   qdev_get_gpio_in(pch_pic, irq),
+   115200, serial_hd(VIRT_UART_COUNT - 1 - i),
is it serial_hd(i) here rather than serial_hd(VIRT_UART_COUNT - 1 - i)? 
In general serial_hd(0) is default serial.



+   DEVICE_LITTLE_ENDIAN);
+fdt_add_uart_node(lvms, pch_pic_phandle, base, irq, i == 0);
+}
  
  /* Network init */

  pci_init_nic_devices(pci_bus, mc->default_nic);
diff --git a/include/hw/pci-host/ls7a.h b/include/hw/pci-host/ls7a.h
index cd7c9ec7bc..79d4ea8501 100644
--- a/include/hw/pci-host/ls7a.h
+++ b/include/hw/pci-host/ls7a.h
@@ -36,17 +36,18 @@
  #define VIRT_PCH_PIC_IRQ_NUM 32
  #define VIRT_GSI_BASE64
  #define VIRT_DEVICE_IRQS 16
+#define VIRT_UART_COUNT  4
  #define VIRT_UART_IRQ(VIRT_GSI_BASE + 2)
  #define VIRT_UART_BASE   0x1fe001e0
-#define VIRT_UART_SIZE   0X100
-#define VIRT_RTC_IRQ (VIRT_GSI_BASE + 3)
+#define VIRT_UART_SIZE   0x100
+#define VIRT_RTC_IRQ (VIRT_GSI_BASE + 6)
  #define VIRT_MISC_REG_BASE   (VIRT_PCH_REG_BASE + 0x0008)
  #define VIRT_RTC_REG_BASE(VIRT_MISC_REG_BASE + 0x00050100)
  #define VIRT_RTC_LEN 0x100
-#define VIRT_SCI_IRQ (VIRT_GSI_BASE + 4)
+#define VIRT_SCI_IRQ (VIRT_GSI_BASE + 7)
  
  #define VIRT_PLATFORM_BUS_BASEADDRESS   0x1600

  #define VIRT_PLATFORM_BUS_SIZE  0x200
  #define VIRT_PLATFORM_BUS_NUM_IRQS  2
-#define VIRT_PLATFORM_BUS_IRQ   (VIRT_GSI_BASE + 5)
+#define VIRT_PLATFORM_BUS_IRQ   (VIRT_GSI_BASE + 8)
  #endif


By the way, serial port for acpi table should be refreshed also, such as
diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c
index 2638f87434..5bd2a9beaa 100644
--- a/hw/loongarch/acpi-build.c
+++ b/hw/loongarch/acpi-build.c
@@ -31,6 +31,7 @@

 #include "hw/acpi/generic_event_device.h"
 #include "hw/pci-host/gpex.h"
+#include "sysemu/sysemu.h"
 #include "sysemu/tpm.h"
 #include "hw/platform-bus.h"
 #include "hw/acpi/aml-build.h"
@@ -252,23 +253,26 @@ struct AcpiBuildState {
 MemoryRegion *linker_mr;
 } AcpiBuildState;

-static void build_uart_device_aml(Aml *table)
+static void build_uart_device_aml(Aml *table, int index)
 {
 Aml *dev;
 Aml *crs;
 Aml *pkg0, *pkg1, 

Re: qemu direct kernel boot on LoongArch

2024-09-05 Thread maobibo




On 2024/9/6 上午12:03, Thomas Weißschuh wrote:

On 2024-09-05 17:18:07+, Jason A. Donenfeld wrote:

On Thu, Sep 5, 2024 at 5:16 PM Thomas Weißschuh  wrote:


On 2024-09-05 17:07:22+, Jason A. Donenfeld wrote:

On Thu, Sep 5, 2024 at 5:05 PM Thomas Weißschuh  wrote:


On 2024-09-05 16:53:55+, Jason A. Donenfeld wrote:

On Thu, Sep 05, 2024 at 07:25:05AM +0200, Thomas Weißschuh wrote:

On 2024-09-05 06:04:12+, Jason A. Donenfeld wrote:

On Thu, Sep 5, 2024 at 5:45 AM maobibo  wrote:


Jason,

With the latest qemu 9.1 version, elf format booting is supported.


Thanks, I just figured this out too, about 4 minutes ago. Excellent.
And the 1G minimum ram limit is gone too.

Now working on how to trigger resets.


With "reset" do you mean normal (non-panic) system shutdown/poweroff?
Since QEMU 9.1 and a recent kernel you can use the pvpanic device for
that in a cross-architecture way.


What I mean is that I need for userspace calling `reboot(RB_AUTOBOOT);`
to actually result in QEMU being told to reboot the system. Sounds like
that's not possible (yet?) in 9.1?


With reboot(RB_POWER_OFF) this is indeed the exact usecase for pvpanic


I'm actually using reboot(RB_AUTOBOOT) wth QEMU's -no-reboot, because
that tends to be far more compatible with a greater number of
platforms, for example, x86 without acpi. Shucks.


You can check that both QEMU and the kernel support pvpanic shutdown
through sysfs and if so use reboot(RB_POWER_OFF); and
reboot(RB_AUTOBOOT) otherwise.


I guess. But the whole idea is to bloat the code as little as possible
and use one interface for everything. Pushing that all up into
userspace is pretty icky.


If it works through ACPI everywhere then sure.


It sounds like LoongArch already supports this via ACPI GED, but
there's some plumbing that needs to be done still. So maybe I'll just
wait for that.


Also sounds reasonable.

yeap, will submit a patch to expose ACPI GED pm interface with FDT method.




Meanwhile, any idea about adding a second serial to the platform? I've
been futzing with it for a bit now to no avail.


No idea, sorry.

Will investigate the second serial method.

Regards
Bibo Mao




Re: qemu direct kernel boot on LoongArch

2024-09-05 Thread maobibo




On 2024/9/5 下午11:49, Jason A. Donenfeld wrote:

On Thu, Sep 05, 2024 at 04:54:41PM +0200, Jason A. Donenfeld wrote:

On Thu, Sep 05, 2024 at 02:11:32PM +0800, maobibo wrote:



On 2024/9/5 下午1:25, Thomas Weißschuh wrote:

On 2024-09-05 06:04:12+, Jason A. Donenfeld wrote:

On Thu, Sep 5, 2024 at 5:45 AM maobibo  wrote:


Jason,

With the latest qemu 9.1 version, elf format booting is supported.


Thanks, I just figured this out too, about 4 minutes ago. Excellent.
And the 1G minimum ram limit is gone too.

Now working on how to trigger resets.


With "reset" do you mean normal (non-panic) system shutdown/poweroff?
Since QEMU 9.1 and a recent kernel you can use the pvpanic device for
that in a cross-architecture way.

LoongArch uses acpi GED device to reboot machine. Now there is no FDT
table description and FDT driver for acpi GED device :(


So you mean that QEMU exposes it via ACPI, but not via FDT, and the
kernel doesn't know how to recognize it, even with ACPI?


Ahh, it looks like QEMU exposes it via ACPI, but ACPI is broken (?) when
booting directly from ELF. So it needs to be exposed via FDT instead? Or
ACPI needs to be fixed with direct ELF boot?
We plant to expose ACPI GED via FDT interface with syscon method, and 
the reboot driver in linux kernel side is

drivers/power/reset/syscon-reboot.c.

The only difference is that ACPI GED register is accessed with 
byte-mode, it seems that it works well with draft version.


Regards
Bibo Mao







Re: qemu direct kernel boot on LoongArch

2024-09-04 Thread maobibo




On 2024/9/5 下午1:25, Thomas Weißschuh wrote:

On 2024-09-05 06:04:12+, Jason A. Donenfeld wrote:

On Thu, Sep 5, 2024 at 5:45 AM maobibo  wrote:


Jason,

With the latest qemu 9.1 version, elf format booting is supported.


Thanks, I just figured this out too, about 4 minutes ago. Excellent.
And the 1G minimum ram limit is gone too.

Now working on how to trigger resets.


With "reset" do you mean normal (non-panic) system shutdown/poweroff?
Since QEMU 9.1 and a recent kernel you can use the pvpanic device for
that in a cross-architecture way.
LoongArch uses acpi GED device to reboot machine. Now there is no FDT 
table description and FDT driver for acpi GED device :(


We will investigate pvpanic method.

Regards
Bibo Mao



Thomas






Re: qemu direct kernel boot on LoongArch

2024-09-04 Thread maobibo

Jason,

With the latest qemu 9.1 version, elf format booting is supported. Qemu 
9.0 does not support it still, here is example command line.


./qemu-system-loongarch64  -m 4G -smp 2 --cpu la464 --machine virt 
-serial stdio   -monitor telnet:localhost:4495,server,nowait -kernel 
/root/linux_larch/vmlinux -initrd ramdisk  -append "root=/dev/ram 
rdinit=/sbin/init console=ttyS0,115200" --nographic


Regards
Bibo Mao

On 2024/9/5 上午11:12, Jason A. Donenfeld wrote:

On Tue, Oct 10, 2023 at 09:12:46AM +0800, maobibo wrote:

Thomas,

Thanks for reporting this issue.

It is the problem of QEMU for LoongArch system, QEMU does not support
booting vmlinux with elf format without UEFI bios now. We will add
support to boot vmlinux directly on QEMU LoongArch side.


I ran into this same issue when trying to boot my test kernel for
Ruoyao's recent vDSO getrandom work. Is this something that was ever
addressed on the QEMU side?

Jason






Re: [PATCH for-9.1] hw/loongarch: Fix length for lowram in ACPI SRAT

2024-08-20 Thread maobibo




On 2024/8/21 上午2:42, Jiaxun Yang wrote:

The size of lowram should be "gap" instead of the whole node.

This is failing kernel's sanity check:

[0.00] ACPI: SRAT: Node 0 PXM 0 [mem 0x-0x]
[0.00] ACPI: SRAT: Node 0 PXM 0 [mem 0x8000-0x16fff]
[0.00] ACPI: SRAT: Node 1 PXM 1 [mem 0x17000-0x26fff]
[0.00] Warning: node 0 [mem 0x-0x] overlaps with itself 
[mem 0x8000-0x16fff]

Fixes: fc100011f38d ("hw/loongarch: Refine acpi srat table for numa memory")
Signed-off-by: Jiaxun Yang 
---
  hw/loongarch/acpi-build.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c
index 72bfc35ae6c2..2638f8743463 100644
--- a/hw/loongarch/acpi-build.c
+++ b/hw/loongarch/acpi-build.c
@@ -218,7 +218,7 @@ build_srat(GArray *table_data, BIOSLinker *linker, 
MachineState *machine)
   *   highram: [VIRT_HIGHMEM_BASE, +(len - gap))
   */
  if (len >= gap) {
-build_srat_memory(table_data, base, len, i, MEM_AFFINITY_ENABLED);
+build_srat_memory(table_data, base, gap, i, MEM_AFFINITY_ENABLED);
  len -= gap;
  base = VIRT_HIGHMEM_BASE;
  gap = machine->ram_size - VIRT_LOWMEM_SIZE;

---
base-commit: 075fd020afe3150a0e6c4b049705b358b597b65a
change-id: 20240820-fix-numa-range-f1f0302e138d

Best regards,


Thanks for catching this.

Reviewed-by: Bibo Mao 




Re: [PULL 01/28] hw/intc/loongson_ipi: Rename LoongsonIPI -> LoongsonIPIState

2024-08-07 Thread maobibo

Philippe,

I checkout the latest code, it works well.
Thanks for your efforts.

Regards
Bibo Mao

On 2024/8/6 下午8:51, Philippe Mathieu-Daudé wrote:

From: Bibo Mao 

We'll have to add LoongsonIPIClass in few commits,
so rename LoongsonIPI as LoongsonIPIState for clarity.

Signed-off-by: Bibo Mao 
[PMD: Extracted from bigger commit, added commit description]
Co-Developed-by: Philippe Mathieu-Daudé 
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Bibo Mao 
Tested-by: Bibo Mao 
Acked-by: Song Gao 
Reviewed-by: Richard Henderson 
Reviewed-by: Jiaxun Yang 
Tested-by: Jiaxun Yang 
Message-Id: <20240805180622.21001-2-phi...@linaro.org>
---
  include/hw/intc/loongson_ipi.h |  6 +++---
  hw/intc/loongson_ipi.c | 16 
  2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/include/hw/intc/loongson_ipi.h b/include/hw/intc/loongson_ipi.h
index 3f795edbf3..efb772f384 100644
--- a/include/hw/intc/loongson_ipi.h
+++ b/include/hw/intc/loongson_ipi.h
@@ -31,10 +31,10 @@
  #define IPI_MBX_NUM   4
  
  #define TYPE_LOONGSON_IPI "loongson_ipi"

-OBJECT_DECLARE_SIMPLE_TYPE(LoongsonIPI, LOONGSON_IPI)
+OBJECT_DECLARE_SIMPLE_TYPE(LoongsonIPIState, LOONGSON_IPI)
  
  typedef struct IPICore {

-LoongsonIPI *ipi;
+LoongsonIPIState *ipi;
  MemoryRegion *ipi_mmio_mem;
  uint32_t status;
  uint32_t en;
@@ -45,7 +45,7 @@ typedef struct IPICore {
  qemu_irq irq;
  } IPICore;
  
-struct LoongsonIPI {

+struct LoongsonIPIState {
  SysBusDevice parent_obj;
  MemoryRegion ipi_iocsr_mem;
  MemoryRegion ipi64_iocsr_mem;
diff --git a/hw/intc/loongson_ipi.c b/hw/intc/loongson_ipi.c
index 682cec96f3..903483ae80 100644
--- a/hw/intc/loongson_ipi.c
+++ b/hw/intc/loongson_ipi.c
@@ -64,7 +64,7 @@ static MemTxResult loongson_ipi_iocsr_readl(void *opaque, 
hwaddr addr,
  uint64_t *data,
  unsigned size, MemTxAttrs attrs)
  {
-LoongsonIPI *ipi = opaque;
+LoongsonIPIState *ipi = opaque;
  IPICore *s;
  
  if (attrs.requester_id >= ipi->num_cpu) {

@@ -160,7 +160,7 @@ static MemTxResult loongson_ipi_core_writel(void *opaque, 
hwaddr addr,
  MemTxAttrs attrs)
  {
  IPICore *s = opaque;
-LoongsonIPI *ipi = s->ipi;
+LoongsonIPIState *ipi = s->ipi;
  int index = 0;
  uint32_t cpuid;
  uint8_t vector;
@@ -214,7 +214,7 @@ static MemTxResult loongson_ipi_iocsr_writel(void *opaque, 
hwaddr addr,
  uint64_t val, unsigned size,
  MemTxAttrs attrs)
  {
-LoongsonIPI *ipi = opaque;
+LoongsonIPIState *ipi = opaque;
  IPICore *s;
  
  if (attrs.requester_id >= ipi->num_cpu) {

@@ -277,7 +277,7 @@ static const MemoryRegionOps loongson_ipi64_ops = {
  
  static void loongson_ipi_realize(DeviceState *dev, Error **errp)

  {
-LoongsonIPI *s = LOONGSON_IPI(dev);
+LoongsonIPIState *s = LOONGSON_IPI(dev);
  SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
  int i;
  
@@ -320,7 +320,7 @@ static void loongson_ipi_realize(DeviceState *dev, Error **errp)
  
  static void loongson_ipi_unrealize(DeviceState *dev)

  {
-LoongsonIPI *s = LOONGSON_IPI(dev);
+LoongsonIPIState *s = LOONGSON_IPI(dev);
  
  g_free(s->cpu);

  }
@@ -344,14 +344,14 @@ static const VMStateDescription vmstate_loongson_ipi = {
  .version_id = 2,
  .minimum_version_id = 2,
  .fields = (const VMStateField[]) {
-VMSTATE_STRUCT_VARRAY_POINTER_UINT32(cpu, LoongsonIPI, num_cpu,
+VMSTATE_STRUCT_VARRAY_POINTER_UINT32(cpu, LoongsonIPIState, num_cpu,
   vmstate_ipi_core, IPICore),
  VMSTATE_END_OF_LIST()
  }
  };
  
  static Property ipi_properties[] = {

-DEFINE_PROP_UINT32("num-cpu", LoongsonIPI, num_cpu, 1),
+DEFINE_PROP_UINT32("num-cpu", LoongsonIPIState, num_cpu, 1),
  DEFINE_PROP_END_OF_LIST(),
  };
  
@@ -369,7 +369,7 @@ static const TypeInfo loongson_ipi_types[] = {

  {
  .name   = TYPE_LOONGSON_IPI,
  .parent = TYPE_SYS_BUS_DEVICE,
-.instance_size  = sizeof(LoongsonIPI),
+.instance_size  = sizeof(LoongsonIPIState),
  .class_init = loongson_ipi_class_init,
  }
  };






Re: [PATCH v2] hw/loongarch: Remove unimplemented extioi INT_encode mode

2024-07-18 Thread maobibo

Reviewed-by: Bibo Mao 

On 2024/7/18 下午4:32, Song Gao wrote:

Remove extioi INT_encode encode mode, because we don't emulate it.

Signed-off-by: Song Gao 
---
  include/hw/intc/loongarch_extioi.h | 1 -
  1 file changed, 1 deletion(-)

diff --git a/include/hw/intc/loongarch_extioi.h 
b/include/hw/intc/loongarch_extioi.h
index eccc2e0d18..626a37dfa1 100644
--- a/include/hw/intc/loongarch_extioi.h
+++ b/include/hw/intc/loongarch_extioi.h
@@ -50,7 +50,6 @@
  #define  EXTIOI_HAS_CPU_ENCODE   (3)
  #define  EXTIOI_VIRT_HAS_FEATURES(BIT(EXTIOI_HAS_VIRT_EXTENSION)  \
| BIT(EXTIOI_HAS_ENABLE_OPTION) \
-  | BIT(EXTIOI_HAS_INT_ENCODE)\
| BIT(EXTIOI_HAS_CPU_ENCODE))
  #define EXTIOI_VIRT_CONFIG   (0x4)
  #define  EXTIOI_ENABLE   (1)






Re: [PATCH] hw/loongarch: Remove unimplemented extioi INT_encode mode

2024-07-18 Thread maobibo




On 2024/7/18 下午3:25, Song Gao wrote:

Remove extioi INT_encode encode mode, because we don't emulate it.

Signed-off-by: Song Gao 
---
  hw/loongarch/virt.c| 6 --
  include/hw/intc/loongarch_extioi.h | 1 -
  2 files changed, 7 deletions(-)

diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index e592b1b6b7..2103a1069f 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -951,9 +951,6 @@ static MemTxResult virt_iocsr_misc_write(void *opaque, 
hwaddr addr,
  if (val & BIT_ULL(IOCSRM_EXTIOI_EN)) {
  features |= BIT(EXTIOI_ENABLE);
  }
-if (val & BIT_ULL(IOCSRM_EXTIOI_INT_ENCODE)) {
-features |= BIT(EXTIOI_ENABLE_INT_ENCODE);
-}

I do not think this modification is necessary.

  
  address_space_stl(&lvms->as_iocsr,

EXTIOI_VIRT_BASE + EXTIOI_VIRT_CONFIG,
@@ -1002,9 +999,6 @@ static MemTxResult virt_iocsr_misc_read(void *opaque, 
hwaddr addr,
  if (features & BIT(EXTIOI_ENABLE)) {
  ret |= BIT_ULL(IOCSRM_EXTIOI_EN);
  }
-if (features & BIT(EXTIOI_ENABLE_INT_ENCODE)) {
-ret |= BIT_ULL(IOCSRM_EXTIOI_INT_ENCODE);
-}

Ditto, I do not think this modification is necessary also.

  break;
  default:
  g_assert_not_reached();
diff --git a/include/hw/intc/loongarch_extioi.h 
b/include/hw/intc/loongarch_extioi.h
index eccc2e0d18..626a37dfa1 100644
--- a/include/hw/intc/loongarch_extioi.h
+++ b/include/hw/intc/loongarch_extioi.h
@@ -50,7 +50,6 @@
  #define  EXTIOI_HAS_CPU_ENCODE   (3)
  #define  EXTIOI_VIRT_HAS_FEATURES(BIT(EXTIOI_HAS_VIRT_EXTENSION)  \
| BIT(EXTIOI_HAS_ENABLE_OPTION) \
-  | BIT(EXTIOI_HAS_INT_ENCODE)\
| BIT(EXTIOI_HAS_CPU_ENCODE))

Only this modification will be ok.

Regards
Bibo Mao

  #define EXTIOI_VIRT_CONFIG   (0x4)
  #define  EXTIOI_ENABLE   (1)






Re: [PATCH v3 04/17] hw/intc/loongson_ipi: Extract loongson_ipi_common_realize()

2024-07-17 Thread maobibo




On 2024/7/18 上午5:46, Philippe Mathieu-Daudé wrote:

From: Bibo Mao 

In preparation to extract common IPI code in few commits,
extract loongson_ipi_common_realize().

Signed-off-by: Bibo Mao 
[PMD: Extracted from bigger commit, added commit description]
Signed-off-by: Philippe Mathieu-Daudé 
---
  hw/intc/loongson_ipi.c | 25 ++---
  1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/hw/intc/loongson_ipi.c b/hw/intc/loongson_ipi.c
index 3b3481c43e..40ac769aad 100644
--- a/hw/intc/loongson_ipi.c
+++ b/hw/intc/loongson_ipi.c
@@ -275,7 +275,7 @@ static const MemoryRegionOps loongson_ipi64_ops = {
  .endianness = DEVICE_LITTLE_ENDIAN,
  };
  
-static void loongson_ipi_realize(DeviceState *dev, Error **errp)

+static void loongson_ipi_common_realize(DeviceState *dev, Error **errp)
  {
  LoongsonIPIState *s = LOONGSON_IPI(dev);
  SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
@@ -301,20 +301,31 @@ static void loongson_ipi_realize(DeviceState *dev, Error 
**errp)
  sysbus_init_mmio(sbd, &s->ipi64_iocsr_mem);
  
  s->cpu = g_new0(IPICore, s->num_cpu);

-if (s->cpu == NULL) {
-error_setg(errp, "Memory allocation for IPICore faile");

Philippe,

Thanks for the whole series, it looks to me. It is split into small 
patches and adds new option CONFIG_LOONGSON_IPI_COMMON, it is easier to 
review and compile for multiple targets.


One small nit, do we need keep checking sentence for if (s->cpu == NULL)?

Overall, for the whole series it is ok for me and works well on 
LoongArch machine.


Reviewed-by: Bibo Mao 
Tested-by: Bibo Mao 


+for (i = 0; i < s->num_cpu; i++) {
+s->cpu[i].ipi = s;
+
+qdev_init_gpio_out(dev, &s->cpu[i].irq, 1);
+}
+}
+
+static void loongson_ipi_realize(DeviceState *dev, Error **errp)
+{
+LoongsonIPIState *s = LOONGSON_IPI(dev);
+SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+Error *local_err = NULL;
+
+loongson_ipi_common_realize(dev, &local_err);
+if (local_err) {
+error_propagate(errp, local_err);
  return;
  }
  
-for (i = 0; i < s->num_cpu; i++) {

-s->cpu[i].ipi = s;
+for (unsigned i = 0; i < s->num_cpu; i++) {
  s->cpu[i].ipi_mmio_mem = g_new0(MemoryRegion, 1);
  g_autofree char *name = g_strdup_printf("loongson_ipi_cpu%d_mmio", i);
  memory_region_init_io(s->cpu[i].ipi_mmio_mem, OBJECT(dev),
&loongson_ipi_core_ops, &s->cpu[i], name, 0x48);
  sysbus_init_mmio(sbd, s->cpu[i].ipi_mmio_mem);
-
-qdev_init_gpio_out(dev, &s->cpu[i].irq, 1);
  }
  }
  






Re: [PATCH v2 0/4] Reconstruct loongson ipi driver

2024-07-17 Thread maobibo




On 2024/7/16 下午2:40, Philippe Mathieu-Daudé wrote:

On 16/7/24 03:29, maobibo wrote:



On 2024/7/16 上午9:04, maobibo wrote:



On 2024/7/15 下午11:17, Philippe Mathieu-Daudé wrote:

On 4/7/24 05:37, Bibo Mao wrote:

Now loongson ipi and loongarch ipi share the same code with different
macro, loongson ipi has its separate function such mmio region,
loongarch ipi has other requirement such as irqchip in kernel.

Interrupt irqchip has strong relationship with architecture, since
it sends irq to vcpu and interfaces to get irqchip register is also
architecture specific.

Here like other architectures, base class TYPE_LOONGSON_IPI_COMMON
is added, it comes from loongson ipi mostly. And it defined four 
abstract
interfaces which can be used for MIPS 3A4000 and Loongarch 3A5000 
machine,

also can be used for 3A5000 irqchip in kernel mode soon.

Also Loongarch ipi and loongson ipi device are added here, it inherits
from base class TYPE_LOONGSON_IPI_COMMON. Loongarch ipi is tested,
loongson ipi device only passes to compile and make check, it is not
tested.

Bibo Mao (4):
   hw/intc/loongson_ipi_common: Add loongson ipi common class
   hw/intc/loongarch_ipi: Add loongarch ipi support
   hw/loongarch/virt: Replace loongson ipi with loongarch ipi
   hw/intc/loongson_ipi: reconstruct driver inherit from common class


I'll try to respin a clearer v3.
I am ok with it since it solve the problem, and it is suitable for 
9.1 release. Only that in the long time we hope that intc emulation 
driver has common base class + tcg/kvm driver, similar with other 
architecture.



Sorry for the confusion, I had thought it was another topic.

Thanks for pointing out the problem and welcome the v3 version.


Please do not post v3, let me post it.

Hi Philippe,

QEMU 9.1 is coming to soft frozen stage, do you have enough time working 
on it?  Is it ok to use bugfix patch for 9.1 release version?

https://lore.kernel.org/all/20240627125819.62779-2-phi...@linaro.org/

After 9.1 is released, there will be enough time for patch v3.

Regards
Bibo, Mao




Re: [PATCH v2] target/loongarch/gdbstub: Add vector registers support

2024-07-15 Thread maobibo




On 2024/7/11 上午10:44, Song Gao wrote:

GDB already support LoongArch vector extension[1], QEMU gdb adds
LoongArch vector registers support, so that users can use 'info all-registers'
to get all vector registers values.

[1]: 
https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=1e9569f383a3d5a88ee07d0c2401bd95613c222e

Signed-off-by: Song Gao 
---
based-on:
  https://patchew.org/QEMU/20240607035016.2975799-1-maob...@loongson.cn/

v2:
- fix tab line wrapper issue.
- Link to v1: 
https://patchew.org/QEMU/20240621065406.864232-1-gaos...@loongson.cn/

  configs/targets/loongarch64-linux-user.mak |  2 +-
  configs/targets/loongarch64-softmmu.mak|  2 +-
  target/loongarch/gdbstub.c | 70 +-
  gdb-xml/loongarch-lasx.xml | 60 +++
  gdb-xml/loongarch-lsx.xml  | 59 ++
  5 files changed, 189 insertions(+), 4 deletions(-)
  create mode 100644 gdb-xml/loongarch-lasx.xml
  create mode 100644 gdb-xml/loongarch-lsx.xml

diff --git a/configs/targets/loongarch64-linux-user.mak 
b/configs/targets/loongarch64-linux-user.mak
index d878e5a113..ea9b7e839a 100644
--- a/configs/targets/loongarch64-linux-user.mak
+++ b/configs/targets/loongarch64-linux-user.mak
@@ -1,4 +1,4 @@
  # Default configuration for loongarch64-linux-user
  TARGET_ARCH=loongarch64
  TARGET_BASE_ARCH=loongarch
-TARGET_XML_FILES=gdb-xml/loongarch-base64.xml gdb-xml/loongarch-fpu.xml
+TARGET_XML_FILES=gdb-xml/loongarch-base64.xml gdb-xml/loongarch-fpu.xml 
gdb-xml/loongarch-lsx.xml gdb-xml/loongarch-lasx.xml
diff --git a/configs/targets/loongarch64-softmmu.mak 
b/configs/targets/loongarch64-softmmu.mak
index 65b65e0c34..ce19ab6a16 100644
--- a/configs/targets/loongarch64-softmmu.mak
+++ b/configs/targets/loongarch64-softmmu.mak
@@ -2,6 +2,6 @@ TARGET_ARCH=loongarch64
  TARGET_BASE_ARCH=loongarch
  TARGET_KVM_HAVE_GUEST_DEBUG=y
  TARGET_SUPPORTS_MTTCG=y
-TARGET_XML_FILES= gdb-xml/loongarch-base32.xml gdb-xml/loongarch-base64.xml 
gdb-xml/loongarch-fpu.xml
+TARGET_XML_FILES= gdb-xml/loongarch-base32.xml gdb-xml/loongarch-base64.xml 
gdb-xml/loongarch-fpu.xml gdb-xml/loongarch-lsx.xml gdb-xml/loongarch-lasx.xml
  # all boards require libfdt
  TARGET_NEED_FDT=y
diff --git a/target/loongarch/gdbstub.c b/target/loongarch/gdbstub.c
index a0e1439bd0..8ac327d286 100644
--- a/target/loongarch/gdbstub.c
+++ b/target/loongarch/gdbstub.c
@@ -116,8 +116,74 @@ static int loongarch_gdb_set_fpu(CPUState *cs, uint8_t 
*mem_buf, int n)
  return length;
  }
  
+static int loongarch_gdb_get_vec(CPUState *cs, GByteArray *mem_buf, int n, int vl)

+{
+LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+CPULoongArchState *env = &cpu->env;
+int i, length = 0;
+
+if (0 <= n && n < 32) {
+for (i = 0; i < vl / 64; i++) {
+length += gdb_get_reg64(mem_buf, env->fpr[n].vreg.D(i));
+}
+}
+
+return length;
+}
+
+static int loongarch_gdb_set_vec(CPUState *cs, uint8_t *mem_buf, int n, int vl)
+{
+LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+CPULoongArchState *env = &cpu->env;
+int i, length = 0;
+
+if (0 <= n && n < 32) {
+for (i = 0; i < vl / 64; i++) {
+env->fpr[n].vreg.D(i) = ldq_le_p(mem_buf + 8 * i);
+length += 8;
+}
+}
+
+return length;
+}
+
+static int loongarch_gdb_get_lsx(CPUState *cs, GByteArray *mem_buf, int n)
+{
+return loongarch_gdb_get_vec(cs, mem_buf, n, LSX_LEN);
+}
+
+static int loongarch_gdb_set_lsx(CPUState *cs, uint8_t *mem_buf, int n)
+{
+return loongarch_gdb_set_vec(cs, mem_buf, n, LSX_LEN);
+}
+
+static int loongarch_gdb_get_lasx(CPUState *cs, GByteArray *mem_buf, int n)
+{
+return loongarch_gdb_get_vec(cs, mem_buf, n, LASX_LEN);
+}
+
+static int loongarch_gdb_set_lasx(CPUState *cs, uint8_t *mem_buf, int n)
+{
+return loongarch_gdb_set_vec(cs, mem_buf, n, LASX_LEN);
+}
+
  void loongarch_cpu_register_gdb_regs_for_features(CPUState *cs)
  {
-gdb_register_coprocessor(cs, loongarch_gdb_get_fpu, loongarch_gdb_set_fpu,
- gdb_find_static_feature("loongarch-fpu.xml"), 0);
+LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+CPULoongArchState *env = &cpu->env;
+
+if (FIELD_EX32(env->cpucfg[2], CPUCFG2, FP)) {
+gdb_register_coprocessor(cs, loongarch_gdb_get_fpu, 
loongarch_gdb_set_fpu,
+ gdb_find_static_feature("loongarch-fpu.xml"), 
0);
+}
+
+if (FIELD_EX32(env->cpucfg[2], CPUCFG2, LSX)) {
+gdb_register_coprocessor(cs, loongarch_gdb_get_lsx, 
loongarch_gdb_set_lsx,
+ gdb_find_static_feature("loongarch-lsx.xml"), 
0);
+}
+
+if (FIELD_EX32(env->cpucfg[2], CPUCFG2, LASX)) {
+gdb_register_coprocessor(cs, loongarch_gdb_get_lasx, 
loongarch_gdb_set_lasx,
+ 
gdb_find_static_feature("loongarch-lasx.xml"), 0);
+}
I prefer to only one FPU print log, however gdb LoongArch client forcely 
prin

Re: [PATCH v2 0/4] Reconstruct loongson ipi driver

2024-07-15 Thread maobibo




On 2024/7/16 上午9:04, maobibo wrote:



On 2024/7/15 下午11:17, Philippe Mathieu-Daudé wrote:

On 4/7/24 05:37, Bibo Mao wrote:

Now loongson ipi and loongarch ipi share the same code with different
macro, loongson ipi has its separate function such mmio region,
loongarch ipi has other requirement such as irqchip in kernel.

Interrupt irqchip has strong relationship with architecture, since
it sends irq to vcpu and interfaces to get irqchip register is also
architecture specific.

Here like other architectures, base class TYPE_LOONGSON_IPI_COMMON
is added, it comes from loongson ipi mostly. And it defined four 
abstract
interfaces which can be used for MIPS 3A4000 and Loongarch 3A5000 
machine,

also can be used for 3A5000 irqchip in kernel mode soon.

Also Loongarch ipi and loongson ipi device are added here, it inherits
from base class TYPE_LOONGSON_IPI_COMMON. Loongarch ipi is tested,
loongson ipi device only passes to compile and make check, it is not
tested.

Bibo Mao (4):
   hw/intc/loongson_ipi_common: Add loongson ipi common class
   hw/intc/loongarch_ipi: Add loongarch ipi support
   hw/loongarch/virt: Replace loongson ipi with loongarch ipi
   hw/intc/loongson_ipi: reconstruct driver inherit from common class


I'll try to respin a clearer v3.
I am ok with it since it solve the problem, and it is suitable for 9.1 
release. Only that in the long time we hope that intc emulation driver 
has common base class + tcg/kvm driver, similar with other architecture.



Sorry for the confusion, I had thought it was another topic.

Thanks for pointing out the problem and welcome the v3 version.

Regards
Bibo Mao

Regards
Bibo mao






Re: [PATCH v2 1/4] hw/intc/loongson_ipi_common: Add loongson ipi common class

2024-07-15 Thread maobibo




On 2024/7/15 下午11:31, Philippe Mathieu-Daudé wrote:

On 4/7/24 05:37, Bibo Mao wrote:

Loongson ipi common class and instance is created here, it comes
from file loongson_ipi mostly. For the new added loongson ipi
common class, there is four interfaces defined here:
  1. Interfaces pre_save/post_load are used for future kvm child class
  2. Interface get_iocsr_as can be used for different architectures,
now MIPS 3A4000 and LoongArch 3A5000 machine use this ip, can inherit
this common class.
  3. Interace cpu_by_arch_id is added, by default generic function
cpu_by_arch_id() is used to search vcpu from physical cpuid, it is
generic searching method. Different machine may define other search
methods such binary searching method.

Signed-off-by: Bibo Mao 
---
  hw/intc/loongson_ipi_common.c | 394 ++
  include/hw/intc/loongson_ipi_common.h |  77 +
  2 files changed, 471 insertions(+)
  create mode 100644 hw/intc/loongson_ipi_common.c
  create mode 100644 include/hw/intc/loongson_ipi_common.h



+static MemTxResult send_ipi_data(LoongsonIPICommonState *ipi, 
CPUState *cpu,

+ uint64_t val,
+ hwaddr addr, MemTxAttrs attrs)
+{
+    int i, mask = 0, data = 0;
+    AddressSpace *iocsr_as;
+    LoongsonIPICommonClass *licc = LOONGSON_IPI_COMMON_GET_CLASS(ipi);
+
+    iocsr_as = NULL;
+    if (licc->get_iocsr_as) {
+    iocsr_as = licc->get_iocsr_as(cpu);
+    }
+
+    if (!iocsr_as) {
+    return MEMTX_DECODE_ERROR;
+    }
+
+    /*
+ * bit 27-30 is mask for byte writing,
+ * if the mask is 0, we need not to do anything.
+ */
+    if ((val >> 27) & 0xf) {
+    data = address_space_ldl_le(iocsr_as, addr, attrs, NULL);


Adding/removing files make noticing the uncommented changes very hard
(see my v3).

Here you use little-endian instead of host one. This device is L-E only
so this makes sense, but I'd have appreciate at least a comment about
it.


Good catch, there is compile warning when address_space_ldl() is used, 
so address_space_ldl_le() is used to remove compile warning. I will 
double check the compile warning issue.


Regard
Bibo Mao



+    for (i = 0; i < 4; i++) {
+    /* get mask for byte writing */
+    if (val & (0x1 << (27 + i))) {
+    mask |= 0xff << (i * 8);
+    }
+    }
+    }
+
+    data &= mask;
+    data |= (val >> 32) & ~mask;
+    address_space_stl_le(iocsr_as, addr, data, attrs, NULL);


Ditto.


+    return MEMTX_OK;
+}







Re: [PATCH v2 0/4] Reconstruct loongson ipi driver

2024-07-15 Thread maobibo




On 2024/7/15 下午11:17, Philippe Mathieu-Daudé wrote:

On 4/7/24 05:37, Bibo Mao wrote:

Now loongson ipi and loongarch ipi share the same code with different
macro, loongson ipi has its separate function such mmio region,
loongarch ipi has other requirement such as irqchip in kernel.

Interrupt irqchip has strong relationship with architecture, since
it sends irq to vcpu and interfaces to get irqchip register is also
architecture specific.

Here like other architectures, base class TYPE_LOONGSON_IPI_COMMON
is added, it comes from loongson ipi mostly. And it defined four abstract
interfaces which can be used for MIPS 3A4000 and Loongarch 3A5000 
machine,

also can be used for 3A5000 irqchip in kernel mode soon.

Also Loongarch ipi and loongson ipi device are added here, it inherits
from base class TYPE_LOONGSON_IPI_COMMON. Loongarch ipi is tested,
loongson ipi device only passes to compile and make check, it is not
tested.

Bibo Mao (4):
   hw/intc/loongson_ipi_common: Add loongson ipi common class
   hw/intc/loongarch_ipi: Add loongarch ipi support
   hw/loongarch/virt: Replace loongson ipi with loongarch ipi
   hw/intc/loongson_ipi: reconstruct driver inherit from common class


I'll try to respin a clearer v3.
I am ok with it since it solve the problem, and it is suitable for 9.1 
release. Only that in the long time we hope that intc emulation driver 
has common base class + tcg/kvm driver, similar with other architecture.


Regards
Bibo mao




Re: [PATCH v2 0/1] hw/intc/loongson_ipi: Fix for LoongArch

2024-07-15 Thread maobibo




On 2024/7/15 下午5:57, Philippe Mathieu-Daudé wrote:

On 27/6/24 14:58, Philippe Mathieu-Daudé wrote:

v2:
- Only skip mmio-related code in loongson_ipi_realize()

Jiaxun Yang (1):
   hw/intc/loongson_ipi: Gate MMIO regions creation with property

  include/hw/intc/loongson_ipi.h |  1 +
  hw/intc/loongson_ipi.c | 16 ++--
  hw/mips/loongson3_virt.c   |  1 +
  3 files changed, 12 insertions(+), 6 deletions(-)



ping?

Hi Philippe,

It is only temporary fix, in the long term we hope that interrupt 
controller emulation is similar with other architectures in directory

hw/intc/, and we post the patch at website:

https://lore.kernel.org/qemu-devel/20240704033802.3838618-1-maob...@loongson.cn/

Regards
Bibo Mao




Re: [PATCH] target/loongarch/gdbstub: Add vector registers support

2024-07-10 Thread maobibo




On 2024/6/21 下午2:54, Song Gao wrote:

GDB already support LoongArch vector extension[1], QEMU gdb adds
LoongArch vector registers support, so that users can use 'info all-registers'
to get all vector registers values.

[1]: 
https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=1e9569f383a3d5a88ee07d0c2401bd95613c222e

Signed-off-by: Song Gao 
---
based-on:
  https://patchew.org/QEMU/20240607035016.2975799-1-maob...@loongson.cn/

  configs/targets/loongarch64-linux-user.mak |  2 +-
  configs/targets/loongarch64-softmmu.mak|  2 +-
  gdb-xml/loongarch-lasx.xml | 60 +++
  gdb-xml/loongarch-lsx.xml  | 59 ++
  target/loongarch/gdbstub.c | 70 +-
  5 files changed, 189 insertions(+), 4 deletions(-)
  create mode 100644 gdb-xml/loongarch-lasx.xml
  create mode 100644 gdb-xml/loongarch-lsx.xml

diff --git a/configs/targets/loongarch64-linux-user.mak 
b/configs/targets/loongarch64-linux-user.mak
index d878e5a113..ea9b7e839a 100644
--- a/configs/targets/loongarch64-linux-user.mak
+++ b/configs/targets/loongarch64-linux-user.mak
@@ -1,4 +1,4 @@
  # Default configuration for loongarch64-linux-user
  TARGET_ARCH=loongarch64
  TARGET_BASE_ARCH=loongarch
-TARGET_XML_FILES=gdb-xml/loongarch-base64.xml gdb-xml/loongarch-fpu.xml
+TARGET_XML_FILES=gdb-xml/loongarch-base64.xml gdb-xml/loongarch-fpu.xml 
gdb-xml/loongarch-lsx.xml gdb-xml/loongarch-lasx.xml
diff --git a/configs/targets/loongarch64-softmmu.mak 
b/configs/targets/loongarch64-softmmu.mak
index 65b65e0c34..ce19ab6a16 100644
--- a/configs/targets/loongarch64-softmmu.mak
+++ b/configs/targets/loongarch64-softmmu.mak
@@ -2,6 +2,6 @@ TARGET_ARCH=loongarch64
  TARGET_BASE_ARCH=loongarch
  TARGET_KVM_HAVE_GUEST_DEBUG=y
  TARGET_SUPPORTS_MTTCG=y
-TARGET_XML_FILES= gdb-xml/loongarch-base32.xml gdb-xml/loongarch-base64.xml 
gdb-xml/loongarch-fpu.xml
+TARGET_XML_FILES= gdb-xml/loongarch-base32.xml gdb-xml/loongarch-base64.xml 
gdb-xml/loongarch-fpu.xml gdb-xml/loongarch-lsx.xml gdb-xml/loongarch-lasx.xml
  # all boards require libfdt
  TARGET_NEED_FDT=y
diff --git a/gdb-xml/loongarch-lasx.xml b/gdb-xml/loongarch-lasx.xml
new file mode 100644
index 00..753b982c65
--- /dev/null
+++ b/gdb-xml/loongarch-lasx.xml
@@ -0,0 +1,60 @@
+
+
+
+
+
+  
+  
+  
+  
+  
+  
+  
+
+  
+
+
+
+
+
+
+
+  
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
diff --git a/gdb-xml/loongarch-lsx.xml b/gdb-xml/loongarch-lsx.xml
new file mode 100644
index 00..51af1c6fd5
--- /dev/null
+++ b/gdb-xml/loongarch-lsx.xml
@@ -0,0 +1,59 @@
+
+
+
+
+
+  
+  
+  
+  
+  
+  
+
+  
+
+
+
+
+
+
+
+  
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
diff --git a/target/loongarch/gdbstub.c b/target/loongarch/gdbstub.c
index a0e1439bd0..c9e2ddd943 100644
--- a/target/loongarch/gdbstub.c
+++ b/target/loongarch/gdbstub.c
@@ -116,8 +116,74 @@ static int loongarch_gdb_set_fpu(CPUState *cs, uint8_t 
*mem_buf, int n)
  return length;
  }
  
+static int loongarch_gdb_get_vec(CPUState *cs, GByteArray *mem_buf, int n, int vl)

+{
+LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+CPULoongArchState *env = &cpu->env;
+int i, length = 0;
+
+if (0 <= n && n < 32) {
+for (i = 0; i < vl / 64; i++) {
+length += gdb_get_reg64(mem_buf, env->fpr[n].vreg.D(i));
+   }

There is tab line wrapper issue.


+}
+
+return length;
+}
+
+static int loongarch_gdb_set_vec(CPUState *cs, uint8_t *mem_buf, int n, int vl)
+{
+LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+CPULoongArchState *env = &cpu->env;
+int i, length = 0;
+
+if (0 <= n && n < 32) {
+for (i = 0; i < vl / 64; i++) {
+env->fpr[n].vreg.D(i) = ldq_le_p(mem_buf + 8 * i);
+length += 8;
+}
+}
+
+return length;
+}
+
+static int loongarch_gdb_get_lsx(CPUState *cs, GByteArray *mem_buf, int n)
+{
+return loongarch_gdb_get_vec(cs, mem_buf, n, LSX_LEN);
+}
+
+static int loongarch_gdb_set_lsx(CPUState *cs, uint8_t *mem_buf, int n)
+{
+return loongarch_gdb_set_vec(cs, mem_buf, n, LSX_LEN);
+}
+
+static int loongarch_gdb_get_lasx(CPUState *cs, GByteArray *mem_buf, int n)
+{
+return loongarch_gdb_get_vec(cs, mem_buf, n, LASX_LEN);
+}
+
+static int loongarch_gdb_set_lasx(CPUState *cs, uint8_t *mem_buf, int n)
+{
+return loongarch_gdb_set_vec(cs, mem_buf, n, LASX_LEN);
+}
+
  void loongarch_cpu_register_gdb_regs_for_features(CPUState *cs)
  {
-gdb_register_coprocessor(cs, loongarch_gdb_get_fpu, loongarch_gdb_set_fpu,
- gdb_find_static_feature("loongarch-fpu.xml"), 0);
+LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+CPULoongArchState *env = &cpu->env;
+
+if (FIELD_EX32(env->cpucfg[2], CPUCFG2, FP)) {
+ 

Re: [PATCH v2 0/4] Reconstruct loongson ipi driver

2024-07-09 Thread maobibo




On 2024/7/10 下午12:00, Jiaxun Yang wrote:



在2024年7月9日七月 下午8:04,maobibo写道:

Hi Philippe/Jiaxun,

Could you do me a favor giving a review about this patch?


Hi Bibo,

I’m currently traveling, will test and review next week.

I’m not really convinced to give a R-b but I’m fine with a T-b.

That is ok for me, have a good time.

Regards
Bibo Mao


Thanks



Regards
Bibo Mao

On 2024/7/4 上午11:37, Bibo Mao wrote:

Now loongson ipi and loongarch ipi share the same code with different
macro, loongson ipi has its separate function such mmio region,
loongarch ipi has other requirement such as irqchip in kernel.

Interrupt irqchip has strong relationship with architecture, since
it sends irq to vcpu and interfaces to get irqchip register is also
architecture specific.

Here like other architectures, base class TYPE_LOONGSON_IPI_COMMON
is added, it comes from loongson ipi mostly. And it defined four abstract
interfaces which can be used for MIPS 3A4000 and Loongarch 3A5000 machine,
also can be used for 3A5000 irqchip in kernel mode soon.

Also Loongarch ipi and loongson ipi device are added here, it inherits
from base class TYPE_LOONGSON_IPI_COMMON. Loongarch ipi is tested,
loongson ipi device only passes to compile and make check, it is not
tested.

Bibo Mao (4):
hw/intc/loongson_ipi_common: Add loongson ipi common class
hw/intc/loongarch_ipi: Add loongarch ipi support
hw/loongarch/virt: Replace loongson ipi with loongarch ipi
hw/intc/loongson_ipi: reconstruct driver inherit from common class

   hw/intc/Kconfig   |   3 +
   hw/intc/loongarch_ipi.c   |  80 ++
   hw/intc/loongson_ipi.c| 330 ++---
   hw/intc/loongson_ipi_common.c | 394 ++
   hw/intc/meson.build   |   3 +-
   hw/loongarch/Kconfig  |   2 +-
   hw/loongarch/virt.c   |   4 +-
   include/hw/intc/loongarch_ipi.h   |  33 +++
   include/hw/intc/loongson_ipi.h|  54 ++--
   include/hw/intc/loongson_ipi_common.h |  77 +
   include/hw/loongarch/virt.h   |   1 -
   11 files changed, 632 insertions(+), 349 deletions(-)
   create mode 100644 hw/intc/loongarch_ipi.c
   create mode 100644 hw/intc/loongson_ipi_common.c
   create mode 100644 include/hw/intc/loongarch_ipi.h
   create mode 100644 include/hw/intc/loongson_ipi_common.h


base-commit: 6746482d12da3b6e4d3cdf06481a0027a797f719








Re: [PATCH v2 0/4] Reconstruct loongson ipi driver

2024-07-09 Thread maobibo

Hi Philippe/Jiaxun,

Could you do me a favor giving a review about this patch?

Regards
Bibo Mao

On 2024/7/4 上午11:37, Bibo Mao wrote:

Now loongson ipi and loongarch ipi share the same code with different
macro, loongson ipi has its separate function such mmio region,
loongarch ipi has other requirement such as irqchip in kernel.

Interrupt irqchip has strong relationship with architecture, since
it sends irq to vcpu and interfaces to get irqchip register is also
architecture specific.

Here like other architectures, base class TYPE_LOONGSON_IPI_COMMON
is added, it comes from loongson ipi mostly. And it defined four abstract
interfaces which can be used for MIPS 3A4000 and Loongarch 3A5000 machine,
also can be used for 3A5000 irqchip in kernel mode soon.

Also Loongarch ipi and loongson ipi device are added here, it inherits
from base class TYPE_LOONGSON_IPI_COMMON. Loongarch ipi is tested,
loongson ipi device only passes to compile and make check, it is not
tested.

Bibo Mao (4):
   hw/intc/loongson_ipi_common: Add loongson ipi common class
   hw/intc/loongarch_ipi: Add loongarch ipi support
   hw/loongarch/virt: Replace loongson ipi with loongarch ipi
   hw/intc/loongson_ipi: reconstruct driver inherit from common class

  hw/intc/Kconfig   |   3 +
  hw/intc/loongarch_ipi.c   |  80 ++
  hw/intc/loongson_ipi.c| 330 ++---
  hw/intc/loongson_ipi_common.c | 394 ++
  hw/intc/meson.build   |   3 +-
  hw/loongarch/Kconfig  |   2 +-
  hw/loongarch/virt.c   |   4 +-
  include/hw/intc/loongarch_ipi.h   |  33 +++
  include/hw/intc/loongson_ipi.h|  54 ++--
  include/hw/intc/loongson_ipi_common.h |  77 +
  include/hw/loongarch/virt.h   |   1 -
  11 files changed, 632 insertions(+), 349 deletions(-)
  create mode 100644 hw/intc/loongarch_ipi.c
  create mode 100644 hw/intc/loongson_ipi_common.c
  create mode 100644 include/hw/intc/loongarch_ipi.h
  create mode 100644 include/hw/intc/loongson_ipi_common.h


base-commit: 6746482d12da3b6e4d3cdf06481a0027a797f719






Re: [PATCH v2 1/2] target/loongarch: Set CSR_PRCFG1 and CSR_PRCFG2 values

2024-07-07 Thread maobibo




On 2024/7/5 上午10:18, Song Gao wrote:

We set the value of register CSR_PRCFG3, but left out CSR_PRCFG1
and CSR_PRCFG2. Set CSR_PRCFG1 and CSR_PRCFG2 according to the
default values of the physical machine.

Signed-off-by: Song Gao 
---
v2:
  - Add a new patch fix set CSR_CRMD wrong value;
  - Set PRCFG1-PRCFG3 values in loongarch_la464_initfn.

  target/loongarch/cpu.c | 17 -
  1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 270f711f11..55d468af3c 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -457,6 +457,18 @@ static void loongarch_la464_initfn(Object *obj)
  env->cpucfg[20] = data;
  
  env->CSR_ASID = FIELD_DP64(0, CSR_ASID, ASIDBITS, 0xa);

+
+env->CSR_PRCFG1 = FIELD_DP64(env->CSR_PRCFG1, CSR_PRCFG1, SAVE_NUM, 8);
+env->CSR_PRCFG1 = FIELD_DP64(env->CSR_PRCFG1, CSR_PRCFG1, TIMER_BITS, 
0x2f);
+env->CSR_PRCFG1 = FIELD_DP64(env->CSR_PRCFG1, CSR_PRCFG1, VSMAX, 7);
+
+env->CSR_PRCFG2 = 0x3000;
+
+env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, TLB_TYPE, 2);
+env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, MTLB_ENTRY, 63);
+env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, STLB_WAYS, 7);
+env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, STLB_SETS, 8);
+


By LA32 manual, PRCFG does not exist, it is only in effective on LA64.

Reviewed-by: Bibo Mao 


  loongarch_cpu_post_init(obj);
  }
  
@@ -538,11 +550,6 @@ static void loongarch_cpu_reset_hold(Object *obj, ResetType type)

  env->CSR_MERRCTL = FIELD_DP64(env->CSR_MERRCTL, CSR_MERRCTL, ISMERR, 0);
  env->CSR_TID = cs->cpu_index;
  
-env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, TLB_TYPE, 2);

-env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, MTLB_ENTRY, 63);
-env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, STLB_WAYS, 7);
-env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, STLB_SETS, 8);
-
  for (n = 0; n < 4; n++) {
  env->CSR_DMW[n] = FIELD_DP64(env->CSR_DMW[n], CSR_DMW, PLV0, 0);
  env->CSR_DMW[n] = FIELD_DP64(env->CSR_DMW[n], CSR_DMW, PLV1, 0);






Re: [PATCH v2 2/2] target/loongarch: Fix cpu_reset set wrong CSR_CRMD

2024-07-07 Thread maobibo




On 2024/7/5 上午10:18, Song Gao wrote:

After cpu_reset, DATF in CSR_CRMD is 0, DATM is 0.
See the manual[1] 6.4.

   [1]: 
https://github.com/loongson/LoongArch-Documentation/releases/download/2023.04.20/LoongArch-Vol1-v1.10-EN.pdf

Signed-off-by: Song Gao 
---
  target/loongarch/cpu.c | 6 +++---
  1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 55d468af3c..763cde41c3 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -523,13 +523,13 @@ static void loongarch_cpu_reset_hold(Object *obj, 
ResetType type)
  env->fcsr0 = 0x0;
  
  int n;

-/* Set csr registers value after reset */
+/* Set csr registers value after reset, see the manual 6.4. */
  env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, PLV, 0);
  env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, IE, 0);
  env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, DA, 1);
  env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, PG, 0);
-env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, DATF, 1);
-env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, DATM, 1);
+env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, DATF, 0);
+env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, DATM, 0);
  
  env->CSR_EUEN = FIELD_DP64(env->CSR_EUEN, CSR_EUEN, FPE, 0);

  env->CSR_EUEN = FIELD_DP64(env->CSR_EUEN, CSR_EUEN, SXE, 0);


Reviewed-by: Bibo Mao 




Re: [PATCH] target/loongarch: Set CSR_PRCFG1 and CSR_PRCFG2 values

2024-07-04 Thread maobibo




On 2024/7/4 下午7:12, Song Gao wrote:

We set the value of register CSR_PRCFG3, but left out CSR_PRCFG1
and CSR_PRCFG2. Set CSR_PRCFG1 and CSR_PRCFG2 according to the
default values of the physical machine.

Signed-off-by: Song Gao 
---
  target/loongarch/cpu.c | 6 ++
  1 file changed, 6 insertions(+)

diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 270f711f11..ad40750701 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -538,6 +538,12 @@ static void loongarch_cpu_reset_hold(Object *obj, 
ResetType type)
  env->CSR_MERRCTL = FIELD_DP64(env->CSR_MERRCTL, CSR_MERRCTL, ISMERR, 0);
  env->CSR_TID = cs->cpu_index;
  
+env->CSR_PRCFG1 = FIELD_DP64(env->CSR_PRCFG1, CSR_PRCFG1, SAVE_NUM, 8);

+env->CSR_PRCFG1 = FIELD_DP64(env->CSR_PRCFG1, CSR_PRCFG1, TIMER_BITS, 
0x2f);
+env->CSR_PRCFG1 = FIELD_DP64(env->CSR_PRCFG1, CSR_PRCFG1, VSMAX, 7);
+
+env->CSR_PRCFG2 = 0x3000;
+
  env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, TLB_TYPE, 2);
  env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, MTLB_ENTRY, 63);
  env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, STLB_WAYS, 7);


For the function, it looks good to me. There are some nits:
For PRCFG1-PRCFG3, it is constant. I thinks it had better be put at cpu 
instance_init() or instance_finalize().


Also it is strange that most of cpu_state should be cleared with 0 
besides cpucfg/prcfg etc, such as end_reset_fields marker in other 
architectures.


Maybe it will better if there is double check with cpu state change 
callback such as init/reset etc :)


Regards
Bibo Mao




Re: [RFC v3 1/2] target/loongarch: Add loongson binary translation feature

2024-07-03 Thread maobibo




On 2024/7/3 下午5:43, Huacai Chen wrote:

On Wed, Jul 3, 2024 at 3:51 PM Jiaxun Yang  wrote:




在2024年7月1日七月 下午2:57,Jiaxun Yang写道:

在2024年5月30日五月 上午7:49,Bibo Mao写道:

Loongson Binary Translation (LBT) is used to accelerate binary
translation, which contains 4 scratch registers (scr0 to scr3), x86/ARM
eflags (eflags) and x87 fpu stack pointer (ftop).

Now LBT feature is added in kvm mode, not supported in TCG mode since
it is not emulated. Feature variable lbt is added with OnOffAuto type,
If lbt feature is not supported with KVM host, it reports error if there
is lbt=on command line.

If there is no any command line about lbt parameter, it checks whether
KVM host supports lbt feature and set the corresponding value in cpucfg.

Signed-off-by: Bibo Mao 

Hi Bibo,

I was going across recent LoongArch changes and this comes into my attention:


---
  target/loongarch/cpu.c| 53 +++
  target/loongarch/cpu.h|  6 +++
  target/loongarch/kvm/kvm.c| 26 +
  target/loongarch/kvm/kvm_loongarch.h  | 16 
  target/loongarch/loongarch-qmp-cmds.c |  2 +-
  5 files changed, 102 insertions(+), 1 deletion(-)

diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index b5c1ec94af..14265b6667 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -571,6 +571,30 @@ static void loongarch_cpu_disas_set_info(CPUState
*s, disassemble_info *info)
  info->print_insn = print_insn_loongarch;
  }

+static void loongarch_cpu_check_lbt(CPUState *cs, Error **errp)
+{
+CPULoongArchState *env = cpu_env(cs);
+LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+bool kvm_supported;
+
+kvm_supported = kvm_feature_supported(cs, LOONGARCH_FEATURE_LBT);


IMHO if there is no global states that should be saved/restored VM wise,
this should be handled at per CPU level, preferably with CPUCFG flags hint.

We should minimize non-privilege KVM feature bits to prevent hindering
asymmetry ISA system.


+ Huacai for further discussion

Hi Bibo, Huacai,

I investigated the topic further and went through the thread on kernel side.

I think Huacai and me are all on the same page that we should unify the 
interface for per-CPU
level feature probing and setting interface. Huacai purposed converting all 
features to VM feature
but I still believe CPUCFG is the best interface.

To probe LBT before actual vcpu creation, we can borrow the approach used by 
other architectures
(kvm_arm_create_scratch_host_vcpu() & kvm_riscv_create_scratch_vcpu()).

Kernel will reject setting unknown CPUCFG bits with -EINVAL, so to probe LBT we 
just need to perform
KVM_SET_REGS to scratch vcpu with LBT set to see if it's valid for kernel. 
There is no need for any other
probing interface.

I do think scratch CPU interface is also necessary if we are going to implement 
cpu = host.

Huacai, would you agree with me?

For me the important thing is consistency, all vm-features or all
vcpu-features are both accepted.
To understand features immediately is difficult job for me. There is 
supported features/used features usages etc, overall feature detection 
should be VM relative by my knowledge.


Maybe after host machine type and migration feature detection and 
checking is finished, there will be further upstanding -:(


Regards
Bibo Mao



Huacai



Thanks
- Jiaxun



Thanks
- Jiaxun

--
- Jiaxun


--
- Jiaxun





Re: [PATCH 1/3] hw/intc/loongson_ipi_common: Add loongson ipi common class

2024-07-03 Thread maobibo




On 2024/7/3 下午3:33, Jiaxun Yang wrote:



在2024年7月3日七月 下午2:40,maobibo写道:
[...]
Hi Bobo,


MMIO is loongson ipi specific, it is not necessary to put into common
function. Functions loongson_ipi_core_readl/loongson_ipi_core_writel can
be exported in header file include/hw/intc/loongson_ipi_common.h, or get
MemoryRegionOps of first memoryregion of loongson_ipi instance.

There is pseudo code:


Thanks for your demonstration. I'm still not quite convinced it's worthy to 
split
but I'm not going to block you if we don't have other oppositions.

Do you mind to finish conversion of loongson_ipi as well? Since you are 
drafting the
design.
It depends on schedule, I hope Loongarch IPI can merge before qemu is 
frozen. However I will try to write loongson_ipi but it can just pass to 
compile, no test. If it takes too long time to merge both Loongarch IPI 
and loongson ipi, I will only provide support for Loongarch IPI :)






static void loongson_ipi_realize(DeviceState *dev, Error **errp)
{
  LoongarchIPIState *s = LOONGARCH_IPI(dev);
  LoongarchIPIClass *lic = LOONGARCH_IPI_GET_CLASS(s);
  Error *local_err = NULL;

  lic->parent_realize(dev, &local_err);
  if (local_err) {
  error_propagate(errp, local_err);
  return;
  }

  
  *do mmio specific implematation in loongson ipi itself*
}

static void loongson_ipi_class_init(ObjectClass *klass, void *data)
{
  DeviceClass *dc = DEVICE_CLASS(klass);
  LoongsonIPICommonClass *licc = LOONGSON_IPI_COMMON_CLASS(klass);
  LoongarchIPIClass *lic = LOONGARCH_IPI_CLASS(klass);

  device_class_set_parent_realize(dc, loongson_ipi_realize,
&lic->parent_realize);
  licc->get_iocsr_as = get_iocsr_as;
}



If current implementation is hindering your future plan can you elaborate so we
can work on a resolution.

I'm happy to help with devlopment and testing.


   3. Interace cpu_by_arch_id is added, by default generic function
cpu_by_arch_id() is used to search vcpu from physical cpuid, it is
generic searching method. Different machine may define another search
method such binary searching method.


If you are going to implement some faster searching algorithm why don't we
   make it generic for all architectures?

It depends on the detailed physical id layout, is physical id is growing
up with logic cpu id or irrelative with logic cpu id? Different
architecture has different logic definition about physical id.


For x86' APIC id and RISC-V's hardid they are all somehow linear.
I'd suggest you to post a RFC patch regarding better algorithm.
Thanks for your suggestion, currently there is no such plan, it is above 
my ability :(


Regards
Bibo Mao


Thanks
- Jiaxun


Regards
Bibo Mao



Thanks
- Jiaxun



Signed-off-by: Bibo Mao 
---
   hw/intc/loongson_ipi_common.c | 394 ++
   include/hw/intc/loongson_ipi_common.h |  71 +
   2 files changed, 465 insertions(+)
   create mode 100644 hw/intc/loongson_ipi_common.c
   create mode 100644 include/hw/intc/loongson_ipi_common.h

diff --git a/hw/intc/loongson_ipi_common.c
b/hw/intc/loongson_ipi_common.c
new file mode 100644
index 00..f462f24f32
--- /dev/null
+++ b/hw/intc/loongson_ipi_common.c
@@ -0,0 +1,394 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Loongson ipi interrupt support
+ *
+ * Copyright (C) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "hw/boards.h"
+#include "hw/sysbus.h"
+#include "hw/intc/loongson_ipi_common.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+#include "qapi/error.h"
+#include "qemu/log.h"
+#include "exec/address-spaces.h"
+#include "exec/memory.h"
+#include "migration/vmstate.h"
+#include "trace.h"
+
+static MemTxResult loongson_ipi_core_readl(void *opaque, hwaddr addr,
+   uint64_t *data,
+   unsigned size, MemTxAttrs
attrs)
+{
+IPICore *s = opaque;
+uint64_t ret = 0;
+int index = 0;
+
+addr &= 0xff;
+switch (addr) {
+case CORE_STATUS_OFF:
+ret = s->status;
+break;
+case CORE_EN_OFF:
+ret = s->en;
+break;
+case CORE_SET_OFF:
+ret = 0;
+break;
+case CORE_CLEAR_OFF:
+ret = 0;
+break;
+case CORE_BUF_20 ... CORE_BUF_38 + 4:
+index = (addr - CORE_BUF_20) >> 2;
+ret = s->buf[index];
+break;
+default:
+qemu_log_mask(LOG_UNIMP, "invalid read: %x", (uint32_t)addr);
+break;
+}
+
+trace_loongson_ipi_read(size, (uint64_t)addr, ret);
+*data = ret;
+return MEMTX_OK;
+}
+
+static MemTxResult loongson_ipi_iocsr_readl(void *opaque, hwaddr addr,
+uint64_t *

Re: [PATCH 1/3] hw/intc/loongson_ipi_common: Add loongson ipi common class

2024-07-02 Thread maobibo




On 2024/7/3 下午2:16, Jiaxun Yang wrote:



在2024年7月3日七月 上午10:12,Bibo Mao写道:

Loongson ipi common class and instance is created here, it comes
from file loongson_ipi mostly. For the new added loongson ipi
common class, there is four interfaces defined here:
  1. Interfaces pre_save/post_load are used for future kvm child class
  2. Interface get_iocsr_as can be used for different architectures,
now MIPS 3A4000 and LoongArch 3A5000 machine use this ip, can inherit
this common class.


Please consider MMIO implementation here as well. Can you demonstrate
how would you share implementation with MMIO based IPI? In current
implementation we share memory R/W callbacks but in your implementation
that's nolonger possible.

Jiaxun,

Thanks for your quick response.

MMIO is loongson ipi specific, it is not necessary to put into common 
function. Functions loongson_ipi_core_readl/loongson_ipi_core_writel can 
be exported in header file include/hw/intc/loongson_ipi_common.h, or get 
MemoryRegionOps of first memoryregion of loongson_ipi instance.


There is pseudo code:

static void loongson_ipi_realize(DeviceState *dev, Error **errp)
{
LoongarchIPIState *s = LOONGARCH_IPI(dev);
LoongarchIPIClass *lic = LOONGARCH_IPI_GET_CLASS(s);
Error *local_err = NULL;

lic->parent_realize(dev, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
}


*do mmio specific implematation in loongson ipi itself*
}

static void loongson_ipi_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
LoongsonIPICommonClass *licc = LOONGSON_IPI_COMMON_CLASS(klass);
LoongarchIPIClass *lic = LOONGARCH_IPI_CLASS(klass);

device_class_set_parent_realize(dc, loongson_ipi_realize, 
&lic->parent_realize);

licc->get_iocsr_as = get_iocsr_as;
}



If current implementation is hindering your future plan can you elaborate so we
can work on a resolution.

I'm happy to help with devlopment and testing.


  3. Interace cpu_by_arch_id is added, by default generic function
cpu_by_arch_id() is used to search vcpu from physical cpuid, it is
generic searching method. Different machine may define another search
method such binary searching method.


If you are going to implement some faster searching algorithm why don't we
  make it generic for all architectures?
It depends on the detailed physical id layout, is physical id is growing 
up with logic cpu id or irrelative with logic cpu id? Different 
architecture has different logic definition about physical id.


Regards
Bibo Mao



Thanks
- Jiaxun



Signed-off-by: Bibo Mao 
---
  hw/intc/loongson_ipi_common.c | 394 ++
  include/hw/intc/loongson_ipi_common.h |  71 +
  2 files changed, 465 insertions(+)
  create mode 100644 hw/intc/loongson_ipi_common.c
  create mode 100644 include/hw/intc/loongson_ipi_common.h

diff --git a/hw/intc/loongson_ipi_common.c
b/hw/intc/loongson_ipi_common.c
new file mode 100644
index 00..f462f24f32
--- /dev/null
+++ b/hw/intc/loongson_ipi_common.c
@@ -0,0 +1,394 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Loongson ipi interrupt support
+ *
+ * Copyright (C) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "hw/boards.h"
+#include "hw/sysbus.h"
+#include "hw/intc/loongson_ipi_common.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+#include "qapi/error.h"
+#include "qemu/log.h"
+#include "exec/address-spaces.h"
+#include "exec/memory.h"
+#include "migration/vmstate.h"
+#include "trace.h"
+
+static MemTxResult loongson_ipi_core_readl(void *opaque, hwaddr addr,
+   uint64_t *data,
+   unsigned size, MemTxAttrs
attrs)
+{
+IPICore *s = opaque;
+uint64_t ret = 0;
+int index = 0;
+
+addr &= 0xff;
+switch (addr) {
+case CORE_STATUS_OFF:
+ret = s->status;
+break;
+case CORE_EN_OFF:
+ret = s->en;
+break;
+case CORE_SET_OFF:
+ret = 0;
+break;
+case CORE_CLEAR_OFF:
+ret = 0;
+break;
+case CORE_BUF_20 ... CORE_BUF_38 + 4:
+index = (addr - CORE_BUF_20) >> 2;
+ret = s->buf[index];
+break;
+default:
+qemu_log_mask(LOG_UNIMP, "invalid read: %x", (uint32_t)addr);
+break;
+}
+
+trace_loongson_ipi_read(size, (uint64_t)addr, ret);
+*data = ret;
+return MEMTX_OK;
+}
+
+static MemTxResult loongson_ipi_iocsr_readl(void *opaque, hwaddr addr,
+uint64_t *data,
+unsigned size, MemTxAttrs
attrs)
+{
+LoongsonIPICommonState *ipi = opaque;
+IPICore *s;
+
+if (attrs.requester_id >= ipi->num_cpu) {
+return MEMTX_DECODE_ERROR;
+}
+
+s = &ipi->cpu[attrs.requester_id];
+return loongson_ipi_core_readl(s, addr, data, size, attrs);
+}
+
+static Mem

Re: [RFC v3 1/2] target/loongarch: Add loongson binary translation feature

2024-07-01 Thread maobibo




On 2024/7/1 下午4:42, Jiaxun Yang wrote:



在2024年7月1日七月 上午8:32,maobibo写道:
[...]


+static void loongarch_cpu_check_lbt(CPUState *cs, Error **errp)
+{
+CPULoongArchState *env = cpu_env(cs);
+LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+bool kvm_supported;
+
+kvm_supported = kvm_feature_supported(cs, LOONGARCH_FEATURE_LBT);


IMHO if there is no global states that should be saved/restored VM wise,
this should be handled at per CPU level, preferably with CPUCFG flags hint.

We should minimize non-privilege KVM feature bits to prevent hindering
asymmetry ISA system.

For "asymmetry ISA system", do you meaning some vcpus have LBT feature,
however some vcpus does have LBT features? That does not exists at all.


Yes, we should always prepare for the future :-)

 From Weiwu's presentations, I believe LASX asymmetry product is already on the
roadmap. So for LBT it's also a possibility.
I never hear such product plan with different LASX/LSX capability even 
for the future big-little product.




Even if such product won't land in near future, we should still try our best
to bound to vCPU creation, not to the system.



It will be big disaster for such products, how does application use this?


Affinity placement etc, there are many possibilities.

On Arm side, there are already systems with Big.Little asymmetry CPU that
some of the processor equipped 32 bit EL0 mode while others doesn't. They
managed that well with affinity.

See: arm64: Allow mismatched 32-bit EL0 support

Is it only 32 bit EL0 mode or 32bit compatible mode and 64 bit also?

What is the detailed product name and how does Linux/KVM support this 
product?


Regards
Bibo Mao


Thanks


Regards
Bibo


Thanks
- Jiaxun








Re: [PATCH v3 1/4] hw/intc: Remove loongarch_ipi.c

2024-07-01 Thread maobibo




On 2024/7/1 下午4:29, Jiaxun Yang wrote:



在2024年7月1日七月 上午8:22,maobibo写道:

On 2024/7/1 下午3:01, Jiaxun Yang wrote:



在2024年7月1日七月 上午7:44,maobibo写道:

Also this patch is problematic on LoongArch.

The original patch is to search physical cpuid rather than logic cpuid.

We want to make ipi module better and better, however now it comes back
to initial state at the beginning :(


Isn't arch_id the "physical id" you want? "cs->cpu_index" is the logical ID
for QEMU.

arch_id is setup by arch code, like APIC ID for x86.

I had come across the old ipi_getcpu  implementation, and I'm sure we were
looking at arch_id as well.

So, where is implementation code for function get_arch_id() looking for
vcpu with physical index?


Hi Bibo,

cpu_by_arch_id will be redirected to:

```
CPUState *cpu_by_arch_id(int64_t id)
{
 CPUState *cpu;

 CPU_FOREACH(cpu) {
 CPUClass *cc = CPU_GET_CLASS(cpu);

 if (cc->get_arch_id(cpu) == id) {
 return cpu;
 }
 }
 return NULL;
}
```

It iterates over all vcpus and return CPUStates with corresponding arch_id.

Whereas, for LoongArch's get_arch_id implementation:
```
static int64_t loongarch_cpu_get_arch_id(CPUState *cs)
{
 LoongArchCPU *cpu = LOONGARCH_CPU(cs);

 return cpu->phy_id;
}
```
I believe it matches our intension here.

yes, you are right.

Got it, I miss the architecture specific implementation, and thanks for 
pointing it out with patience.


Regards


Thanks



Regards
Bibo Mao



Thanks
- Jiaxun


commit 03ca348b6b9038ce284916b36c19f700ac0ce7a6
Author: Jiaxun Yang 
Date:   Wed Jun 5 10:04:27 2024

   hw/intc/loongson_ipi: Replace ipi_getcpu with cpu_by_arch_id

   cpu_by_arch_id is doing the same thing as our ipi_getcpu logic.

   Signed-off-by: Jiaxun Yang 
   Reviewed-by: Song Gao 
   Message-ID: <20240605-loongson3-ipi-v3-4-ddd2c0e03...@flygoat.com>
   Signed-off-by: Philippe Mathieu-Daudé 


Regards
Bibo Mao








Re: [RFC v3 1/2] target/loongarch: Add loongson binary translation feature

2024-07-01 Thread maobibo




On 2024/7/1 下午2:57, Jiaxun Yang wrote:



在2024年5月30日五月 上午7:49,Bibo Mao写道:

Loongson Binary Translation (LBT) is used to accelerate binary
translation, which contains 4 scratch registers (scr0 to scr3), x86/ARM
eflags (eflags) and x87 fpu stack pointer (ftop).

Now LBT feature is added in kvm mode, not supported in TCG mode since
it is not emulated. Feature variable lbt is added with OnOffAuto type,
If lbt feature is not supported with KVM host, it reports error if there
is lbt=on command line.

If there is no any command line about lbt parameter, it checks whether
KVM host supports lbt feature and set the corresponding value in cpucfg.

Signed-off-by: Bibo Mao 

Hi Bibo,

I was going across recent LoongArch changes and this comes into my attention:


---
  target/loongarch/cpu.c| 53 +++
  target/loongarch/cpu.h|  6 +++
  target/loongarch/kvm/kvm.c| 26 +
  target/loongarch/kvm/kvm_loongarch.h  | 16 
  target/loongarch/loongarch-qmp-cmds.c |  2 +-
  5 files changed, 102 insertions(+), 1 deletion(-)

diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index b5c1ec94af..14265b6667 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -571,6 +571,30 @@ static void loongarch_cpu_disas_set_info(CPUState
*s, disassemble_info *info)
  info->print_insn = print_insn_loongarch;
  }

+static void loongarch_cpu_check_lbt(CPUState *cs, Error **errp)
+{
+CPULoongArchState *env = cpu_env(cs);
+LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+bool kvm_supported;
+
+kvm_supported = kvm_feature_supported(cs, LOONGARCH_FEATURE_LBT);


IMHO if there is no global states that should be saved/restored VM wise,
this should be handled at per CPU level, preferably with CPUCFG flags hint.

We should minimize non-privilege KVM feature bits to prevent hindering
asymmetry ISA system.
For "asymmetry ISA system", do you meaning some vcpus have LBT feature, 
however some vcpus does have LBT features? That does not exists at all.


It will be big disaster for such products, how does application use this?

Regards
Bibo


Thanks
- Jiaxun






Re: [PATCH v3 1/4] hw/intc: Remove loongarch_ipi.c

2024-07-01 Thread maobibo




On 2024/7/1 下午3:08, Jiaxun Yang wrote:



在2024年7月1日七月 上午2:35,maobibo写道:
[...]


How about split loongson_ipi.c into
loongson_ipi_base.c/loongson_ipi_loongson.c/loongson_ipi_loongarch.c,

File loongson_ipi_base.c contains the common code, loongson_ipi_xxx.c
contains arch specific. Soon we will submit irqchip in kernel function,
it will be much different for architectures, since ioctl command is
different for two architectures to save/restore ipi registers.


MIPS's in kernel IPI IOCTL interface is non-existent so far, so if you are going
to design something, I think it will be adopted by MIPS if necessary. There is 
still
no need to create divergence in between.

That being said, You are more than welcomed to draft a patch so we can discuss 
based
on that.

Sure, will do.

Regards
Bibo Mao


Thanks


Regards
Bibo Mao







Re: [PATCH v3 1/4] hw/intc: Remove loongarch_ipi.c

2024-07-01 Thread maobibo




On 2024/7/1 下午3:01, Jiaxun Yang wrote:



在2024年7月1日七月 上午7:44,maobibo写道:

Also this patch is problematic on LoongArch.

The original patch is to search physical cpuid rather than logic cpuid.

We want to make ipi module better and better, however now it comes back
to initial state at the beginning :(


Isn't arch_id the "physical id" you want? "cs->cpu_index" is the logical ID
for QEMU.

arch_id is setup by arch code, like APIC ID for x86.

I had come across the old ipi_getcpu  implementation, and I'm sure we were
looking at arch_id as well.
So, where is implementation code for function get_arch_id() looking for 
vcpu with physical index?


Regards
Bibo Mao



Thanks
- Jiaxun


commit 03ca348b6b9038ce284916b36c19f700ac0ce7a6
Author: Jiaxun Yang 
Date:   Wed Jun 5 10:04:27 2024

  hw/intc/loongson_ipi: Replace ipi_getcpu with cpu_by_arch_id

  cpu_by_arch_id is doing the same thing as our ipi_getcpu logic.

  Signed-off-by: Jiaxun Yang 
  Reviewed-by: Song Gao 
  Message-ID: <20240605-loongson3-ipi-v3-4-ddd2c0e03...@flygoat.com>
  Signed-off-by: Philippe Mathieu-Daudé 


Regards
Bibo Mao






Re: [PATCH v3 1/4] hw/intc: Remove loongarch_ipi.c

2024-06-30 Thread maobibo

Also this patch is problematic on LoongArch.

The original patch is to search physical cpuid rather than logic cpuid.

We want to make ipi module better and better, however now it comes back 
to initial state at the beginning :(


commit 03ca348b6b9038ce284916b36c19f700ac0ce7a6
Author: Jiaxun Yang 
Date:   Wed Jun 5 10:04:27 2024

hw/intc/loongson_ipi: Replace ipi_getcpu with cpu_by_arch_id

cpu_by_arch_id is doing the same thing as our ipi_getcpu logic.

Signed-off-by: Jiaxun Yang 
Reviewed-by: Song Gao 
Message-ID: <20240605-loongson3-ipi-v3-4-ddd2c0e03...@flygoat.com>
Signed-off-by: Philippe Mathieu-Daudé 


Regards
Bibo Mao

On 2024/7/1 上午9:35, maobibo wrote:

Hi Philippe,

On 2024/6/27 下午9:02, Philippe Mathieu-Daudé wrote:

On 27/6/24 04:44, gaosong wrote:

在 2024/6/26 下午8:10, Philippe Mathieu-Daudé 写道:

Hi Bibo,

On 26/6/24 06:11, maobibo wrote:



On 2024/6/5 上午10:15, Jiaxun Yang wrote:

It was missed out in previous commit.

Fixes: b4a12dfc2132 ("hw/intc/loongarch_ipi: Rename as loongson_ipi")
Signed-off-by: Jiaxun Yang 
---
  hw/intc/loongarch_ipi.c | 347 


  1 file changed, 347 deletions(-)




-static void loongarch_ipi_realize(DeviceState *dev, Error **errp)
-{
-    LoongArchIPI *s = LOONGARCH_IPI(dev);
-    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
-    int i;
-
-    if (s->num_cpu == 0) {
-    error_setg(errp, "num-cpu must be at least 1");
-    return;
-    }
-
-    memory_region_init_io(&s->ipi_iocsr_mem, OBJECT(dev), 
&loongarch_ipi_ops,

-  s, "loongarch_ipi_iocsr", 0x48);
-
-    /* loongarch_ipi_iocsr performs re-entrant IO through 
ipi_send */

-    s->ipi_iocsr_mem.disable_reentrancy_guard = true;
-
-    sysbus_init_mmio(sbd, &s->ipi_iocsr_mem);
-
-    memory_region_init_io(&s->ipi64_iocsr_mem, OBJECT(dev),
-  &loongarch_ipi64_ops,
-  s, "loongarch_ipi64_iocsr", 0x118);
-    sysbus_init_mmio(sbd, &s->ipi64_iocsr_mem);

It is different with existing implementation.

With hw/intc/loongson_ipi.c, every vcpu has one ipi_mmio_mem, 
however on loongarch ipi machine, there is no ipi_mmio_mem memory 
region.


So if machine has 256 vcpus, there will be 256 ipi_mmio_mem memory 
regions. In function sysbus_init_mmio(), memory region can not exceed

QDEV_MAX_MMIO (32).  With so many memory regions, it slows down memory
region search speed also.

void sysbus_init_mmio(SysBusDevice *dev, MemoryRegion *memory)
{
 int n;

 assert(dev->num_mmio < QDEV_MAX_MMIO);
 n = dev->num_mmio++;
 dev->mmio[n].addr = -1;
 dev->mmio[n].memory = memory;
}

Can we revert this patch? We want to do production usable by real 
users rather than show pure technology.


Since commit b4a12dfc2132 this file is not built/tested anymore:

-specific_ss.add(when: 'CONFIG_LOONGARCH_IPI', if_true: 
files('loongarch_ipi.c'))
+specific_ss.add(when: 'CONFIG_LOONGSON_IPI', if_true: 
files('loongson_ipi.c'))


We don't want to maintain dead code.


Hi,  Philippe

It is commmit 49eba52a5 that causes Loongarch to fail to start.

What bibao means is that LoongArch and mips do not share 
"lloongson_ipi.c".

This avoids mutual influence.


My understanding of the next sentence is as follows.

Nowadays, most of the open source operating systems in China use the 
latest QEMU.
e.g. OpenEuler/OpenAnolis/OpenCloudOS, etc. These operating systems 
have a large
  number of real users. so we need to maintain the stability of the 
LoongArch architecture
of the QEMU community as much as possible. This will reduce 
maintenance costs.


I'm glad there is a such large number of users :)

Therefore, we would like to restore the 'loongarch_ipi.c' file. what 
do you think?


My preference on "reducing maintenance cost" is code reuse instead of
duplication.

Before reverting, lets try to fix the issue. I suggested a v2:
https://lore.kernel.org/qemu-devel/20240627125819.62779-2-phi...@linaro.org 


Sorry for late reply.

How about split loongson_ipi.c into 
loongson_ipi_base.c/loongson_ipi_loongson.c/loongson_ipi_loongarch.c,


File loongson_ipi_base.c contains the common code, loongson_ipi_xxx.c 
contains arch specific. Soon we will submit irqchip in kernel function,
it will be much different for architectures, since ioctl command is 
different for two architectures to save/restore ipi registers.


Regards
Bibo Mao



That said, both current patch and the suggested fix pass our
Avocado CI test suite (running tests/avocado/machine_loongarch.py).

Is your use case not covered? Could you expand the CI tests so
we don't hit this problem again? (Also we could reproduce and
fix more easily).

Thanks,

Phil.







Re: [PATCH v3 1/4] hw/intc: Remove loongarch_ipi.c

2024-06-30 Thread maobibo

Hi Philippe,

On 2024/6/27 下午9:02, Philippe Mathieu-Daudé wrote:

On 27/6/24 04:44, gaosong wrote:

在 2024/6/26 下午8:10, Philippe Mathieu-Daudé 写道:

Hi Bibo,

On 26/6/24 06:11, maobibo wrote:



On 2024/6/5 上午10:15, Jiaxun Yang wrote:

It was missed out in previous commit.

Fixes: b4a12dfc2132 ("hw/intc/loongarch_ipi: Rename as loongson_ipi")
Signed-off-by: Jiaxun Yang 
---
  hw/intc/loongarch_ipi.c | 347 


  1 file changed, 347 deletions(-)




-static void loongarch_ipi_realize(DeviceState *dev, Error **errp)
-{
-    LoongArchIPI *s = LOONGARCH_IPI(dev);
-    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
-    int i;
-
-    if (s->num_cpu == 0) {
-    error_setg(errp, "num-cpu must be at least 1");
-    return;
-    }
-
-    memory_region_init_io(&s->ipi_iocsr_mem, OBJECT(dev), 
&loongarch_ipi_ops,

-  s, "loongarch_ipi_iocsr", 0x48);
-
-    /* loongarch_ipi_iocsr performs re-entrant IO through ipi_send */
-    s->ipi_iocsr_mem.disable_reentrancy_guard = true;
-
-    sysbus_init_mmio(sbd, &s->ipi_iocsr_mem);
-
-    memory_region_init_io(&s->ipi64_iocsr_mem, OBJECT(dev),
-  &loongarch_ipi64_ops,
-  s, "loongarch_ipi64_iocsr", 0x118);
-    sysbus_init_mmio(sbd, &s->ipi64_iocsr_mem);

It is different with existing implementation.

With hw/intc/loongson_ipi.c, every vcpu has one ipi_mmio_mem, 
however on loongarch ipi machine, there is no ipi_mmio_mem memory 
region.


So if machine has 256 vcpus, there will be 256 ipi_mmio_mem memory 
regions. In function sysbus_init_mmio(), memory region can not exceed

QDEV_MAX_MMIO (32).  With so many memory regions, it slows down memory
region search speed also.

void sysbus_init_mmio(SysBusDevice *dev, MemoryRegion *memory)
{
 int n;

 assert(dev->num_mmio < QDEV_MAX_MMIO);
 n = dev->num_mmio++;
 dev->mmio[n].addr = -1;
 dev->mmio[n].memory = memory;
}

Can we revert this patch? We want to do production usable by real 
users rather than show pure technology.


Since commit b4a12dfc2132 this file is not built/tested anymore:

-specific_ss.add(when: 'CONFIG_LOONGARCH_IPI', if_true: 
files('loongarch_ipi.c'))
+specific_ss.add(when: 'CONFIG_LOONGSON_IPI', if_true: 
files('loongson_ipi.c'))


We don't want to maintain dead code.


Hi,  Philippe

It is commmit 49eba52a5 that causes Loongarch to fail to start.

What bibao means is that LoongArch and mips do not share 
"lloongson_ipi.c".

This avoids mutual influence.


My understanding of the next sentence is as follows.

Nowadays, most of the open source operating systems in China use the 
latest QEMU.
e.g. OpenEuler/OpenAnolis/OpenCloudOS, etc. These operating systems 
have a large
  number of real users. so we need to maintain the stability of the 
LoongArch architecture
of the QEMU community as much as possible. This will reduce 
maintenance costs.


I'm glad there is a such large number of users :)

Therefore, we would like to restore the 'loongarch_ipi.c' file. what 
do you think?


My preference on "reducing maintenance cost" is code reuse instead of
duplication.

Before reverting, lets try to fix the issue. I suggested a v2:
https://lore.kernel.org/qemu-devel/20240627125819.62779-2-phi...@linaro.org

Sorry for late reply.

How about split loongson_ipi.c into 
loongson_ipi_base.c/loongson_ipi_loongson.c/loongson_ipi_loongarch.c,


File loongson_ipi_base.c contains the common code, loongson_ipi_xxx.c 
contains arch specific. Soon we will submit irqchip in kernel function,
it will be much different for architectures, since ioctl command is 
different for two architectures to save/restore ipi registers.


Regards
Bibo Mao



That said, both current patch and the suggested fix pass our
Avocado CI test suite (running tests/avocado/machine_loongarch.py).

Is your use case not covered? Could you expand the CI tests so
we don't hit this problem again? (Also we could reproduce and
fix more easily).

Thanks,

Phil.





Re: [PATCH v3 1/4] hw/intc: Remove loongarch_ipi.c

2024-06-26 Thread maobibo




On 2024/6/26 下午3:40, Jiaxun Yang wrote:



在2024年6月26日六月 上午5:11,maobibo写道:
[...]

It is different with existing implementation.

What do you mean? Isn't this the actual hardware behaviour?



With hw/intc/loongson_ipi.c, every vcpu has one ipi_mmio_mem, however on
loongarch ipi machine, there is no ipi_mmio_mem memory region.
So if machine has 256 vcpus, there will be 256 ipi_mmio_mem memory
regions. In function sysbus_init_mmio(), memory region can not exceed
QDEV_MAX_MMIO (32).  With so many memory regions, it slows down memory
region search speed also.

Ouch, never thought about that before, but I think we can control the
registration of sysbus_mmio with a device property or even ifdef so LoongArch
machine won't be affected.

For MIPS loongson3-virt machine, our CPU number is capped, so that won't
be a problem.

I'm currently travelling without access to my PC, I'll prepare a patch
as soon as I gain access again. Feel free to send a patch before me with
this approach if you desperately want to fix it.



void sysbus_init_mmio(SysBusDevice *dev, MemoryRegion *memory)
{
  int n;

  assert(dev->num_mmio < QDEV_MAX_MMIO);
  n = dev->num_mmio++;
  dev->mmio[n].addr = -1;
  dev->mmio[n].memory = memory;
}

Can we revert this patch? We want to do production usable by real users
rather than show pure technology.


I don't really get your point, we have at leat 4 real users requesting SMP
support for loongson3-virt on gitlab issues, plus I need this to test
MIPS/Loongson64 SMP kernel.

If there is a problem with your use case, we can fix it. Why we do want to
remove the functionality when there is an easy fix?
I do not think we have the ability to abstract hw and continuous 
maintenance for two different architecture, including you and me.


So I suggest that different files will be better for the present. After 
one year or later, if we have further understanding about system, it is 
ok to merge them into one file.


Regards
Bibo Mao


It’s not only the features necessary for you that made QEMU an outstanding
project; it’s everything coming together that completes it.

Thanks
- Jiaxun


Regards
Bibo Mao


-
-s->cpu = g_new0(IPICore, s->num_cpu);
-if (s->cpu == NULL) {
-error_setg(errp, "Memory allocation for ExtIOICore faile");
-return;
-}
-
-for (i = 0; i < s->num_cpu; i++) {
-qdev_init_gpio_out(dev, &s->cpu[i].irq, 1);
-}
-}
-
-static const VMStateDescription vmstate_ipi_core = {
-.name = "ipi-single",
-.version_id = 2,
-.minimum_version_id = 2,
-.fields = (const VMStateField[]) {
-VMSTATE_UINT32(status, IPICore),
-VMSTATE_UINT32(en, IPICore),
-VMSTATE_UINT32(set, IPICore),
-VMSTATE_UINT32(clear, IPICore),
-VMSTATE_UINT32_ARRAY(buf, IPICore, IPI_MBX_NUM * 2),
-VMSTATE_END_OF_LIST()
-}
-};
-
-static const VMStateDescription vmstate_loongarch_ipi = {
-.name = TYPE_LOONGARCH_IPI,
-.version_id = 2,
-.minimum_version_id = 2,
-.fields = (const VMStateField[]) {
-VMSTATE_STRUCT_VARRAY_POINTER_UINT32(cpu, LoongArchIPI, num_cpu,
- vmstate_ipi_core, IPICore),
-VMSTATE_END_OF_LIST()
-}
-};
-
-static Property ipi_properties[] = {
-DEFINE_PROP_UINT32("num-cpu", LoongArchIPI, num_cpu, 1),
-DEFINE_PROP_END_OF_LIST(),
-};
-
-static void loongarch_ipi_class_init(ObjectClass *klass, void *data)
-{
-DeviceClass *dc = DEVICE_CLASS(klass);
-
-dc->realize = loongarch_ipi_realize;
-device_class_set_props(dc, ipi_properties);
-dc->vmsd = &vmstate_loongarch_ipi;
-}
-
-static void loongarch_ipi_finalize(Object *obj)
-{
-LoongArchIPI *s = LOONGARCH_IPI(obj);
-
-g_free(s->cpu);
-}
-
-static const TypeInfo loongarch_ipi_info = {
-.name  = TYPE_LOONGARCH_IPI,
-.parent= TYPE_SYS_BUS_DEVICE,
-.instance_size = sizeof(LoongArchIPI),
-.class_init= loongarch_ipi_class_init,
-.instance_finalize = loongarch_ipi_finalize,
-};
-
-static void loongarch_ipi_register_types(void)
-{
-type_register_static(&loongarch_ipi_info);
-}
-
-type_init(loongarch_ipi_register_types)








Re: [PATCH v3 1/4] hw/intc: Remove loongarch_ipi.c

2024-06-25 Thread maobibo




On 2024/6/5 上午10:15, Jiaxun Yang wrote:

It was missed out in previous commit.

Fixes: b4a12dfc2132 ("hw/intc/loongarch_ipi: Rename as loongson_ipi")
Signed-off-by: Jiaxun Yang 
---
  hw/intc/loongarch_ipi.c | 347 
  1 file changed, 347 deletions(-)

diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c
deleted file mode 100644
index 44b3b9c138d6..
--- a/hw/intc/loongarch_ipi.c
+++ /dev/null
@@ -1,347 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * LoongArch ipi interrupt support
- *
- * Copyright (C) 2021 Loongson Technology Corporation Limited
- */
-
-#include "qemu/osdep.h"
-#include "hw/boards.h"
-#include "hw/sysbus.h"
-#include "hw/intc/loongarch_ipi.h"
-#include "hw/irq.h"
-#include "hw/qdev-properties.h"
-#include "qapi/error.h"
-#include "qemu/log.h"
-#include "exec/address-spaces.h"
-#include "migration/vmstate.h"
-#include "target/loongarch/cpu.h"
-#include "trace.h"
-
-static MemTxResult loongarch_ipi_readl(void *opaque, hwaddr addr,
-   uint64_t *data,
-   unsigned size, MemTxAttrs attrs)
-{
-IPICore *s;
-LoongArchIPI *ipi = opaque;
-uint64_t ret = 0;
-int index = 0;
-
-s = &ipi->cpu[attrs.requester_id];
-addr &= 0xff;
-switch (addr) {
-case CORE_STATUS_OFF:
-ret = s->status;
-break;
-case CORE_EN_OFF:
-ret = s->en;
-break;
-case CORE_SET_OFF:
-ret = 0;
-break;
-case CORE_CLEAR_OFF:
-ret = 0;
-break;
-case CORE_BUF_20 ... CORE_BUF_38 + 4:
-index = (addr - CORE_BUF_20) >> 2;
-ret = s->buf[index];
-break;
-default:
-qemu_log_mask(LOG_UNIMP, "invalid read: %x", (uint32_t)addr);
-break;
-}
-
-trace_loongarch_ipi_read(size, (uint64_t)addr, ret);
-*data = ret;
-return MEMTX_OK;
-}
-
-static void send_ipi_data(CPULoongArchState *env, uint64_t val, hwaddr addr,
-  MemTxAttrs attrs)
-{
-int i, mask = 0, data = 0;
-
-/*
- * bit 27-30 is mask for byte writing,
- * if the mask is 0, we need not to do anything.
- */
-if ((val >> 27) & 0xf) {
-data = address_space_ldl(env->address_space_iocsr, addr,
- attrs, NULL);
-for (i = 0; i < 4; i++) {
-/* get mask for byte writing */
-if (val & (0x1 << (27 + i))) {
-mask |= 0xff << (i * 8);
-}
-}
-}
-
-data &= mask;
-data |= (val >> 32) & ~mask;
-address_space_stl(env->address_space_iocsr, addr,
-  data, attrs, NULL);
-}
-
-static int archid_cmp(const void *a, const void *b)
-{
-   CPUArchId *archid_a = (CPUArchId *)a;
-   CPUArchId *archid_b = (CPUArchId *)b;
-
-   return archid_a->arch_id - archid_b->arch_id;
-}
-
-static CPUArchId *find_cpu_by_archid(MachineState *ms, uint32_t id)
-{
-CPUArchId apic_id, *found_cpu;
-
-apic_id.arch_id = id;
-found_cpu = bsearch(&apic_id, ms->possible_cpus->cpus,
-ms->possible_cpus->len, sizeof(*ms->possible_cpus->cpus),
-archid_cmp);
-
-return found_cpu;
-}
-
-static CPUState *ipi_getcpu(int arch_id)
-{
-MachineState *machine = MACHINE(qdev_get_machine());
-CPUArchId *archid;
-
-archid = find_cpu_by_archid(machine, arch_id);
-if (archid) {
-return CPU(archid->cpu);
-}
-
-return NULL;
-}
-
-static MemTxResult mail_send(uint64_t val, MemTxAttrs attrs)
-{
-uint32_t cpuid;
-hwaddr addr;
-CPUState *cs;
-
-cpuid = extract32(val, 16, 10);
-cs = ipi_getcpu(cpuid);
-if (cs == NULL) {
-return MEMTX_DECODE_ERROR;
-}
-
-/* override requester_id */
-addr = SMP_IPI_MAILBOX + CORE_BUF_20 + (val & 0x1c);
-attrs.requester_id = cs->cpu_index;
-send_ipi_data(&LOONGARCH_CPU(cs)->env, val, addr, attrs);
-return MEMTX_OK;
-}
-
-static MemTxResult any_send(uint64_t val, MemTxAttrs attrs)
-{
-uint32_t cpuid;
-hwaddr addr;
-CPUState *cs;
-
-cpuid = extract32(val, 16, 10);
-cs = ipi_getcpu(cpuid);
-if (cs == NULL) {
-return MEMTX_DECODE_ERROR;
-}
-
-/* override requester_id */
-addr = val & 0x;
-attrs.requester_id = cs->cpu_index;
-send_ipi_data(&LOONGARCH_CPU(cs)->env, val, addr, attrs);
-return MEMTX_OK;
-}
-
-static MemTxResult loongarch_ipi_writel(void *opaque, hwaddr addr, uint64_t 
val,
-unsigned size, MemTxAttrs attrs)
-{
-LoongArchIPI *ipi = opaque;
-IPICore *s;
-int index = 0;
-uint32_t cpuid;
-uint8_t vector;
-CPUState *cs;
-
-s = &ipi->cpu[attrs.requester_id];
-addr &= 0xff;
-trace_loongarch_ipi_write(size, (uint64_t)addr, val);
-switch (addr) {
-case CORE_STATUS_OFF:
-qemu_log_mask(LOG_GUEST_ERROR, "can not be written");
-break;
-case CORE_EN_OFF:
-  

Re: [PATCH 0/3] S3 and S4 sleep for loongarch/virt & microvm

2024-06-14 Thread maobibo




On 2024/6/14 下午10:03, Daniel P. Berrangé wrote:

On Fri, Jun 14, 2024 at 01:17:39PM +0800, maobibo wrote:



On 2024/6/14 下午12:27, Jiaxun Yang wrote:



在2024年6月14日六月 上午4:32,maobibo写道:

It is interesting.

How to wakeup VM if it sleeps in S3/S4, from emulated keyboard or
ethernet magic packet or qemu monitor command in background?


Hi Bibo,

The best way to wake the guest is system_wakeup command in monitor.

Ok, I see.

It is useful and it can be used to test S3/S4 in TCG mode at least.

Can we add feature capability, enabled in TCG mode, disabled in KVM mode by
default? If vm deploys in cloud, users in general help it is power-on
always.


Please avoid creating differing defaults between TCG and KVM where
practical.
There is bad experience for me, remote VM suddenly freezes and all 
network connection are lost if virt-machine does not support S3/S4 on 
LoongArch machines.


However it does not happen on x86 machine, how does x86 KVM VM machine 
stop this?


Regards
Bibo Mao


With regards,
Daniel






Re: [PATCH 0/3] S3 and S4 sleep for loongarch/virt & microvm

2024-06-13 Thread maobibo




On 2024/6/14 下午12:27, Jiaxun Yang wrote:



在2024年6月14日六月 上午4:32,maobibo写道:

It is interesting.

How to wakeup VM if it sleeps in S3/S4, from emulated keyboard or
ethernet magic packet or qemu monitor command in background?


Hi Bibo,

The best way to wake the guest is system_wakeup command in monitor.

Ok, I see.

It is useful and it can be used to test S3/S4 in TCG mode at least.

Can we add feature capability, enabled in TCG mode, disabled in KVM mode 
by default? If vm deploys in cloud, users in general help it is power-on 
always.


Regards
Bibo Mao


Thanks
- Jiaxun



Regards
Bibo Mao


On 2024/6/14 上午1:30, Jiaxun Yang wrote:

Hi all,

This series implemented S3 and S4 sleep for loongarch virt machine
and microvm.

For loongarch/virt a kernel patch is requried [1].

[1]: 
https://lore.kernel.org/loongarch/20240613-loongarch64-sleep-v1-0-a245232af...@flygoat.com/

Please review.
Thanks

Signed-off-by: Jiaxun Yang 
---
Jiaxun Yang (3):
acpi/ged: Implement S3 and S4 sleep
hw/loongarch/virt: Wire up S3 and S4 sleep
hw/i386/microvm: Wire up S3 and S4 sleep

   hw/acpi/generic_event_device.c | 70 
++
   hw/i386/acpi-microvm.c | 18 +
   hw/i386/microvm.c  |  3 ++
   hw/loongarch/acpi-build.c  | 18 +
   hw/loongarch/virt.c|  3 ++
   include/hw/acpi/generic_event_device.h | 12 +-
   6 files changed, 115 insertions(+), 9 deletions(-)
---
base-commit: f3e8cc47de2bc537d4991e883a85208e4e1c0f98
change-id: 20240613-loongarch64-sleep-37b2466b8d76

Best regards,








Re: [PATCH 0/3] S3 and S4 sleep for loongarch/virt & microvm

2024-06-13 Thread maobibo



It is interesting.

How to wakeup VM if it sleeps in S3/S4, from emulated keyboard or 
ethernet magic packet or qemu monitor command in background?


Regards
Bibo Mao


On 2024/6/14 上午1:30, Jiaxun Yang wrote:

Hi all,

This series implemented S3 and S4 sleep for loongarch virt machine
and microvm.

For loongarch/virt a kernel patch is requried [1].

[1]: 
https://lore.kernel.org/loongarch/20240613-loongarch64-sleep-v1-0-a245232af...@flygoat.com/

Please review.
Thanks

Signed-off-by: Jiaxun Yang 
---
Jiaxun Yang (3):
   acpi/ged: Implement S3 and S4 sleep
   hw/loongarch/virt: Wire up S3 and S4 sleep
   hw/i386/microvm: Wire up S3 and S4 sleep

  hw/acpi/generic_event_device.c | 70 ++
  hw/i386/acpi-microvm.c | 18 +
  hw/i386/microvm.c  |  3 ++
  hw/loongarch/acpi-build.c  | 18 +
  hw/loongarch/virt.c|  3 ++
  include/hw/acpi/generic_event_device.h | 12 +-
  6 files changed, 115 insertions(+), 9 deletions(-)
---
base-commit: f3e8cc47de2bc537d4991e883a85208e4e1c0f98
change-id: 20240613-loongarch64-sleep-37b2466b8d76

Best regards,






Re: [PULL 06/10] hw/loongarch: Refine fwcfg memory map

2024-06-10 Thread maobibo




On 2024/6/7 下午10:31, Peter Maydell wrote:

On Thu, 23 May 2024 at 02:48, Song Gao  wrote:


From: Bibo Mao 

Memory map table for fwcfg is used for UEFI BIOS, UEFI BIOS uses the first
entry from fwcfg memory map as the first memory HOB, the second memory HOB
will be used if the first memory HOB is used up.

Memory map table for fwcfg does not care about numa node, however in
generic the first memory HOB is part of numa node0, so that runtime
memory of UEFI which is allocated from the first memory HOB is located
at numa node0.

Signed-off-by: Bibo Mao 
Reviewed-by: Song Gao 
Message-Id: <20240515093927.3453674-4-maob...@loongson.cn>
Signed-off-by: Song Gao 


Hi; Coverity points out a possible issue with this code
(CID 1546441):


+static void fw_cfg_add_memory(MachineState *ms)
+{
+hwaddr base, size, ram_size, gap;
+int nb_numa_nodes, nodes;
+NodeInfo *numa_info;
+
+ram_size = ms->ram_size;
+base = VIRT_LOWMEM_BASE;
+gap = VIRT_LOWMEM_SIZE;
+nodes = nb_numa_nodes = ms->numa_state->num_nodes;
+numa_info = ms->numa_state->nodes;
+if (!nodes) {
+nodes = 1;
+}
+
+/* add fw_cfg memory map of node0 */
+if (nb_numa_nodes) {
+size = numa_info[0].node_mem;
+} else {
+size = ram_size;
+}
+
+if (size >= gap) {
+memmap_add_entry(base, gap, 1);
+size -= gap;
+base = VIRT_HIGHMEM_BASE;
+gap = ram_size - VIRT_LOWMEM_SIZE;


In this if() statement we set 'gap'...


+}
+
+if (size) {
+memmap_add_entry(base, size, 1);
+base += size;
+}
+
+if (nodes < 2) {
+return;
+}
+
+/* add fw_cfg memory map of other nodes */
+size = ram_size - numa_info[0].node_mem;
+gap  = VIRT_LOWMEM_BASE + VIRT_LOWMEM_SIZE;


...but then later here we unconditionally overwrite 'gap',
without ever using it in between, making the previous
assignment useless.

What was the intention here ?

It is abuse about variable gap, sometimes it represents low memory size,
sometimes it represents the end address of low memory.

It can be removed at both placed, what is this patch?

--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -1054,7 +1054,6 @@ static void fw_cfg_add_memory(MachineState *ms)
 memmap_add_entry(base, gap, 1);
 size -= gap;
 base = VIRT_HIGHMEM_BASE;
-gap = ram_size - VIRT_LOWMEM_SIZE;
 }

 if (size) {
@@ -1068,15 +1067,14 @@ static void fw_cfg_add_memory(MachineState *ms)

 /* add fw_cfg memory map of other nodes */
 size = ram_size - numa_info[0].node_mem;
-gap  = VIRT_LOWMEM_BASE + VIRT_LOWMEM_SIZE;
-if (base < gap && (base + size) > gap) {
+if (numa_info[0].node_mem < gap && ram_size > gap) {
 /*
  * memory map for the maining nodes splited into two part
- *   lowram:  [base, +(gap - base))
- *   highram: [VIRT_HIGHMEM_BASE, +(size - (gap - base)))
+ * lowram:  [base, +(gap - numa_info[0].node_mem))
+ * highram: [VIRT_HIGHMEM_BASE, +(size - (gap - 
numa_info[0].node_mem)))

  */
-memmap_add_entry(base, gap - base, 1);
-size -= gap - base;
+memmap_add_entry(base, gap - numa_info[0].node_mem, 1);
+size -= gap - numa_info[0].node_mem;
 base = VIRT_HIGHMEM_BASE;
 }

Regards
Bibo Mao




thanks
-- PMM






Re: [PATCH v2 2/2] util/bufferiszero: Add loongarch64 vector acceleration

2024-06-06 Thread maobibo




On 2024/6/7 上午8:24, Richard Henderson wrote:

Use inline assembly because no release compiler allows
per-function selection of the ISA.

Signed-off-by: Richard Henderson 
---
  .../loongarch64/host/bufferiszero.c.inc   | 143 ++
  1 file changed, 143 insertions(+)
  create mode 100644 host/include/loongarch64/host/bufferiszero.c.inc

diff --git a/host/include/loongarch64/host/bufferiszero.c.inc 
b/host/include/loongarch64/host/bufferiszero.c.inc
new file mode 100644
index 00..69891eac80
--- /dev/null
+++ b/host/include/loongarch64/host/bufferiszero.c.inc
@@ -0,0 +1,143 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * buffer_is_zero acceleration, loongarch64 version.
+ */
+
+/*
+ * Builtins for LSX and LASX are introduced by gcc 14 and llvm 18,
+ * but as yet neither has support for attribute target, so neither
+ * is able to enable the optimization without globally enabling
+ * vector support.  Since we want runtime detection, use assembly.
+ */
+
+static bool buffer_is_zero_lsx(const void *buf, size_t len)
+{
+const void *p = QEMU_ALIGN_PTR_DOWN(buf + 16, 16);
+const void *e = QEMU_ALIGN_PTR_DOWN(buf + len - 1, 16) - (7 * 16);
+const void *l = buf + len;
+bool ret;
+
+asm("vld $vr0,%2,0\n\t" /* first: buf + 0 */
+"vld $vr1,%4,-16\n\t"   /* last: buf + len - 16 */
+"vld $vr2,%3,0\n\t" /* e[0] */
+"vld $vr3,%3,16\n\t"/* e[1] */
+"vld $vr4,%3,32\n\t"/* e[2] */
+"vld $vr5,%3,48\n\t"/* e[3] */
+"vld $vr6,%3,64\n\t"/* e[4] */
+"vld $vr7,%3,80\n\t"/* e[5] */
+"vld $vr8,%3,96\n\t"/* e[6] */
+"vor.v $vr0,$vr0,$vr1\n\t"
+"vor.v $vr2,$vr2,$vr3\n\t"
+"vor.v $vr4,$vr4,$vr5\n\t"
+"vor.v $vr6,$vr6,$vr7\n\t"
+"vor.v $vr0,$vr0,$vr2\n\t"
+"vor.v $vr4,$vr4,$vr6\n\t"
+"vor.v $vr0,$vr0,$vr4\n\t"
+"vor.v $vr0,$vr0,$vr8\n\t"
+"or %0,$r0,$r0\n"   /* prepare return false */
+"1:\n\t"
+"vsetnez.v $fcc0,$vr0\n\t"
+"bcnez $fcc0,2f\n\t"
+"vld $vr0,%1,0\n\t" /* p[0] */
+"vld $vr1,%1,16\n\t"/* p[1] */
+"vld $vr2,%1,32\n\t"/* p[2] */
+"vld $vr3,%1,48\n\t"/* p[3] */
+"vld $vr4,%1,64\n\t"/* p[4] */
+"vld $vr5,%1,80\n\t"/* p[5] */
+"vld $vr6,%1,96\n\t"/* p[6] */
+"vld $vr7,%1,112\n\t"   /* p[7] */
+"addi.d %1,%1,128\n\t"
+"vor.v $vr0,$vr0,$vr1\n\t"
+"vor.v $vr2,$vr2,$vr3\n\t"
+"vor.v $vr4,$vr4,$vr5\n\t"
+"vor.v $vr6,$vr6,$vr7\n\t"
+"vor.v $vr0,$vr0,$vr2\n\t"
+"vor.v $vr4,$vr4,$vr6\n\t"
+"vor.v $vr0,$vr0,$vr4\n\t"
+"bltu %1,%3,1b\n\t"
+"vsetnez.v $fcc0,$vr0\n\t"
+"bcnez $fcc0,2f\n\t"
+"ori %0,$r0,1\n"
+"2:"
+: "=&r"(ret), "+r"(p)
+: "r"(buf), "r"(e), "r"(l)
+: "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "fcc0");
+
+return ret;
+}
+
+static bool buffer_is_zero_lasx(const void *buf, size_t len)
+{
+const void *p = QEMU_ALIGN_PTR_DOWN(buf + 32, 32);
+const void *e = QEMU_ALIGN_PTR_DOWN(buf + len - 1, 32) - (7 * 32);
+const void *l = buf + len;
+bool ret;
+
+asm("xvld $xr0,%2,0\n\t" /* first: buf + 0 */
+"xvld $xr1,%4,-32\n\t"   /* last: buf + len - 32 */
+"xvld $xr2,%3,0\n\t" /* e[0] */
+"xvld $xr3,%3,32\n\t"/* e[1] */
+"xvld $xr4,%3,64\n\t"/* e[2] */
+"xvld $xr5,%3,96\n\t"/* e[3] */
+"xvld $xr6,%3,128\n\t"   /* e[4] */
+"xvld $xr7,%3,160\n\t"   /* e[5] */
+"xvld $xr8,%3,192\n\t"   /* e[6] */
+"xvor.v $xr0,$xr0,$xr1\n\t"
+"xvor.v $xr2,$xr2,$xr3\n\t"
+"xvor.v $xr4,$xr4,$xr5\n\t"
+"xvor.v $xr6,$xr6,$xr7\n\t"
+"xvor.v $xr0,$xr0,$xr2\n\t"
+"xvor.v $xr4,$xr4,$xr6\n\t"
+"xvor.v $xr0,$xr0,$xr4\n\t"
+"xvor.v $xr0,$xr0,$xr8\n\t"
+"or %0,$r0,$r0\n\t"  /* prepare return false */
+"bgeu %1,%3,2f\n"
+"1:\n\t"
+"xvsetnez.v $fcc0,$xr0\n\t"
+"bcnez $fcc0,3f\n\t"
+"xvld $xr0,%1,0\n\t" /* p[0] */
+"xvld $xr1,%1,32\n\t"/* p[1] */
+"xvld $xr2,%1,64\n\t"/* p[2] */
+"xvld $xr3,%1,96\n\t"/* p[3] */
+"xvld $xr4,%1,128\n\t"   /* p[4] */
+"xvld $xr5,%1,160\n\t"   /* p[5] */
+"xvld $xr6,%1,192\n\t"   /* p[6] */
+"xvld $xr7,%1,224\n\t"   /* p[7] */
+"addi.d %1,%1,256\n\t"
+"xvor.v $xr0,$xr0,$xr1\n\t"
+"xvor.v $xr2,$xr2,$xr3\n\t"
+"xvor.v $xr4,$xr4,$xr5\n\t"
+"xvor.v $xr6,$xr6,$xr7\n\t"
+

Re: [PATCH 2/2] util/bufferiszero: Add simd acceleration for loongarch64

2024-06-05 Thread maobibo




On 2024/6/6 上午11:42, Richard Henderson wrote:

On 6/5/24 20:36, maobibo wrote:

static biz_accel_fn const accel_table[] = {
 buffer_is_zero_int_ge256,
#ifdef __loongarch_sx
 buffer_is_zero_lsx,
#endif
#ifdef __loongarch_asx
 buffer_is_zero_lasx,
#endif
};

static unsigned best_accel(void)
{
#ifdef __loongarch_asx
 /* lasx may be index 1 or 2, but always last */
 return ARRAY_SIZE(accel_table) - 1;
#else
 /* lsx is always index 1 */
 return 1;
#endif
}
size of accel_table is decided at compile-time, will it be better if 
runtime checking is added also?  something like this:


  unsigned info = cpuinfo_init();

  #ifdef __loongarch_asx
  if (info & CPUINFO_LASX) {
   /* lasx may be index 1 or 2, but always last */
   return ARRAY_SIZE(accel_table) - 1;
  }
  #endif


No, because the ifdef checks that the *compiler* is prepared to use 
LASX/LSX instructions itself without further checks.  There's no point 
in qemu checking further.
By my understanding, currently compiler option is the same with all 
files, there is no separate compiler option with single file or file 
function.


So if compiler is prepared to use LASX/LSX instructions itself, host 
hardware must support LASX/LSX instructions, else there will be problem.


My main concern is that there is one hw machine which supports LSX, but 
no LASX, no KVM neither.  QEMU binary maybe fails to run on such hw 
machine if it is compiled with LASX option.


Regards
Bibo Mao



r~





Re: [PATCH 2/2] util/bufferiszero: Add simd acceleration for loongarch64

2024-06-05 Thread maobibo




On 2024/6/6 上午11:27, Richard Henderson wrote:

On 6/5/24 20:18, Richard Henderson wrote:

On 6/5/24 19:30, maobibo wrote:



On 2024/6/6 上午7:51, Richard Henderson wrote:

On 6/5/24 02:32, Bibo Mao wrote:

Different gcc versions have different features, macro CONFIG_LSX_OPT
and CONFIG_LASX_OPT is added here to detect whether gcc supports
built-in lsx/lasx macro.

Function buffer_zero_lsx() is added for 128bit simd fpu optimization,
and function buffer_zero_lasx() is for 256bit simd fpu optimization.

Loongarch gcc built-in lsx/lasx macro can be used only when compiler
option -mlsx/-mlasx is added, and there is no separate compiler option
for function only. So it is only in effect when qemu is compiled with
parameter --extra-cflags="-mlasx"

Signed-off-by: Bibo Mao 
---
  meson.build |  11 +
  util/bufferiszero.c | 103 


  2 files changed, 114 insertions(+)

diff --git a/meson.build b/meson.build
index 6386607144..29bc362d7a 100644
--- a/meson.build
+++ b/meson.build
@@ -2855,6 +2855,17 @@ 
config_host_data.set('CONFIG_ARM_AES_BUILTIN', cc.compiles('''

  void foo(uint8x16_t *p) { *p = vaesmcq_u8(*p); }
    '''))
+# For Loongarch64, detect if LSX/LASX are available.
+ config_host_data.set('CONFIG_LSX_OPT', cc.compiles('''
+    #include "lsxintrin.h"
+    int foo(__m128i v) { return __lsx_bz_v(v); }
+  '''))
+
+config_host_data.set('CONFIG_LASX_OPT', cc.compiles('''
+    #include "lasxintrin.h"
+    int foo(__m256i v) { return __lasx_xbz_v(v); }
+  '''))


Both of these are introduced by gcc 14 and llvm 18, so I'm not 
certain of the utility of separate tests.  We might simplify this with


   config_host_data.set('CONFIG_LSX_LASX_INTRIN_H',
 cc.has_header('lsxintrin.h') && cc.has_header('lasxintrin.h'))


As you say, these headers require vector instructions to be enabled 
at compile-time rather than detecting them at runtime.  This is a 
point where the compilers could be improved to support 
__attribute__((target("xyz"))) and the builtins with that.  The i386 
port does this, for instance.


In the meantime, it means that you don't need a runtime test.  
Similar to aarch64 and the use of __ARM_NEON as a compile-time test 
for simd support.  Perhaps


#elif defined(CONFIG_LSX_LASX_INTRIN_H) && \
   (defined(__loongarch_sx) || defined(__loongarch_asx))
# ifdef __loongarch_sx
   ...
# endif
# ifdef __loongarch_asx
   ...
# endif

Sure, will do in this way.
And also there is runtime check coming from hwcap, such this:

unsigned info = cpuinfo_init();
   if (info & CPUINFO_LASX)


static biz_accel_fn const accel_table[] = {
 buffer_is_zero_int_ge256,
#ifdef __loongarch_sx
 buffer_is_zero_lsx,
#endif
#ifdef __loongarch_asx
 buffer_is_zero_lasx,
#endif
};

static unsigned best_accel(void)
{
#ifdef __loongarch_asx
 /* lasx may be index 1 or 2, but always last */
 return ARRAY_SIZE(accel_table) - 1;
#else
 /* lsx is always index 1 */
 return 1;
#endif
}
size of accel_table is decided at compile-time, will it be better if 
runtime checking is added also?  something like this:


 unsigned info = cpuinfo_init();

 #ifdef __loongarch_asx
 if (info & CPUINFO_LASX) {
  /* lasx may be index 1 or 2, but always last */
  return ARRAY_SIZE(accel_table) - 1;
 }
 #endif



It occurs to me that by accumulating host specific sections to this 
file, we should split it like the atomics.  Put each portion in 
host/include/*/host/bufferiszero.h.inc.

sure, will do.



I'll send a patch set handling the existing two hosts.


r~






Re: [PATCH 2/2] util/bufferiszero: Add simd acceleration for loongarch64

2024-06-05 Thread maobibo




On 2024/6/6 上午7:51, Richard Henderson wrote:

On 6/5/24 02:32, Bibo Mao wrote:

Different gcc versions have different features, macro CONFIG_LSX_OPT
and CONFIG_LASX_OPT is added here to detect whether gcc supports
built-in lsx/lasx macro.

Function buffer_zero_lsx() is added for 128bit simd fpu optimization,
and function buffer_zero_lasx() is for 256bit simd fpu optimization.

Loongarch gcc built-in lsx/lasx macro can be used only when compiler
option -mlsx/-mlasx is added, and there is no separate compiler option
for function only. So it is only in effect when qemu is compiled with
parameter --extra-cflags="-mlasx"

Signed-off-by: Bibo Mao 
---
  meson.build |  11 +
  util/bufferiszero.c | 103 
  2 files changed, 114 insertions(+)

diff --git a/meson.build b/meson.build
index 6386607144..29bc362d7a 100644
--- a/meson.build
+++ b/meson.build
@@ -2855,6 +2855,17 @@ config_host_data.set('CONFIG_ARM_AES_BUILTIN', 
cc.compiles('''

  void foo(uint8x16_t *p) { *p = vaesmcq_u8(*p); }
    '''))
+# For Loongarch64, detect if LSX/LASX are available.
+ config_host_data.set('CONFIG_LSX_OPT', cc.compiles('''
+    #include "lsxintrin.h"
+    int foo(__m128i v) { return __lsx_bz_v(v); }
+  '''))
+
+config_host_data.set('CONFIG_LASX_OPT', cc.compiles('''
+    #include "lasxintrin.h"
+    int foo(__m256i v) { return __lasx_xbz_v(v); }
+  '''))


Both of these are introduced by gcc 14 and llvm 18, so I'm not certain 
of the utility of separate tests.  We might simplify this with


   config_host_data.set('CONFIG_LSX_LASX_INTRIN_H',
     cc.has_header('lsxintrin.h') && cc.has_header('lasxintrin.h'))


As you say, these headers require vector instructions to be enabled at 
compile-time rather than detecting them at runtime.  This is a point 
where the compilers could be improved to support 
__attribute__((target("xyz"))) and the builtins with that.  The i386 
port does this, for instance.


In the meantime, it means that you don't need a runtime test.  Similar 
to aarch64 and the use of __ARM_NEON as a compile-time test for simd 
support.  Perhaps


#elif defined(CONFIG_LSX_LASX_INTRIN_H) && \
   (defined(__loongarch_sx) || defined(__loongarch_asx))
# ifdef __loongarch_sx
   ...
# endif
# ifdef __loongarch_asx
   ...
# endif

Sure, will do in this way.
And also there is runtime check coming from hwcap, such this:

unsigned info = cpuinfo_init();
  if (info & CPUINFO_LASX)




The actual code is perfectly fine, of course, since it follows the 
pattern from the others.  How much improvement do you see from 
bufferiszero-bench?

yes, it is much easier to follow others, it is not new things.

Here is the benchmark result, no obvious improvement with 1K
buffer size. 200% improvement with LASX, 100% improve with LSX
with 16K page size.

# /root/src/qemu/b/tests/bench/bufferiszero-bench --tap -k
# Start of cutils tests
# Start of bufferiszero tests
# buffer_is_zero #0:  1KB13460 MB/sec
# buffer_is_zero #0:  4KB36857 MB/sec
# buffer_is_zero #0: 16KB69884 MB/sec
# buffer_is_zero #0: 64KB80863 MB/sec
#
# buffer_is_zero #1:  1KB11180 MB/sec
# buffer_is_zero #1:  4KB27972 MB/sec
# buffer_is_zero #1: 16KB42951 MB/sec
# buffer_is_zero #1: 64KB43293 MB/sec
#
# buffer_is_zero #2:  1KB10026 MB/sec
# buffer_is_zero #2:  4KB18373 MB/sec
# buffer_is_zero #2: 16KB23933 MB/sec
# buffer_is_zero #2: 64KB25180 MB/sec

Regards
Bibo Mao




r~





Re: [PATCH 1/2] util: Add lasx cpuinfo for loongarch64

2024-06-05 Thread maobibo




On 2024/6/5 下午7:53, Philippe Mathieu-Daudé wrote:

On 5/6/24 11:32, Bibo Mao wrote:

Lasx is 256bit vector FPU capability, lsx is 128bit vector VFP. lsx
is added already, lasx is added here.

Signed-off-by: Bibo Mao 
---
  host/include/loongarch64/host/cpuinfo.h | 1 +
  util/cpuinfo-loongarch.c    | 1 +
  2 files changed, 2 insertions(+)

diff --git a/host/include/loongarch64/host/cpuinfo.h 
b/host/include/loongarch64/host/cpuinfo.h

index fab664a10b..d7bf27501d 100644
--- a/host/include/loongarch64/host/cpuinfo.h
+++ b/host/include/loongarch64/host/cpuinfo.h
@@ -8,6 +8,7 @@
  #define CPUINFO_ALWAYS  (1u << 0)  /* so cpuinfo is nonzero */
  #define CPUINFO_LSX (1u << 1)
+#define CPUINFO_LASX    (1u << 2)
  /* Initialized with a constructor. */
  extern unsigned cpuinfo;
diff --git a/util/cpuinfo-loongarch.c b/util/cpuinfo-loongarch.c
index 08b6d7460c..bb1f7f698b 100644
--- a/util/cpuinfo-loongarch.c
+++ b/util/cpuinfo-loongarch.c
@@ -29,6 +29,7 @@ unsigned __attribute__((constructor)) 
cpuinfo_init(void)

  info = CPUINFO_ALWAYS;
  info |= (hwcap & HWCAP_LOONGARCH_LSX ? CPUINFO_LSX : 0);
+    info |= (hwcap & HWCAP_LOONGARCH_LASX ? CPUINFO_LASX : 0);
  cpuinfo = info;
  return info;


This is 
https://lore.kernel.org/qemu-devel/20240527211912.14060-6-richard.hender...@linaro.org/ 

oops, I did not notice this.

And I will drop patch 1 and refresh the patch based on this weblink.

Regards
Bibo Mao




Re: [PATCH v4 3/3] hw/loongarch/virt: Enable extioi virt extension

2024-06-04 Thread maobibo




On 2024/5/28 下午4:38, Song Gao wrote:

This patch adds a new board attribute 'v-eiointc'.
A value of true enables the virt extended I/O interrupt controller.
VMs working in kvm mode have 'v-eiointc' enabled by default.

Signed-off-by: Song Gao 
---
  include/hw/loongarch/virt.h |  1 +
  target/loongarch/cpu.h  |  1 +
  hw/loongarch/virt.c | 88 +++--
  3 files changed, 87 insertions(+), 3 deletions(-)

diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
index 2c4f5cf9c8..8fdfacf268 100644
--- a/include/hw/loongarch/virt.h
+++ b/include/hw/loongarch/virt.h
@@ -50,6 +50,7 @@ struct LoongArchVirtMachineState {
  Notifier machine_done;
  Notifier powerdown_notifier;
  OnOffAutoacpi;
+OnOffAutoveiointc;
  char *oem_id;
  char *oem_table_id;
  DeviceState  *acpi_ged;
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index 41b8e6d96d..6c41fafb70 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -36,6 +36,7 @@
  #define CPUNAME_REG 0x20
  #define MISC_FUNC_REG   0x420
  #define IOCSRM_EXTIOI_EN48
+#define IOCSRM_EXTIOI_INT_ENCODE 49
  
  #define IOCSR_MEM_SIZE  0x428
  
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c

index a70eeda2fd..b33b1ad9d3 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -11,6 +11,7 @@
  #include "hw/boards.h"
  #include "hw/char/serial.h"
  #include "sysemu/kvm.h"
+#include "sysemu/tcg.h"
  #include "sysemu/sysemu.h"
  #include "sysemu/qtest.h"
  #include "sysemu/runstate.h"
@@ -47,6 +48,31 @@
  #include "hw/block/flash.h"
  #include "qemu/error-report.h"
  
+static bool virt_is_veiointc_enabled(LoongArchVirtMachineState *lvms)

+{
+if (lvms->veiointc == ON_OFF_AUTO_OFF) {
+return false;
+}
+return true;
+}
+
+static void virt_get_veiointc(Object *obj, Visitor *v, const char *name,
+  void *opaque, Error **errp)
+{
+LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);
+OnOffAuto veiointc = lvms->veiointc;
+
+visit_type_OnOffAuto(v, name, &veiointc, errp);
+}
+
+static void virt_set_veiointc(Object *obj, Visitor *v, const char *name,
+  void *opaque, Error **errp)
+{
+LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);
+
+visit_type_OnOffAuto(v, name, &lvms->veiointc, errp);
+}
+
  static PFlashCFI01 *virt_flash_create1(LoongArchVirtMachineState *lvms,
 const char *name,
 const char *alias_prop_name)
@@ -789,9 +815,16 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
  /* Create EXTIOI device */
  extioi = qdev_new(TYPE_LOONGARCH_EXTIOI);
  qdev_prop_set_uint32(extioi, "num-cpu", ms->smp.cpus);
+if (virt_is_veiointc_enabled(lvms)) {
+qdev_prop_set_bit(extioi, "has-virtualization-extension", true);
+}
  sysbus_realize_and_unref(SYS_BUS_DEVICE(extioi), &error_fatal);
  memory_region_add_subregion(&lvms->system_iocsr, APIC_BASE,
-   sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), 0));
+sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), 0));
+if (virt_is_veiointc_enabled(lvms)) {
+memory_region_add_subregion(&lvms->system_iocsr, EXTIOI_VIRT_BASE,
+sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), 1));
+}
  
  /*

   * connect ext irq to the cpu irq
@@ -898,11 +931,37 @@ static void virt_firmware_init(LoongArchVirtMachineState 
*lvms)
  }
  }
  
-

  static MemTxResult virt_iocsr_misc_write(void *opaque, hwaddr addr,
   uint64_t val, unsigned size,
   MemTxAttrs attrs)
  {
+LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(opaque);
+uint64_t features;
+
+switch (addr) {
+case MISC_FUNC_REG:
+if (!virt_is_veiointc_enabled(lvms)) {
+return MEMTX_OK;
+}
+
+features = address_space_ldl(&lvms->as_iocsr,
+ EXTIOI_VIRT_BASE + EXTIOI_VIRT_CONFIG,
+ attrs, NULL);
+if (val & BIT_ULL(IOCSRM_EXTIOI_EN)) {
+features |= BIT(EXTIOI_ENABLE);
+}
+if (val & BIT_ULL(IOCSRM_EXTIOI_INT_ENCODE)) {
+features |= BIT(EXTIOI_ENABLE_INT_ENCODE);
+}
+
+address_space_stl(&lvms->as_iocsr,
+  EXTIOI_VIRT_BASE + EXTIOI_VIRT_CONFIG,
+  features, attrs, NULL);
+break;
+default:
+g_assert_not_reached();
+}
+
  return MEMTX_OK;
  }
  
@@ -910,7 +969,9 @@ static MemTxResult virt_iocsr_misc_read(void *opaque, hwaddr addr,

  uint64_t *data,
  unsigned size, MemTxAttrs attrs)
  {
+Loong

Re: [PATCH v4 2/3] hw/loongarch/virt: Use MemTxAttrs interface for misc ops

2024-06-04 Thread maobibo




On 2024/5/28 下午4:38, Song Gao wrote:

Use MemTxAttrs interface read_with_attrs/write_with_attrs
for virt_iocsr_misc_ops.

Signed-off-by: Song Gao 
---
  hw/loongarch/virt.c | 36 
  1 file changed, 24 insertions(+), 12 deletions(-)

diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 4db0d82dbd..a70eeda2fd 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -899,37 +899,49 @@ static void virt_firmware_init(LoongArchVirtMachineState 
*lvms)
  }
  
  
-static void virt_iocsr_misc_write(void *opaque, hwaddr addr,

-  uint64_t val, unsigned size)
+static MemTxResult virt_iocsr_misc_write(void *opaque, hwaddr addr,
+ uint64_t val, unsigned size,
+ MemTxAttrs attrs)
  {
+return MEMTX_OK;
  }
  
-static uint64_t virt_iocsr_misc_read(void *opaque, hwaddr addr, unsigned size)

+static MemTxResult virt_iocsr_misc_read(void *opaque, hwaddr addr,
+uint64_t *data,
+unsigned size, MemTxAttrs attrs)
  {
-uint64_t ret;
+uint64_t ret = 0;
  
  switch (addr) {

  case VERSION_REG:
-return 0x11ULL;
+ret = 0x11ULL;
+break;
  case FEATURE_REG:
  ret = BIT(IOCSRF_MSI) | BIT(IOCSRF_EXTIOI) | BIT(IOCSRF_CSRIPI);
  if (kvm_enabled()) {
  ret |= BIT(IOCSRF_VM);
  }
-return ret;
+break;
  case VENDOR_REG:
-return 0x6e6f73676e6f6f4cULL; /* "Loongson" */
+ret = 0x6e6f73676e6f6f4cULL; /* "Loongson" */
+break;
  case CPUNAME_REG:
-return 0x303030354133ULL; /* "3A5000" */
+ret = 0x303030354133ULL; /* "3A5000" */
+break;
  case MISC_FUNC_REG:
-return BIT_ULL(IOCSRM_EXTIOI_EN);
+ret = BIT_ULL(IOCSRM_EXTIOI_EN);
+break;
+default:
+g_assert_not_reached();
  }
-return 0ULL;
+
+*data = ret;
+return MEMTX_OK;
  }
  
  static const MemoryRegionOps virt_iocsr_misc_ops = {

-.read  = virt_iocsr_misc_read,
-.write = virt_iocsr_misc_write,
+.read_with_attrs  = virt_iocsr_misc_read,
+.write_with_attrs = virt_iocsr_misc_write,
  .endianness = DEVICE_LITTLE_ENDIAN,
  .valid = {
  .min_access_size = 4,


Reviewed-by: Bibo Mao 




Re: [RFC v2 1/2] target/loongarch: Add loongson binary translation feature

2024-05-29 Thread maobibo




On 2024/5/28 下午8:56, gaosong wrote:

在 2024/5/28 上午9:07, maobibo 写道:

Hi Philippe,

Thanks for reviewing my patch.
I reply inline.

On 2024/5/27 下午6:37, Philippe Mathieu-Daudé wrote:

Hi Bibo,

On 27/5/24 10:35, Bibo Mao wrote:

Loongson Binary Translation (LBT) is used to accelerate binary
translation, which contains 4 scratch registers (scr0 to scr3), x86/ARM
eflags (eflags) and x87 fpu stack pointer (ftop).

Now LBT feature is added in kvm mode, not supported in TCG mode since
it is not emulated. There are two feature flags such as forced_features
and default_features for each vcpu, the real feature is still in 
cpucfg.

Flag forced_features is parsed from command line, default_features is
parsed from cpu type.

Flag forced_features has higher priority than flag default_features,
default_features will be used if there is no command line option for 
LBT
feature. If the feature is not supported with KVM host, it reports 
error
and exits if forced_features is set, else it disables feature and 
continues

if default_features is set.

Signed-off-by: Bibo Mao 
---
  target/loongarch/cpu.c    | 69 
+++

  target/loongarch/cpu.h    | 12 +
  target/loongarch/kvm/kvm.c    | 26 ++
  target/loongarch/kvm/kvm_loongarch.h  | 16 +++
  target/loongarch/loongarch-qmp-cmds.c |  2 +-
  5 files changed, 124 insertions(+), 1 deletion(-)




+static void loongarch_set_lbt(Object *obj, bool value, Error **errp)
+{
+    LoongArchCPU *cpu = LOONGARCH_CPU(obj);
+
+    if (!kvm_enabled()) {


Either set errp, ...


+    return;
+    }
+
+    if (value) {
+    /* Enable binary translation for all architectures */
+    cpu->env.forced_features |= BIT_ULL(LOONGARCH_FEATURE_LBT);
+    } else {
+    /* Disable default features also */
+    cpu->env.default_features &= ~BIT_ULL(LOONGARCH_FEATURE_LBT);
+    }
+}
+
  void loongarch_cpu_post_init(Object *obj)
  {
  object_property_add_bool(obj, "lsx", loongarch_get_lsx,
   loongarch_set_lsx);
  object_property_add_bool(obj, "lasx", loongarch_get_lasx,
   loongarch_set_lasx);


... or only add the property if KVM is enabled:

    if (kvm_enabled()) {

Sure, will do. I think this method is better.

By the way bitmap method forced_features/default_feature is variant
of OnOffAuto method. Bitmap method uses two bit, OnOffAuto method uses 
separate feature variable. We do not know which method is better or 
which is the future trend.



I think the OnOffAuto variable is better.

The default_features is just a copy of cpucfg, and is not required.

No, it is not copy of cpucfg. If so, OnOffAuto is also copy of cpucfg.

Combination of forced_features/default_feature bitmap is another 
implementation of OnOffAuto variable.


  Forced_features  Default_features
 1   x == ON_OFF_AUTO_ON
 0   0 == ON_OFF_AUTO_OFF
 0   1 == ON_OFF_AUTO_AUTO

Maybe we can rename Default_features with Hint_features.

Regards
Bibo Mao



Thanks.
Song Gao

Regards
Bibo Mao



+    object_property_add_bool(obj, "lbt", loongarch_get_lbt,
+ loongarch_set_lbt);
  }







Re: [PATCH] tests/libqos: Add loongarch virt machine node

2024-05-29 Thread maobibo

Thomas,

Thanks for reviewing the patch.

On 2024/5/29 下午3:10, Thomas Huth wrote:

On 28/05/2024 10.20, Bibo Mao wrote:

Add loongarch virt machine to the graph. It is a modified copy of
the existing riscv virtmachine in riscv-virt-machine.c

It contains a generic-pcihost controller, and an extra function
loongarch_config_qpci_bus() to configure GPEX pci host controller
information, such as ecam and pio_base addresses.

Also hotplug handle checking about TYPE_VIRTIO_IOMMU_PCI device is
added on loongarch virt machine, since virtio_mmu_pci device requires
it.

Signed-off-by: Bibo Mao 
---
  hw/loongarch/virt.c |   2 +
  tests/qtest/libqos/loongarch-virt-machine.c | 114 
  tests/qtest/libqos/meson.build  |   1 +
  3 files changed, 117 insertions(+)
  create mode 100644 tests/qtest/libqos/loongarch-virt-machine.c

diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 3e6e93edf3..2d7f718570 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -45,6 +45,7 @@
  #include "sysemu/tpm.h"
  #include "sysemu/block-backend.h"
  #include "hw/block/flash.h"
+#include "hw/virtio/virtio-iommu.h"
  #include "qemu/error-report.h"
  static PFlashCFI01 *virt_flash_create1(LoongArchVirtMachineState *lvms,
@@ -1213,6 +1214,7 @@ static HotplugHandler 
*virt_get_hotplug_handler(MachineState *machine,

  MachineClass *mc = MACHINE_GET_CLASS(machine);
  if (device_is_dynamic_sysbus(mc, dev) ||
+    object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI) ||
  memhp_type_supported(dev)) {
  return HOTPLUG_HANDLER(machine);
  }
diff --git a/tests/qtest/libqos/loongarch-virt-machine.c 
b/tests/qtest/libqos/loongarch-virt-machine.c

new file mode 100644
index 00..c12089c015
--- /dev/null
+++ b/tests/qtest/libqos/loongarch-virt-machine.c
@@ -0,0 +1,114 @@
+/*
+ * libqos driver framework
+ *
+ * Copyright (c) 2018 Emanuele Giuseppe Esposito 


+ *


Don't you want to add your information here, too?

Will add in next version.



Anyway:
Acked-by: Thomas Huth 

I assume this will go through the loongarch tree. Let me know if you 
want to get this merged through the qtest tree instead.

yes, I think it will go through the loongarch tree.

Regards
Bibo Mao




Re: [RFC v2 0/2] target/loongarch: Add loongson binary translation feature

2024-05-27 Thread maobibo




On 2024/5/27 下午6:39, Philippe Mathieu-Daudé wrote:

Hi Bibo,

On 27/5/24 10:34, Bibo Mao wrote:

Loongson Binary Translation (LBT) is used to accelerate binary
translation. LBT feature is added in kvm mode, not supported in TCG
mode since it is not emulated. And only LBT feature is added here, LBT
registers saving and restoring is not supported since it depeeds on LBT
feautre implemented in KVM kernel


How do you test?

There is a test application using LBT instruction as followings.

If LBT is not enabled, it reports illegal instruction. And it does not 
report error during VM migration.


Regards
Bibo Mao

--
#include 
#include 
int main()
{
int a = 0, b = 0;
for (;;)
{
asm(
"li.d $t0, 0xff  \n\t"
".word ((0x17<<18)|(0x3f<<10)|(1<<5)|0xc) \n\t" // mtflag
".word ((0x17<<18)|(0x3f<<10)|(0<<5)|0xc) \n\t" // mfflag
".word ((0x17<<18)|(0x3f<<10)|(1<<5)|0xc) \n\t" // mtflag
"move %0, $t0 \n\t"
: "=r"(a) : : );
sched_yield();
asm(
".word ((0x17<<18)|(0x3f<<10)|(0<<5)|0xc) \n\t" // mfflag
"move %0, $t0 \n\t"
: "=r"(b) : :);

if (a != b)
{
printf("in: 0x%x <=> out 0x%x \n", a, b);
return 1;
}

sched_yield();
int top = 0;
asm(
".word (0x8008) \n\t" // settm
".word ((0x70 << 8) | (5 << 5)) \n\t" // mttop 1
".word (0x8009) \n\t" // inctop
: : :);
sched_yield();
asm(
".word ((0x3a0 << 5) | (0xc)) \n\t" // mfftop
"move %0, $t0 \n\t"
: "=r"(top) : : );

if (top != 6)
{
printf("top: %d \n", top);
return 1;
}
}
return 0;
}



Thanks,

Phil.





Re: [RFC v2 1/2] target/loongarch: Add loongson binary translation feature

2024-05-27 Thread maobibo

Hi Philippe,

Thanks for reviewing my patch.
I reply inline.

On 2024/5/27 下午6:37, Philippe Mathieu-Daudé wrote:

Hi Bibo,

On 27/5/24 10:35, Bibo Mao wrote:

Loongson Binary Translation (LBT) is used to accelerate binary
translation, which contains 4 scratch registers (scr0 to scr3), x86/ARM
eflags (eflags) and x87 fpu stack pointer (ftop).

Now LBT feature is added in kvm mode, not supported in TCG mode since
it is not emulated. There are two feature flags such as forced_features
and default_features for each vcpu, the real feature is still in cpucfg.
Flag forced_features is parsed from command line, default_features is
parsed from cpu type.

Flag forced_features has higher priority than flag default_features,
default_features will be used if there is no command line option for LBT
feature. If the feature is not supported with KVM host, it reports error
and exits if forced_features is set, else it disables feature and 
continues

if default_features is set.

Signed-off-by: Bibo Mao 
---
  target/loongarch/cpu.c    | 69 +++
  target/loongarch/cpu.h    | 12 +
  target/loongarch/kvm/kvm.c    | 26 ++
  target/loongarch/kvm/kvm_loongarch.h  | 16 +++
  target/loongarch/loongarch-qmp-cmds.c |  2 +-
  5 files changed, 124 insertions(+), 1 deletion(-)




+static void loongarch_set_lbt(Object *obj, bool value, Error **errp)
+{
+    LoongArchCPU *cpu = LOONGARCH_CPU(obj);
+
+    if (!kvm_enabled()) {


Either set errp, ...


+    return;
+    }
+
+    if (value) {
+    /* Enable binary translation for all architectures */
+    cpu->env.forced_features |= BIT_ULL(LOONGARCH_FEATURE_LBT);
+    } else {
+    /* Disable default features also */
+    cpu->env.default_features &= ~BIT_ULL(LOONGARCH_FEATURE_LBT);
+    }
+}
+
  void loongarch_cpu_post_init(Object *obj)
  {
  object_property_add_bool(obj, "lsx", loongarch_get_lsx,
   loongarch_set_lsx);
  object_property_add_bool(obj, "lasx", loongarch_get_lasx,
   loongarch_set_lasx);


... or only add the property if KVM is enabled:

    if (kvm_enabled()) {

Sure, will do. I think this method is better.

By the way bitmap method forced_features/default_feature is variant
of OnOffAuto method. Bitmap method uses two bit, OnOffAuto method uses 
separate feature variable. We do not know which method is better or 
which is the future trend.


Regards
Bibo Mao



+    object_property_add_bool(obj, "lbt", loongarch_get_lbt,
+ loongarch_set_lbt);
  }





Re: [PATCH v3 0/3] Add extioi virt extension support

2024-05-23 Thread maobibo



Song will online next week.
Please correct me if there is something wrong, song.

On 2024/5/24 上午7:50, Jiaxun Yang wrote:



在2024年5月21日五月 下午1:32,Song Gao写道:

On LoongArch, IRQs can be routed to four vcpus with hardware extioi.
This patch adds the extioi virt extension support so that the IRQ can
route to 256 vcpus.


Hi Song,

Sorry for chime in here, I'm a little bit confused by this series, can
you give me a little bit of context behind?
Currently interrupt can be routed to only 4 vcpus with one HW extioi. On 
virt machine, there are 256 vcpus even more in future.


Extioi virt extension is introduced here to route irq to more vcpus.


I don't see this functionality on 3A5000/3A6000's user manual, so is this
some sort of undocumented hardware feature?
No, it is not real HW, it is Extioi virt extension, it is virt machine 
model only.




I checked openEuler kernel patch you referred, it seems like this applies to
hypervisor mode only. I suppose it should be handled by KVM subsystem in
kernel, why do we need this in user mode device emulation?
Will do when irqchip is emulated in kernel. Now irqchip is emulated in 
userspace, so it is implemented in userspace firstly.


However it is necessary to emulate in userspace. User can select to 
whether to emulate irqchip in userspace or kernel space, user space 
emulation is easy to debug, kernel space has higher performance. Both 
need extioi virt extension.


Currently, LoongArch's in-kernel irqchip functionality does not include such
feature, can we see KVM side support for this, or at least a draft 
specification?
yeap, maybe more documentation need written for the extioi virt 
extension model.


We are preparing to port irqchip to kernel space, this function will be 
added in kernel space also.



Regards
Bibo Mao


Thanks
- Jiaxun



v3:
- Split patch2 to two small patch.
- remove unused code.
- loongarch_extioi_reset() clear status without checking virt extioi
   features.
- Link to v2:
https://patchew.org/QEMU/20240514090756.988096-1-gaos...@loongson.cn/

v2:
- Split the patch to two small patch.
- Drop 'RFC' title. extioi virt extension suport only enable on kvm
   mode and  the extioi driver need patch[1].
   but this series do not affect the old codes in any way.
- Link to v1:
https://lore.kernel.org/all/20240116022526.498613-1-gaos...@loongson.cn/#r

[1]:
https://gitee.com/openeuler/kernel/commit/5d97cff72f91f4f20a536efd60eca75bfcb78a64

Thanks.
Song Gao

Song Gao (3):
   hw/intc/loongarch_extioi: Add extioi virt extension definition
   hw/loongarch/virt: Enable extioi virt extension
   hw/loongarch/virt: Use MemTxAttrs interface for misc ops

  include/hw/intc/loongarch_extioi.h |  21 ++
  include/hw/loongarch/virt.h|   2 +
  target/loongarch/cpu.h |   1 +
  hw/intc/loongarch_extioi.c |  88 +-
  hw/loongarch/virt.c| 116 +
  5 files changed, 210 insertions(+), 18 deletions(-)

--
2.34.1







Re: [PATCH v3 3/3] hw/loongarch/virt: Use MemTxAttrs interface for misc ops

2024-05-23 Thread maobibo




On 2024/5/21 下午8:32, Song Gao wrote:

Use MemTxAttrs interface read_with_attrs/write_with_attrs
for virt_iocsr_misc_ops.

Signed-off-by: Song Gao 
---
  hw/loongarch/virt.c | 26 --
  1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index e7edc6c9f9..0ab2b6860a 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -866,8 +866,9 @@ static void virt_firmware_init(LoongArchVirtMachineState 
*lvms)
  }
  }
  
-static void virt_iocsr_misc_write(void *opaque, hwaddr addr,

-  uint64_t val, unsigned size)
+static MemTxResult virt_iocsr_misc_write(void *opaque, hwaddr addr,
+ uint64_t val, unsigned size,
+ MemTxAttrs attrs)
  {
  LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(opaque);
  uint64_t features;
@@ -875,12 +876,12 @@ static void virt_iocsr_misc_write(void *opaque, hwaddr 
addr,
  switch (addr) {
  case MISC_FUNC_REG:
  if (!virt_is_veiointc_enabled(lvms)) {
-return;
+return MEMTX_OK;
  }
  
  features = address_space_ldl(&lvms->as_iocsr,

   EXTIOI_VIRT_BASE + EXTIOI_VIRT_CONFIG,
- MEMTXATTRS_UNSPECIFIED, NULL);
+ attrs, NULL);
  if (val & BIT_ULL(IOCSRM_EXTIOI_EN)) {
  features |= BIT(EXTIOI_ENABLE);
  }
@@ -890,11 +891,15 @@ static void virt_iocsr_misc_write(void *opaque, hwaddr 
addr,
  
  address_space_stl(&lvms->as_iocsr,

EXTIOI_VIRT_BASE + EXTIOI_VIRT_CONFIG,
-  features, MEMTXATTRS_UNSPECIFIED, NULL);
+  features, attrs, NULL);
  }
+
+return MEMTX_OK;
  }
  
-static uint64_t virt_iocsr_misc_read(void *opaque, hwaddr addr, unsigned size)

+static MemTxResult virt_iocsr_misc_read(void *opaque, hwaddr addr,
+uint64_t *data,
+unsigned size, MemTxAttrs attrs)
  {
  LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(opaque);
  uint64_t ret = 0;
@@ -924,7 +929,7 @@ static uint64_t virt_iocsr_misc_read(void *opaque, hwaddr 
addr, unsigned size)
  
  features = address_space_ldl(&lvms->as_iocsr,

   EXTIOI_VIRT_BASE + EXTIOI_VIRT_CONFIG,
- MEMTXATTRS_UNSPECIFIED, NULL);
+ attrs, NULL);
  if (features & BIT(EXTIOI_ENABLE)) {
  ret |= BIT_ULL(IOCSRM_EXTIOI_EN);
  }
@@ -933,12 +938,13 @@ static uint64_t virt_iocsr_misc_read(void *opaque, hwaddr 
addr, unsigned size)
  }
  }
  
-return ret;

+*data = ret;
+return MEMTX_OK;
  }
  
  static const MemoryRegionOps virt_iocsr_misc_ops = {

-.read  = virt_iocsr_misc_read,
-.write = virt_iocsr_misc_write,
+.read_with_attrs  = virt_iocsr_misc_read,
+.write_with_attrs = virt_iocsr_misc_write,
  .endianness = DEVICE_LITTLE_ENDIAN,
  .valid = {
  .min_access_size = 4,

I think patch3 should be put ahead of patch2. Without patch3, there is 
potential problem to access iocsr EXTIOI_VIRT_CONFIG register with 
MEMTXATTRS_UNSPECIFIED attr.


Now extioi is emulated in user space, it will be better if hypervisor 
and VM know whether v-extioi extension is supported.


Regards
Bibo Mao




Re: [PATCH v3 1/3] hw/intc/loongarch_extioi: Add extioi virt extension definition

2024-05-23 Thread maobibo



On 2024/5/21 下午8:32, Song Gao wrote:

On LoongArch, IRQs can be routed to four vcpus with hardware extioi.
This patch adds the extioi virt extension definition so that the IRQ can
route to 256 vcpus.

Signed-off-by: Song Gao 
---
  include/hw/intc/loongarch_extioi.h | 21 +++
  hw/intc/loongarch_extioi.c | 88 --
  2 files changed, 105 insertions(+), 4 deletions(-)

diff --git a/include/hw/intc/loongarch_extioi.h 
b/include/hw/intc/loongarch_extioi.h
index 410c6e1121..eccc2e0d18 100644
--- a/include/hw/intc/loongarch_extioi.h
+++ b/include/hw/intc/loongarch_extioi.h
@@ -41,6 +41,24 @@
  #define EXTIOI_COREMAP_END   (0xD00 - APIC_OFFSET)
  #define EXTIOI_SIZE  0x800
  
+#define EXTIOI_VIRT_BASE (0x4000)

+#define EXTIOI_VIRT_SIZE (0x1000)
+#define EXTIOI_VIRT_FEATURES (0x0)
+#define  EXTIOI_HAS_VIRT_EXTENSION   (0)
+#define  EXTIOI_HAS_ENABLE_OPTION(1)
+#define  EXTIOI_HAS_INT_ENCODE   (2)
+#define  EXTIOI_HAS_CPU_ENCODE   (3)
+#define  EXTIOI_VIRT_HAS_FEATURES(BIT(EXTIOI_HAS_VIRT_EXTENSION)  \
+  | BIT(EXTIOI_HAS_ENABLE_OPTION) \
+  | BIT(EXTIOI_HAS_INT_ENCODE)\
+  | BIT(EXTIOI_HAS_CPU_ENCODE))
+#define EXTIOI_VIRT_CONFIG   (0x4)
+#define  EXTIOI_ENABLE   (1)
+#define  EXTIOI_ENABLE_INT_ENCODE(2)
+#define  EXTIOI_ENABLE_CPU_ENCODE(3)
+#define EXTIOI_VIRT_COREMAP_START(0x40)
+#define EXTIOI_VIRT_COREMAP_END  (0x240)
+
  typedef struct ExtIOICore {
  uint32_t coreisr[EXTIOI_IRQS_GROUP_COUNT];
  DECLARE_BITMAP(sw_isr[LS3A_INTC_IP], EXTIOI_IRQS);
@@ -52,6 +70,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(LoongArchExtIOI, LOONGARCH_EXTIOI)
  struct LoongArchExtIOI {
  SysBusDevice parent_obj;
  uint32_t num_cpu;
+uint32_t features;
+uint32_t status;
  /* hardware state */
  uint32_t nodetype[EXTIOI_IRQS_NODETYPE_COUNT / 2];
  uint32_t bounce[EXTIOI_IRQS_GROUP_COUNT];
@@ -65,5 +85,6 @@ struct LoongArchExtIOI {
  qemu_irq irq[EXTIOI_IRQS];
  ExtIOICore *cpu;
  MemoryRegion extioi_system_mem;
+MemoryRegion virt_extend;
  };
  #endif /* LOONGARCH_EXTIOI_H */
diff --git a/hw/intc/loongarch_extioi.c b/hw/intc/loongarch_extioi.c
index 0b358548eb..e605ca64d5 100644
--- a/hw/intc/loongarch_extioi.c
+++ b/hw/intc/loongarch_extioi.c
@@ -143,10 +143,13 @@ static inline void 
extioi_update_sw_coremap(LoongArchExtIOI *s, int irq,
  
  for (i = 0; i < 4; i++) {

  cpu = val & 0xff;
-cpu = ctz32(cpu);
-cpu = (cpu >= 4) ? 0 : cpu;
  val = val >> 8;
  
+if (!(s->status & BIT(EXTIOI_ENABLE_CPU_ENCODE))) {

+cpu = ctz32(cpu);
+cpu = (cpu >= 4) ? 0 : cpu;
+}
+
  if (s->sw_coremap[irq + i] == cpu) {
  continue;
  }
@@ -265,6 +268,61 @@ static const MemoryRegionOps extioi_ops = {
  .endianness = DEVICE_LITTLE_ENDIAN,
  };
  
+static MemTxResult extioi_virt_readw(void *opaque, hwaddr addr, uint64_t *data,

+ unsigned size, MemTxAttrs attrs)
+{
+LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque);
+
+switch (addr) {
+case EXTIOI_VIRT_FEATURES:
+*data = s->features;
+break;
+case EXTIOI_VIRT_CONFIG:
+*data = s->status;
+break;
+default:
+break;
+}
+
+return MEMTX_OK;
+}
+
+static MemTxResult extioi_virt_writew(void *opaque, hwaddr addr,
+  uint64_t val, unsigned size,
+  MemTxAttrs attrs)
+{
+LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque);
+
+switch (addr) {
+case EXTIOI_VIRT_FEATURES:
+return MEMTX_ACCESS_ERROR;
+
+case EXTIOI_VIRT_CONFIG:
+/*
+ * extioi features can only be set at disabled status
+ */
+if ((s->status & BIT(EXTIOI_ENABLE)) && val) {
+return MEMTX_ACCESS_ERROR;
+}
+
+s->status = val & s->features;
+break;
+default:
+break;
+}
+return MEMTX_OK;
+}
+
+static const MemoryRegionOps extioi_virt_ops = {
+.read_with_attrs = extioi_virt_readw,
+.write_with_attrs = extioi_virt_writew,
+.impl.min_access_size = 4,
+.impl.max_access_size = 4,
+.valid.min_access_size = 4,
+.valid.max_access_size = 8,
+.endianness = DEVICE_LITTLE_ENDIAN,
+};
+
  static void loongarch_extioi_realize(DeviceState *dev, Error **errp)
  {
  LoongArchExtIOI *s = LOONGARCH_EXTIOI(dev);
@@ -284,6 +342,16 @@ static void loongarch_extioi_realize(DeviceState *dev, 
Error **errp)
  memory_region_init_io(&s->extioi_system_mem, OBJECT(s), &extioi_ops,
s, "extioi_system_mem", 0x900);
  sysbus_init_mmio(sbd, &s->extioi_system_mem);
+
+if (s->features & BIT(EXTIOI_HAS_VIRT_EXTENSION)) {
+memory_region_init_io(&s->virt_extend, OBJECT(

Re: [PATCH v2 2/2] hw/loongarch/virt: Enable extioi virt extension

2024-05-16 Thread maobibo




On 2024/5/14 下午5:07, Song Gao wrote:

This patch adds a new board attribute 'v-eiointc'.
A value of true enables the virt extended I/O interrupt controller.
VMs working in kvm mode have 'v-eiointc' enabled by default.

Signed-off-by: Song Gao 
---
  include/hw/loongarch/virt.h |   2 +
  target/loongarch/cpu.h  |   1 +
  hw/loongarch/virt.c | 117 +++-
  3 files changed, 106 insertions(+), 14 deletions(-)

diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
index 2c4f5cf9c8..433e7dd7f7 100644
--- a/include/hw/loongarch/virt.h
+++ b/include/hw/loongarch/virt.h
@@ -50,11 +50,13 @@ struct LoongArchVirtMachineState {
  Notifier machine_done;
  Notifier powerdown_notifier;
  OnOffAutoacpi;
+OnOffAutoveiointc;
  char *oem_id;
  char *oem_table_id;
  DeviceState  *acpi_ged;
  int  fdt_size;
  DeviceState *platform_bus_dev;
+DeviceState  *extioi;
  PCIBus   *pci_bus;
  PFlashCFI01  *flash[2];
  MemoryRegion system_iocsr;
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index 41b8e6d96d..6c41fafb70 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -36,6 +36,7 @@
  #define CPUNAME_REG 0x20
  #define MISC_FUNC_REG   0x420
  #define IOCSRM_EXTIOI_EN48
+#define IOCSRM_EXTIOI_INT_ENCODE 49
  
  #define IOCSR_MEM_SIZE  0x428
  
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c

index 95f9ed5cae..f7468d61ae 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -11,6 +11,7 @@
  #include "hw/boards.h"
  #include "hw/char/serial.h"
  #include "sysemu/kvm.h"
+#include "sysemu/tcg.h"
  #include "sysemu/sysemu.h"
  #include "sysemu/qtest.h"
  #include "sysemu/runstate.h"
@@ -47,6 +48,31 @@
  #include "hw/block/flash.h"
  #include "qemu/error-report.h"
  
+static bool virt_is_veiointc_enabled(LoongArchVirtMachineState *lvms)

+{
+if (lvms->veiointc == ON_OFF_AUTO_OFF) {
+return false;
+}
+return true;
+}
+
+static void virt_get_veiointc(Object *obj, Visitor *v, const char *name,
+  void *opaque, Error **errp)
+{
+LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);
+OnOffAuto veiointc = lvms->veiointc;
+
+visit_type_OnOffAuto(v, name, &veiointc, errp);
+}
+
+static void virt_set_veiointc(Object *obj, Visitor *v, const char *name,
+  void *opaque, Error **errp)
+{
+LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);
+
+visit_type_OnOffAuto(v, name, &lvms->veiointc, errp);
+}
+
  static PFlashCFI01 *virt_flash_create1(LoongArchVirtMachineState *lvms,
 const char *name,
 const char *alias_prop_name)
@@ -724,9 +750,17 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
  /* Create EXTIOI device */
  extioi = qdev_new(TYPE_LOONGARCH_EXTIOI);
  qdev_prop_set_uint32(extioi, "num-cpu", ms->smp.cpus);
+if (virt_is_veiointc_enabled(lvms)) {
+qdev_prop_set_bit(extioi, "has-virtualization-extension", true);
+}
  sysbus_realize_and_unref(SYS_BUS_DEVICE(extioi), &error_fatal);
  memory_region_add_subregion(&lvms->system_iocsr, APIC_BASE,
-   sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), 0));
+sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), 0));
+if (virt_is_veiointc_enabled(lvms)) {
+memory_region_add_subregion(&lvms->system_iocsr, EXTIOI_VIRT_BASE,
+sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), 1));
+}
+lvms->extioi = extioi;

Where is usage of lvms->extioi ? it seems that it is never used.

  
  /*

   * connect ext irq to the cpu irq
@@ -833,38 +867,85 @@ static void virt_firmware_init(LoongArchVirtMachineState 
*lvms)
  }
  }
  
-

-static void virt_iocsr_misc_write(void *opaque, hwaddr addr,
-  uint64_t val, unsigned size)
+static MemTxResult virt_iocsr_misc_write(void *opaque, hwaddr addr,
+ uint64_t val, unsigned size,
+ MemTxAttrs attrs)
  {
+LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(opaque);
+uint64_t features;
+
+switch (addr) {
+case MISC_FUNC_REG:
+if (!virt_is_veiointc_enabled(lvms)) {
+return MEMTX_OK;
+}
+
+features = address_space_ldl(&lvms->as_iocsr,
+ EXTIOI_VIRT_BASE + EXTIOI_VIRT_CONFIG,
+ attrs, NULL);
+if (val & BIT_ULL(IOCSRM_EXTIOI_EN)) {
+features |= BIT(EXTIOI_ENABLE);
+}
+if (val & BIT_ULL(IOCSRM_EXTIOI_INT_ENCODE)) {
+features |= BIT(EXTIOI_ENABLE_INT_ENCODE);
+}
+
+address_space_stl(&lvms->as_iocsr,
+  EXTIOI_VIRT_BASE +

Re: [PATCH v2 1/2] hw/intc/loongarch_extioi: Add extioi virt extension definition

2024-05-16 Thread maobibo




On 2024/5/14 下午5:07, Song Gao wrote:

On LoongArch, IRQs can be routed to four vcpus with hardware extioi.
This patch adds the extioi virt extension definition so that the IRQ can
route to 256 vcpus.

Signed-off-by: Song Gao 
---
  include/hw/intc/loongarch_extioi.h | 21 +++
  hw/intc/loongarch_extioi.c | 92 --
  2 files changed, 109 insertions(+), 4 deletions(-)

diff --git a/include/hw/intc/loongarch_extioi.h 
b/include/hw/intc/loongarch_extioi.h
index 410c6e1121..d4646fab9f 100644
--- a/include/hw/intc/loongarch_extioi.h
+++ b/include/hw/intc/loongarch_extioi.h
@@ -41,6 +41,24 @@
  #define EXTIOI_COREMAP_END   (0xD00 - APIC_OFFSET)
  #define EXTIOI_SIZE  0x800
  
+#define EXTIOI_VIRT_BASE (0x4000)

+#define EXTIOI_VIRT_SIZE (0x1000)
+#define EXTIOI_VIRT_FEATURES (0x0)
+#define  EXTIOI_HAS_VIRT_EXTENSION (0)
+#define  EXTIOI_HAS_ENABLE_OPTION  (1)
+#define  EXTIOI_HAS_INT_ENCODE (2)
+#define  EXTIOI_HAS_CPU_ENCODE (3)
+#define  EXTIOI_VIRT_HAS_FEATURES  (BIT(EXTIOI_HAS_VIRT_EXTENSION)  \
+| BIT(EXTIOI_HAS_ENABLE_OPTION) \
+| BIT(EXTIOI_HAS_INT_ENCODE)\
+   | BIT(EXTIOI_HAS_CPU_ENCODE))
+#define EXTIOI_VIRT_CONFIG   (0x4)
+#define  EXTIOI_ENABLE (1)
+#define  EXTIOI_ENABLE_INT_ENCODE  (2)
+#define  EXTIOI_ENABLE_CPU_ENCODE  (3)
+#define EXTIOI_VIRT_COREMAP_START(0x40)
+#define EXTIOI_VIRT_COREMAP_END  (0x240)
+
  typedef struct ExtIOICore {
  uint32_t coreisr[EXTIOI_IRQS_GROUP_COUNT];
  DECLARE_BITMAP(sw_isr[LS3A_INTC_IP], EXTIOI_IRQS);
@@ -52,6 +70,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(LoongArchExtIOI, LOONGARCH_EXTIOI)
  struct LoongArchExtIOI {
  SysBusDevice parent_obj;
  uint32_t num_cpu;
+uint32_t features;
+uint32_t status;
  /* hardware state */
  uint32_t nodetype[EXTIOI_IRQS_NODETYPE_COUNT / 2];
  uint32_t bounce[EXTIOI_IRQS_GROUP_COUNT];
@@ -65,5 +85,6 @@ struct LoongArchExtIOI {
  qemu_irq irq[EXTIOI_IRQS];
  ExtIOICore *cpu;
  MemoryRegion extioi_system_mem;
+MemoryRegion virt_extend;
  };
  #endif /* LOONGARCH_EXTIOI_H */
diff --git a/hw/intc/loongarch_extioi.c b/hw/intc/loongarch_extioi.c
index 0b358548eb..89afdb1c3c 100644
--- a/hw/intc/loongarch_extioi.c
+++ b/hw/intc/loongarch_extioi.c
@@ -143,10 +143,13 @@ static inline void 
extioi_update_sw_coremap(LoongArchExtIOI *s, int irq,
  
  for (i = 0; i < 4; i++) {

  cpu = val & 0xff;
-cpu = ctz32(cpu);
-cpu = (cpu >= 4) ? 0 : cpu;
  val = val >> 8;
  
+if (!(s->status & BIT(EXTIOI_ENABLE_CPU_ENCODE))) {

+cpu = ctz32(cpu);
+cpu = (cpu >= 4) ? 0 : cpu;
+}
+
  if (s->sw_coremap[irq + i] == cpu) {
  continue;
  }
@@ -265,6 +268,61 @@ static const MemoryRegionOps extioi_ops = {
  .endianness = DEVICE_LITTLE_ENDIAN,
  };
  
+static MemTxResult extioi_virt_readw(void *opaque, hwaddr addr, uint64_t *data,

+ unsigned size, MemTxAttrs attrs)
+{
+LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque);
+
+switch (addr) {
+case EXTIOI_VIRT_FEATURES:
+*data = s->features;
+break;
+case EXTIOI_VIRT_CONFIG:
+*data = s->status;
+break;
+default:
+break;
+}
+
+return MEMTX_OK;
+}
+
+static MemTxResult extioi_virt_writew(void *opaque, hwaddr addr,
+  uint64_t val, unsigned size,
+  MemTxAttrs attrs)
+{
+LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque);
+
+switch (addr) {
+case EXTIOI_VIRT_FEATURES:
+return MEMTX_ACCESS_ERROR;
+
+case EXTIOI_VIRT_CONFIG:
+/*
+ * extioi features can only be set at disabled status
+ */
+if ((s->status & BIT(EXTIOI_ENABLE)) && val) {
+return MEMTX_ACCESS_ERROR;
+}
+
+s->status = val & s->features;
+break;
+default:
+break;
+}
+return MEMTX_OK;
+}
+
+static const MemoryRegionOps extioi_virt_ops = {
+.read_with_attrs = extioi_virt_readw,
+.write_with_attrs = extioi_virt_writew,
+.impl.min_access_size = 4,
+.impl.max_access_size = 4,
+.valid.min_access_size = 4,
+.valid.max_access_size = 8,
+.endianness = DEVICE_LITTLE_ENDIAN,
+};
+
  static void loongarch_extioi_realize(DeviceState *dev, Error **errp)
  {
  LoongArchExtIOI *s = LOONGARCH_EXTIOI(dev);
@@ -284,6 +342,16 @@ static void loongarch_extioi_realize(DeviceState *dev, 
Error **errp)
  memory_region_init_io(&s->extioi_system_mem, OBJECT(s), &extioi_ops,
s, "extioi_system_mem", 0x900);
  sysbus_init_mmio(sbd, &s->extioi_system_mem);
+
+if (s->features & BIT(EXTIOI_HAS_VIRT_EXTENSION)) {
+memory_region_init_io(&s

Re: [PATCH] tests/libqos: Add loongarch virt machine node

2024-05-15 Thread maobibo




On 2024/5/15 下午5:01, gaosong wrote:

在 2024/5/14 下午7:51, Bibo Mao 写道:

Add loongarch virt machine to the graph. It is a modified copy of
the existing riscv virtmachine in riscv-virt-machine.c

It contains a generic-pcihost controller, and an extra function
loongarch_config_qpci_bus() to configure GPEX pci host controller
information, such as ecam and pio_base addresses.

Also hotplug handle checking about TYPE_VIRTIO_IOMMU_PCI device is
added on loongarch virt machine, since virtio_mmu_pci device requires
it.

Signed-off-by: Bibo Mao 
---

qos-test failed.

  6/14 qemu:qtest+qtest-loongarch64 / 
qtest-loongarch64/qos-test   TIMEOUT 120.01s killed 
by signal 11 SIGSEGV
 >>> QTEST_QEMU_IMG=./qemu-img 
PYTHON=/root/work/code/clean/github/qemu/build/pyvenv/bin/python3 
QTEST_QEMU_STORAGE_DAEMON_BINARY=./storage-daemon/qemu-storage-daemon 
MALLOC_PERTURB_=47 
G_TEST_DBUS_DAEMON=/root/work/code/clean/github/qemu/tests/dbus-vmstate-daemon.sh 
QTEST_QEMU_BINARY=./qemu-system-loongarch64 
/root/work/code/clean/github/qemu/build/tests/qtest/qos-test --tap -k
― ✀ 
―

stderr:
qemu-system-loongarch64: ram_size must be greater than 1G.
Broken pipe
../tests/qtest/libqtest.c:195: kill_qemu() tried to terminate QEMU 
process but encountered exit status 1 (expected 0)


TAP parsing error: Too few tests run (expected 128, got 60)

I think this patch depends on your numa series and migration series 
patches.

Yes, it depends on numa/migration testcase patchset.

Regards
Bibo Mao


Thanks.
Song Gao

  hw/loongarch/virt.c |   2 +
  tests/qtest/libqos/loongarch-virt-machine.c | 114 
  tests/qtest/libqos/meson.build  |   1 +
  3 files changed, 117 insertions(+)
  create mode 100644 tests/qtest/libqos/loongarch-virt-machine.c

diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index db43b2fe4b..7f5ef87be4 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -45,6 +45,7 @@
  #include "sysemu/tpm.h"
  #include "sysemu/block-backend.h"
  #include "hw/block/flash.h"
+#include "hw/virtio/virtio-iommu.h"
  #include "qemu/error-report.h"
  static PFlashCFI01 *virt_flash_create1(LoongArchVirtMachineState *lvms,
@@ -1212,6 +1213,7 @@ static HotplugHandler 
*virt_get_hotplug_handler(MachineState *machine,

  MachineClass *mc = MACHINE_GET_CLASS(machine);
  if (device_is_dynamic_sysbus(mc, dev) ||
+    object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI) ||
  memhp_type_supported(dev)) {
  return HOTPLUG_HANDLER(machine);
  }
diff --git a/tests/qtest/libqos/loongarch-virt-machine.c 
b/tests/qtest/libqos/loongarch-virt-machine.c

new file mode 100644
index 00..c12089c015
--- /dev/null
+++ b/tests/qtest/libqos/loongarch-virt-machine.c
@@ -0,0 +1,114 @@
+/*
+ * libqos driver framework
+ *
+ * Copyright (c) 2018 Emanuele Giuseppe Esposito 


+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see 


+ */
+
+#include "qemu/osdep.h"
+#include "../libqtest.h"
+#include "qemu/module.h"
+#include "libqos-malloc.h"
+#include "qgraph.h"
+#include "virtio-mmio.h"
+#include "generic-pcihost.h"
+#include "hw/pci/pci_regs.h"
+
+#define LOONGARCH_PAGE_SIZE   0x1000
+#define LOONGARCH_VIRT_RAM_ADDR   0x10
+#define LOONGARCH_VIRT_RAM_SIZE   0xFF0
+
+#define LOONGARCH_VIRT_PIO_BASE   0x1800
+#define LOONGARCH_VIRT_PCIE_PIO_OFFSET    0x4000
+#define LOONGARCH_VIRT_PCIE_PIO_LIMIT 0x1
+#define LOONGARCH_VIRT_PCIE_ECAM_BASE 0x2000
+#define LOONGARCH_VIRT_PCIE_MMIO32_BASE   0x4000
+#define LOONGARCH_VIRT_PCIE_MMIO32_LIMIT  0x8000
+
+typedef struct QVirtMachine QVirtMachine;
+
+struct QVirtMachine {
+    QOSGraphObject obj;
+    QGuestAllocator alloc;
+    QVirtioMMIODevice virtio_mmio;
+    QGenericPCIHost bridge;
+};
+
+static void virt_destructor(QOSGraphObject *obj)
+{
+    QVirtMachine *machine = (QVirtMachine *) obj;
+    alloc_destroy(&machine->alloc);
+}
+
+static void *virt_get_driver(void *object, const char *interface)
+{
+    QVirtMachine *machine = object;
+    if (!g_strcmp0(interface, "memory")) {
+    return &machine->alloc;
+    }
+
+    fprintf(stderr, "%s not present in loongarch/virtio\n", interface);
+    g_assert_not_reached();
+}
+
+static QOSGraphObjec

Re: [PATCH] target/loongarch/kvm: fpu save the vreg registers high 192bit

2024-05-14 Thread maobibo

Reviewed-by: Bibo Mao 

On 2024/5/14 下午7:07, Song Gao wrote:

On kvm side, get_fpu/set_fpu save the vreg registers high 192bits,
but QEMU missing.

Signed-off-by: Song Gao 
---
  target/loongarch/kvm/kvm.c | 6 ++
  1 file changed, 6 insertions(+)

diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
index a9f9020071..0b5dbb7ed8 100644
--- a/target/loongarch/kvm/kvm.c
+++ b/target/loongarch/kvm/kvm.c
@@ -436,6 +436,9 @@ static int kvm_loongarch_get_regs_fp(CPUState *cs)
  env->fcsr0 = fpu.fcsr;
  for (i = 0; i < 32; i++) {
  env->fpr[i].vreg.UD[0] = fpu.fpr[i].val64[0];
+env->fpr[i].vreg.UD[1] = fpu.fpr[i].val64[1];
+env->fpr[i].vreg.UD[2] = fpu.fpr[i].val64[2];
+env->fpr[i].vreg.UD[3] = fpu.fpr[i].val64[3];
  }
  for (i = 0; i < 8; i++) {
  env->cf[i] = fpu.fcc & 0xFF;
@@ -455,6 +458,9 @@ static int kvm_loongarch_put_regs_fp(CPUState *cs)
  fpu.fcc = 0;
  for (i = 0; i < 32; i++) {
  fpu.fpr[i].val64[0] = env->fpr[i].vreg.UD[0];
+fpu.fpr[i].val64[1] = env->fpr[i].vreg.UD[1];
+fpu.fpr[i].val64[2] = env->fpr[i].vreg.UD[2];
+fpu.fpr[i].val64[3] = env->fpr[i].vreg.UD[3];
  }
  
  for (i = 0; i < 8; i++) {







Re: [RFC PATCH] target/loongarch/kvm: Add pmu support

2024-05-14 Thread maobibo




On 2024/5/14 下午5:46, Song Gao wrote:

This patch adds PMU support, We just sets some cpucfg6 default value
to PMU config on kvm mode, and then check the PMU config with kvm ioctl
KVM_GET_DEVICE_ATTR.
   e.g
 '...  -cpu max,pmu=on,pmnum=[1-16]';
 '...  -cpu max,pmu=on' (default pmnum = 4);

Do we need expose interface pmnum to user?
The default PMU number is 4 on la464/la664, it should equal to real HW.
There is no much meaning with pmnum == 1 although it supports.


 '...  -cpu max,pmu=off' (disable PMU)

Signed-off-by: Song Gao 
---

This patch adds the 'RFC' heading because it requires
the kernel to merge into patch[1] first

[1]: https://lore.kernel.org/all/20240507120140.3119714-1-gaos...@loongson.cn/


  target/loongarch/cpu.h|  2 +
  target/loongarch/cpu.c| 64 +++
  target/loongarch/kvm/kvm.c| 55 ++-
  target/loongarch/loongarch-qmp-cmds.c |  2 +-
  4 files changed, 121 insertions(+), 2 deletions(-)

diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index 6c41fafb70..d834649106 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -184,6 +184,8 @@ FIELD(CPUCFG6, PMNUM, 4, 4)
  FIELD(CPUCFG6, PMBITS, 8, 6)
  FIELD(CPUCFG6, UPM, 14, 1)
  
+#define PMNUM_MAX 16

+
  /* cpucfg[16] bits */
  FIELD(CPUCFG16, L1_IUPRE, 0, 1)
  FIELD(CPUCFG16, L1_IUUNIFY, 1, 1)
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index a0cad53676..c78ee3f0b1 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -8,6 +8,7 @@
  #include "qemu/osdep.h"
  #include "qemu/log.h"
  #include "qemu/qemu-print.h"
+#include "qemu/error-report.h"
  #include "qapi/error.h"
  #include "qemu/module.h"
  #include "sysemu/qtest.h"
@@ -19,6 +20,7 @@
  #include "internals.h"
  #include "fpu/softfloat-helpers.h"
  #include "cpu-csr.h"
+#include "qapi/visitor.h"
  #ifndef CONFIG_USER_ONLY
  #include "sysemu/reset.h"
  #endif
@@ -421,6 +423,14 @@ static void loongarch_la464_initfn(Object *obj)
  data = FIELD_DP32(data, CPUCFG5, CC_DIV, 1);
  env->cpucfg[5] = data;
  
+if (kvm_enabled()) {

+data = 0;
+data = FIELD_DP32(data, CPUCFG6, PMP, 1);
+data = FIELD_DP32(data, CPUCFG6, PMNUM, 3);
+data = FIELD_DP32(data, CPUCFG6, PMBITS, 63);
+env->cpucfg[6] = data;
+}
+
  data = 0;
  data = FIELD_DP32(data, CPUCFG16, L1_IUPRE, 1);
  data = FIELD_DP32(data, CPUCFG16, L1_DPRE, 1);
@@ -643,6 +653,48 @@ static void loongarch_set_lasx(Object *obj, bool value, 
Error **errp)
  }
  }
  
+static bool loongarch_get_pmu(Object *obj, Error **errp)

+{
+LoongArchCPU *cpu = LOONGARCH_CPU(obj);
+
+return  !!(FIELD_EX32(cpu->env.cpucfg[6], CPUCFG6, PMP));
+}
+
+static void loongarch_set_pmu(Object *obj, bool value,  Error **errp)
+{
+LoongArchCPU *cpu = LOONGARCH_CPU(obj);
+
+cpu->env.cpucfg[6] = FIELD_DP32(cpu->env.cpucfg[6], CPUCFG6, PMP, value);
+}
+
+static void loongarch_get_pmnum(Object *obj, Visitor *v,
+const char *name, void *opaque,
+Error **errp)
+{
+LoongArchCPU *cpu = LOONGARCH_CPU(obj);
+uint32_t value = FIELD_EX32(cpu->env.cpucfg[6], CPUCFG6, PMNUM);
+
+visit_type_uint32(v, name, &value, errp);
+}
+
+static void loongarch_set_pmnum(Object *obj, Visitor *v,
+const char *name, void *opaque,
+Error **errp)
+{
+LoongArchCPU *cpu = LOONGARCH_CPU(obj);
+uint32_t *value= opaque;
+
+if (!visit_type_uint32(v, name, value, errp)) {
+return;
+}
+if ((*value <= PMNUM_MAX) && (*value > 0)) {
+cpu->env.cpucfg[6] = FIELD_DP32(cpu->env.cpucfg[6], CPUCFG6, PMNUM, 
*value -1);
+} else {
+error_report("Performance counter number need be in [1- %d]\n", 
PMNUM_MAX);
+exit(EXIT_FAILURE);
+}
+}
+
  void loongarch_cpu_post_init(Object *obj)
  {
  LoongArchCPU *cpu = LOONGARCH_CPU(obj);
@@ -655,6 +707,18 @@ void loongarch_cpu_post_init(Object *obj)
  object_property_add_bool(obj, "lasx", loongarch_get_lasx,
   loongarch_set_lasx);
  }
+
+if (kvm_enabled()) {
+object_property_add_bool(obj, "pmu", loongarch_get_pmu,
+ loongarch_set_pmu);
+if (FIELD_EX32(cpu->env.cpucfg[6], CPUCFG6, PMP)) {
+uint32_t value = 4;
+object_property_add(obj, "pmnum", "uint32",
+loongarch_get_pmnum,
+loongarch_set_pmnum, NULL,
+(void *)&value);
+}
+}
  }
  
  static void loongarch_cpu_init(Object *obj)

diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
index bc75552d0f..a9f9020071 100644
--- a/target/loongarch/kvm/kvm.c
+++ b/target/loongarch/kvm/kvm.c
@@ -556,6 +556,53 @@ static int kvm_check_cpucfg2(CPUState *cs)
  return 

Re: [PATCH] tests/qtest/boot-serial-test: Add support on LoongArch system

2024-05-08 Thread maobibo




On 2024/5/8 下午5:00, Thomas Huth wrote:

On 08/05/2024 10.55, Bibo Mao wrote:

Add boot-serial-test test case support on LoongArch system.


... and also the filter tests?

yes, it is :) Will update changelog in next version.




Signed-off-by: Bibo Mao 
---
  tests/qtest/boot-serial-test.c | 10 ++
  tests/qtest/meson.build    |  4 
  2 files changed, 14 insertions(+)

diff --git a/tests/qtest/boot-serial-test.c 
b/tests/qtest/boot-serial-test.c

index e3b7d65fe5..631015e8c8 100644
--- a/tests/qtest/boot-serial-test.c
+++ b/tests/qtest/boot-serial-test.c
@@ -129,6 +129,14 @@ static const uint8_t kernel_stm32vldiscovery[] = {
  0x04, 0x38, 0x01, 0x40  /* 0x40013804 = USART1 
TXD */

  };
+static const uint8_t bios_loongarch64[] = {
+    0x0c, 0xc0, 0x3f, 0x14,    /* lu12i.w $t0,  0x1fe00    */
+    0x8c, 0x81, 0x87, 0x03,    /* ori $t0,  $t0, 0x1e0 */
+    0x0d, 0x50, 0x81, 0x03,    /* li.w    $t1,  'T'    */
+    0x8d, 0x01, 0x00, 0x29,    /* st.b    $t1, $t0,  0 */
+    0xff, 0xf3, 0xff, 0x53,    /*  b  -16  #loop   */
+};
+
  typedef struct testdef {
  const char *arch;   /* Target architecture */
  const char *machine;    /* Name of the machine */
@@ -181,6 +189,8 @@ static const testdef_t tests[] = {
  { "arm", "microbit", "", "T", sizeof(kernel_nrf51), kernel_nrf51 },
  { "arm", "stm32vldiscovery", "", "T",
    sizeof(kernel_stm32vldiscovery), kernel_stm32vldiscovery },
+    { "loongarch64", "virt", "-cpu max", "TT", sizeof(bios_loongarch64),
+  NULL, bios_loongarch64 },
  { NULL }
  };
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 6f2f594ace..6619b630e6 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -256,6 +256,10 @@ qtests_s390x = \
  qtests_riscv32 = \
    (config_all_devices.has_key('CONFIG_SIFIVE_E_AON') ? 
['sifive-e-aon-watchdog-test'] : [])

+ qtests_loongarch64 = \
+  qtests_filter + \
+  ['boot-serial-test']


It's already a little bit messed up, but I think we originally had the 
entries in alphabetical order, so I'd like to suggest to add this 
between qtests_hppa and qtests_m68k instead.

sure, will do.

Regards
Bibo Mao


  Thomas



  qos_test_ss = ss.source_set()
  qos_test_ss.add(
    'ac97-test.c',

base-commit: 4e66a08546a2588a4667766a1edab9caccf24ce3







Re: [PATCH v3 1/5] hw/loongarch: Rename LOONGARCH_MACHINE with VIRT_MACHINE

2024-05-07 Thread maobibo




On 2024/5/7 下午2:10, Thomas Huth wrote:

On 07/05/2024 03.18, maobibo wrote:



On 2024/5/6 下午2:09, maobibo wrote:



On 2024/5/6 下午12:24, Thomas Huth wrote:

On 06/05/2024 05.02, Bibo Mao wrote:

On LoongArch system, there is only virt machine type now, name
LOONGARCH_MACHINE is confused, rename it with VIRT_MACHINE. Machine 
name

about Other real hw boards can be added in future.

Signed-off-by: Bibo Mao 
---

...
@@ -1245,7 +1244,7 @@ static void loongarch_class_init(ObjectClass 
*oc, void *data)

  static const TypeInfo loongarch_machine_types[] = {
  {
-    .name   = TYPE_LOONGARCH_MACHINE,
+    .name   = TYPE_VIRT_MACHINE,
  .parent = TYPE_MACHINE,
  .instance_size  = sizeof(LoongArchMachineState),
  .class_init = loongarch_class_init,
diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
index 4e14bf6060..5ea2f0370d 100644
--- a/include/hw/loongarch/virt.h
+++ b/include/hw/loongarch/virt.h
@@ -73,8 +73,8 @@ struct LoongArchMachineState {
  struct loongarch_boot_info bootinfo;
  };
-#define TYPE_LOONGARCH_MACHINE  MACHINE_TYPE_NAME("virt")
-OBJECT_DECLARE_SIMPLE_TYPE(LoongArchMachineState, LOONGARCH_MACHINE)
+#define TYPE_VIRT_MACHINE  MACHINE_TYPE_NAME("virt")
+OBJECT_DECLARE_SIMPLE_TYPE(LoongArchMachineState, VIRT_MACHINE)
  bool loongarch_is_acpi_enabled(LoongArchMachineState *lams);
  void loongarch_acpi_setup(LoongArchMachineState *lams);
  #endif


  Hi,

there are currently some efforts going on to create the possibility 
to link a QEMU binary that contains all targets in one binary. Since 
we already have a TYPE_VIRT_MACHINE for other targets, I wonder 
whether it might be better to use LOONGARCH_VIRT_MACHINE than just 
VIRT_MACHINE here? Philippe, could you comment on this?


It is great if there is one QEMU binary which supports different 
targets. And LOONGARCH_VIRT_MACHINE is ok for me.

Hi Thomas, Philippe,

Does machine name "virt" need be changed if LOONGARCH_VIRT_MACHINE is 
used? There will be compatible issues if "virt" machine type is not 
suggested to use.


However CPU type "max" is not widely used now, can we get different 
architectures from CPU type rather than machine type for one QEMU 
binary which supports different targets?


I assume it should be fine to keep the "virt" machine name and "max" CPU 
type for each target, we've got a bunch of those already. I assume we'll 
keep the binary names as symlinks to the generic binary around and then 
decide via argv[0] about the main target...? Philippe, do you have 
already concrete plans for this?
The method using symlinks to generic binary is great. It is transparent 
to detailed architectures. I will refresh the patch and use 
LOONGARCH_VIRT_MACHINE macro.


Regards
Bibo Mao


  Thomas







Re: [PATCH v3 1/5] hw/loongarch: Rename LOONGARCH_MACHINE with VIRT_MACHINE

2024-05-06 Thread maobibo




On 2024/5/6 下午2:09, maobibo wrote:



On 2024/5/6 下午12:24, Thomas Huth wrote:

On 06/05/2024 05.02, Bibo Mao wrote:

On LoongArch system, there is only virt machine type now, name
LOONGARCH_MACHINE is confused, rename it with VIRT_MACHINE. Machine name
about Other real hw boards can be added in future.

Signed-off-by: Bibo Mao 
---

...
@@ -1245,7 +1244,7 @@ static void loongarch_class_init(ObjectClass 
*oc, void *data)

  static const TypeInfo loongarch_machine_types[] = {
  {
-    .name   = TYPE_LOONGARCH_MACHINE,
+    .name   = TYPE_VIRT_MACHINE,
  .parent = TYPE_MACHINE,
  .instance_size  = sizeof(LoongArchMachineState),
  .class_init = loongarch_class_init,
diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
index 4e14bf6060..5ea2f0370d 100644
--- a/include/hw/loongarch/virt.h
+++ b/include/hw/loongarch/virt.h
@@ -73,8 +73,8 @@ struct LoongArchMachineState {
  struct loongarch_boot_info bootinfo;
  };
-#define TYPE_LOONGARCH_MACHINE  MACHINE_TYPE_NAME("virt")
-OBJECT_DECLARE_SIMPLE_TYPE(LoongArchMachineState, LOONGARCH_MACHINE)
+#define TYPE_VIRT_MACHINE  MACHINE_TYPE_NAME("virt")
+OBJECT_DECLARE_SIMPLE_TYPE(LoongArchMachineState, VIRT_MACHINE)
  bool loongarch_is_acpi_enabled(LoongArchMachineState *lams);
  void loongarch_acpi_setup(LoongArchMachineState *lams);
  #endif


  Hi,

there are currently some efforts going on to create the possibility to 
link a QEMU binary that contains all targets in one binary. Since we 
already have a TYPE_VIRT_MACHINE for other targets, I wonder whether 
it might be better to use LOONGARCH_VIRT_MACHINE than just 
VIRT_MACHINE here? Philippe, could you comment on this?


It is great if there is one QEMU binary which supports different 
targets. And LOONGARCH_VIRT_MACHINE is ok for me.

Hi Thomas, Philippe,

Does machine name "virt" need be changed if LOONGARCH_VIRT_MACHINE is 
used? There will be compatible issues if "virt" machine type is not 
suggested to use.


However CPU type "max" is not widely used now, can we get different 
architectures from CPU type rather than machine type for one QEMU binary 
which supports different targets?


Regards
Bibo Mao



Regards
Bibo Mao


  Thomas







Re: [PATCH v3 1/5] hw/loongarch: Rename LOONGARCH_MACHINE with VIRT_MACHINE

2024-05-05 Thread maobibo




On 2024/5/6 下午12:24, Thomas Huth wrote:

On 06/05/2024 05.02, Bibo Mao wrote:

On LoongArch system, there is only virt machine type now, name
LOONGARCH_MACHINE is confused, rename it with VIRT_MACHINE. Machine name
about Other real hw boards can be added in future.

Signed-off-by: Bibo Mao 
---

...
@@ -1245,7 +1244,7 @@ static void loongarch_class_init(ObjectClass 
*oc, void *data)

  static const TypeInfo loongarch_machine_types[] = {
  {
-    .name   = TYPE_LOONGARCH_MACHINE,
+    .name   = TYPE_VIRT_MACHINE,
  .parent = TYPE_MACHINE,
  .instance_size  = sizeof(LoongArchMachineState),
  .class_init = loongarch_class_init,
diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
index 4e14bf6060..5ea2f0370d 100644
--- a/include/hw/loongarch/virt.h
+++ b/include/hw/loongarch/virt.h
@@ -73,8 +73,8 @@ struct LoongArchMachineState {
  struct loongarch_boot_info bootinfo;
  };
-#define TYPE_LOONGARCH_MACHINE  MACHINE_TYPE_NAME("virt")
-OBJECT_DECLARE_SIMPLE_TYPE(LoongArchMachineState, LOONGARCH_MACHINE)
+#define TYPE_VIRT_MACHINE  MACHINE_TYPE_NAME("virt")
+OBJECT_DECLARE_SIMPLE_TYPE(LoongArchMachineState, VIRT_MACHINE)
  bool loongarch_is_acpi_enabled(LoongArchMachineState *lams);
  void loongarch_acpi_setup(LoongArchMachineState *lams);
  #endif


  Hi,

there are currently some efforts going on to create the possibility to 
link a QEMU binary that contains all targets in one binary. Since we 
already have a TYPE_VIRT_MACHINE for other targets, I wonder whether it 
might be better to use LOONGARCH_VIRT_MACHINE than just VIRT_MACHINE 
here? Philippe, could you comment on this?


It is great if there is one QEMU binary which supports different 
targets. And LOONGARCH_VIRT_MACHINE is ok for me.


Regards
Bibo Mao


  Thomas





Re: [PATCH 0/5] hw/loongarch: Refine numa memory map

2024-04-30 Thread maobibo

Sure, I will rebase and send the new version.

Regards
Bibo Mao

On 2024/4/30 下午4:15, gaosong wrote:

Hi,

在 2024/3/18 下午4:01, Bibo Mao 写道:

One LoongArch virt machine platform, there is limitation for memory
map information. The minimum memory size is 256M and minimum memory
size for numa node0 is 256M also. With qemu numa qtest, it is possible
that memory size of numa node0 is 128M.

Limitations for minimum memory size for both total memory and numa
node0 is removed here, including acpi srat table, fadt memory map table
and fw_cfg memory map table.

Also remove numa node about memory region, there is only low memory
region and how memory region.

For this series,
Reviewed-by: Song Gao 

After PR[1] merge in, patch3 and patch4 need Rebase.
Also, how about enabling LoongArch architecture numa-test?

like this:

    --- a/tests/qtest/meson.build
    +++ b/tests/qtest/meson.build
    @@ -127,6 +127,8 @@ else
        dbus_vmstate1 = []
      endif

    +qtests_loongarch64 = ['numa-test'] + qtests_filter
    +
      qtests_x86_64 = qtests_i386

      qtests_alpha = ['boot-serial-test'] + \


[1] https://patchew.org/QEMU/20240429023043.2607982-1-gaos...@loongson.cn/


Thanks.
Song Gao

Bibo Mao (5):
   hw/loongarch: Refine acpi srat table for numa memory
   hw/loongarch: Refine fadt memory table for numa memory
   hw/loongarch: Refine fwcfg memory map
   hw/loongarch: Refine system dram memory region
   hw/loongarch: Remove minimum and default memory size

  hw/loongarch/acpi-build.c |  58 +++--
  hw/loongarch/virt.c   | 168 ++
  2 files changed, 152 insertions(+), 74 deletions(-)


base-commit: ba49d760eb04630e7b15f423ebecf6c871b8f77b







Re: [PATCH v7 06/17] hw/loongarch: Init efi_boot_memmap table

2024-04-27 Thread maobibo




On 2024/4/26 下午5:15, Song Gao wrote:

Message test is also missing there :(


Signed-off-by: Song Gao 
Message-Id: <20240307164835.300412-7-gaos...@loongson.cn>
---
  include/hw/loongarch/boot.h | 27 +
  include/hw/loongarch/virt.h | 10 ++
  hw/loongarch/boot.c | 40 +
  hw/loongarch/virt.c | 11 ++
  4 files changed, 79 insertions(+), 9 deletions(-)

diff --git a/include/hw/loongarch/boot.h b/include/hw/loongarch/boot.h
index cf0e4d4f91..76622af2e2 100644
--- a/include/hw/loongarch/boot.h
+++ b/include/hw/loongarch/boot.h
@@ -21,6 +21,15 @@ typedef struct {
  uint8_t b[16];
  } efi_guid_t QEMU_ALIGNED(8);
  
+#define EFI_GUID(a, b, c, d...) (efi_guid_t){ {\

+(a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, 
\
+(b) & 0xff, ((b) >> 8) & 0xff, 
\
+(c) & 0xff, ((c) >> 8) & 0xff, d } }
+
+#define LINUX_EFI_BOOT_MEMMAP_GUID \
+EFI_GUID(0x800f683f, 0xd08b, 0x423a,  0xa2, 0x93, \
+ 0x96, 0x5c, 0x3c, 0x6f, 0xe2, 0xb4)
+
  struct efi_config_table {
  efi_guid_t guid;
  uint64_t *ptr;
@@ -56,6 +65,24 @@ struct efi_system_table {
  struct efi_configuration_table *tables;
  };
  
+typedef struct {

+uint32_t type;
+uint32_t pad;
+uint64_t phys_addr;
+uint64_t virt_addr;
+uint64_t num_pages;
+uint64_t attribute;
+} efi_memory_desc_t;
+
+struct efi_boot_memmap {
+uint64_t map_size;
+uint64_t desc_size;
+uint32_t desc_ver;
+uint64_t map_key;
+uint64_t buff_size;
+efi_memory_desc_t map[32];
+};
+
  struct loongarch_boot_info {
  uint64_t ram_size;
  const char *kernel_filename;
diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
index d7a074d69f..8a9fe4053d 100644
--- a/include/hw/loongarch/virt.h
+++ b/include/hw/loongarch/virt.h
@@ -35,6 +35,16 @@
  
  #define COMMAND_LINE_SIZE   512
  
+extern struct memmap_entry *memmap_table;

+extern unsigned memmap_entries;
+
+struct memmap_entry {
+uint64_t address;
+uint64_t length;
+uint32_t type;
+uint32_t reserved;
+};
+
  struct LoongArchMachineState {
  /*< private >*/
  MachineState parent_obj;
diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
index 46a241a04c..18aae3434d 100644
--- a/hw/loongarch/boot.c
+++ b/hw/loongarch/boot.c
@@ -63,8 +63,41 @@ static const unsigned int slave_boot_code[] = {
  0x4c20,   /* jirl   $zero, $ra,0   */
  };
  
+static inline void *guidcpy(void *dst, const void *src)

+{
+return memcpy(dst, src, sizeof(efi_guid_t));
+}
+
+static void init_efi_boot_memmap(struct efi_system_table *systab,
+ void *p, void *start)
+{
+unsigned i;
+struct efi_boot_memmap *boot_memmap = p;
+efi_guid_t tbl_guid = LINUX_EFI_BOOT_MEMMAP_GUID;
+
+/* efi_configuration_table 1 */
+guidcpy(&systab->tables[0].guid, &tbl_guid);
+systab->tables[0].table = (struct efi_configuration_table *)(p - start);
+systab->nr_tables = 1;
+
+boot_memmap->desc_size = sizeof(efi_memory_desc_t);
+boot_memmap->desc_ver = 1;
+boot_memmap->map_size = 0;
+
+efi_memory_desc_t *map = p + sizeof(struct efi_boot_memmap);
+for (i = 0; i < memmap_entries; i++) {
+map = (void *)boot_memmap + sizeof(*map);
+map[i].type = memmap_table[i].type;
+map[i].phys_addr = ROUND_UP(memmap_table[i].address, 64 * KiB);
+map[i].num_pages = ROUND_DOWN(memmap_table[i].address +
+memmap_table[i].length - map[i].phys_addr, 64 * KiB);
+p += sizeof(efi_memory_desc_t);
+}
+}


Do you verify that memory size of VM is the same with qemu command line 
setting? I am ok if the test result is the same.


Reviewed-by: Bibo Mao 

+
  static void init_systab(struct loongarch_boot_info *info, void *p, void 
*start)
  {
+void *bp_tables_start;
  struct efi_system_table *systab = p;
  
  info->a2 = (uint64_t)p - (uint64_t)start;

@@ -80,6 +113,13 @@ static void init_systab(struct loongarch_boot_info *info, 
void *p, void *start)
  p += ROUND_UP(sizeof(struct efi_system_table), 64 * KiB);
  
  systab->tables = p;

+bp_tables_start = p;
+
+init_efi_boot_memmap(systab, p, start);
+p += ROUND_UP(sizeof(struct efi_boot_memmap) +
+  sizeof(efi_memory_desc_t) * memmap_entries, 64 * KiB);
+
+systab->tables = (struct efi_configuration_table *)(bp_tables_start - 
start);
  }
  
  static void init_cmdline(struct loongarch_boot_info *info, void *p, void *start)

diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index bfb88aedab..708aa8bc60 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -378,15 +378,8 @@ static void virt_powerdown_req(Notifier *notifier, void 
*opaque)
  acpi_send_event(s->acpi_ged, ACPI_POWER_DOWN_STATUS);
  }
  
-struct memm

Re: [PATCH v7 03/17] hw/loongarch: Add slave cpu boot_code

2024-04-27 Thread maobibo




On 2024/4/26 下午5:15, Song Gao wrote:

Message text is missing here :(


Signed-off-by: Song Gao 
Message-Id: <20240307164835.300412-4-gaos...@loongson.cn>

It is strange that there is "Message-Id:" string. Is it required here?

The others look good to me, especially when bootrom for AP is put at 
BIOS flash area.


Regards
Bibo Mao


---
  hw/loongarch/boot.c | 62 -
  1 file changed, 61 insertions(+), 1 deletion(-)

diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
index a9522d6912..d1a8434127 100644
--- a/hw/loongarch/boot.c
+++ b/hw/loongarch/boot.c
@@ -15,6 +15,54 @@
  #include "sysemu/reset.h"
  #include "sysemu/qtest.h"
  
+static const unsigned int slave_boot_code[] = {

+  /* Configure reset ebase.*/
+0x0400302c,   /* csrwr  $t0, LOONGARCH_CSR_EENTRY  */
+
+  /* Disable interrupt.*/
+0x0380100c,   /* ori$t0, $zero,0x4 */
+0x04000180,   /* csrxchg$zero, $t0, LOONGARCH_CSR_CRMD */
+
+  /* Clear mailbox.*/
+0x142d,   /* lu12i.w$t1, 1(0x1)*/
+0x038081ad,   /* ori$t1, $t1, CORE_BUF_20  */
+0x06481da0,   /* iocsrwr.d  $zero, $t1 */
+
+  /* Enable IPI interrupt. */
+0x142c,   /* lu12i.w$t0, 1(0x1)*/
+0x0400118c,   /* csrxchg$t0, $t0, LOONGARCH_CSR_ECFG   */
+0x02fffc0c,   /* addi.d $t0, $r0,-1(0xfff) */
+0x142d,   /* lu12i.w$t1, 1(0x1)*/
+0x038011ad,   /* ori$t1, $t1, CORE_EN_OFF  */
+0x064819ac,   /* iocsrwr.w  $t0, $t1   */
+0x142d,   /* lu12i.w$t1, 1(0x1)*/
+0x038081ad,   /* ori$t1, $t1, CORE_BUF_20  */
+
+  /* Wait for wakeup  <.L11>:  */
+0x06488000,   /* idle   0x0*/
+0x0340,   /* andi   $zero, $zero, 0x0  */
+0x064809ac,   /* iocsrrd.w  $t0, $t1   */
+0x43fff59f,   /* beqz   $t0, -12(0x74) # 48 <.L11> */
+
+  /* Read and clear IPI interrupt. */
+0x142d,   /* lu12i.w$t1, 1(0x1)*/
+0x064809ac,   /* iocsrrd.w  $t0, $t1   */
+0x142d,   /* lu12i.w$t1, 1(0x1)*/
+0x038031ad,   /* ori$t1, $t1, CORE_CLEAR_OFF   */
+0x064819ac,   /* iocsrwr.w  $t0, $t1   */
+
+  /* Disable  IPI interrupt.   */
+0x142c,   /* lu12i.w$t0, 1(0x1)*/
+0x04001180,   /* csrxchg$zero, $t0, LOONGARCH_CSR_ECFG */
+
+  /* Read mail buf and jump to specified entry */
+0x142d,   /* lu12i.w$t1, 1(0x1)*/
+0x038081ad,   /* ori$t1, $t1, CORE_BUF_20  */
+0x06480dac,   /* iocsrrd.d  $t0, $t1   */
+0x00150181,   /* move   $ra, $t0   */
+0x4c20,   /* jirl   $zero, $ra,0   */
+};
+
  static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr)
  {
  return addr & MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS);
@@ -126,11 +174,23 @@ static void loongarch_direct_kernel_boot(struct 
loongarch_boot_info *info)
  }
  }
  
+/* Load slave boot code at pflash0 . */

+void *boot_code = g_malloc0(VIRT_FLASH0_SIZE);
+memcpy(boot_code, &slave_boot_code, sizeof(slave_boot_code));
+rom_add_blob_fixed("boot_code", boot_code, VIRT_FLASH0_SIZE, 
VIRT_FLASH0_BASE);
+
  CPU_FOREACH(cs) {
  lacpu = LOONGARCH_CPU(cs);
  lacpu->env.load_elf = true;
-lacpu->env.elf_address = kernel_addr;
+if (cs == first_cpu) {
+lacpu->env.elf_address = kernel_addr;
+} else {
+lacpu->env.elf_address = VIRT_FLASH0_BASE;
+}
+lacpu->env.boot_info = info;
  }
+
+g_free(boot_code);
  }
  
  void loongarch_load_kernel(MachineState *ms, struct loongarch_boot_info *info)







Re: [PATCH v6 03/17] hw/loongarch: Add slave cpu boot_code

2024-03-13 Thread maobibo




On 2024/3/11 下午2:50, maobibo wrote:



On 2024/3/8 下午5:36, gaosong wrote:



在 2024/3/8 16:27, maobibo 写道:



On 2024/3/8 上午12:48, Song Gao wrote:

Signed-off-by: Song Gao 
Message-Id: <20240301093839.663947-4-gaos...@loongson.cn>
---
  hw/loongarch/boot.c | 70 
-

  1 file changed, 69 insertions(+), 1 deletion(-)

diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
index 149deb2e01..e560ac178a 100644
--- a/hw/loongarch/boot.c
+++ b/hw/loongarch/boot.c
@@ -15,6 +15,54 @@
  #include "sysemu/reset.h"
  #include "sysemu/qtest.h"
+static const unsigned int slave_boot_code[] = {
+  /* Configure reset ebase. */
+    0x0400302c,   /* csrwr  $r12,0xc    */
+
+  /* Disable interrupt. */
+    0x0380100c,   /* ori    $r12,$r0,0x4    */
+    0x04000180,   /* csrxchg    $r0,$r12,0x0    */
+
+  /* Clear mailbox. */
+    0x142d,   /* lu12i.w    $r13,1(0x1) */
+    0x038081ad,   /* ori    $r13,$r13,0x20  */
+    0x06481da0,   /* iocsrwr.d  $r0,$r13    */
+
+  /* Enable IPI interrupt.  */
+    0x142c,   /* lu12i.w    $r12,1(0x1) */
+    0x0400118c,   /* csrxchg    $r12,$r12,0x4   */
+    0x02fffc0c,   /* addi.d $r12,$r0,-1(0xfff)  */
+    0x142d,   /* lu12i.w    $r13,1(0x1) */
+    0x038011ad,   /* ori    $r13,$r13,0x4   */
+    0x064819ac,   /* iocsrwr.w  $r12,$r13   */
+    0x142d,   /* lu12i.w    $r13,1(0x1) */
+    0x038081ad,   /* ori    $r13,$r13,0x20  */
+
+  /* Wait for wakeup  <.L11>:   */
+    0x06488000,   /* idle   0x0 */
+    0x0340,   /* andi   $r0,$r0,0x0 */
+    0x064809ac,   /* iocsrrd.w  $r12,$r13   */
+    0x43fff59f,   /* beqz   $r12,-12(0x74) # 48 <.L11> */
+
+  /* Read and clear IPI interrupt.  */
+    0x142d,   /* lu12i.w    $r13,1(0x1) */
+    0x064809ac,   /* iocsrrd.w  $r12,$r13   */
+    0x142d,   /* lu12i.w    $r13,1(0x1) */
+    0x038031ad,   /* ori    $r13,$r13,0xc   */
+    0x064819ac,   /* iocsrwr.w  $r12,$r13   */
+
+  /* Disable  IPI interrupt.    */
+    0x142c,   /* lu12i.w    $r12,1(0x1) */
+    0x04001180,   /* csrxchg    $r0,$r12,0x4    */
+
+  /* Read mail buf and jump to specified entry */
+    0x142d,   /* lu12i.w    $r13,1(0x1) */
+    0x038081ad,   /* ori    $r13,$r13,0x20  */
+    0x06480dac,   /* iocsrrd.d  $r12,$r13   */
+    0x00150181,   /* move   $r1,$r12    */
+    0x4c20,   /* jirl   $r0,$r1,0   */
+};
+
  static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t 
addr)

  {
  return addr & MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS);
@@ -111,8 +159,15 @@ static void 
loongarch_firmware_boot(LoongArchMachineState *lams,

  fw_cfg_add_kernel_info(info, lams->fw_cfg);
  }
+static void init_boot_rom(struct loongarch_boot_info *info, void *p)
+{
+    memcpy(p, &slave_boot_code, sizeof(slave_boot_code));
+    p += sizeof(slave_boot_code);
+}
+
  static void loongarch_direct_kernel_boot(struct 
loongarch_boot_info *info)

  {
+    void  *p, *bp;
  int64_t kernel_addr = 0;
  LoongArchCPU *lacpu;
  CPUState *cs;
@@ -126,11 +181,24 @@ static void 
loongarch_direct_kernel_boot(struct loongarch_boot_info *info)

  }
  }
+    /* Load 'boot_rom' at [0 - 1MiB] */
+    p = g_malloc0(1 * MiB);
+    bp = p;
+    init_boot_rom(info, p);
+    rom_add_blob_fixed("boot_rom", bp, 1 * MiB, 0);
+
The secondary cpu waiting on the bootrom located memory address 
0x0-0x10.


Is it possible that primary cpu clears the memory located at bootrom
and then wakeup the secondary cpu?


I think it impossible,0-1M is ROM。

I am not sure whether it is ok if area between 0-1M is ROM.

For the memory map table, low memory area (0 - 256M) is still ddr ram.
And it is passed to kernel with fdt system table, rather than 
area(1-256M). Is that right?


There are some lines like this:
     /* Node0 memory */
     memmap_add_entry(VIRT_LOWMEM_BASE, VIRT_LOWMEM_SIZE, 1);

Song,

Can the base memory address of bootrom for secondary cpus be set as base 
address of flash like bios, such as VIRT_FLASH0_BASE/VIRT_FLASH1_BASE?


And ddr memory map area is kept unchanged.

Regards
Bibo Mao



Regards
Bibo Mao



Thanks.
Song Gao

Regards
Bibo Mao


  CPU_FOREACH(cs) {
  lacpu = LOONGARCH_CPU(cs);
  lacpu->env.load_elf = true;
-    lacpu->env.elf_address = kernel_addr;
+    if (cs == first_cpu) {
+    lacpu->env.elf_address = kernel_addr;
+    } else {
+    lacpu->env.elf_address = 0;
+    }
+    lacpu->env.boot_info = info;

Re: [PATCH v6 03/17] hw/loongarch: Add slave cpu boot_code

2024-03-10 Thread maobibo




On 2024/3/8 下午5:36, gaosong wrote:



在 2024/3/8 16:27, maobibo 写道:



On 2024/3/8 上午12:48, Song Gao wrote:

Signed-off-by: Song Gao 
Message-Id: <20240301093839.663947-4-gaos...@loongson.cn>
---
  hw/loongarch/boot.c | 70 -
  1 file changed, 69 insertions(+), 1 deletion(-)

diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
index 149deb2e01..e560ac178a 100644
--- a/hw/loongarch/boot.c
+++ b/hw/loongarch/boot.c
@@ -15,6 +15,54 @@
  #include "sysemu/reset.h"
  #include "sysemu/qtest.h"
+static const unsigned int slave_boot_code[] = {
+  /* Configure reset ebase. */
+    0x0400302c,   /* csrwr  $r12,0xc    */
+
+  /* Disable interrupt. */
+    0x0380100c,   /* ori    $r12,$r0,0x4    */
+    0x04000180,   /* csrxchg    $r0,$r12,0x0    */
+
+  /* Clear mailbox. */
+    0x142d,   /* lu12i.w    $r13,1(0x1) */
+    0x038081ad,   /* ori    $r13,$r13,0x20  */
+    0x06481da0,   /* iocsrwr.d  $r0,$r13    */
+
+  /* Enable IPI interrupt.  */
+    0x142c,   /* lu12i.w    $r12,1(0x1) */
+    0x0400118c,   /* csrxchg    $r12,$r12,0x4   */
+    0x02fffc0c,   /* addi.d $r12,$r0,-1(0xfff)  */
+    0x142d,   /* lu12i.w    $r13,1(0x1) */
+    0x038011ad,   /* ori    $r13,$r13,0x4   */
+    0x064819ac,   /* iocsrwr.w  $r12,$r13   */
+    0x142d,   /* lu12i.w    $r13,1(0x1) */
+    0x038081ad,   /* ori    $r13,$r13,0x20  */
+
+  /* Wait for wakeup  <.L11>:   */
+    0x06488000,   /* idle   0x0 */
+    0x0340,   /* andi   $r0,$r0,0x0 */
+    0x064809ac,   /* iocsrrd.w  $r12,$r13   */
+    0x43fff59f,   /* beqz   $r12,-12(0x74) # 48 <.L11> */
+
+  /* Read and clear IPI interrupt.  */
+    0x142d,   /* lu12i.w    $r13,1(0x1) */
+    0x064809ac,   /* iocsrrd.w  $r12,$r13   */
+    0x142d,   /* lu12i.w    $r13,1(0x1) */
+    0x038031ad,   /* ori    $r13,$r13,0xc   */
+    0x064819ac,   /* iocsrwr.w  $r12,$r13   */
+
+  /* Disable  IPI interrupt.    */
+    0x142c,   /* lu12i.w    $r12,1(0x1) */
+    0x04001180,   /* csrxchg    $r0,$r12,0x4    */
+
+  /* Read mail buf and jump to specified entry */
+    0x142d,   /* lu12i.w    $r13,1(0x1) */
+    0x038081ad,   /* ori    $r13,$r13,0x20  */
+    0x06480dac,   /* iocsrrd.d  $r12,$r13   */
+    0x00150181,   /* move   $r1,$r12    */
+    0x4c20,   /* jirl   $r0,$r1,0   */
+};
+
  static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t 
addr)

  {
  return addr & MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS);
@@ -111,8 +159,15 @@ static void 
loongarch_firmware_boot(LoongArchMachineState *lams,

  fw_cfg_add_kernel_info(info, lams->fw_cfg);
  }
+static void init_boot_rom(struct loongarch_boot_info *info, void *p)
+{
+    memcpy(p, &slave_boot_code, sizeof(slave_boot_code));
+    p += sizeof(slave_boot_code);
+}
+
  static void loongarch_direct_kernel_boot(struct loongarch_boot_info 
*info)

  {
+    void  *p, *bp;
  int64_t kernel_addr = 0;
  LoongArchCPU *lacpu;
  CPUState *cs;
@@ -126,11 +181,24 @@ static void loongarch_direct_kernel_boot(struct 
loongarch_boot_info *info)

  }
  }
+    /* Load 'boot_rom' at [0 - 1MiB] */
+    p = g_malloc0(1 * MiB);
+    bp = p;
+    init_boot_rom(info, p);
+    rom_add_blob_fixed("boot_rom", bp, 1 * MiB, 0);
+
The secondary cpu waiting on the bootrom located memory address 
0x0-0x10.


Is it possible that primary cpu clears the memory located at bootrom
and then wakeup the secondary cpu?


I think it impossible,0-1M is ROM。

I am not sure whether it is ok if area between 0-1M is ROM.

For the memory map table, low memory area (0 - 256M) is still ddr ram.
And it is passed to kernel with fdt system table, rather than 
area(1-256M). Is that right?


There are some lines like this:
/* Node0 memory */
memmap_add_entry(VIRT_LOWMEM_BASE, VIRT_LOWMEM_SIZE, 1);

Regards
Bibo Mao



Thanks.
Song Gao

Regards
Bibo Mao


  CPU_FOREACH(cs) {
  lacpu = LOONGARCH_CPU(cs);
  lacpu->env.load_elf = true;
-    lacpu->env.elf_address = kernel_addr;
+    if (cs == first_cpu) {
+    lacpu->env.elf_address = kernel_addr;
+    } else {
+    lacpu->env.elf_address = 0;
+    }
+    lacpu->env.boot_info = info;
  }
+
+    g_free(bp);
  }
  void loongarch_load_kernel(MachineState *ms, struct 
loongarch_boot_info *info)







Re: [PATCH v6 17/17] hw/loongarch: Add cells missing from rtc node

2024-03-08 Thread maobibo




On 2024/3/8 上午12:48, Song Gao wrote:

rtc node need interrupts and interrupt-parent cells.

Signed-off-by: Song Gao 
Message-Id: <20240301093839.663947-18-gaos...@loongson.cn>
---
  hw/loongarch/virt.c | 12 +---
  1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 58957a8d9a..676f1f5227 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -231,7 +231,8 @@ static void fdt_add_flash_node(LoongArchMachineState *lams)
  g_free(nodename);
  }
  
-static void fdt_add_rtc_node(LoongArchMachineState *lams)

+static void fdt_add_rtc_node(LoongArchMachineState *lams,
+ uint32_t *pch_pic_phandle)
  {
  char *nodename;
  hwaddr base = VIRT_RTC_REG_BASE;
@@ -240,8 +241,13 @@ static void fdt_add_rtc_node(LoongArchMachineState *lams)
  
  nodename = g_strdup_printf("/rtc@%" PRIx64, base);

  qemu_fdt_add_subnode(ms->fdt, nodename);
-qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", 
"loongson,ls7a-rtc");
+qemu_fdt_setprop_string(ms->fdt, nodename, "compatible",
+"loongson,ls7a-rtc");
  qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", 2, base, 2, size);
+qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts",
+   VIRT_RTC_IRQ - VIRT_GSI_BASE , 0x4);
+qemu_fdt_setprop_cell(ms->fdt, nodename, "interrupt-parent",
+  *pch_pic_phandle);
  g_free(nodename);
  }
  
@@ -647,7 +653,7 @@ static void loongarch_devices_init(DeviceState *pch_pic,

  sysbus_create_simple("ls7a_rtc", VIRT_RTC_REG_BASE,
   qdev_get_gpio_in(pch_pic,
   VIRT_RTC_IRQ - VIRT_GSI_BASE));
-fdt_add_rtc_node(lams);
+fdt_add_rtc_node(lams, pch_pic_phandle);
  
  /* acpi ged */

  lams->acpi_ged = create_acpi_ged(pch_pic, lams);


Reviewed-by: Bibo Mao 




Re: [PATCH v6 16/17] hw/loongarch: Add cells missing from uart node

2024-03-08 Thread maobibo




On 2024/3/8 上午12:48, Song Gao wrote:

uart node need interrupts and interrupt-parent cells.

Signed-off-by: Song Gao 
Message-Id: <20240301093839.663947-17-gaos...@loongson.cn>
---
  hw/loongarch/virt.c | 9 +++--
  1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index c80732a223..58957a8d9a 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -245,7 +245,8 @@ static void fdt_add_rtc_node(LoongArchMachineState *lams)
  g_free(nodename);
  }
  
-static void fdt_add_uart_node(LoongArchMachineState *lams)

+static void fdt_add_uart_node(LoongArchMachineState *lams,
+  uint32_t *pch_pic_phandle)
  {
  char *nodename;
  hwaddr base = VIRT_UART_BASE;
@@ -258,6 +259,10 @@ static void fdt_add_uart_node(LoongArchMachineState *lams)
  qemu_fdt_setprop_cells(ms->fdt, nodename, "reg", 0x0, base, 0x0, size);
  qemu_fdt_setprop_cell(ms->fdt, nodename, "clock-frequency", 1);
  qemu_fdt_setprop_string(ms->fdt, "/chosen", "stdout-path", nodename);
+qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts",
+   VIRT_UART_IRQ - VIRT_GSI_BASE, 0x4);
+qemu_fdt_setprop_cell(ms->fdt, nodename, "interrupt-parent",
+  *pch_pic_phandle);
  g_free(nodename);
  }
  
@@ -629,7 +634,7 @@ static void loongarch_devices_init(DeviceState *pch_pic,

 qdev_get_gpio_in(pch_pic,
  VIRT_UART_IRQ - VIRT_GSI_BASE),
 115200, serial_hd(0), DEVICE_LITTLE_ENDIAN);
-fdt_add_uart_node(lams);
+fdt_add_uart_node(lams, pch_pic_phandle);
  
  /* Network init */

  pci_init_nic_devices(pci_bus, mc->default_nic);


Reviewed-by: Bibo Mao 




Re: [PATCH v6 14/17] hw/loongarch: fdt adds pcie irq_map node

2024-03-08 Thread maobibo




On 2024/3/8 上午12:48, Song Gao wrote:

Signed-off-by: Song Gao 
Message-Id: <20240301093839.663947-15-gaos...@loongson.cn>
---
  hw/loongarch/virt.c | 73 ++---
  1 file changed, 69 insertions(+), 4 deletions(-)

diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 1e767c49f8..d00343f0c2 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -352,7 +352,62 @@ static void fdt_add_fw_cfg_node(const 
LoongArchMachineState *lams)
  g_free(nodename);
  }
  
-static void fdt_add_pcie_node(const LoongArchMachineState *lams)

+static void fdt_add_pcie_irq_map_node(const LoongArchMachineState *lams,
+  char *nodename,
+  uint32_t *pch_pic_phandle)
+{
+int pin, dev;
+uint32_t irq_map_stride = 0;
+uint32_t full_irq_map[GPEX_NUM_IRQS *GPEX_NUM_IRQS * 10] = {};
+uint32_t *irq_map = full_irq_map;
+const MachineState *ms = MACHINE(lams);
+
+/* This code creates a standard swizzle of interrupts such that
+ * each device's first interrupt is based on it's PCI_SLOT number.
+ * (See pci_swizzle_map_irq_fn())
+ *
+ * We only need one entry per interrupt in the table (not one per
+ * possible slot) seeing the interrupt-map-mask will allow the table
+ * to wrap to any number of devices.
+ */
+
+for (dev = 0; dev < GPEX_NUM_IRQS; dev++) {
+int devfn = dev * 0x8;
+
+for (pin = 0; pin  < GPEX_NUM_IRQS; pin++) {
+int irq_nr = 16 + ((pin + PCI_SLOT(devfn)) % GPEX_NUM_IRQS);
+int i = 0;
+
+/* Fill PCI address cells */
+irq_map[i] = cpu_to_be32(devfn << 8);
+i += 3;
+
+/* Fill PCI Interrupt cells */
+irq_map[i] = cpu_to_be32(pin + 1);
+i += 1;
+
+/* Fill interrupt controller phandle and cells */
+irq_map[i++] = cpu_to_be32(*pch_pic_phandle);
+irq_map[i++] = cpu_to_be32(irq_nr);
+
+if (!irq_map_stride) {
+irq_map_stride = i;
+}
+irq_map += irq_map_stride;
+}
+}
+
+
+qemu_fdt_setprop(ms->fdt, nodename, "interrupt-map", full_irq_map,
+ GPEX_NUM_IRQS * GPEX_NUM_IRQS *
+ irq_map_stride * sizeof(uint32_t));
+qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupt-map-mask",
+ 0x1800, 0, 0, 0x7);
+}
+
+static void fdt_add_pcie_node(const LoongArchMachineState *lams,
+  uint32_t *pch_pic_phandle,
+  uint32_t *pch_msi_phandle)
  {
  char *nodename;
  hwaddr base_mmio = VIRT_PCI_MEM_BASE;
@@ -383,6 +438,11 @@ static void fdt_add_pcie_node(const LoongArchMachineState 
*lams)
   2, base_pio, 2, size_pio,
   1, FDT_PCI_RANGE_MMIO, 2, base_mmio,
   2, base_mmio, 2, size_mmio);
+qemu_fdt_setprop_cells(ms->fdt, nodename, "msi-map",
+   0, *pch_msi_phandle, 0, 0x1);
+
+fdt_add_pcie_irq_map_node(lams, nodename, pch_pic_phandle);
+
  g_free(nodename);
  }
  
@@ -541,7 +601,10 @@ static DeviceState *create_platform_bus(DeviceState *pch_pic)

  return dev;
  }
  
-static void loongarch_devices_init(DeviceState *pch_pic, LoongArchMachineState *lams)

+static void loongarch_devices_init(DeviceState *pch_pic,
+   LoongArchMachineState *lams,
+   uint32_t *pch_pic_phandle,
+   uint32_t *pch_msi_phandle)
  {
  MachineClass *mc = MACHINE_GET_CLASS(lams);
  DeviceState *gpex_dev;
@@ -587,6 +650,9 @@ static void loongarch_devices_init(DeviceState *pch_pic, 
LoongArchMachineState *
  gpex_set_irq_num(GPEX_HOST(gpex_dev), i, 16 + i);
  }
  
+/* Add pcie node */

+fdt_add_pcie_node(lams, pch_pic_phandle, pch_msi_phandle);
+
  serial_mm_init(get_system_memory(), VIRT_UART_BASE, 0,
 qdev_get_gpio_in(pch_pic,
  VIRT_UART_IRQ - VIRT_GSI_BASE),
@@ -733,7 +799,7 @@ static void loongarch_irq_init(LoongArchMachineState *lams)
  /* Add PCH MSI node */
  fdt_add_pch_msi_node(lams, &eiointc_phandle, &pch_msi_phandle);
  
-loongarch_devices_init(pch_pic, lams);

+loongarch_devices_init(pch_pic, lams, &pch_pic_phandle, &pch_msi_phandle);
  }
  
  static void loongarch_firmware_init(LoongArchMachineState *lams)

@@ -956,7 +1022,6 @@ static void loongarch_init(MachineState *machine)
  lams->powerdown_notifier.notify = virt_powerdown_req;
  qemu_register_powerdown_notifier(&lams->powerdown_notifier);
  
-fdt_add_pcie_node(lams);

  /*
   * Since lowmem region starts from 0 and Linux kernel legacy start address
   * at 2 MiB, FDT base address is located at 1 MiB to avoid NULL pointer


Reviewed-by: Bibo Ma

Re: [PATCH v6 15/17] hw/loongarch: fdt remove unused irqchip node

2024-03-08 Thread maobibo




On 2024/3/8 上午12:48, Song Gao wrote:

Signed-off-by: Song Gao 
Message-Id: <20240301093839.663947-16-gaos...@loongson.cn>
---
  hw/loongarch/virt.c | 31 +--
  1 file changed, 1 insertion(+), 30 deletions(-)

diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index d00343f0c2..c80732a223 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -446,34 +446,6 @@ static void fdt_add_pcie_node(const LoongArchMachineState 
*lams,
  g_free(nodename);
  }
  
-static void fdt_add_irqchip_node(LoongArchMachineState *lams)

-{
-MachineState *ms = MACHINE(lams);
-char *nodename;
-uint32_t irqchip_phandle;
-
-irqchip_phandle = qemu_fdt_alloc_phandle(ms->fdt);
-qemu_fdt_setprop_cell(ms->fdt, "/", "interrupt-parent", irqchip_phandle);
-
-nodename = g_strdup_printf("/intc@%lx", VIRT_IOAPIC_REG_BASE);
-qemu_fdt_add_subnode(ms->fdt, nodename);
-qemu_fdt_setprop_cell(ms->fdt, nodename, "#interrupt-cells", 3);
-qemu_fdt_setprop(ms->fdt, nodename, "interrupt-controller", NULL, 0);
-qemu_fdt_setprop_cell(ms->fdt, nodename, "#address-cells", 0x2);
-qemu_fdt_setprop_cell(ms->fdt, nodename, "#size-cells", 0x2);
-qemu_fdt_setprop(ms->fdt, nodename, "ranges", NULL, 0);
-
-qemu_fdt_setprop_string(ms->fdt, nodename, "compatible",
-"loongarch,ls7a");
-
-qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg",
- 2, VIRT_IOAPIC_REG_BASE,
- 2, PCH_PIC_ROUTE_ENTRY_OFFSET);
-
-qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle", irqchip_phandle);
-g_free(nodename);
-}
-
  static void fdt_add_memory_node(MachineState *ms,
  uint64_t base, uint64_t size, int node_id)
  {
@@ -1011,8 +983,7 @@ static void loongarch_init(MachineState *machine)
  
  /* Initialize the IO interrupt subsystem */

  loongarch_irq_init(lams);
-fdt_add_irqchip_node(lams);
-platform_bus_add_all_fdt_nodes(machine->fdt, "/intc",
+platform_bus_add_all_fdt_nodes(machine->fdt, "/platic",
 VIRT_PLATFORM_BUS_BASEADDRESS,
 VIRT_PLATFORM_BUS_SIZE,
 VIRT_PLATFORM_BUS_IRQ);


Reviewed-by: Bibo Mao 




Re: [PATCH v6 13/17] hw/loongarch: fdt adds pch_msi Controller

2024-03-08 Thread maobibo




On 2024/3/8 上午12:48, Song Gao wrote:

fdt adds pch msi controller, we use 'loongson,pch-msi-1.0'.

See:
https://github.com/torvalds/linux/blob/v6.7/drivers/irqchip/irq-loongson-pch-msi.c
https://lore.kernel.org/r/20200528152757.1028711-6-jiaxun.y...@flygoat.com

Signed-off-by: Song Gao 
Message-Id: <20240301093839.663947-14-gaos...@loongson.cn>
---
  hw/loongarch/virt.c| 33 -
  include/hw/pci-host/ls7a.h |  1 +
  2 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 2b7b653fc1..1e767c49f8 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -173,6 +173,34 @@ static void fdt_add_pch_pic_node(LoongArchMachineState 
*lams,
  g_free(nodename);
  }
  
+static void fdt_add_pch_msi_node(LoongArchMachineState *lams,

+ uint32_t *eiointc_phandle,
+ uint32_t *pch_msi_phandle)
+{
+MachineState *ms = MACHINE(lams);
+char *nodename;
+hwaddr pch_msi_base = VIRT_PCH_MSI_ADDR_LOW;
+hwaddr pch_msi_size = VIRT_PCH_MSI_SIZE;
+
+*pch_msi_phandle = qemu_fdt_alloc_phandle(ms->fdt);
+nodename = g_strdup_printf("/msi@%" PRIx64, pch_msi_base);
+qemu_fdt_add_subnode(ms->fdt, nodename);
+qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle", *pch_msi_phandle);
+qemu_fdt_setprop_string(ms->fdt, nodename, "compatible",
+"loongson,pch-msi-1.0");
+qemu_fdt_setprop_cells(ms->fdt, nodename, "reg",
+   0, pch_msi_base,
+   0, pch_msi_size);
+qemu_fdt_setprop(ms->fdt, nodename, "interrupt-controller", NULL, 0);
+qemu_fdt_setprop_cell(ms->fdt, nodename, "interrupt-parent",
+  *eiointc_phandle);
+qemu_fdt_setprop_cell(ms->fdt, nodename, "loongson,msi-base-vec",
+  VIRT_PCH_PIC_IRQ_NUM);
+qemu_fdt_setprop_cell(ms->fdt, nodename, "loongson,msi-num-vecs",
+  EXTIOI_IRQS - VIRT_PCH_PIC_IRQ_NUM);
+g_free(nodename);
+}
+
  static void fdt_add_flash_node(LoongArchMachineState *lams)
  {
  MachineState *ms = MACHINE(lams);
@@ -594,7 +622,7 @@ static void loongarch_irq_init(LoongArchMachineState *lams)
  CPULoongArchState *env;
  CPUState *cpu_state;
  int cpu, pin, i, start, num;
-uint32_t cpuintc_phandle, eiointc_phandle, pch_pic_phandle;
+uint32_t cpuintc_phandle, eiointc_phandle, pch_pic_phandle, 
pch_msi_phandle;
  
  /*

   * The connection of interrupts:
@@ -702,6 +730,9 @@ static void loongarch_irq_init(LoongArchMachineState *lams)
qdev_get_gpio_in(extioi, i + start));
  }
  
+/* Add PCH MSI node */

+fdt_add_pch_msi_node(lams, &eiointc_phandle, &pch_msi_phandle);
+
  loongarch_devices_init(pch_pic, lams);
  }
  
diff --git a/include/hw/pci-host/ls7a.h b/include/hw/pci-host/ls7a.h

index fe260f0183..cd7c9ec7bc 100644
--- a/include/hw/pci-host/ls7a.h
+++ b/include/hw/pci-host/ls7a.h
@@ -25,6 +25,7 @@
  #define VIRT_IOAPIC_REG_BASE (VIRT_PCH_REG_BASE)
  #define VIRT_PCH_MSI_ADDR_LOW0x2FF0UL
  #define VIRT_PCH_REG_SIZE0x400
+#define VIRT_PCH_MSI_SIZE0x8
  
  /*

   * GSI_BASE is hard-coded with 64 in linux kernel, else kernel fails to boot


Reviewed-by: Bibo Mao 




Re: [PATCH v6 12/17] hw/loongarch: fdt adds pch_pic Controller

2024-03-08 Thread maobibo




On 2024/3/8 上午12:48, Song Gao wrote:

fdt adds pch pic controller, we use 'loongson,pch-pic-1.0'

See:
https://github.com/torvalds/linux/blob/v6.7/drivers/irqchip/irq-loongson-pch-pic.c
https://lore.kernel.org/r/20200528152757.1028711-4-jiaxun.y...@flygoat.com

Signed-off-by: Song Gao 
Message-Id: <20240301093839.663947-13-gaos...@loongson.cn>
---
  hw/loongarch/virt.c| 30 +-
  include/hw/pci-host/ls7a.h |  1 +
  2 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 822f070c45..2b7b653fc1 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -148,6 +148,31 @@ static void fdt_add_eiointc_node(LoongArchMachineState 
*lams,
  g_free(nodename);
  }
  
+static void fdt_add_pch_pic_node(LoongArchMachineState *lams,

+ uint32_t *eiointc_phandle,
+ uint32_t *pch_pic_phandle)
+{
+MachineState *ms = MACHINE(lams);
+char *nodename;
+hwaddr pch_pic_base = VIRT_PCH_REG_BASE;
+hwaddr pch_pic_size = VIRT_PCH_REG_SIZE;
+
+*pch_pic_phandle = qemu_fdt_alloc_phandle(ms->fdt);
+nodename = g_strdup_printf("/platic@%" PRIx64, pch_pic_base);
+qemu_fdt_add_subnode(ms->fdt, nodename);
+qemu_fdt_setprop_cell(ms->fdt,  nodename, "phandle", *pch_pic_phandle);
+qemu_fdt_setprop_string(ms->fdt, nodename, "compatible",
+"loongson,pch-pic-1.0");
+qemu_fdt_setprop_cells(ms->fdt, nodename, "reg", 0,
+   pch_pic_base, 0, pch_pic_size);
+qemu_fdt_setprop(ms->fdt, nodename, "interrupt-controller", NULL, 0);
+qemu_fdt_setprop_cell(ms->fdt, nodename, "#interrupt-cells", 2);
+qemu_fdt_setprop_cell(ms->fdt, nodename, "interrupt-parent",
+  *eiointc_phandle);
+qemu_fdt_setprop_cell(ms->fdt, nodename, "loongson,pic-base-vec", 0);
+g_free(nodename);
+}
+
  static void fdt_add_flash_node(LoongArchMachineState *lams)
  {
  MachineState *ms = MACHINE(lams);
@@ -569,7 +594,7 @@ static void loongarch_irq_init(LoongArchMachineState *lams)
  CPULoongArchState *env;
  CPUState *cpu_state;
  int cpu, pin, i, start, num;
-uint32_t cpuintc_phandle, eiointc_phandle;
+uint32_t cpuintc_phandle, eiointc_phandle, pch_pic_phandle;
  
  /*

   * The connection of interrupts:
@@ -660,6 +685,9 @@ static void loongarch_irq_init(LoongArchMachineState *lams)
  qdev_connect_gpio_out(DEVICE(d), i, qdev_get_gpio_in(extioi, i));
  }
  
+/* Add PCH PIC node */

+fdt_add_pch_pic_node(lams, &eiointc_phandle, &pch_pic_phandle);
+
  pch_msi = qdev_new(TYPE_LOONGARCH_PCH_MSI);
  start   =  num;
  num = EXTIOI_IRQS - start;
diff --git a/include/hw/pci-host/ls7a.h b/include/hw/pci-host/ls7a.h
index e753449593..fe260f0183 100644
--- a/include/hw/pci-host/ls7a.h
+++ b/include/hw/pci-host/ls7a.h
@@ -24,6 +24,7 @@
  #define VIRT_PCH_REG_BASE0x1000UL
  #define VIRT_IOAPIC_REG_BASE (VIRT_PCH_REG_BASE)
  #define VIRT_PCH_MSI_ADDR_LOW0x2FF0UL
+#define VIRT_PCH_REG_SIZE0x400
  
  /*

   * GSI_BASE is hard-coded with 64 in linux kernel, else kernel fails to boot


Reviewed-by: Bibo Mao 




Re: [PATCH v6 11/17] hw/loongarch: fdt adds Extend I/O Interrupt Controller

2024-03-08 Thread maobibo




On 2024/3/8 上午12:48, Song Gao wrote:

fdt adds Extend I/O Interrupt Controller,
we use 'loongson,ls2k2000-eiointc'.

See:
https://github.com/torvalds/linux/blob/v6.7/drivers/irqchip/irq-loongson-eiointc.c
https://lore.kernel.org/r/764e02d924094580ac0f1d15535f4b98308705c6.1683279769.git.zhoubin...@loongson.cn

Signed-off-by: Song Gao 
Message-Id: <20240301093839.663947-12-gaos...@loongson.cn>
---
  hw/loongarch/virt.c| 30 +-
  include/hw/intc/loongarch_extioi.h |  1 +
  2 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index d260f933a5..822f070c45 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -123,6 +123,31 @@ static void fdt_add_cpuic_node(LoongArchMachineState *lams,
  g_free(nodename);
  }
  
+static void fdt_add_eiointc_node(LoongArchMachineState *lams,

+  uint32_t *cpuintc_phandle,
+  uint32_t *eiointc_phandle)
+{
+MachineState *ms = MACHINE(lams);
+char *nodename;
+hwaddr extioi_base = APIC_BASE;
+hwaddr extioi_size = EXTIOI_SIZE;
+
+*eiointc_phandle = qemu_fdt_alloc_phandle(ms->fdt);
+nodename = g_strdup_printf("/eiointc@%" PRIx64, extioi_base);
+qemu_fdt_add_subnode(ms->fdt, nodename);
+qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle", *eiointc_phandle);
+qemu_fdt_setprop_string(ms->fdt, nodename, "compatible",
+"loongson,ls2k2000-eiointc");
+qemu_fdt_setprop(ms->fdt, nodename, "interrupt-controller", NULL, 0);
+qemu_fdt_setprop_cell(ms->fdt, nodename, "#interrupt-cells", 1);
+qemu_fdt_setprop_cell(ms->fdt, nodename, "interrupt-parent",
+  *cpuintc_phandle);
+qemu_fdt_setprop_cell(ms->fdt, nodename, "interrupts", 3);
+qemu_fdt_setprop_cells(ms->fdt, nodename, "reg", 0x0,
+   extioi_base, 0x0, extioi_size);
+g_free(nodename);
+}
+
  static void fdt_add_flash_node(LoongArchMachineState *lams)
  {
  MachineState *ms = MACHINE(lams);
@@ -544,7 +569,7 @@ static void loongarch_irq_init(LoongArchMachineState *lams)
  CPULoongArchState *env;
  CPUState *cpu_state;
  int cpu, pin, i, start, num;
-uint32_t cpuintc_phandle;
+uint32_t cpuintc_phandle, eiointc_phandle;
  
  /*

   * The connection of interrupts:
@@ -613,6 +638,9 @@ static void loongarch_irq_init(LoongArchMachineState *lams)
  }
  }
  
+/* Add Extend I/O Interrupt Controller node */

+fdt_add_eiointc_node(lams, &cpuintc_phandle, &eiointc_phandle);
+
  pch_pic = qdev_new(TYPE_LOONGARCH_PCH_PIC);
  num = VIRT_PCH_PIC_IRQ_NUM;
  qdev_prop_set_uint32(pch_pic, "pch_pic_irq_num", num);
diff --git a/include/hw/intc/loongarch_extioi.h 
b/include/hw/intc/loongarch_extioi.h
index a0a46b888c..410c6e1121 100644
--- a/include/hw/intc/loongarch_extioi.h
+++ b/include/hw/intc/loongarch_extioi.h
@@ -39,6 +39,7 @@
  #define EXTIOI_COREISR_END   (0xB20 - APIC_OFFSET)
  #define EXTIOI_COREMAP_START (0xC00 - APIC_OFFSET)
  #define EXTIOI_COREMAP_END   (0xD00 - APIC_OFFSET)
+#define EXTIOI_SIZE  0x800
  
  typedef struct ExtIOICore {

  uint32_t coreisr[EXTIOI_IRQS_GROUP_COUNT];


Reviewed-by: Bibo Mao 




Re: [PATCH v6 10/17] hw/loongarch: fdt adds cpu interrupt controller node

2024-03-08 Thread maobibo




On 2024/3/8 上午12:48, Song Gao wrote:

fdt adds cpu interrupt controller node,
we use 'loongson,cpu-interrupt-controller'.

See:
https://github.com/torvalds/linux/blob/v6.7/drivers/irqchip/irq-loongarch-cpu.c
https://lore.kernel.org/r/20221114113824.1880-2-liupei...@loongson.cn

Signed-off-by: Song Gao 
Message-Id: <20240301093839.663947-11-gaos...@loongson.cn>
---
  hw/loongarch/virt.c | 21 +
  1 file changed, 21 insertions(+)

diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 10fdfec5dd..d260f933a5 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -106,6 +106,23 @@ static void virt_flash_map(LoongArchMachineState *lams,
  virt_flash_map1(flash1, VIRT_FLASH1_BASE, VIRT_FLASH1_SIZE, sysmem);
  }
  
+static void fdt_add_cpuic_node(LoongArchMachineState *lams,

+   uint32_t *cpuintc_phandle)
+{
+MachineState *ms = MACHINE(lams);
+char *nodename;
+
+*cpuintc_phandle = qemu_fdt_alloc_phandle(ms->fdt);
+nodename = g_strdup_printf("/cpuic");
+qemu_fdt_add_subnode(ms->fdt, nodename);
+qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle", *cpuintc_phandle);
+qemu_fdt_setprop_string(ms->fdt, nodename, "compatible",
+"loongson,cpu-interrupt-controller");
+qemu_fdt_setprop(ms->fdt, nodename, "interrupt-controller", NULL, 0);
+qemu_fdt_setprop_cell(ms->fdt, nodename, "#interrupt-cells", 1);
+g_free(nodename);
+}
+
  static void fdt_add_flash_node(LoongArchMachineState *lams)
  {
  MachineState *ms = MACHINE(lams);
@@ -527,6 +544,7 @@ static void loongarch_irq_init(LoongArchMachineState *lams)
  CPULoongArchState *env;
  CPUState *cpu_state;
  int cpu, pin, i, start, num;
+uint32_t cpuintc_phandle;
  
  /*

   * The connection of interrupts:
@@ -561,6 +579,9 @@ static void loongarch_irq_init(LoongArchMachineState *lams)
  memory_region_add_subregion(&lams->system_iocsr, MAIL_SEND_ADDR,
 sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 1));
  
+/* Add cpu interrupt-controller */

+fdt_add_cpuic_node(lams, &cpuintc_phandle);
+
  for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
  cpu_state = qemu_get_cpu(cpu);
  cpudev = DEVICE(cpu_state);


Reviewed-by: Bibo Mao 




Re: [PATCH v6 09/17] hw/loongarch: Fix fdt memory node wrong 'reg'

2024-03-08 Thread maobibo




On 2024/3/8 上午12:48, Song Gao wrote:

The right fdt memory node like [1], not [2]

   [1]
 memory@0 {
 device_type = "memory";
 reg = <0x00 0x00 0x00 0x1000>;
 };
   [2]
 memory@0 {
 device_type = "memory";
 reg = <0x02 0x00 0x02 0x1000>;
 };

Reviewed-by: Bibo Mao 
Signed-off-by: Song Gao 
Message-Id: <20240301093839.663947-10-gaos...@loongson.cn>
---
  hw/loongarch/virt.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 8981b57b12..10fdfec5dd 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -325,7 +325,7 @@ static void fdt_add_memory_node(MachineState *ms,
  char *nodename = g_strdup_printf("/memory@%" PRIx64, base);
  
  qemu_fdt_add_subnode(ms->fdt, nodename);

-qemu_fdt_setprop_cells(ms->fdt, nodename, "reg", 2, base, 2, size);
+qemu_fdt_setprop_cells(ms->fdt, nodename, "reg", 0, base, 0, size);
  qemu_fdt_setprop_string(ms->fdt, nodename, "device_type", "memory");
  
  if (ms->numa_state && ms->numa_state->num_nodes) {



Reviewed-by: Bibo Mao 




Re: [PATCH v6 08/17] hw/loongarch: Init efi_fdt table

2024-03-08 Thread maobibo




On 2024/3/8 上午12:48, Song Gao wrote:

Signed-off-by: Song Gao 
Message-Id: <20240301093839.663947-9-gaos...@loongson.cn>
---
  hw/loongarch/boot.c | 11 +++
  include/hw/loongarch/boot.h |  4 
  2 files changed, 15 insertions(+)

diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
index 6126a37858..c6c6e6d194 100644
--- a/hw/loongarch/boot.c
+++ b/hw/loongarch/boot.c
@@ -112,6 +112,16 @@ static void init_efi_initrd_table(struct efi_system_table 
*systab,
  initrd_table->size = initrd_size;
  }
  
+static void init_efi_fdt_table(struct efi_system_table *systab)

+{
+efi_guid_t tbl_guid = DEVICE_TREE_GUID;
+
+/* efi_configuration_table 3 */
+guidcpy(&systab->tables[2].guid, &tbl_guid);
+systab->tables[2].table = (void *)0x10; /* fdt_base 1MiB */

Can we use macro for 0x10?

otherwise LGTM
Reviewed-by: Bibo Mao 


+systab->nr_tables = 3;
+}
+
  static void init_systab(struct loongarch_boot_info *info, void *p, void 
*start)
  {
  void *bp_tables_start;
@@ -137,6 +147,7 @@ static void init_systab(struct loongarch_boot_info *info, 
void *p, void *start)
sizeof(efi_memory_desc_t) * memmap_entries, 64);
  init_efi_initrd_table(systab, p, start);
  p += ROUND_UP(sizeof(struct efi_initrd), 64);
+init_efi_fdt_table(systab);
  
  systab->tables = (struct efi_configuration_table *)(bp_tables_start - start);

  }
diff --git a/include/hw/loongarch/boot.h b/include/hw/loongarch/boot.h
index ddcb279874..9de673a0fd 100644
--- a/include/hw/loongarch/boot.h
+++ b/include/hw/loongarch/boot.h
@@ -34,6 +34,10 @@ typedef struct {
  EFI_GUID(0x5568e427, 0x68fc, 0x4f3d,  0xac, 0x74, \
   0xca, 0x55, 0x52, 0x31, 0xcc, 0x68)
  
+#define DEVICE_TREE_GUID \

+EFI_GUID(0xb1b621d5, 0xf19c, 0x41a5,  0x83, 0x0b, \
+ 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0)
+
  struct efi_config_table {
  efi_guid_t guid;
  uint64_t *ptr;






Re: [PATCH v6 07/17] hw/loongarch: Init efi_initrd table

2024-03-08 Thread maobibo




On 2024/3/8 上午12:48, Song Gao wrote:

Signed-off-by: Song Gao 
Message-Id: <20240301093839.663947-8-gaos...@loongson.cn>
---
  hw/loongarch/boot.c | 23 +--
  include/hw/loongarch/boot.h |  9 +
  2 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
index 2896c1ea40..6126a37858 100644
--- a/hw/loongarch/boot.c
+++ b/hw/loongarch/boot.c
@@ -15,6 +15,9 @@
  #include "sysemu/reset.h"
  #include "sysemu/qtest.h"
  
+ram_addr_t initrd_offset;

+uint64_t initrd_size;
+
  static const unsigned int slave_boot_code[] = {
/* Configure reset ebase. */
  0x0400302c,   /* csrwr  $r12,0xc*/
@@ -94,6 +97,21 @@ static void init_efi_boot_memmap(struct efi_system_table 
*systab,
  }
  }
  
+static void init_efi_initrd_table(struct efi_system_table *systab,

+  void *p, void *start)
+{
+efi_guid_t tbl_guid = LINUX_EFI_INITRD_MEDIA_GUID;
+struct efi_initrd *initrd_table  = p;
+
+/* efi_configuration_table 2 */
+guidcpy(&systab->tables[1].guid, &tbl_guid);
+systab->tables[1].table = (struct efi_configuration_table *)(p - start);
+systab->nr_tables = 2;
+
+initrd_table->base = initrd_offset;
+initrd_table->size = initrd_size;
+}
+
  static void init_systab(struct loongarch_boot_info *info, void *p, void 
*start)
  {
  void *bp_tables_start;
@@ -117,6 +135,8 @@ static void init_systab(struct loongarch_boot_info *info, 
void *p, void *start)
  init_efi_boot_memmap(systab, p, start);
  p += ROUND_UP(sizeof(struct efi_boot_memmap) +
sizeof(efi_memory_desc_t) * memmap_entries, 64);
+init_efi_initrd_table(systab, p, start);
+p += ROUND_UP(sizeof(struct efi_initrd), 64);
  
  systab->tables = (struct efi_configuration_table *)(bp_tables_start - start);

  }
@@ -138,8 +158,7 @@ static uint64_t cpu_loongarch_virt_to_phys(void *opaque, 
uint64_t addr)
  
  static int64_t load_kernel_info(struct loongarch_boot_info *info)

  {
-uint64_t kernel_entry, kernel_low, kernel_high, initrd_size;
-ram_addr_t initrd_offset;
+uint64_t kernel_entry, kernel_low, kernel_high;
  ssize_t kernel_size;
  
  kernel_size = load_elf(info->kernel_filename, NULL,

diff --git a/include/hw/loongarch/boot.h b/include/hw/loongarch/boot.h
index f71c693f43..ddcb279874 100644
--- a/include/hw/loongarch/boot.h
+++ b/include/hw/loongarch/boot.h
@@ -30,6 +30,10 @@ typedef struct {
  EFI_GUID(0x800f683f, 0xd08b, 0x423a,  0xa2, 0x93, \
   0x96, 0x5c, 0x3c, 0x6f, 0xe2, 0xb4)
  
+#define LINUX_EFI_INITRD_MEDIA_GUID \

+EFI_GUID(0x5568e427, 0x68fc, 0x4f3d,  0xac, 0x74, \
+ 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68)
+
  struct efi_config_table {
  efi_guid_t guid;
  uint64_t *ptr;
@@ -83,6 +87,11 @@ struct efi_boot_memmap {
  efi_memory_desc_t map[32];
  };
  
+struct efi_initrd {

+uint64_t base;
+uint64_t size;
+};
+
  struct loongarch_boot_info {
  uint64_t ram_size;
  const char *kernel_filename;


Reviewed-by: Bibo Mao 




Re: [PATCH v6 06/17] hw/loongarch: Init efi_boot_memmap table

2024-03-08 Thread maobibo




On 2024/3/8 上午12:48, Song Gao wrote:

Signed-off-by: Song Gao 
Message-Id: <20240301093839.663947-7-gaos...@loongson.cn>
---
  hw/loongarch/boot.c | 39 +
  hw/loongarch/virt.c | 11 ++-
  include/hw/loongarch/boot.h | 27 +
  include/hw/loongarch/virt.h | 10 ++
  4 files changed, 78 insertions(+), 9 deletions(-)

diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
index 1e31e2a59f..2896c1ea40 100644
--- a/hw/loongarch/boot.c
+++ b/hw/loongarch/boot.c
@@ -63,8 +63,40 @@ static const unsigned int slave_boot_code[] = {
  0x4c20,   /* jirl   $r0,$r1,0   */
  };
  
+static inline void *guidcpy(void *dst, const void *src)

+{
+return memcpy(dst, src, sizeof(efi_guid_t));
+}
+
+static void init_efi_boot_memmap(struct efi_system_table *systab,
+ void *p, void *start)
+{
+unsigned i;
+struct efi_boot_memmap *boot_memmap = p;
+efi_guid_t tbl_guid = LINUX_EFI_BOOT_MEMMAP_GUID;
+
+/* efi_configuration_table 1 */
+guidcpy(&systab->tables[0].guid, &tbl_guid);
+systab->tables[0].table = (struct efi_configuration_table *)(p - start);
+systab->nr_tables = 1;
+
+boot_memmap->desc_size = sizeof(efi_memory_desc_t);
+boot_memmap->desc_ver = 1;
+boot_memmap->map_size = 0;
+
+efi_memory_desc_t *map = p + sizeof(struct efi_boot_memmap);
+for (i = 0; i < memmap_entries; i++) {
+map = (void *)boot_memmap + sizeof(*map);
+map[i].type = memmap_table[i].type;
+map[i].phys_addr = memmap_table[i].address;
+map[i].num_pages = memmap_table[i].length >> 16; /* 64KB align*/

64KB aligned or 64KB page size? In generic page size is 4K by EFI spec IIRC.

Regards
Bibo Mao


+p += sizeof(efi_memory_desc_t);
+}
+}
+
  static void init_systab(struct loongarch_boot_info *info, void *p, void 
*start)
  {
+void *bp_tables_start;
  struct efi_system_table *systab = p;
  
  info->a2 = (uint64_t)p - (uint64_t)start;

@@ -80,6 +112,13 @@ static void init_systab(struct loongarch_boot_info *info, 
void *p, void *start)
  p += ROUND_UP(sizeof(struct efi_system_table), 64);
  
  systab->tables = p;

+bp_tables_start = p;
+
+init_efi_boot_memmap(systab, p, start);
+p += ROUND_UP(sizeof(struct efi_boot_memmap) +
+  sizeof(efi_memory_desc_t) * memmap_entries, 64);
+
+systab->tables = (struct efi_configuration_table *)(bp_tables_start - 
start);
  }
  
  static void init_cmdline(struct loongarch_boot_info *info, void *p, void *start)

diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index bbd5cc1d4d..8981b57b12 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -377,15 +377,8 @@ static void virt_powerdown_req(Notifier *notifier, void 
*opaque)
  acpi_send_event(s->acpi_ged, ACPI_POWER_DOWN_STATUS);
  }
  
-struct memmap_entry {

-uint64_t address;
-uint64_t length;
-uint32_t type;
-uint32_t reserved;
-};
-
-static struct memmap_entry *memmap_table;
-static unsigned memmap_entries;
+struct memmap_entry *memmap_table;
+unsigned memmap_entries;
  
  static void memmap_add_entry(uint64_t address, uint64_t length, uint32_t type)

  {
diff --git a/include/hw/loongarch/boot.h b/include/hw/loongarch/boot.h
index 65ad406f02..f71c693f43 100644
--- a/include/hw/loongarch/boot.h
+++ b/include/hw/loongarch/boot.h
@@ -21,6 +21,15 @@ typedef struct {
  uint8_t b[16];
  } efi_guid_t __attribute__((aligned(8)));
  
+#define EFI_GUID(a, b, c, d...) (efi_guid_t){ {\

+(a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, 
\
+(b) & 0xff, ((b) >> 8) & 0xff, 
\
+(c) & 0xff, ((c) >> 8) & 0xff, d } }
+
+#define LINUX_EFI_BOOT_MEMMAP_GUID \
+EFI_GUID(0x800f683f, 0xd08b, 0x423a,  0xa2, 0x93, \
+ 0x96, 0x5c, 0x3c, 0x6f, 0xe2, 0xb4)
+
  struct efi_config_table {
  efi_guid_t guid;
  uint64_t *ptr;
@@ -56,6 +65,24 @@ struct efi_system_table {
  struct efi_configuration_table *tables;
  };
  
+typedef struct {

+uint32_t type;
+uint32_t pad;
+uint64_t phys_addr;
+uint64_t virt_addr;
+uint64_t num_pages;
+uint64_t attribute;
+} efi_memory_desc_t;
+
+struct efi_boot_memmap {
+uint64_t map_size;
+uint64_t desc_size;
+uint32_t desc_ver;
+uint64_t map_key;
+uint64_t buff_size;
+efi_memory_desc_t map[32];
+};
+
  struct loongarch_boot_info {
  uint64_t ram_size;
  const char *kernel_filename;
diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
index d7a074d69f..8a9fe4053d 100644
--- a/include/hw/loongarch/virt.h
+++ b/include/hw/loongarch/virt.h
@@ -35,6 +35,16 @@
  
  #define COMMAND_LINE_SIZE   512
  
+extern struct memmap_entry *memmap_table;

+extern unsigned memmap_entries;
+
+struct memmap_entry {
+uint64_t address;
+uint64_t le

Re: [PATCH v6 05/17] hw/loongarch: Init efi_system_table

2024-03-08 Thread maobibo




On 2024/3/8 上午12:48, Song Gao wrote:

Add init_systab and set boot_info->a2

Signed-off-by: Song Gao 
Message-Id: <20240301093839.663947-6-gaos...@loongson.cn>
---
  hw/loongarch/boot.c | 22 +
  include/hw/loongarch/boot.h | 48 +
  2 files changed, 70 insertions(+)

diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
index ca65dfde07..1e31e2a59f 100644
--- a/hw/loongarch/boot.c
+++ b/hw/loongarch/boot.c
@@ -63,6 +63,25 @@ static const unsigned int slave_boot_code[] = {
  0x4c20,   /* jirl   $r0,$r1,0   */
  };
  
+static void init_systab(struct loongarch_boot_info *info, void *p, void *start)

+{
+struct efi_system_table *systab = p;
+
+info->a2 = (uint64_t)p - (uint64_t)start;
+
+systab->hdr.signature = EFI_SYSTEM_TABLE_SIGNATURE;
+systab->hdr.revision = EFI_SPECIFICATION_VERSION;
+systab->hdr.revision = sizeof(struct efi_system_table),
+systab->fw_revision = FW_VERSION << 16 | FW_PATCHLEVEL << 8;
+systab->runtime = 0;
+systab->boottime = 0;
+systab->nr_tables = 0;
+
+p += ROUND_UP(sizeof(struct efi_system_table), 64);
+
+systab->tables = p;
+}
+
  static void init_cmdline(struct loongarch_boot_info *info, void *p, void 
*start)
  {
  hwaddr cmdline_addr = (hwaddr)p - (hwaddr)start;
@@ -135,6 +154,7 @@ static void reset_load_elf(void *opaque)
if (cpu == LOONGARCH_CPU(first_cpu)) {
  env->gpr[4] = env->boot_info->a0;
  env->gpr[5] = env->boot_info->a1;
+env->gpr[6] = env->boot_info->a2;
  }
  cpu_set_pc(CPU(cpu), env->elf_address);
  }
@@ -182,6 +202,8 @@ static void init_boot_rom(struct loongarch_boot_info *info, 
void *p)
  
  init_cmdline(info, p, start);

  p += COMMAND_LINE_SIZE;
+
+init_systab(info, p, start);
  }
  
  static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info)

diff --git a/include/hw/loongarch/boot.h b/include/hw/loongarch/boot.h
index 3275c1e295..65ad406f02 100644
--- a/include/hw/loongarch/boot.h
+++ b/include/hw/loongarch/boot.h
@@ -8,6 +8,54 @@
  #ifndef HW_LOONGARCH_BOOT_H
  #define HW_LOONGARCH_BOOT_H
  
+/* UEFI 2.10 */

+#define EFI_SYSTEM_TABLE_SIGNATURE   0x5453595320494249
+#define EFI_2_100_SYSTEM_TABLE_REVISION  ((2<<16) | (100))
+#define EFI_SPECIFICATION_VERSIONEFI_SYSTEM_TABLE_REVISION
+#define EFI_SYSTEM_TABLE_REVISIONEFI_2_100_SYSTEM_TABLE_REVISION
+
+#define FW_VERSION 0x1
+#define FW_PATCHLEVEL 0x0
+
+typedef struct {
+uint8_t b[16];
+} efi_guid_t __attribute__((aligned(8)));
+
+struct efi_config_table {
+efi_guid_t guid;
+uint64_t *ptr;
+const char name[16];
+};
+
+typedef struct {
+uint64_t signature;
+uint32_t revision;
+uint32_t headersize;
+uint32_t crc32;
+uint32_t reserved;
+} efi_table_hdr_t;
+
+struct efi_configuration_table {
+efi_guid_t guid;
+void *table;
+};
+
+struct efi_system_table {
+efi_table_hdr_t hdr;
+uint64_t fw_vendor;/* physical addr of CHAR16 vendor string */
+uint32_t fw_revision;
+uint64_t con_in_handle;
+uint64_t *con_in;
+uint64_t con_out_handle;
+uint64_t *con_out;
+uint64_t stderr_handle;
+uint64_t stderr_placeholder;
+uint64_t *runtime;
+uint64_t *boottime;
+uint64_t nr_tables;
+struct efi_configuration_table *tables;
+};
+
  struct loongarch_boot_info {
  uint64_t ram_size;
  const char *kernel_filename;


Reviewed-by: Bibo Mao 




Re: [PATCH v6 04/17] hw/loongarch: Add init_cmdline

2024-03-08 Thread maobibo




On 2024/3/8 上午12:48, Song Gao wrote:

Add init_cmline and set boot_info->a0, a1

Signed-off-by: Song Gao 
Message-Id: <20240301093839.663947-5-gaos...@loongson.cn>
---
  hw/loongarch/boot.c | 19 +++
  include/hw/loongarch/virt.h |  2 ++
  target/loongarch/cpu.h  |  2 ++
  3 files changed, 23 insertions(+)

diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
index e560ac178a..ca65dfde07 100644
--- a/hw/loongarch/boot.c
+++ b/hw/loongarch/boot.c
@@ -63,6 +63,16 @@ static const unsigned int slave_boot_code[] = {
  0x4c20,   /* jirl   $r0,$r1,0   */
  };
  
+static void init_cmdline(struct loongarch_boot_info *info, void *p, void *start)

+{
+hwaddr cmdline_addr = (hwaddr)p - (hwaddr)start;
+
+info->a0 = 1;
+info->a1 = cmdline_addr;
+
+memcpy(p, info->kernel_cmdline, COMMAND_LINE_SIZE);
+}
+
  static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr)
  {
  return addr & MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS);
@@ -122,6 +132,10 @@ static void reset_load_elf(void *opaque)
  
  cpu_reset(CPU(cpu));

  if (env->load_elf) {
+   if (cpu == LOONGARCH_CPU(first_cpu)) {
+env->gpr[4] = env->boot_info->a0;
+env->gpr[5] = env->boot_info->a1;
+}
  cpu_set_pc(CPU(cpu), env->elf_address);
  }
  }
@@ -161,8 +175,13 @@ static void loongarch_firmware_boot(LoongArchMachineState 
*lams,
  
  static void init_boot_rom(struct loongarch_boot_info *info, void *p)

  {
+void *start = p;
+
  memcpy(p, &slave_boot_code, sizeof(slave_boot_code));
  p += sizeof(slave_boot_code);
+
+init_cmdline(info, p, start);
+p += COMMAND_LINE_SIZE;
  }
  
  static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info)

diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
index cf2f2bfb19..d7a074d69f 100644
--- a/include/hw/loongarch/virt.h
+++ b/include/hw/loongarch/virt.h
@@ -33,6 +33,8 @@
  #define VIRT_GED_MEM_ADDR   (VIRT_GED_EVT_ADDR + ACPI_GED_EVT_SEL_LEN)
  #define VIRT_GED_REG_ADDR   (VIRT_GED_MEM_ADDR + MEMORY_HOTPLUG_IO_LEN)
  
+#define COMMAND_LINE_SIZE   512

+
  struct LoongArchMachineState {
  /*< private >*/
  MachineState parent_obj;
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index ec37579fd6..ce02ef3979 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -361,6 +361,8 @@ typedef struct CPUArchState {
  uint32_t mp_state;
  /* Store ipistate to access from this struct */
  DeviceState *ipistate;
+
+struct loongarch_boot_info *boot_info;
  #endif
  } CPULoongArchState;
  


Reviewed-by: Bibo Mao 




Re: [PATCH v6 03/17] hw/loongarch: Add slave cpu boot_code

2024-03-08 Thread maobibo




On 2024/3/8 上午12:48, Song Gao wrote:

Signed-off-by: Song Gao 
Message-Id: <20240301093839.663947-4-gaos...@loongson.cn>
---
  hw/loongarch/boot.c | 70 -
  1 file changed, 69 insertions(+), 1 deletion(-)

diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
index 149deb2e01..e560ac178a 100644
--- a/hw/loongarch/boot.c
+++ b/hw/loongarch/boot.c
@@ -15,6 +15,54 @@
  #include "sysemu/reset.h"
  #include "sysemu/qtest.h"
  
+static const unsigned int slave_boot_code[] = {

+  /* Configure reset ebase. */
+0x0400302c,   /* csrwr  $r12,0xc*/
+
+  /* Disable interrupt. */
+0x0380100c,   /* ori$r12,$r0,0x4*/
+0x04000180,   /* csrxchg$r0,$r12,0x0*/
+
+  /* Clear mailbox. */
+0x142d,   /* lu12i.w$r13,1(0x1) */
+0x038081ad,   /* ori$r13,$r13,0x20  */
+0x06481da0,   /* iocsrwr.d  $r0,$r13*/
+
+  /* Enable IPI interrupt.  */
+0x142c,   /* lu12i.w$r12,1(0x1) */
+0x0400118c,   /* csrxchg$r12,$r12,0x4   */
+0x02fffc0c,   /* addi.d $r12,$r0,-1(0xfff)  */
+0x142d,   /* lu12i.w$r13,1(0x1) */
+0x038011ad,   /* ori$r13,$r13,0x4   */
+0x064819ac,   /* iocsrwr.w  $r12,$r13   */
+0x142d,   /* lu12i.w$r13,1(0x1) */
+0x038081ad,   /* ori$r13,$r13,0x20  */
+
+  /* Wait for wakeup  <.L11>:   */
+0x06488000,   /* idle   0x0 */
+0x0340,   /* andi   $r0,$r0,0x0 */
+0x064809ac,   /* iocsrrd.w  $r12,$r13   */
+0x43fff59f,   /* beqz   $r12,-12(0x74) # 48 <.L11> */
+
+  /* Read and clear IPI interrupt.  */
+0x142d,   /* lu12i.w$r13,1(0x1) */
+0x064809ac,   /* iocsrrd.w  $r12,$r13   */
+0x142d,   /* lu12i.w$r13,1(0x1) */
+0x038031ad,   /* ori$r13,$r13,0xc   */
+0x064819ac,   /* iocsrwr.w  $r12,$r13   */
+
+  /* Disable  IPI interrupt.*/
+0x142c,   /* lu12i.w$r12,1(0x1) */
+0x04001180,   /* csrxchg$r0,$r12,0x4*/
+
+  /* Read mail buf and jump to specified entry */
+0x142d,   /* lu12i.w$r13,1(0x1) */
+0x038081ad,   /* ori$r13,$r13,0x20  */
+0x06480dac,   /* iocsrrd.d  $r12,$r13   */
+0x00150181,   /* move   $r1,$r12*/
+0x4c20,   /* jirl   $r0,$r1,0   */
+};
+
  static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr)
  {
  return addr & MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS);
@@ -111,8 +159,15 @@ static void loongarch_firmware_boot(LoongArchMachineState 
*lams,
  fw_cfg_add_kernel_info(info, lams->fw_cfg);
  }
  
+static void init_boot_rom(struct loongarch_boot_info *info, void *p)

+{
+memcpy(p, &slave_boot_code, sizeof(slave_boot_code));
+p += sizeof(slave_boot_code);
+}
+
  static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info)
  {
+void  *p, *bp;
  int64_t kernel_addr = 0;
  LoongArchCPU *lacpu;
  CPUState *cs;
@@ -126,11 +181,24 @@ static void loongarch_direct_kernel_boot(struct 
loongarch_boot_info *info)
  }
  }
  
+/* Load 'boot_rom' at [0 - 1MiB] */

+p = g_malloc0(1 * MiB);
+bp = p;
+init_boot_rom(info, p);
+rom_add_blob_fixed("boot_rom", bp, 1 * MiB, 0);
+
The secondary cpu waiting on the bootrom located memory address 
0x0-0x10.


Is it possible that primary cpu clears the memory located at bootrom
and then wakeup the secondary cpu?

Regards
Bibo Mao


  CPU_FOREACH(cs) {
  lacpu = LOONGARCH_CPU(cs);
  lacpu->env.load_elf = true;
-lacpu->env.elf_address = kernel_addr;
+if (cs == first_cpu) {
+lacpu->env.elf_address = kernel_addr;
+} else {
+lacpu->env.elf_address = 0;
+}
+lacpu->env.boot_info = info;
  }
+
+g_free(bp);
  }
  
  void loongarch_load_kernel(MachineState *ms, struct loongarch_boot_info *info)







Re: [PATCH v6 02/17] hw/loongarch: Add load initrd

2024-03-08 Thread maobibo




On 2024/3/8 上午12:48, Song Gao wrote:

we load initrd ramdisk after kernel_high address

Signed-off-by: Song Gao 
Message-Id: <20240301093839.663947-3-gaos...@loongson.cn>
---
  hw/loongarch/boot.c | 29 -
  1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
index a8a725a0a8..149deb2e01 100644
--- a/hw/loongarch/boot.c
+++ b/hw/loongarch/boot.c
@@ -22,7 +22,8 @@ static uint64_t cpu_loongarch_virt_to_phys(void *opaque, 
uint64_t addr)
  
  static int64_t load_kernel_info(struct loongarch_boot_info *info)

  {
-uint64_t kernel_entry, kernel_low, kernel_high;
+uint64_t kernel_entry, kernel_low, kernel_high, initrd_size;
+ram_addr_t initrd_offset;
  ssize_t kernel_size;
  
  kernel_size = load_elf(info->kernel_filename, NULL,

@@ -37,6 +38,32 @@ static int64_t load_kernel_info(struct loongarch_boot_info 
*info)
   load_elf_strerror(kernel_size));
  exit(1);
  }
+
+if (info->initrd_filename) {
+initrd_size = get_image_size(info->initrd_filename);
+if (initrd_size > 0) {
+initrd_offset = ROUND_UP(kernel_high + 4 * kernel_size, 64 * KiB);
+
+if (initrd_offset + initrd_size > info->ram_size) {
+error_report("memory too small for initial ram disk '%s'",
+ info->initrd_filename);
+exit(1);
+}
+
+initrd_size = load_image_targphys(info->initrd_filename, 
initrd_offset,
+  info->ram_size - initrd_offset);
+}
+
+if (initrd_size == (target_ulong)-1) {
+error_report("could not load initial ram disk '%s'",
+ info->initrd_filename);
+exit(1);
+}
+} else {
+error_report("Need initrd!");
+exit(1);
+}
+
  return kernel_entry;
  }
  


Reviewed-by: Bibo Mao 




Re: [PATCH v6 01/17] hw/loongarch: Move boot fucntions to boot.c

2024-03-08 Thread maobibo




On 2024/3/8 上午12:48, Song Gao wrote:

Move some boot functions to boot.c and struct
loongarch_boot_info into struct LoongArchMachineState.

Signed-off-by: Song Gao 
Message-Id: <20240301093839.663947-2-gaos...@loongson.cn>
---
  hw/loongarch/boot.c | 128 
  hw/loongarch/meson.build|   1 +
  hw/loongarch/virt.c | 121 +++---
  include/hw/loongarch/boot.h |  21 ++
  include/hw/loongarch/virt.h |   2 +
  5 files changed, 160 insertions(+), 113 deletions(-)
  create mode 100644 hw/loongarch/boot.c
  create mode 100644 include/hw/loongarch/boot.h

diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
new file mode 100644
index 00..a8a725a0a8
--- /dev/null
+++ b/hw/loongarch/boot.c
@@ -0,0 +1,128 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * LoongArch boot helper functions.
+ *
+ * Copyright (c) 2023 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/units.h"
+#include "target/loongarch/cpu.h"
+#include "hw/loongarch/virt.h"
+#include "hw/loader.h"
+#include "elf.h"
+#include "qemu/error-report.h"
+#include "sysemu/reset.h"
+#include "sysemu/qtest.h"
+
+static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr)
+{
+return addr & MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS);
+}
+
+static int64_t load_kernel_info(struct loongarch_boot_info *info)
+{
+uint64_t kernel_entry, kernel_low, kernel_high;
+ssize_t kernel_size;
+
+kernel_size = load_elf(info->kernel_filename, NULL,
+   cpu_loongarch_virt_to_phys, NULL,
+   &kernel_entry, &kernel_low,
+   &kernel_high, NULL, 0,
+   EM_LOONGARCH, 1, 0);
+
+if (kernel_size < 0) {
+error_report("could not load kernel '%s': %s",
+ info->kernel_filename,
+ load_elf_strerror(kernel_size));
+exit(1);
+}
+return kernel_entry;
+}
+
+static void reset_load_elf(void *opaque)
+{
+LoongArchCPU *cpu = opaque;
+CPULoongArchState *env = &cpu->env;
+
+cpu_reset(CPU(cpu));
+if (env->load_elf) {
+cpu_set_pc(CPU(cpu), env->elf_address);
+}
+}
+
+static void fw_cfg_add_kernel_info(struct loongarch_boot_info *info,
+   FWCfgState *fw_cfg)
+{
+/*
+ * Expose the kernel, the command line, and the initrd in fw_cfg.
+ * We don't process them here at all, it's all left to the
+ * firmware.
+ */
+load_image_to_fw_cfg(fw_cfg,
+ FW_CFG_KERNEL_SIZE, FW_CFG_KERNEL_DATA,
+ info->kernel_filename,
+ false);
+
+if (info->initrd_filename) {
+load_image_to_fw_cfg(fw_cfg,
+ FW_CFG_INITRD_SIZE, FW_CFG_INITRD_DATA,
+ info->initrd_filename, false);
+}
+
+if (info->kernel_cmdline) {
+fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE,
+   strlen(info->kernel_cmdline) + 1);
+fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA,
+  info->kernel_cmdline);
+}
+}
+
+static void loongarch_firmware_boot(LoongArchMachineState *lams,
+struct loongarch_boot_info *info)
+{
+fw_cfg_add_kernel_info(info, lams->fw_cfg);
+}
+
+static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info)
+{
+int64_t kernel_addr = 0;
+LoongArchCPU *lacpu;
+CPUState *cs;
+
+if (info->kernel_filename) {
+kernel_addr = load_kernel_info(info);
+} else {
+if (!qtest_enabled()) {
+error_report("Need kernel filename\n");
+exit(1);
+}
+}
+
+CPU_FOREACH(cs) {
+lacpu = LOONGARCH_CPU(cs);
+lacpu->env.load_elf = true;
+lacpu->env.elf_address = kernel_addr;
+}
+}
+
+void loongarch_load_kernel(MachineState *ms, struct loongarch_boot_info *info)
+{
+LoongArchMachineState *lams = LOONGARCH_MACHINE(ms);
+int i;
+
+/* register reset function */
+for (i = 0; i < ms->smp.cpus; i++) {
+qemu_register_reset(reset_load_elf, LOONGARCH_CPU(qemu_get_cpu(i)));
+}
+
+info->kernel_filename = ms->kernel_filename;
+info->kernel_cmdline = ms->kernel_cmdline;
+info->initrd_filename = ms->initrd_filename;
+
+if (lams->bios_loaded) {
+loongarch_firmware_boot(lams, info);
+} else {
+loongarch_direct_kernel_boot(info);
+}
+}
diff --git a/hw/loongarch/meson.build b/hw/loongarch/meson.build
index c0421502ab..d306d82c2e 100644
--- a/hw/loongarch/meson.build
+++ b/hw/loongarch/meson.build
@@ -1,6 +1,7 @@
  loongarch_ss = ss.source_set()
  loongarch_ss.add(files(
  'fw_cfg.c',
+'boot.c',
  ))
  loongarch_ss.add(when: 'CONFIG_LOONGARCH_VIRT', if_true: [files('virt.c'), 
fdt])
  loongarch_ss.add(when: 'CONFIG_ACPI', if_true: files('acpi-build.c'))
d

Re: [PATCH V2 1/1] target/loongarch: Fixed tlb huge page loading issue

2024-03-05 Thread maobibo

Sorry, manual is updated already and we do not notice that still.

https://www.loongson.cn/uploads/images/2023102309132647981.%E9%BE%99%E8%8A%AF%E6%9E%B6%E6%9E%84%E5%8F%82%E8%80%83%E6%89%8B%E5%86%8C%E5%8D%B7%E4%B8%80_r1p10.pdf

It is Chinese web link, English manual is not updated. Here is English 
translation by manual with instruction  "lddir rd, rj, level"


If the bit[14:13] of the register rj is not equal to 0 and its bit[6] 
is 1, the value of the register rj is a marked as HugePage page entries. 
In this case, the value from register rj is written directly to register rd.


If the bit[14:13] of the register rj is equal to 0 and its bit[6] is 1, 
the value of the register rj is an Hugepage table entry. In this case, 
replace the bit[14:13] of the register RJ value with level[1:0], the val 
is written to the register rd.


If the bit[6] bit of register rj is 0, the value of the universal 
register rj is the page table entry, it is  physical address base page 
table. In this case, if the LDDIR command is executed, the address will 
be refilled according to the TLB currently processed. Retrieve the base 
address of the next-level page table and write it to the common register 
rd.


We will remove temporary lddir_ps, and record page size with bit[14:13] 
in next version.


Regards
Bibo Mao

On 2024/3/6 下午12:10, Richard Henderson wrote:

On 3/5/24 17:52, lixianglai wrote:
The LDDIR_PS variable is not described in detail in the manual, but is 
only an intermediate variable to assist in page size calculation 
during tcg simulation.


This is exactly why I believe adding this intermediate variable is wrong.

What happens if LDPTE is *not* preceded by LDDIR?  It's not the usual 
way a tlb fill routine works, but *something* should happen if you 
construct a valid huge page tlb entry by hand and pass it directly to 
LDPTE.


With your implementation, this will not work because lddir_ps will not 
be initialized. But I expect that on real hardware it would work.


If this does not work on real hardware, then there *is* some heretofore 
undocumented hardware state.  If so, then we need a description of this 
state from the hardware engineers -- the documentation of LDDIR and 
LDPTE need updating.  Finally, this new hardware state needs to be added 
to the migration state.



r~





  1   2   >