Re: [RFC 0/1] i2c/aspeed: Add slave device handling in new register mode

2022-06-01 Thread Cédric Le Goater

[ Adding Joe ]

On 5/25/22 22:50, Peter Delevoryas wrote:

The AST2600/AST1030 new register mode patches[1] and the I2C slave device
patches[2] will be really useful, but we still need DMA slave device
handling in the new register mode too for the use-cases I'm thinking of
(OpenBIC Zephyr kernel using Aspeed SDK drivers[3]).

My test images are on Github[4]. They can be used with the ast1030-evb, or
the oby35-cl and oby35-bb machines in the fb qemu branch[5].

I'm submitting this as an RFC cause I just want to see how other people
expect these changes to be made based on the previously submitted "new
register mode" and "old register mode slave device" patches.



Currently, my preferred approach would be to start with Joe's patchset
because the registerfields conversion is a huge effort and it's adding
new mode support which should cover the needs for the AST1030 SoC [1].

Troy, could you please confirm this is OK with you ? I have pushed
the patches on :

  https://github.com/legoater/qemu/commits/aspeed-7.1

Then, adding slave support for old [2] and new mode (this patch)
shouldn't be too much of a problem since they are small.

we lack a test case for this controller and writing a I2C Aspeed bus
driver for qtest is not an easy task.

It might be easier to start an ast2600-evb machine with a lightweight
userspace (buildroot, I can host that somewhere on GH) and run some I2C
get/set/detect commands from a python/expect framework, like avocado.
I2C devices can be added on the command line for the purpose.


Thanks,

C.

 

Thanks,
Peter

[1] 
https://patchwork.kernel.org/project/qemu-devel/list/?series=626028&archive=both
[2] 
https://patchwork.kernel.org/project/qemu-devel/list/?series=627914&archive=both
[3] 
https://github.com/AspeedTech-BMC/zephyr/blob/db3dbcc9c52e67a47180890ac938ed380b33f91c/drivers/i2c/i2c_aspeed.c#L1362-L1368
[4] https://github.com/peterdelevoryas/OpenBIC/releases/tag/oby35-cl-2022.13.01
[5] https://github.com/facebook/openbmc-qemu

Peter Delevoryas (1):
   i2c/aspeed: Add slave device handling in new register mode

  hw/i2c/aspeed_i2c.c | 118 ++--
  include/hw/i2c/aspeed_i2c.h |  14 +++--
  2 files changed, 124 insertions(+), 8 deletions(-)






Re: [RFC PATCH v4 11/36] i386/tdx: Initialize TDX before creating TD vcpus

2022-06-01 Thread Xiaoyao Li

On 5/24/2022 2:57 PM, Gerd Hoffmann wrote:

   Hi,


Hmm, hooking *vm* initialization into *vcpu* creation looks wrong to me.


That's because for TDX, it has to do VM-scope (feature) initialization
before creating vcpu. This is new to KVM and QEMU, that every feature is
vcpu-scope and configured per-vcpu before.

To minimize the change to QEMU, we want to utilize @cpu and @cpu->env to
grab the configuration info. That's why it goes this way.

Do you have any better idea on it?


Maybe it's a bit more work to add VM-scope initialization support to
qemu.  


If just introducing VM-scope initialization to QEMU, it would be easy. 
What matters is what needs to be done inside VM-scope initialization.


For TDX, we need to settle down the features that configured for the TD. 
Typically, the features are attributes of cpu object, parsed from "-cpu" 
option and stored in cpu object.


I cannot think up a clean solution for it, other than
1) implement the same attributes from cpu object to machine object, or
2) create a CPU object when initializing machine object and collect all 
the info from "-cpu" and drop it in the end; then why not do it when 
creating 1st vcpu like this patch.


That's what I can think up. Let's see if anyone has better idea.


But I expect that approach will work better long-term.  You need
this mutex and the 'initialized' variable in your code to make sure it
runs only once because the way you hook it in is not ideal ...

[ disclaimer: I'm not that familiar with the kvm interface in qemu ]

take care,
   Gerd






Re: [PATCH] target/ppc/cpu-models: Update max alias to power10

2022-06-01 Thread Thomas Huth

On 31/05/2022 19.27, Murilo Opsfelder Araujo wrote:

Update max alias to power10 so users can take advantage of a more
recent CPU model when '-cpu max' is provided.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1038
Cc: Daniel P. Berrangé 
Cc: Thomas Huth 
Cc: Cédric Le Goater 
Cc: Daniel Henrique Barboza 
Cc: Fabiano Rosas 
Signed-off-by: Murilo Opsfelder Araujo 
---
  target/ppc/cpu-models.c | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/target/ppc/cpu-models.c b/target/ppc/cpu-models.c
index 976be5e0d1..c15fcb43a1 100644
--- a/target/ppc/cpu-models.c
+++ b/target/ppc/cpu-models.c
@@ -879,7 +879,6 @@ PowerPCCPUAlias ppc_cpu_aliases[] = {
  { "755", "755_v2.8" },
  { "goldfinger", "755_v2.8" },
  { "7400", "7400_v2.9" },
-{ "max", "7400_v2.9" },
  { "g4",  "7400_v2.9" },
  { "7410", "7410_v1.4" },
  { "nitro", "7410_v1.4" },
@@ -910,6 +909,8 @@ PowerPCCPUAlias ppc_cpu_aliases[] = {
  { "power8nvl", "power8nvl_v1.0" },
  { "power9", "power9_v2.0" },
  { "power10", "power10_v2.0" },
+/* Update the 'max' alias to the latest CPU model */
+{ "max", "power10_v2.0" },
  #endif


I'm not sure whether "max" should really be fixed alias in this list here? 
What if a user runs with KVM on a POWER8 host - then "max" won't work this 
way, will it?


And in the long run, it would also be good if this would work with other 
machines like the "g3beige", too (which don't support the new 64-bit POWER 
CPUs), so you should at least mention in the commit description that this is 
only a temporary hack for the pseries machine, I think.


 Thomas




Re: [PATCH 8/9] tests: add python3-venv to debian10.docker

2022-06-01 Thread Thomas Huth

On 31/05/2022 20.28, John Snow wrote:

On Mon, May 30, 2022 at 3:33 AM Thomas Huth  wrote:


On 26/05/2022 02.09, John Snow wrote:

This is needed to be able to add a venv-building step to 'make check';
the clang-user job in particular needs this to be able to run
check-unit.

Signed-off-by: John Snow 
---
   tests/docker/dockerfiles/debian10.docker | 1 +
   1 file changed, 1 insertion(+)

diff --git a/tests/docker/dockerfiles/debian10.docker 
b/tests/docker/dockerfiles/debian10.docker
index b414af1b9f7..03be9230664 100644
--- a/tests/docker/dockerfiles/debian10.docker
+++ b/tests/docker/dockerfiles/debian10.docker
@@ -34,4 +34,5 @@ RUN apt update && \
   python3 \
   python3-sphinx \
   python3-sphinx-rtd-theme \
+python3-venv \
   $(apt-get -s build-dep --arch-only qemu | egrep ^Inst | fgrep 
'[all]' | cut -d\  -f2)


Note that we'll (hopefully) drop the debian 10 container soon, since Debian
10 is EOL by the time we publish the next QEMU release.



Noted -- do you think it'd be OK to sneak this change in first and
have you move the requisite to the new container? :)


I don't mind - whatever comes first ... I just wanted to make you aware that 
there might be conflicts ;-)


 Thomas





Re: [PATCH v2 12/16] ppc/pnv: remove pnv-phb3-root-port

2022-06-01 Thread Daniel Henrique Barboza




On 5/31/22 18:49, Daniel Henrique Barboza wrote:

The unified pnv-phb-root-port can be used in its place. There is no ABI
breakage in doing so because no official QEMU release introduced user
creatable pnv-phb3-root-port devices.

Signed-off-by: Daniel Henrique Barboza 
---
  hw/pci-host/pnv_phb.c  | 10 --
  hw/pci-host/pnv_phb3.c | 57 --
  hw/ppc/pnv.c   |  1 +
  include/hw/pci-host/pnv_phb3.h |  6 
  4 files changed, 8 insertions(+), 66 deletions(-)

diff --git a/hw/pci-host/pnv_phb.c b/hw/pci-host/pnv_phb.c
index 5047e90d3a..d1e8d28e97 100644
--- a/hw/pci-host/pnv_phb.c
+++ b/hw/pci-host/pnv_phb.c
@@ -35,7 +35,7 @@ static void pnv_phb_realize(DeviceState *dev, Error **errp)
  switch (phb->version) {
  case 3:
  phb_typename = g_strdup(TYPE_PNV_PHB3);
-phb_rootport_typename = g_strdup(TYPE_PNV_PHB3_ROOT_PORT);
+phb_rootport_typename = g_strdup(TYPE_PNV_PHB_ROOT_PORT);
  break;
  case 4:
  phb_typename = g_strdup(TYPE_PNV_PHB4);
@@ -170,6 +170,11 @@ static void pnv_phb_root_port_realize(DeviceState *dev, 
Error **errp)
  pci_config_set_interrupt_pin(pci->config, 0);
  }
  
+static Property pnv_phb_root_port_properties[] = {

+DEFINE_PROP_UINT32("version", PnvPHB, version, 0),
+DEFINE_PROP_END_OF_LIST(),
+};
+
  static void pnv_phb_root_port_class_init(ObjectClass *klass, void *data)
  {
  DeviceClass *dc = DEVICE_CLASS(klass);
@@ -180,11 +185,10 @@ static void pnv_phb_root_port_class_init(ObjectClass 
*klass, void *data)
  
  device_class_set_parent_realize(dc, pnv_phb_root_port_realize,

  &rpc->parent_realize);
-
  device_class_set_parent_reset(dc, pnv_phb_root_port_reset,
&rpc->parent_reset);
  dc->reset = &pnv_phb_root_port_reset;
-
+device_class_set_props(dc, pnv_phb_root_port_properties);
  dc->user_creatable = true;
  
  k->vendor_id = PCI_VENDOR_ID_IBM;

diff --git a/hw/pci-host/pnv_phb3.c b/hw/pci-host/pnv_phb3.c
index 839c2dad00..dc1068443a 100644
--- a/hw/pci-host/pnv_phb3.c
+++ b/hw/pci-host/pnv_phb3.c
@@ -1152,66 +1152,9 @@ static const TypeInfo pnv_phb3_root_bus_info = {
  },
  };
  
-static void pnv_phb3_root_port_realize(DeviceState *dev, Error **errp)

-{
-PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(dev);
-PCIDevice *pci = PCI_DEVICE(dev);
-PCIBus *bus = pci_get_bus(pci);
-PnvPHB *phb = NULL;
-Error *local_err = NULL;
-
-phb = (PnvPHB *) object_dynamic_cast(OBJECT(bus->qbus.parent),
- TYPE_PNV_PHB);
-
-if (!phb) {
-error_setg(errp,
-"pnv_phb3_root_port devices must be connected to pnv-phb3 buses");
-return;
-}
-
-/* Set unique chassis/slot values for the root port */
-qdev_prop_set_uint8(&pci->qdev, "chassis", phb->chip_id);
-qdev_prop_set_uint16(&pci->qdev, "slot", phb->phb_id);
-
-rpc->parent_realize(dev, &local_err);
-if (local_err) {
-error_propagate(errp, local_err);
-return;
-}
-pci_config_set_interrupt_pin(pci->config, 0);
-}
-
-static void pnv_phb3_root_port_class_init(ObjectClass *klass, void *data)
-{
-DeviceClass *dc = DEVICE_CLASS(klass);
-PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
-PCIERootPortClass *rpc = PCIE_ROOT_PORT_CLASS(klass);
-
-dc->desc = "IBM PHB3 PCIE Root Port";
-
-device_class_set_parent_realize(dc, pnv_phb3_root_port_realize,
-&rpc->parent_realize);
-dc->user_creatable = true;
-
-k->vendor_id = PCI_VENDOR_ID_IBM;
-k->device_id = 0x03dc;
-k->revision  = 0;
-
-rpc->exp_offset = 0x48;
-rpc->aer_offset = 0x100;
-}
-
-static const TypeInfo pnv_phb3_root_port_info = {
-.name  = TYPE_PNV_PHB3_ROOT_PORT,
-.parent= TYPE_PCIE_ROOT_PORT,
-.instance_size = sizeof(PnvPHB3RootPort),
-.class_init= pnv_phb3_root_port_class_init,
-};
-
  static void pnv_phb3_register_types(void)
  {
  type_register_static(&pnv_phb3_root_bus_info);
-type_register_static(&pnv_phb3_root_port_info);
  type_register_static(&pnv_phb3_type_info);
  type_register_static(&pnv_phb3_iommu_memory_region_info);
  }
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 4d2ea405db..5da5067b67 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -2148,6 +2148,7 @@ static void pnv_machine_power8_class_init(ObjectClass 
*oc, void *data)
  
  static GlobalProperty phb_compat[] = {

  { TYPE_PNV_PHB, "version", "3" },
+{ TYPE_PNV_PHB_ROOT_PORT, "version", "3" },


Not sure how this ended up here. Consider it removed.



Daniel


  };
  
  mc->desc = "IBM PowerNV (Non-Virtualized) POWER8";

diff --git a/include/hw/pci-host/pnv_phb3.h b/include/hw/pci-host/pnv_phb3.h
index 3b9ff1096a..bff69201d9 100644
--- a/include/hw/pci-host/pnv_phb3.h
+++ b/include/hw/pci-host/pnv_phb3.h
@@ -108,12 +108

Re: [PATCH] target/ppc/cpu-models: Update max alias to power10

2022-06-01 Thread Cédric Le Goater

On 6/1/22 09:27, Thomas Huth wrote:

On 31/05/2022 19.27, Murilo Opsfelder Araujo wrote:

Update max alias to power10 so users can take advantage of a more
recent CPU model when '-cpu max' is provided.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1038
Cc: Daniel P. Berrangé 
Cc: Thomas Huth 
Cc: Cédric Le Goater 
Cc: Daniel Henrique Barboza 
Cc: Fabiano Rosas 
Signed-off-by: Murilo Opsfelder Araujo 
---
  target/ppc/cpu-models.c | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/target/ppc/cpu-models.c b/target/ppc/cpu-models.c
index 976be5e0d1..c15fcb43a1 100644
--- a/target/ppc/cpu-models.c
+++ b/target/ppc/cpu-models.c
@@ -879,7 +879,6 @@ PowerPCCPUAlias ppc_cpu_aliases[] = {
  { "755", "755_v2.8" },
  { "goldfinger", "755_v2.8" },
  { "7400", "7400_v2.9" },
-    { "max", "7400_v2.9" },
  { "g4",  "7400_v2.9" },
  { "7410", "7410_v1.4" },
  { "nitro", "7410_v1.4" },
@@ -910,6 +909,8 @@ PowerPCCPUAlias ppc_cpu_aliases[] = {
  { "power8nvl", "power8nvl_v1.0" },
  { "power9", "power9_v2.0" },
  { "power10", "power10_v2.0" },
+    /* Update the 'max' alias to the latest CPU model */
+    { "max", "power10_v2.0" },
  #endif


I'm not sure whether "max" should really be fixed alias in this list here? What if a user 
runs with KVM on a POWER8 host - then "max" won't work this way, will it?

And in the long run, it would also be good if this would work with other machines like 
the "g3beige", too (which don't support the new 64-bit POWER CPUs), so you 
should at least mention in the commit description that this is only a temporary hack for 
the pseries machine, I think.


Yes. You are right, Thomas.

s390 and x86 have a nice way to address "max".

Thanks,

C.



  Thomas






Re: [RFC PATCH v4 11/36] i386/tdx: Initialize TDX before creating TD vcpus

2022-06-01 Thread Gerd Hoffmann
On Wed, Jun 01, 2022 at 03:20:46PM +0800, Xiaoyao Li wrote:
> On 5/24/2022 2:57 PM, Gerd Hoffmann wrote:
> >Hi,
> > Maybe it's a bit more work to add VM-scope initialization support to
> > qemu.
> 
> If just introducing VM-scope initialization to QEMU, it would be easy. What
> matters is what needs to be done inside VM-scope initialization.
> 
> For TDX, we need to settle down the features that configured for the TD.
> Typically, the features are attributes of cpu object, parsed from "-cpu"
> option and stored in cpu object.

> 2) create a CPU object when initializing machine object and collect all the
> info from "-cpu" and drop it in the end; then why not do it when creating
> 1st vcpu like this patch.

Do VM-scope tdx initialization late enough that cpu objects are already
created at that point, so you can collect the info you need without a
dummy cpu?

I guess it could be helpful for the discussion when you can outine the
'big picture' for tdx initialization.  How does kvm accel setup look
like without TDX, and what additional actions are needed for TDX?  What
ordering requirements and other constrains exist?

take care,
  Gerd




Re: [PATCH 0/3] recover hardware corrupted page by virtio balloon

2022-06-01 Thread David Hildenbrand
On 01.06.22 04:17, zhenwei pi wrote:
> On 5/31/22 12:08, Jue Wang wrote:
>> On Mon, May 30, 2022 at 8:49 AM Peter Xu  wrote:
>>>
>>> On Mon, May 30, 2022 at 07:33:35PM +0800, zhenwei pi wrote:
 A VM uses RAM of 2M huge page. Once a MCE(@HVAy in [HVAx,HVAz)) occurs, the
 2M([HVAx,HVAz)) of hypervisor becomes unaccessible, but the guest poisons 
 4K
 (@GPAy in [GPAx, GPAz)) only, it may hit another 511 MCE ([GPAx, GPAz)
 except GPAy). This is the worse case, so I want to add
   '__le32 corrupted_pages' in struct virtio_balloon_config, it is used in 
 the
 next step: reporting 512 * 4K 'corrupted_pages' to the guest, the guest has
 a chance to isolate the other 511 pages ahead of time. And the guest
 actually loses 2M, fixing 512*4K seems to help significantly.
>>>
>>> It sounds hackish to teach a virtio device to assume one page will always
>>> be poisoned in huge page granule.  That's only a limitation to host kernel
>>> not virtio itself.
>>>
>>> E.g. there're upstream effort ongoing with enabling doublemap on hugetlbfs
>>> pages so hugetlb pages can be mapped in 4k with it.  It provides potential
>>> possibility to do page poisoning with huge pages in 4k too.  When that'll
>>> be ready the assumption can go away, and that does sound like a better
>>> approach towards this problem.
>>
>> +1.
>>
>> A hypervisor should always strive to minimize the guest memory loss.
>>
>> The HugeTLB double mapping enlightened memory poisoning behavior (only
>> poison 4K out of a 2MB huge page and 4K in guest) is a much better
>> solution here. To be completely transparent, it's not _strictly_
>> required to poison the page (whatever the granularity it is) on the
>> host side, as long as the following are true:
>>
>> 1. A hypervisor can emulate the _minimized_ (e.g., 4K) the poison to the 
>> guest.
>> 2. The host page with the UC error is "isolated" (could be PG_HWPOISON
>> or in some other way) and prevented from being reused by other
>> processes.
>>
>> For #2, PG_HWPOISON and HugeTLB double mapping enlightened memory
>> poisoning is a good solution.
>>
>>>

>
> I assume when talking about "the performance memory drops a lot", you
> imply that this patch set can mitigate that performance drop?
>
> But why do you see a performance drop? Because we might lose some
> possible THP candidates (in the host or the guest) and you want to plug
> does holes? I assume you'll see a performance drop simply because
> poisoning memory is expensive, including migrating pages around on CE.
>
> If you have some numbers to share, especially before/after this change,
> that would be great.
>

 The CE storm leads 2 problems I have even seen:
 1, the memory bandwidth slows down to 10%~20%, and the cycles per
 instruction of CPU increases a lot.
 2, the THR (/proc/interrupts) interrupts frequently, the CPU has to use a
 lot time to handle IRQ.
>>>
>>> Totally no good knowledge on CMCI, but if 2) is true then I'm wondering
>>> whether it's necessary to handle the interrupts that frequently.  When I
>>> was reading the Intel CMCI vector handler I stumbled over this comment:
>>>
>>> /*
>>>   * The interrupt handler. This is called on every event.
>>>   * Just call the poller directly to log any events.
>>>   * This could in theory increase the threshold under high load,
>>>   * but doesn't for now.
>>>   */
>>> static void intel_threshold_interrupt(void)
>>>
>>> I think that matches with what I was thinking..  I mean for 2) not sure
>>> whether it can be seen as a CMCI problem and potentially can be optimized
>>> by adjust the cmci threshold dynamically.
>>
>> The CE storm caused performance drop is caused by the extra cycles
>> spent by the ECC steps in memory controller, not in CMCI handling.
>> This is observed in the Google fleet as well. A good solution is to
>> monitor the CE rate closely in user space via /dev/mcelog and migrate
>> all VMs to another host once the CE rate exceeds some threshold.
>>
>> CMCI is a _background_ interrupt that is not handled in the process
>> execution context and its handler is setup to switch to poll (1 / 5
>> min) mode if there are more than ~ a dozen CEs reported via CMCI per
>> second.
>>>
>>> --
>>> Peter Xu
>>>
> 
> Hi, Andrew, David, Naoya
> 
> According to the suggestions, I'd give up the improvement of memory 
> failure on huge page in this series.
> 
> Is it worth recovering corrupted pages for the guest kernel? I'd follow 
> your decision.

Well, as I said, I am not sure if we really need/want this for a handful
of 4k poisoned pages in a VM. As I suspected, doing so might primarily
be interesting for some sort of de-fragmentation (allow again a higher
order page to be placed at the affected PFNs), not because of the slight
reduction of available memory. A simple VM reboot would get the job
similarly done.

As the poisoning refcount code is already a bit shaky as I learned
recently in t

Re: [RESEND PATCH] hw/dma: fix crash caused by race condition

2022-06-01 Thread David Hildenbrand
On 01.06.22 02:20, Tong Zhang wrote:
> Hi David,
> 
> On Mon, May 30, 2022 at 9:19 AM David Hildenbrand  wrote:
>>
>> On 27.04.22 22:51, Tong Zhang wrote:
>>> assert(dbs->acb) is meant to check the return value of io_func per
>>> documented in commit 6bee44ea34 ("dma: the passed io_func does not
>>> return NULL"). However, there is a chance that after calling
>>> aio_context_release(dbs->ctx); the dma_blk_cb function is called before
>>> the assertion and dbs->acb is set to NULL again at line 121. Thus when
>>> we run assert at line 181 it will fail.
>>>
>>>   softmmu/dma-helpers.c:181: dma_blk_cb: Assertion `dbs->acb' failed.
>>>
>>> Reported-by: Francisco Londono 
>>> Signed-off-by: Tong Zhang 
>>> ---
>>>  softmmu/dma-helpers.c | 2 +-
>>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/softmmu/dma-helpers.c b/softmmu/dma-helpers.c
>>> index 7820fec54c..cb81017928 100644
>>> --- a/softmmu/dma-helpers.c
>>> +++ b/softmmu/dma-helpers.c
>>> @@ -177,8 +177,8 @@ static void dma_blk_cb(void *opaque, int ret)
>>>  aio_context_acquire(dbs->ctx);
>>>  dbs->acb = dbs->io_func(dbs->offset, &dbs->iov,
>>>  dma_blk_cb, dbs, dbs->io_func_opaque);
>>> -aio_context_release(dbs->ctx);
>>>  assert(dbs->acb);
>>> +aio_context_release(dbs->ctx);
>>>  }
>>>
>>>  static void dma_aio_cancel(BlockAIOCB *acb)
>>
>> I'm fairly new to that code, but I wonder what prevents dma_blk_cb() to
>> run after you reshuffled the code?
>>
> 
> IMO if the assert is to test whether io_func returns a non-NULL value
> shouldn't it be immediately after calling io_func.
> Also... as suggested by commit 6bee44ea346aed24e12d525daf10542d695508db
>   > dma: the passed io_func does not return NULL

Yes, but I just don't see how it would fix the assertion you document in
the patch description. The locking change to fix the assertion doesn't
make any sense to me, and most probably I am missing something important :)

-- 
Thanks,

David / dhildenb




Re: [PATCH v2 11/16] ppc/pnv: add pnv-phb-root-port device

2022-06-01 Thread Daniel Henrique Barboza




On 6/1/22 02:56, Cédric Le Goater wrote:

On 5/31/22 23:49, Daniel Henrique Barboza wrote:

We have two very similar root-port devices, pnv-phb3-root-port and
pnv-phb4-root-port. Both consist of a wrapper around the PCIESlot device
that, until now, has no additional attributes.

The main difference between the PHB3 and PHB4 root ports is that
pnv-phb4-root-port has the pnv_phb4_root_port_reset() callback. All
other differences can be merged in a single device without too much
trouble.

This patch introduces the unified pnv-phb-root-port that, in time, will
be used as the default root port for the pnv-phb device.

Signed-off-by: Daniel Henrique Barboza 
---
  hw/pci-host/pnv_phb.c | 107 ++
  hw/pci-host/pnv_phb.h |  17 +++
  2 files changed, 116 insertions(+), 8 deletions(-)

diff --git a/hw/pci-host/pnv_phb.c b/hw/pci-host/pnv_phb.c
index 321c4e768a..5047e90d3a 100644
--- a/hw/pci-host/pnv_phb.c
+++ b/hw/pci-host/pnv_phb.c
@@ -114,15 +114,106 @@ static void pnv_phb_class_init(ObjectClass *klass, void 
*data)
  dc->user_creatable = true;
  }
-static void pnv_phb_register_type(void)
+static void pnv_phb_root_port_reset(DeviceState *dev)
  {
-    static const TypeInfo pnv_phb_type_info = {
-    .name  = TYPE_PNV_PHB,
-    .parent    = TYPE_PCIE_HOST_BRIDGE,
-    .instance_size = sizeof(PnvPHB),
-    .class_init    = pnv_phb_class_init,
-    };
+    PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(dev);
+    PnvPHBRootPort *rootport = PNV_PHB_ROOT_PORT(dev);
+    PCIDevice *d = PCI_DEVICE(dev);
+    uint8_t *conf = d->config;
+    rpc->parent_reset(dev);
+
+    if (rootport->version == 3) {
+    return;
+    }
+
+    /* PHB4 and later requires these extra reset steps */
+    pci_byte_test_and_set_mask(conf + PCI_IO_BASE,
+   PCI_IO_RANGE_MASK & 0xff);
+    pci_byte_test_and_clear_mask(conf + PCI_IO_LIMIT,
+ PCI_IO_RANGE_MASK & 0xff);
+    pci_set_word(conf + PCI_MEMORY_BASE, 0);
+    pci_set_word(conf + PCI_MEMORY_LIMIT, 0xfff0);
+    pci_set_word(conf + PCI_PREF_MEMORY_BASE, 0x1);
+    pci_set_word(conf + PCI_PREF_MEMORY_LIMIT, 0xfff1);
+    pci_set_long(conf + PCI_PREF_BASE_UPPER32, 0x1); /* Hack */
+    pci_set_long(conf + PCI_PREF_LIMIT_UPPER32, 0x);
+    pci_config_set_interrupt_pin(conf, 0);
+}
+
+static void pnv_phb_root_port_realize(DeviceState *dev, Error **errp)
+{
+    PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(dev);
+    PCIDevice *pci = PCI_DEVICE(dev);
+    PCIBus *bus = pci_get_bus(pci);
+    PnvPHB *phb = NULL;
+    Error *local_err = NULL;
+
+    phb = (PnvPHB *) object_dynamic_cast(OBJECT(bus->qbus.parent),
+  TYPE_PNV_PHB);
+
+    if (!phb) {
+    error_setg(errp,
+"pnv_phb_root_port devices must be connected to pnv-phb buses");
+    return;
+    }
+
+    /* Set unique chassis/slot values for the root port */
+    qdev_prop_set_uint8(&pci->qdev, "chassis", phb->chip_id);
+    qdev_prop_set_uint16(&pci->qdev, "slot", phb->phb_id);
+
+    rpc->parent_realize(dev, &local_err);
+    if (local_err) {
+    error_propagate(errp, local_err);
+    return;
+    }
+    pci_config_set_interrupt_pin(pci->config, 0);
+}
+
+static void pnv_phb_root_port_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+    PCIERootPortClass *rpc = PCIE_ROOT_PORT_CLASS(klass);
+
+    dc->desc = "IBM PHB PCIE Root Port";
+
+    device_class_set_parent_realize(dc, pnv_phb_root_port_realize,
+    &rpc->parent_realize);
+
+    device_class_set_parent_reset(dc, pnv_phb_root_port_reset,
+  &rpc->parent_reset);
+    dc->reset = &pnv_phb_root_port_reset;
+
+    dc->user_creatable = true;
+
+    k->vendor_id = PCI_VENDOR_ID_IBM;
+    /* device_id represents the latest PHB root port version supported */
+    k->device_id = PNV_PHB5_DEVICE_ID;


does that mean powernv8 machines will see phb devices as phb5 devices ?



I had something like this in this patch that would set device_id properly:


diff --git a/hw/pci-host/pnv_phb.c b/hw/pci-host/pnv_phb.c
index 5d66264a96..d468e8d44a 100644
--- a/hw/pci-host/pnv_phb.c
+++ b/hw/pci-host/pnv_phb.c
@@ -144,6 +144,22 @@ static void pnv_phb_root_port_realize(DeviceState *dev, 
Error **errp)
 PCIBus *bus = pci_get_bus(pci);
 PnvPHB *phb = NULL;
 Error *local_err = NULL;
+PnvPHBRootPort *phb_rp = PNV_PHB_ROOT_PORT(dev);
+PCIDeviceClass *k = PCI_DEVICE_GET_CLASS(pci);
+
+switch (phb_rp->version) {
+case 3:
+k->device_id = PNV_PHB3_DEVICE_ID;
+break;
+case 4:
+k->device_id = PNV_PHB4_DEVICE_ID;
+break;
+case 5:
+k->device_id = PNV_PHB5_DEVICE_ID;
+break;
+default:
+g_assert_not_reached();
+}
 
 phb = (PnvPHB *) object_dynamic_

Re: [PATCH] target/ppc/cpu-models: Update max alias to power10

2022-06-01 Thread Greg Kurz
On Wed, 1 Jun 2022 09:27:31 +0200
Thomas Huth  wrote:

> On 31/05/2022 19.27, Murilo Opsfelder Araujo wrote:
> > Update max alias to power10 so users can take advantage of a more
> > recent CPU model when '-cpu max' is provided.
> > 
> > Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1038
> > Cc: Daniel P. Berrangé 
> > Cc: Thomas Huth 
> > Cc: Cédric Le Goater 
> > Cc: Daniel Henrique Barboza 
> > Cc: Fabiano Rosas 
> > Signed-off-by: Murilo Opsfelder Araujo 
> > ---
> >   target/ppc/cpu-models.c | 3 ++-
> >   1 file changed, 2 insertions(+), 1 deletion(-)
> > 
> > diff --git a/target/ppc/cpu-models.c b/target/ppc/cpu-models.c
> > index 976be5e0d1..c15fcb43a1 100644
> > --- a/target/ppc/cpu-models.c
> > +++ b/target/ppc/cpu-models.c
> > @@ -879,7 +879,6 @@ PowerPCCPUAlias ppc_cpu_aliases[] = {
> >   { "755", "755_v2.8" },
> >   { "goldfinger", "755_v2.8" },
> >   { "7400", "7400_v2.9" },
> > -{ "max", "7400_v2.9" },
> >   { "g4",  "7400_v2.9" },
> >   { "7410", "7410_v1.4" },
> >   { "nitro", "7410_v1.4" },
> > @@ -910,6 +909,8 @@ PowerPCCPUAlias ppc_cpu_aliases[] = {
> >   { "power8nvl", "power8nvl_v1.0" },
> >   { "power9", "power9_v2.0" },
> >   { "power10", "power10_v2.0" },
> > +/* Update the 'max' alias to the latest CPU model */
> > +{ "max", "power10_v2.0" },
> >   #endif
> 
> I'm not sure whether "max" should really be fixed alias in this list here? 
> What if a user runs with KVM on a POWER8 host - then "max" won't work this 
> way, will it?
> 
> And in the long run, it would also be good if this would work with other 
> machines like the "g3beige", too (which don't support the new 64-bit POWER 
> CPUs), so you should at least mention in the commit description that this is 
> only a temporary hack for the pseries machine, I think.
> 

I didn't even know there was a "max" alias :-)

This was introduced by commit:

commit 3fc6c082e3aad85addf25d36740030982963c0c8
Author: Fabrice Bellard 
Date:   Sat Jul 2 20:59:34 2005 +

preliminary patch to support more PowerPC CPUs (Jocelyn Mayer)

This was already a 7400 model at the time. Obviously we've never
maintained that and I hardly see how it is useful... As Thomas
noted, "max" has implicit semantics that depend on the host.
This isn't migration friendly and I'm pretty sure libvirt
doesn't use it (Daniel ?)

We already have the concept of default CPU for the spapr
machine types, that is usually popped up to the newer
CPU model that is going to be supported in production.
This goes with a bump of the machine type version as
well for the sake of migration. This seems a lot more
reliable than the "max" thingy IMHO.

Unless there's a very important use case I'm missing,
I'd rather kill the thing instead of trying to resurrect
it.

Cheers,

--
Greg

>   Thomas
> 




Re: [RFC PATCH v5 0/3] Sysbus device generic QAPI plug support

2022-06-01 Thread Damien Hedde




On 5/31/22 22:43, Mark Cave-Ayland wrote:

On 31/05/2022 10:22, Damien Hedde wrote:


On 5/31/22 10:00, Mark Cave-Ayland wrote:

On 30/05/2022 15:05, Damien Hedde wrote:


On 5/30/22 12:25, Peter Maydell wrote:
On Mon, 30 May 2022 at 10:50, Damien Hedde 
 wrote:

TYPE_SYS_BUS_DEVICE also comes with reset support.
If a device is on not on any bus it is not reached by the root sysbus
reset which propagates to every device (and other sub-buses).
Even if we move all the mmio/sysbus-irq logic into TYPE_DEVICE, we 
will

still miss that. The bus is needed to handle the reset.
For devices created in machine init code, we have the option to do 
it in
the machine reset handler. But for user created device, this is an 
issue.


Yes, the missing reset support in TYPE_DEVICE is a design
flaw that we really should try to address.


I think the easiest way to handle this would be just after calling 
dc->realize; if the device has bus == NULL and dc->reset != NULL then 
manually call qemu_register_reset() for dc->reset. In a qdev world 
dc->reset is intended to be a bus-level reset, but I can't see an 
issue with manual registration for individual devices in this way, 
particularly as there are no reset ordering guarantees for sysbus.


I'm a bit afraid calling qemu_register_reset() outside dc->realize 
might modify the behavior for existing devices. Does any device end up 
having a non-NULL bus right now when using "-device" CLI ?


If you take a look at "info qtree" then that will show you all devices 
that are attached to a bus i.e. ones where bus is not NULL.



If we end up putting in TYPE_DEVICE support for mmios, interrupts and
some way to do the bus reset. What would be the difference between 
the

current TYPE_SYS_BUS_DEVICE ?


There would be none, and the idea would be to get rid of
TYPE_SYS_BUS_DEVICE entirely...

Do you expect the bus object to disappear in the process (bus-less 
system) or transforming the sysbus into a ~TYPE_BUS thing ?


I'd probably lean towards removing sysbus completely since in real 
life devices can exist outside of a bus. If a device needs a bus then 
it should already be modelled in QEMU, and anything that requires a 
hierarchy can already be represented via QOM children


For me, a "memory bus" is a bus. But I understand in QEMU, this is 
modeled by a memory region and we do not want to represent it anymore 
by a qdev/qbus hierarchy.




Assuming we manage to sort out this does cold plugging using the 
following scenario looks ok ? (regarding having to issue one command 
to create the device AND some commands to handle memory-region and 
interrupt lines)


 > device_add driver=ibex-uart id=uart chardev=serial0
 > sysbus-mmio-map device=uart addr=1073741824
 > qom-set path=uart property=sysbus-irq[0] 
value=plic/unnamed-gpio-in[1]


TYPE_DEVICE or TYPE_SYS_BUS_DEVICE, my goal is still to be able to 
cold-plug a "ibex-uart" define its memory map and choose which irq I 
wire where.


Anyhow getting back on topic: my main objection here is that you're 
adding a command "sysbus-mmio-map" when we don't want the concept of 
SysBusDevice to be exposed outside of QEMU at all. Referring back to 
my last email I think we should extend the device concept in the 
monitor to handle the additional functionality perhaps along the 
lines of:


- A monitor command such as "device_map" which is effectively a 
wrapper around
   memory_region_add_subregion(). Do we also want a "device_unmap"? 
We should
   consider allow mapping to other memory regions other than the 
system root.


- A monitor command such as "device_connect" which can be used to 
simplify your IRQ

   wiring, perhaps also with a "device_disconnect"?

- An outline of the monitor commands showing the complete workflow 
from introspection

   of a device to mapping its memory region(s) and connecting its gpios

Does that give you enough information to come up with a more detailed 
proposal?




Yes. Sorry for being not clear enough. I did not wanted to insist on 
specific command names. I've no issues regarding the modifications you 
request about having a device_connect or a device_map.


My question was more about the workflow which does not rely on issuing 
a single 'device_add' command handling mapping/connection using 
parameters. Note that since we are talking supporting of map/connect 
for the base type TYPE_DEVICE, I don't really see how we could have 
parameters for these without impacting subtypes.


I'm not sure I understand what you are saying here? Can you give an 
example?


There are 2 possible workflows:
1. several commands
> device_add ...
> device_map ...
> device_connect ...

2. single command
> device_add ... map={...} connect={...}

The 2nd one is more like how we connect devices with '-device': all is 
done at once. But if this is supposed to apply to TYPE_DEVICE (versus 
TYPE_SYS_BUS_DEVICE), it becomes IMHO hard to prevent using them on 
devices where it does not makes sense (for example: a virtio or pci 
de

Re: [RFC PATCH v5 0/3] Sysbus device generic QAPI plug support

2022-06-01 Thread David Hildenbrand
On 01.06.22 10:39, Damien Hedde wrote:
> 
> 
> On 5/31/22 22:43, Mark Cave-Ayland wrote:
>> On 31/05/2022 10:22, Damien Hedde wrote:
>>
>>> On 5/31/22 10:00, Mark Cave-Ayland wrote:
 On 30/05/2022 15:05, Damien Hedde wrote:

> On 5/30/22 12:25, Peter Maydell wrote:
>> On Mon, 30 May 2022 at 10:50, Damien Hedde 
>>  wrote:
>>> TYPE_SYS_BUS_DEVICE also comes with reset support.
>>> If a device is on not on any bus it is not reached by the root sysbus
>>> reset which propagates to every device (and other sub-buses).
>>> Even if we move all the mmio/sysbus-irq logic into TYPE_DEVICE, we 
>>> will
>>> still miss that. The bus is needed to handle the reset.
>>> For devices created in machine init code, we have the option to do 
>>> it in
>>> the machine reset handler. But for user created device, this is an 
>>> issue.
>>
>> Yes, the missing reset support in TYPE_DEVICE is a design
>> flaw that we really should try to address.

 I think the easiest way to handle this would be just after calling 
 dc->realize; if the device has bus == NULL and dc->reset != NULL then 
 manually call qemu_register_reset() for dc->reset. In a qdev world 
 dc->reset is intended to be a bus-level reset, but I can't see an 
 issue with manual registration for individual devices in this way, 
 particularly as there are no reset ordering guarantees for sysbus.
>>>
>>> I'm a bit afraid calling qemu_register_reset() outside dc->realize 
>>> might modify the behavior for existing devices. Does any device end up 
>>> having a non-NULL bus right now when using "-device" CLI ?
>>
>> If you take a look at "info qtree" then that will show you all devices 
>> that are attached to a bus i.e. ones where bus is not NULL.
>>
>>> If we end up putting in TYPE_DEVICE support for mmios, interrupts and
>>> some way to do the bus reset. What would be the difference between 
>>> the
>>> current TYPE_SYS_BUS_DEVICE ?
>>
>> There would be none, and the idea would be to get rid of
>> TYPE_SYS_BUS_DEVICE entirely...
>>
> Do you expect the bus object to disappear in the process (bus-less 
> system) or transforming the sysbus into a ~TYPE_BUS thing ?

 I'd probably lean towards removing sysbus completely since in real 
 life devices can exist outside of a bus. If a device needs a bus then 
 it should already be modelled in QEMU, and anything that requires a 
 hierarchy can already be represented via QOM children
>>>
>>> For me, a "memory bus" is a bus. But I understand in QEMU, this is 
>>> modeled by a memory region and we do not want to represent it anymore 
>>> by a qdev/qbus hierarchy.
>>>

> Assuming we manage to sort out this does cold plugging using the 
> following scenario looks ok ? (regarding having to issue one command 
> to create the device AND some commands to handle memory-region and 
> interrupt lines)
>
>  > device_add driver=ibex-uart id=uart chardev=serial0
>  > sysbus-mmio-map device=uart addr=1073741824
>  > qom-set path=uart property=sysbus-irq[0] 
> value=plic/unnamed-gpio-in[1]
>
> TYPE_DEVICE or TYPE_SYS_BUS_DEVICE, my goal is still to be able to 
> cold-plug a "ibex-uart" define its memory map and choose which irq I 
> wire where.

 Anyhow getting back on topic: my main objection here is that you're 
 adding a command "sysbus-mmio-map" when we don't want the concept of 
 SysBusDevice to be exposed outside of QEMU at all. Referring back to 
 my last email I think we should extend the device concept in the 
 monitor to handle the additional functionality perhaps along the 
 lines of:

 - A monitor command such as "device_map" which is effectively a 
 wrapper around
    memory_region_add_subregion(). Do we also want a "device_unmap"? 
 We should
    consider allow mapping to other memory regions other than the 
 system root.

 - A monitor command such as "device_connect" which can be used to 
 simplify your IRQ
    wiring, perhaps also with a "device_disconnect"?

 - An outline of the monitor commands showing the complete workflow 
 from introspection
    of a device to mapping its memory region(s) and connecting its gpios

 Does that give you enough information to come up with a more detailed 
 proposal?

>>>
>>> Yes. Sorry for being not clear enough. I did not wanted to insist on 
>>> specific command names. I've no issues regarding the modifications you 
>>> request about having a device_connect or a device_map.
>>>
>>> My question was more about the workflow which does not rely on issuing 
>>> a single 'device_add' command handling mapping/connection using 
>>> parameters. Note that since we are talking supporting of map/connect 
>>> for the base type TYPE_DEVICE, I don't really see how we could have 
>>> parameters for t

Re: [PATCH] target/ppc/cpu-models: Update max alias to power10

2022-06-01 Thread Thomas Huth

On 01/06/2022 10.38, Greg Kurz wrote:

On Wed, 1 Jun 2022 09:27:31 +0200
Thomas Huth  wrote:


On 31/05/2022 19.27, Murilo Opsfelder Araujo wrote:

Update max alias to power10 so users can take advantage of a more
recent CPU model when '-cpu max' is provided.

...

We already have the concept of default CPU for the spapr
machine types, that is usually popped up to the newer
CPU model that is going to be supported in production.
This goes with a bump of the machine type version as
well for the sake of migration. This seems a lot more
reliable than the "max" thingy IMHO.

Unless there's a very important use case I'm missing,
I'd rather kill the thing instead of trying to resurrect
it.


It's about making ppc similar to other architectures, which
have "-cpu max" as well, see:

 https://gitlab.com/qemu-project/qemu/-/issues/1038

It would be nice to get something similar on ppc.

By the way, the warnings that you currently get when running with
TCG are quite ugly, too:

$ ./qemu-system-ppc64
qemu-system-ppc64: warning: TCG doesn't support requested feature, 
cap-cfpc=workaround
qemu-system-ppc64: warning: TCG doesn't support requested feature, 
cap-sbbc=workaround
qemu-system-ppc64: warning: TCG doesn't support requested feature, 
cap-ibs=workaround
qemu-system-ppc64: warning: TCG doesn't support requested feature, 
cap-ccf-assist=on


Maybe these could get fixed with a proper "max" CPU in TCG
mode, too?

 Thomas




Types?

2022-06-01 Thread Kenneth Adam Miller
Hello,

I am working on a qemu target under development. and I am wondering how I
should differentiate the MachineState from the MachineClass.


Re: [External] [PATCH v13 3/8] QIOChannelSocket: Implement io_writev zero copy flag & io_flush for CONFIG_LINUX

2022-06-01 Thread 徐闯



On 2022/5/13 下午2:28, Leonardo Bras wrote:

For CONFIG_LINUX, implement the new zero copy flag and the optional callback
io_flush on QIOChannelSocket, but enables it only when MSG_ZEROCOPY
feature is available in the host kernel, which is checked on
qio_channel_socket_connect_sync()

qio_channel_socket_flush() was implemented by counting how many times
sendmsg(...,MSG_ZEROCOPY) was successfully called, and then reading the
socket's error queue, in order to find how many of them finished sending.
Flush will loop until those counters are the same, or until some error occurs.

Notes on using writev() with QIO_CHANNEL_WRITE_FLAG_ZERO_COPY:
1: Buffer
- As MSG_ZEROCOPY tells the kernel to use the same user buffer to avoid copying,
some caution is necessary to avoid overwriting any buffer before it's sent.
If something like this happen, a newer version of the buffer may be sent 
instead.
- If this is a problem, it's recommended to call qio_channel_flush() before 
freeing
or re-using the buffer.

2: Locked memory
- When using MSG_ZERCOCOPY, the buffer memory will be locked after queued, and
unlocked after it's sent.
- Depending on the size of each buffer, and how often it's sent, it may require
a larger amount of locked memory than usually available to non-root user.
- If the required amount of locked memory is not available, writev_zero_copy
will return an error, which can abort an operation like migration,
- Because of this, when an user code wants to add zero copy as a feature, it
requires a mechanism to disable it, so it can still be accessible to less
privileged users.

Signed-off-by: Leonardo Bras 
Reviewed-by: Peter Xu 
Reviewed-by: Daniel P. Berrangé 
Reviewed-by: Juan Quintela 
---
  include/io/channel-socket.h |   2 +
  io/channel-socket.c | 116 ++--
  2 files changed, 114 insertions(+), 4 deletions(-)

diff --git a/include/io/channel-socket.h b/include/io/channel-socket.h
index e747e63514..513c428fe4 100644
--- a/include/io/channel-socket.h
+++ b/include/io/channel-socket.h
@@ -47,6 +47,8 @@ struct QIOChannelSocket {
  socklen_t localAddrLen;
  struct sockaddr_storage remoteAddr;
  socklen_t remoteAddrLen;
+ssize_t zero_copy_queued;
+ssize_t zero_copy_sent;
  };
  
Hi, Leonardo. I'm also paying attention to the application of 
MSG_ZEROCOPY in live migration recently. I noticed that you defined a 
member `zero_copy_queued` in the struct QIOChannelSocket, but I can't 
find out where the value of this member has been changed in your patch. 
Can you answer it for me?




Re: [PATCH v10 13/14] vfio-user: handle device interrupts

2022-06-01 Thread Stefan Hajnoczi
On Wed, 1 Jun 2022 at 07:40, John Johnson  wrote:
>
> > On May 31, 2022, at 2:45 PM, Alex Williamson  
> > wrote:
> >
> > On Tue, 31 May 2022 22:03:14 +0100
> > Stefan Hajnoczi  wrote:
> >
> >> On Tue, 31 May 2022 at 21:11, Alex Williamson
> >>  wrote:
> >>>
> >>> On Tue, 31 May 2022 15:01:57 +
> >>> Jag Raman  wrote:
> >>>
> > On May 25, 2022, at 10:53 AM, Stefan Hajnoczi  
> > wrote:
> >
> > On Tue, May 24, 2022 at 11:30:32AM -0400, Jagannathan Raman wrote:
> >> Forward remote device's interrupts to the guest
> >>
> >> Signed-off-by: Elena Ufimtseva 
> >> Signed-off-by: John G Johnson 
> >> Signed-off-by: Jagannathan Raman 
> >> ---
> >> include/hw/pci/pci.h  |  13 
> >> include/hw/remote/vfio-user-obj.h |   6 ++
> >> hw/pci/msi.c  |  16 ++--
> >> hw/pci/msix.c |  10 ++-
> >> hw/pci/pci.c  |  13 
> >> hw/remote/machine.c   |  14 +++-
> >> hw/remote/vfio-user-obj.c | 123 ++
> >> stubs/vfio-user-obj.c |   6 ++
> >> MAINTAINERS   |   1 +
> >> hw/remote/trace-events|   1 +
> >> stubs/meson.build |   1 +
> >> 11 files changed, 193 insertions(+), 11 deletions(-)
> >> create mode 100644 include/hw/remote/vfio-user-obj.h
> >> create mode 100644 stubs/vfio-user-obj.c
> >
> > It would be great if Michael Tsirkin and Alex Williamson would review
> > this.
> 
>  Hi Michael and Alex,
> 
>  Do you have any thoughts on this patch?
> >>>
> >>> Ultimately this is just how to insert callbacks to replace the default
> >>> MSI/X triggers so you can send a vector# over the wire for a remote
> >>> machine, right?  I'll let the code owners, Michael and Marcel, comment
> >>> if they have grand vision how to architect this differently.  Thanks,
> >>
> >> An earlier version of the patch intercepted MSI-X at the msix_notify()
> >> level, replacing the entire function. This patch replaces
> >> msix_get_message() and msi_send_message(), leaving the masking logic
> >> in place.
> >>
> >> I haven't seen the latest vfio-user client implementation for QEMU,
> >> but if the idea is to allow the guest to directly control the
> >> vfio-user device's MSI-X table's mask bits, then I think this is a
> >> different design from VFIO kernel where masking is emulated by QEMU
> >> and not passed through to the PCI device.
> >
> > Essentially what's happening here is an implementation of an interrupt
> > handler callback in the remote QEMU instance.  The default handler is
> > to simply write the MSI message data at the MSI message address of the
> > vCPU, vfio-user replaces that with hijacking the MSI message itself to
> > simply report the vector# so that the "handler", ie. trigger, can
> > forward it to the client.  That's very analogous to the kernel
> > implementation.
> >
> > The equivalent masking we have today with vfio kernel would happen on
> > the client side, where the MSI/X code might instead set a pending bit
> > if the vector is masked on the client.  Likewise the possibility
> > remains, just as it does on the kernel side, that the guest masking a
> > vector could be relayed over ioctl/socket to set the equivalent mask on
> > the host/remote.
> >
> > I don't see a fundamental design difference here, but please point out
> > if I'm missing something.  Thanks,
> >
>
>
>
> I don’t think you’ve missed anything.  We were trying to stay
> close to the kernel implementation.

Okay.

Stefan



Re: [PATCH v2] tests/tcg/s390x: Test overflow conditions

2022-06-01 Thread David Hildenbrand
On 31.05.22 20:35, Gautam Agrawal wrote:
> Add a test to check for overflow conditions in s390x.
> This patch is based on the following patches :
> * https://git.qemu.org/?p=qemu.git;a=commitdiff;h=5a2e67a691501
> * https://git.qemu.org/?p=qemu.git;a=commitdiff;h=fc6e0d0f2db51
> 
> Signed-off-by: Gautam Agrawal 

Reviewed-by: David Hildenbrand 


-- 
Thanks,

David / dhildenb




Re: [PATCH v6 2/8] target/s390x: add zpci-interp to cpu models

2022-06-01 Thread David Hildenbrand
On 24.05.22 21:02, Matthew Rosato wrote:
> The zpci-interp feature is used to specify whether zPCI interpretation is
> to be used for this guest.

We have

DEF_FEAT(SIE_PFMFI, "pfmfi", SCLP_CONF_CHAR_EXT, 9, "SIE: PFMF
interpretation facility")

and

DEF_FEAT(SIE_SIGPIF, "sigpif", SCLP_CPU, 12, "SIE: SIGP interpretation
facility")


Should we call this simply "zpcii" or "zpciif" (if the official name
includes "Facility")

> 
> Signed-off-by: Matthew Rosato 
> ---
>  hw/s390x/s390-virtio-ccw.c  | 1 +
>  target/s390x/cpu_features_def.h.inc | 1 +
>  target/s390x/gen-features.c | 2 ++
>  target/s390x/kvm/kvm.c  | 1 +
>  4 files changed, 5 insertions(+)
> 
> diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
> index 047cca0487..b33310a135 100644
> --- a/hw/s390x/s390-virtio-ccw.c
> +++ b/hw/s390x/s390-virtio-ccw.c
> @@ -806,6 +806,7 @@ static void ccw_machine_7_0_instance_options(MachineState 
> *machine)
>  static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V7_0 };
>  
>  ccw_machine_7_1_instance_options(machine);
> +s390_cpudef_featoff_greater(14, 1, S390_FEAT_ZPCI_INTERP);
>  s390_set_qemu_cpu_model(0x8561, 15, 1, qemu_cpu_feat);
>  }
>  
> diff --git a/target/s390x/cpu_features_def.h.inc 
> b/target/s390x/cpu_features_def.h.inc
> index e86662bb3b..4ade3182aa 100644
> --- a/target/s390x/cpu_features_def.h.inc
> +++ b/target/s390x/cpu_features_def.h.inc
> @@ -146,6 +146,7 @@ DEF_FEAT(SIE_CEI, "cei", SCLP_CPU, 43, "SIE: 
> Conditional-external-interception f
>  DEF_FEAT(DAT_ENH_2, "dateh2", MISC, 0, "DAT-enhancement facility 2")
>  DEF_FEAT(CMM, "cmm", MISC, 0, "Collaborative-memory-management facility")
>  DEF_FEAT(AP, "ap", MISC, 0, "AP instructions installed")
> +DEF_FEAT(ZPCI_INTERP, "zpci-interp", MISC, 0, "zPCI interpretation")

How is this feature exposed to the guest, meaning, how can the guest
sense support?

Just a gut feeling: does this toggle enable the host to use
interpretation and the guest cannot really determine the difference
whether it's enabled or not? Then, it's not a guest CPU feature. But
let's hear first what this actually enables :)

>  
>  /* Features exposed via the PLO instruction. */
>  DEF_FEAT(PLO_CL, "plo-cl", PLO, 0, "PLO Compare and load (32 bit in general 
> registers)")
> diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c
> index c03ec2c9a9..f991646c01 100644
> --- a/target/s390x/gen-features.c
> +++ b/target/s390x/gen-features.c
> @@ -554,6 +554,7 @@ static uint16_t full_GEN14_GA1[] = {
>  S390_FEAT_HPMA2,
>  S390_FEAT_SIE_KSS,
>  S390_FEAT_GROUP_MULTIPLE_EPOCH_PTFF,
> +S390_FEAT_ZPCI_INTERP,
>  };
>  
>  #define full_GEN14_GA2 EmptyFeat
> @@ -650,6 +651,7 @@ static uint16_t default_GEN14_GA1[] = {
>  S390_FEAT_GROUP_MSA_EXT_8,
>  S390_FEAT_MULTIPLE_EPOCH,
>  S390_FEAT_GROUP_MULTIPLE_EPOCH_PTFF,
> +S390_FEAT_ZPCI_INTERP,

I'm curious, should we really add this to the default model?

This implies that on any setup where we don't have zpci interpretation
support (including missing kernel support), that a basic "-cpu z14" will
no longer work with the new machine type.

If, OTOH, we expect this feature to be around in any sane installation,
then it's good to include it in the

-- 
Thanks,

David / dhildenb




Re: [PATCH] target/ppc/cpu-models: Update max alias to power10

2022-06-01 Thread Daniel Henrique Barboza




On 6/1/22 06:25, Thomas Huth wrote:

On 01/06/2022 10.38, Greg Kurz wrote:

On Wed, 1 Jun 2022 09:27:31 +0200
Thomas Huth  wrote:


On 31/05/2022 19.27, Murilo Opsfelder Araujo wrote:

Update max alias to power10 so users can take advantage of a more
recent CPU model when '-cpu max' is provided.

...

We already have the concept of default CPU for the spapr
machine types, that is usually popped up to the newer
CPU model that is going to be supported in production.
This goes with a bump of the machine type version as
well for the sake of migration. This seems a lot more
reliable than the "max" thingy IMHO.

Unless there's a very important use case I'm missing,
I'd rather kill the thing instead of trying to resurrect
it.


It's about making ppc similar to other architectures, which
have "-cpu max" as well, see:

  https://gitlab.com/qemu-project/qemu/-/issues/1038

It would be nice to get something similar on ppc.



I agree that it's preferable to fix it.

This is how I would implement -cpu max today:

pseries (default ppc64 machine):
 - kvm: equal to -cpu host
 - tcg: the latest IBM chip available (POWER10 today)

powernv8: POWER8E
powernv9: POWER9
powernv10: POWER10

pseries requires more work because the -cpu max varies with the host CPU
when running with KVM.

About the implementation, for the bug fix it's fine to just hardcode the alias
for each machine-CPU pair. In the long run I would add more code to make -cpu 
max
always point to the current default CPU of the chosen machine by default, with
each machine overwriting it if needed. This would prevent this alias to be
deprecated over time because we forgot to change it after adding new CPUs.

For qemu-system-ppc the default machine seems to be g3beige and its default
CPU is PowerPC 750. I would set -cpu max to this CPU in this case. Matter of
fact I would attempt to set -cpu max = default cpu for all 32 bits CPUs for
simplicity. This is also outside of gitlab 1038 as well since the bug isn't
mentioning 32 bit machines, hence can be done later.


Thanks,

Daniel




By the way, the warnings that you currently get when running with
TCG are quite ugly, too:

$ ./qemu-system-ppc64
qemu-system-ppc64: warning: TCG doesn't support requested feature, 
cap-cfpc=workaround
qemu-system-ppc64: warning: TCG doesn't support requested feature, 
cap-sbbc=workaround
qemu-system-ppc64: warning: TCG doesn't support requested feature, 
cap-ibs=workaround
qemu-system-ppc64: warning: TCG doesn't support requested feature, 
cap-ccf-assist=on

Maybe these could get fixed with a proper "max" CPU in TCG
mode, too?

  Thomas






Re: [PATCH v4 0/9] Record/replay refactoring and stuff

2022-06-01 Thread Paolo Bonzini
Queued, thanks.

Paolo





Re: [PATCH 0/2] i386: fixup number of logical CPUs when host-cache-info=on

2022-06-01 Thread Paolo Bonzini

On 5/31/22 14:44, Igor Mammedov wrote:

Paolo,
  can you pick this up if it looks fine, please?

On Tue, 24 May 2022 11:10:18 -0400
Igor Mammedov  wrote:


Igor Mammedov (2):
   x86: cpu: make sure number of addressable IDs for processor cores
 meets the spec
   x86: cpu: fixup number of addressable IDs for logical processors
 sharing cache

  target/i386/cpu.c | 20 
  1 file changed, 16 insertions(+), 4 deletions(-)





Yup, queued now.  Thanks,

Paolo




Re: [PATCH] tests/Makefile.include: Fix 'make check-help' output

2022-06-01 Thread Paolo Bonzini
> + @echo " $(MAKE) check-report.junit.xml Generates an aggregated TAP test 
> report"

XML now rather than TAP; tweaked and queued, thanks.

Paolo





Re: [PATCH 0/9] tests, python: prepare to expand usage of test venv

2022-06-01 Thread Paolo Bonzini

On 5/27/22 16:27, John Snow wrote:
Paolo: I assume this falls under your jurisdiction...ish, unless Cleber 
(avocado) or Alex (tests more broadly) have any specific inputs.


I'm fine with waiting for reviews, but don't know whose bucket this goes to.



I thought it was yours, but I've queued it now.

Paolo




Re: [PATCH] target/ppc/cpu-models: Update max alias to power10

2022-06-01 Thread Greg Kurz
On Wed, 1 Jun 2022 11:25:43 +0200
Thomas Huth  wrote:

> On 01/06/2022 10.38, Greg Kurz wrote:
> > On Wed, 1 Jun 2022 09:27:31 +0200
> > Thomas Huth  wrote:
> > 
> >> On 31/05/2022 19.27, Murilo Opsfelder Araujo wrote:
> >>> Update max alias to power10 so users can take advantage of a more
> >>> recent CPU model when '-cpu max' is provided.
> ...
> > We already have the concept of default CPU for the spapr
> > machine types, that is usually popped up to the newer
> > CPU model that is going to be supported in production.
> > This goes with a bump of the machine type version as
> > well for the sake of migration. This seems a lot more
> > reliable than the "max" thingy IMHO.
> > 
> > Unless there's a very important use case I'm missing,
> > I'd rather kill the thing instead of trying to resurrect
> > it.
> 
> It's about making ppc similar to other architectures, which
> have "-cpu max" as well, see:
> 
>   https://gitlab.com/qemu-project/qemu/-/issues/1038
> 
> It would be nice to get something similar on ppc.
> 

Problem is that on ppc, given the variety of models and boards,
the concept of "max" is quite fuzzy... i.e. a lot of cases to
consider for a benefit that is unclear to me. Hence my questioning.
If the idea is just to match what other targets do without a specific
use case in mind, this looks quite useless to me.

> By the way, the warnings that you currently get when running with
> TCG are quite ugly, too:
> 
> $ ./qemu-system-ppc64
> qemu-system-ppc64: warning: TCG doesn't support requested feature, 
> cap-cfpc=workaround
> qemu-system-ppc64: warning: TCG doesn't support requested feature, 
> cap-sbbc=workaround
> qemu-system-ppc64: warning: TCG doesn't support requested feature, 
> cap-ibs=workaround
> qemu-system-ppc64: warning: TCG doesn't support requested feature, 
> cap-ccf-assist=on
> 
> Maybe these could get fixed with a proper "max" CPU in TCG
> mode, too?
> 

I don't think so. These warnings are the consequence of pseries
being the default machine for ppc64, and the default pseries
machine decides on the default CPU model and default values for
features (in this case, these are mitigations for spectre/meltdown).
TCG doesn't support them but we certainly don't want to add more
divergence between TCG and KVM.

Cheers,

--
Greg

>   Thomas
> 




Re: [PATCH 0/9] tests, python: prepare to expand usage of test venv

2022-06-01 Thread Paolo Bonzini

On 5/26/22 16:34, John Snow wrote:
(1) If check is engaged without running check-venv first and iotests 
creates its own venv, the python binary it uses will be whichever one is 
your system default, not necessarily the one you configured your build with.


This is reasonable behavior IMO, but if you later run "make check", 
there's no guarantee that Make will re-make the venv with the correct 
python binary  That's a subtle landmine.


Yup, that's also a reason to make initial venv creation part of 
configure.  I consider that on the same level as running Meson and 
setting up git submodules.


(2) Similarly, if the venv requirements.txt (or python/setup.cfg) 
change, iotests doesn't have the logic to notice it ought to re-make the 
venv. Only the makefile does. However, at least in this case, the 
makefile is guaranteed to notice if/when we run "check block" again. The 
odds of these files changing for most people who aren't *me* are pretty 
low, so it may not really come up much. Still, it's not bullet-proof.


Yeah, this is fine.  Compare it with e.g. running clang-query: it needs 
a "make" first to rebuild compile_commands.json.


Paolo

(Bonus not-at-all-subtle problem) I need to remove iotest 297, otherwise 
iotests under a venv that doesn't install mypy/pylint will never run. I 
discussed this upstream recently w/ Kevin, but my series to address it 
isn't ready yet. (Just pre-emptively pointing it out to say I'm aware of 
it!)





Re: Outreachy project task: Adding QEMU block layer APIs resembling Linux ZBD ioctls.

2022-06-01 Thread Sam Li
Hi Damien,

Damien Le Moal  于2022年6月1日周三 13:47写道:
>
> On 6/1/22 11:57, Sam Li wrote:
> > Hi Stefan,
> >
> > Stefan Hajnoczi  于2022年5月30日周一 19:19写道:
> >
> >
> >>
> >> On Mon, 30 May 2022 at 06:09, Sam Li  wrote:
> >>>
> >>> Hi everyone,
> >>> I'm Sam Li, working on the Outreachy project which is to add zoned
> >>> device support to QEMU's virtio-blk emulation.
> >>>
> >>> For the first goal, adding QEMU block layer APIs resembling Linux ZBD
> >>> ioctls, I think the naive approach would be to introduce a new stable
> >>> struct zbd_zone descriptor for the library function interface. More
> >>> specifically, what I'd like to add to the BlockDriver struct are:
> >>> 1. zbd_info as zone block device information: includes numbers of
> >>> zones, size of logical blocks, and physical blocks.
> >>> 2. zbd_zone_type and zbd_zone_state
> >>> 3. zbd_dev_model: host-managed zbd, host-aware zbd
> >>> With those basic structs, we can start to implement new functions as
> >>> bdrv*() APIs for BLOCK*ZONE ioctls.
> >>>
> >>> I'll start to finish this task based on the above description. If
> >>> there is any problem or something I may miss in the design, please let
> >>> me know.
> >>
> >> Hi Sam,
> >> Can you propose function prototypes for the new BlockDriver callbacks
> >> needed for zoned devices?
> >
> > I have made some modifications based on Damien's device in design part
> > 1 and added the function prototypes in design part 2. If there is any
> > problem or part I missed, please let me know.
> >
> > Design of Block Layer APIs in BlockDriver:
> > 1. introduce a new stable struct zbd_zone descriptor for the library
> > function interface.
> >   a. zbd_info as zone block device information: includes numbers of
> > zones, size of blocks, write granularity in byte(minimal write size
> > and alignment
> > - write granularity: 512e SMRs: writes in units of physical block
> > size, 4096 bytes; NVMe ZNS write granularity is equal to the block
> > size.
> > - zone descriptor: start, length, capacity, write pointer, zone type
> >   b. zbd_zone_type
> > - zone type: conventional, sequential write required, sequential
> > write preferred
> >   c. zbd_dev_model: host-managed zbd, host-aware zbd
>
> This explanation is a little hard to understand. It seems to be mixing up
> device level information and per-zone information. I think it would be a
> lot simpler to write a struct definition to directly illustrate what you
> are planning.
>
> It is something like this ?
>
> struct zbd_zone {
> enum zone_type  type;
> enum zone_cond  cond;
> uint64_tstart;
> uint32_tlength;
> uint32_tcap;
> uint64_twp;
> };
>
> strcut zbd_dev {
> enum zone_model model;
> uint32_tblock_size;
> uint32_twrite_granularity;
> uint32_tnr_zones
> struct zbd_zone *zones; /* array of zones */
> };
>

Yes! Sorry that I was not very clear in the descriptions.

> If yes, then my comments are as follows.
>
> For the device struct: It may be good to have also the maximum number of
> open zones and the maximum number of active zones.
>
> For the zone struct: You may need to add a read-write lock per zone to be
> able to write lock zones to ensure a sequential write pattern (virtio
> devices can be multi-queue and so writes may be coming in from different
> contexts) and to correctly emulate zone append operations with an atomic
> update of the wp field.
>

Yes, I haven't thought through the thread-safety problem but I'll come
up with an approach.

> These need to be integrated into the generic block driver interface in
> include/block/block_int-common.h or include/block/block-common.h.
>
> >
> >  2. implement new functions as bdrv*() APIs for BLK*ZONE ioctls
> >a. support basic operations: get the APIs working when executing
> > the zone operations from a guest
> > - zone information access: report
> > - zone manipulation: reset,open,close,finish
>
> These operations are generally referred to as "zone management" operations.
>
> >   b. support zone append operation: zone capacity, write pointer
> > positions of all zones(excluded for now)
> > - can track the zone state we need: zone is full or not.
> >
> > More specifically, the function prototypes for 2a are as follows:
> >
> > int zbd_report_zones(int fd, off_t offset, off_t len, enum
> > zbd_report_opetion ro, struct zbd_zone *zones, unsigned int
> > *nr_zones);
>
> The current virtio zone specification draft does not have a reporting
> option field for the report zones command. However, it has a "partial"
> field that will need to be passed to this function so that the correct
> report zones reply can be built by the driver.
>
> > int zbd_reset_zones(int fd, off_t offset, off_t len);
> > int zbd_open_zones(int fd, off_t offset, off_t len);
> > int zbd_close_zones(int fd, off_t offset, off_t len);
> > int zbd_finish_zones(int fd, off_t offset,

Re: [PATCH v6 3/8] mm/memfd: Introduce MFD_INACCESSIBLE flag

2022-06-01 Thread Chao Peng
On Tue, May 31, 2022 at 12:15:00PM -0700, Vishal Annapurve wrote:
> On Thu, May 19, 2022 at 8:41 AM Chao Peng  wrote:
> >
> > Introduce a new memfd_create() flag indicating the content of the
> > created memfd is inaccessible from userspace through ordinary MMU
> > access (e.g., read/write/mmap). However, the file content can be
> > accessed via a different mechanism (e.g. KVM MMU) indirectly.
> >
> 
> SEV, TDX, pkvm and software-only VMs seem to have usecases to set up
> initial guest boot memory with the needed blobs.
> TDX already supports a KVM IOCTL to transfer contents to private
> memory using the TDX module but rest of the implementations will need
> to invent
> a way to do this.

There are some discussions in https://lkml.org/lkml/2022/5/9/1292
already. I somehow agree with Sean. TDX is using an dedicated ioctl to
copy guest boot memory to private fd so the rest can do that similarly.
The concern is the performance (extra memcpy) but it's trivial since the
initial guest payload is usually optimized in size.

> 
> Is there a plan to support a common implementation for either allowing
> initial write access from userspace to private fd or adding a KVM
> IOCTL to transfer contents to such a file,
> as part of this series through future revisions?

Indeed, adding pre-boot private memory populating on current design
isn't impossible, but there are still some opens, e.g. how to expose
private fd to userspace for access, pKVM and CC usages may have
different requirements. Before that's well-studied I would tend to not
add that and instead use an ioctl to copy. Whether we need a generic
ioctl or feature-specific ioctl, I don't have strong opinion here.
Current TDX uses a feature-specific ioctl so it's not covered in this
series.

Chao
> 
> Regards,
> Vishal



[PATCH v6 08/43] target/loongarch: Add fixed point atomic instruction translation

2022-06-01 Thread Xiaojuan Yang
From: Song Gao 

This includes:
- LL.{W/D}, SC.{W/D}
- AM{SWAP/ADD/AND/OR/XOR/MAX/MIN}[_DB].{W/D}
- AM{MAX/MIN}[_DB].{WU/DU}

Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
Reviewed-by: Richard Henderson 
---
 .../loongarch/insn_trans/trans_atomic.c.inc   | 113 ++
 .../loongarch/insn_trans/trans_memory.c.inc   |   2 +-
 target/loongarch/insns.decode |  44 +++
 target/loongarch/translate.c  |   1 +
 4 files changed, 159 insertions(+), 1 deletion(-)
 create mode 100644 target/loongarch/insn_trans/trans_atomic.c.inc

diff --git a/target/loongarch/insn_trans/trans_atomic.c.inc 
b/target/loongarch/insn_trans/trans_atomic.c.inc
new file mode 100644
index 00..6763c1c301
--- /dev/null
+++ b/target/loongarch/insn_trans/trans_atomic.c.inc
@@ -0,0 +1,113 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+static bool gen_ll(DisasContext *ctx, arg_rr_i *a, MemOp mop)
+{
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv t0 = tcg_temp_new();
+
+tcg_gen_addi_tl(t0, src1, a->imm);
+tcg_gen_qemu_ld_i64(dest, t0, ctx->mem_idx, mop);
+tcg_gen_st_tl(t0, cpu_env, offsetof(CPULoongArchState, lladdr));
+tcg_gen_st_tl(dest, cpu_env, offsetof(CPULoongArchState, llval));
+gen_set_gpr(a->rd, dest, EXT_NONE);
+tcg_temp_free(t0);
+
+return true;
+}
+
+static bool gen_sc(DisasContext *ctx, arg_rr_i *a, MemOp mop)
+{
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv src2 = gpr_src(ctx, a->rd, EXT_NONE);
+TCGv t0 = tcg_temp_new();
+TCGv val = tcg_temp_new();
+
+TCGLabel *l1 = gen_new_label();
+TCGLabel *done = gen_new_label();
+
+tcg_gen_addi_tl(t0, src1, a->imm);
+tcg_gen_brcond_tl(TCG_COND_EQ, t0, cpu_lladdr, l1);
+tcg_gen_movi_tl(dest, 0);
+tcg_gen_br(done);
+
+gen_set_label(l1);
+tcg_gen_mov_tl(val, src2);
+/* generate cmpxchg */
+tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval,
+  val, ctx->mem_idx, mop);
+tcg_gen_setcond_tl(TCG_COND_EQ, dest, t0, cpu_llval);
+gen_set_label(done);
+gen_set_gpr(a->rd, dest, EXT_NONE);
+tcg_temp_free(t0);
+tcg_temp_free(val);
+
+return true;
+}
+
+static bool gen_am(DisasContext *ctx, arg_rrr *a,
+   void (*func)(TCGv, TCGv, TCGv, TCGArg, MemOp),
+   MemOp mop)
+{
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+TCGv addr = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv val = gpr_src(ctx, a->rk, EXT_NONE);
+
+if (a->rd != 0 && (a->rj == a->rd || a->rk == a->rd)) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "Warning: source register overlaps destination register"
+  "in atomic insn at pc=0x" TARGET_FMT_lx "\n",
+  ctx->base.pc_next - 4);
+return false;
+}
+
+func(dest, addr, val, ctx->mem_idx, mop);
+gen_set_gpr(a->rd, dest, EXT_NONE);
+
+return true;
+}
+
+TRANS(ll_w, gen_ll, MO_TESL)
+TRANS(sc_w, gen_sc, MO_TESL)
+TRANS(ll_d, gen_ll, MO_TEUQ)
+TRANS(sc_d, gen_sc, MO_TEUQ)
+TRANS(amswap_w, gen_am, tcg_gen_atomic_xchg_tl, MO_TESL)
+TRANS(amswap_d, gen_am, tcg_gen_atomic_xchg_tl, MO_TEUQ)
+TRANS(amadd_w, gen_am, tcg_gen_atomic_fetch_add_tl, MO_TESL)
+TRANS(amadd_d, gen_am, tcg_gen_atomic_fetch_add_tl, MO_TEUQ)
+TRANS(amand_w, gen_am, tcg_gen_atomic_fetch_and_tl, MO_TESL)
+TRANS(amand_d, gen_am, tcg_gen_atomic_fetch_and_tl, MO_TEUQ)
+TRANS(amor_w, gen_am, tcg_gen_atomic_fetch_or_tl, MO_TESL)
+TRANS(amor_d, gen_am, tcg_gen_atomic_fetch_or_tl, MO_TEUQ)
+TRANS(amxor_w, gen_am, tcg_gen_atomic_fetch_xor_tl, MO_TESL)
+TRANS(amxor_d, gen_am, tcg_gen_atomic_fetch_xor_tl, MO_TEUQ)
+TRANS(ammax_w, gen_am, tcg_gen_atomic_fetch_smax_tl, MO_TESL)
+TRANS(ammax_d, gen_am, tcg_gen_atomic_fetch_smax_tl, MO_TEUQ)
+TRANS(ammin_w, gen_am, tcg_gen_atomic_fetch_smin_tl, MO_TESL)
+TRANS(ammin_d, gen_am, tcg_gen_atomic_fetch_smin_tl, MO_TEUQ)
+TRANS(ammax_wu, gen_am, tcg_gen_atomic_fetch_umax_tl, MO_TESL)
+TRANS(ammax_du, gen_am, tcg_gen_atomic_fetch_umax_tl, MO_TEUQ)
+TRANS(ammin_wu, gen_am, tcg_gen_atomic_fetch_umin_tl, MO_TESL)
+TRANS(ammin_du, gen_am, tcg_gen_atomic_fetch_umin_tl, MO_TEUQ)
+TRANS(amswap_db_w, gen_am, tcg_gen_atomic_xchg_tl, MO_TESL)
+TRANS(amswap_db_d, gen_am, tcg_gen_atomic_xchg_tl, MO_TEUQ)
+TRANS(amadd_db_w, gen_am, tcg_gen_atomic_fetch_add_tl, MO_TESL)
+TRANS(amadd_db_d, gen_am, tcg_gen_atomic_fetch_add_tl, MO_TEUQ)
+TRANS(amand_db_w, gen_am, tcg_gen_atomic_fetch_and_tl, MO_TESL)
+TRANS(amand_db_d, gen_am, tcg_gen_atomic_fetch_and_tl, MO_TEUQ)
+TRANS(amor_db_w, gen_am, tcg_gen_atomic_fetch_or_tl, MO_TESL)
+TRANS(amor_db_d, gen_am, tcg_gen_atomic_fetch_or_tl, MO_TEUQ)
+TRANS(amxor_db_w, gen_am, tcg_gen_atomic_fetch_xor_tl, MO_TESL)
+TRANS(amxor_db_d, gen_am, tcg_gen_atomic_fetch_xor_tl, MO_TEUQ)
+TRANS(ammax_

[PATCH v6 07/43] target/loongarch: Add fixed point load/store instruction translation

2022-06-01 Thread Xiaojuan Yang
From: Song Gao 

This includes:
- LD.{B[U]/H[U]/W[U]/D}, ST.{B/H/W/D}
- LDX.{B[U]/H[U]/W[U]/D}, STX.{B/H/W/D}
- LDPTR.{W/D}, STPTR.{W/D}
- PRELD
- LD{GT/LE}.{B/H/W/D}, ST{GT/LE}.{B/H/W/D}
- DBAR, IBAR

Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
Reviewed-by: Richard Henderson 
---
 target/loongarch/helper.h |   3 +
 .../loongarch/insn_trans/trans_memory.c.inc   | 229 ++
 target/loongarch/insns.decode |  55 +
 target/loongarch/op_helper.c  |  15 ++
 target/loongarch/translate.c  |   6 +
 5 files changed, 308 insertions(+)
 create mode 100644 target/loongarch/insn_trans/trans_memory.c.inc

diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index 04e0245d5e..100622bfc2 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -8,3 +8,6 @@ DEF_HELPER_2(raise_exception, noreturn, env, i32)
 DEF_HELPER_FLAGS_1(bitrev_w, TCG_CALL_NO_RWG_SE, tl, tl)
 DEF_HELPER_FLAGS_1(bitrev_d, TCG_CALL_NO_RWG_SE, tl, tl)
 DEF_HELPER_FLAGS_1(bitswap, TCG_CALL_NO_RWG_SE, tl, tl)
+
+DEF_HELPER_FLAGS_3(asrtle_d, TCG_CALL_NO_WG, void, env, tl, tl)
+DEF_HELPER_FLAGS_3(asrtgt_d, TCG_CALL_NO_WG, void, env, tl, tl)
diff --git a/target/loongarch/insn_trans/trans_memory.c.inc 
b/target/loongarch/insn_trans/trans_memory.c.inc
new file mode 100644
index 00..10914acf52
--- /dev/null
+++ b/target/loongarch/insn_trans/trans_memory.c.inc
@@ -0,0 +1,229 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+static bool gen_load(DisasContext *ctx, arg_rr_i *a, MemOp mop)
+{
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+TCGv addr = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv temp = NULL;
+
+if (a->imm) {
+temp = tcg_temp_new();
+tcg_gen_addi_tl(temp, addr, a->imm);
+addr = temp;
+}
+
+tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, mop);
+gen_set_gpr(a->rd, dest, EXT_NONE);
+
+if (temp) {
+tcg_temp_free(temp);
+}
+
+return true;
+}
+
+static bool gen_store(DisasContext *ctx, arg_rr_i *a, MemOp mop)
+{
+TCGv data = gpr_src(ctx, a->rd, EXT_NONE);
+TCGv addr = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv temp = NULL;
+
+if (a->imm) {
+temp = tcg_temp_new();
+tcg_gen_addi_tl(temp, addr, a->imm);
+addr = temp;
+}
+
+tcg_gen_qemu_st_tl(data, addr, ctx->mem_idx, mop);
+
+if (temp) {
+tcg_temp_free(temp);
+}
+
+return true;
+}
+
+static bool gen_loadx(DisasContext *ctx, arg_rrr *a, MemOp mop)
+{
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
+TCGv addr = tcg_temp_new();
+
+tcg_gen_add_tl(addr, src1, src2);
+tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, mop);
+gen_set_gpr(a->rd, dest, EXT_NONE);
+tcg_temp_free(addr);
+
+return true;
+}
+
+static bool gen_storex(DisasContext *ctx, arg_rrr *a, MemOp mop)
+{
+TCGv data = gpr_src(ctx, a->rd, EXT_NONE);
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
+TCGv addr = tcg_temp_new();
+
+tcg_gen_add_tl(addr, src1, src2);
+tcg_gen_qemu_st_tl(data, addr, ctx->mem_idx, mop);
+tcg_temp_free(addr);
+
+return true;
+}
+
+static bool gen_load_gt(DisasContext *ctx, arg_rrr *a, MemOp mop)
+{
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
+
+gen_helper_asrtgt_d(cpu_env, src1, src2);
+tcg_gen_qemu_ld_tl(dest, src1, ctx->mem_idx, mop);
+gen_set_gpr(a->rd, dest, EXT_NONE);
+
+return true;
+}
+
+static bool gen_load_le(DisasContext *ctx, arg_rrr *a, MemOp mop)
+{
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
+
+gen_helper_asrtle_d(cpu_env, src1, src2);
+tcg_gen_qemu_ld_tl(dest, src1, ctx->mem_idx, mop);
+gen_set_gpr(a->rd, dest, EXT_NONE);
+
+return true;
+}
+
+static bool gen_store_gt(DisasContext *ctx, arg_rrr *a, MemOp mop)
+{
+TCGv data = gpr_src(ctx, a->rd, EXT_NONE);
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
+
+gen_helper_asrtgt_d(cpu_env, src1, src2);
+tcg_gen_qemu_st_tl(data, src1, ctx->mem_idx, mop);
+
+return true;
+}
+
+static bool gen_store_le(DisasContext *ctx, arg_rrr *a, MemOp mop)
+{
+TCGv data = gpr_src(ctx, a->rd, EXT_NONE);
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
+
+gen_helper_asrtle_d(cpu_env, src1, src2);
+tcg_gen_qemu_st_tl(data, src1, ctx->mem_idx, mop);
+
+return true;
+}
+
+static bool trans_preld(DisasContext *ctx, arg_preld *a)
+{
+return true;
+}
+
+static bool trans_dbar(DisasContext *ctx, arg_dbar * a)
+{
+tcg_gen_mb(T

[PATCH v6 13/43] target/loongarch: Add floating point move instruction translation

2022-06-01 Thread Xiaojuan Yang
From: Song Gao 

This includes:
- FMOV.{S/D}
- FSEL
- MOVGR2FR.{W/D}, MOVGR2FRH.W
- MOVFR2GR.{S/D}, MOVFRH2GR.S
- MOVGR2FCSR, MOVFCSR2GR
- MOVFR2CF, MOVCF2FR
- MOVGR2CF, MOVCF2GR

Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
Reviewed-by: Richard Henderson 
---
 target/loongarch/fpu_helper.c|   6 +
 target/loongarch/helper.h|   2 +
 target/loongarch/insn_trans/trans_fmov.c.inc | 157 +++
 target/loongarch/insns.decode|  37 +
 target/loongarch/translate.c |   1 +
 5 files changed, 203 insertions(+)
 create mode 100644 target/loongarch/insn_trans/trans_fmov.c.inc

diff --git a/target/loongarch/fpu_helper.c b/target/loongarch/fpu_helper.c
index 81466678eb..3d0cb8dd0d 100644
--- a/target/loongarch/fpu_helper.c
+++ b/target/loongarch/fpu_helper.c
@@ -854,3 +854,9 @@ uint64_t helper_ftint_w_d(CPULoongArchState *env, uint64_t 
fj)
 update_fcsr0(env, GETPC());
 return fd;
 }
+
+void helper_set_rounding_mode(CPULoongArchState *env, uint32_t fcsr0)
+{
+set_float_rounding_mode(ieee_rm[(fcsr0 >> FCSR0_RM) & 0x3],
+&env->fp_status);
+}
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index 1e8749433a..da1a2bced7 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -90,3 +90,5 @@ DEF_HELPER_2(ftint_w_s, i64, env, i64)
 DEF_HELPER_2(ftint_w_d, i64, env, i64)
 DEF_HELPER_2(frint_s, i64, env, i64)
 DEF_HELPER_2(frint_d, i64, env, i64)
+
+DEF_HELPER_FLAGS_2(set_rounding_mode, TCG_CALL_NO_RWG, void, env, i32)
diff --git a/target/loongarch/insn_trans/trans_fmov.c.inc 
b/target/loongarch/insn_trans/trans_fmov.c.inc
new file mode 100644
index 00..24753d4568
--- /dev/null
+++ b/target/loongarch/insn_trans/trans_fmov.c.inc
@@ -0,0 +1,157 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+static const uint32_t fcsr_mask[4] = {
+UINT32_MAX, FCSR0_M1, FCSR0_M2, FCSR0_M3
+};
+
+static bool trans_fsel(DisasContext *ctx, arg_fsel *a)
+{
+TCGv zero = tcg_constant_tl(0);
+TCGv cond = tcg_temp_new();
+
+tcg_gen_ld8u_tl(cond, cpu_env, offsetof(CPULoongArchState, cf[a->ca]));
+tcg_gen_movcond_tl(TCG_COND_EQ, cpu_fpr[a->fd], cond, zero,
+   cpu_fpr[a->fj], cpu_fpr[a->fk]);
+tcg_temp_free(cond);
+
+return true;
+}
+
+static bool gen_f2f(DisasContext *ctx, arg_ff *a,
+void (*func)(TCGv, TCGv), bool nanbox)
+{
+TCGv dest = cpu_fpr[a->fd];
+TCGv src = cpu_fpr[a->fj];
+
+func(dest, src);
+if (nanbox) {
+gen_nanbox_s(cpu_fpr[a->fd], cpu_fpr[a->fd]);
+}
+
+return true;
+}
+
+static bool gen_r2f(DisasContext *ctx, arg_fr *a,
+void (*func)(TCGv, TCGv))
+{
+TCGv src = gpr_src(ctx, a->rj, EXT_NONE);
+
+func(cpu_fpr[a->fd], src);
+return true;
+}
+
+static bool gen_f2r(DisasContext *ctx, arg_rf *a,
+void (*func)(TCGv, TCGv))
+{
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+
+func(dest, cpu_fpr[a->fj]);
+gen_set_gpr(a->rd, dest, EXT_NONE);
+
+return true;
+}
+
+static bool trans_movgr2fcsr(DisasContext *ctx, arg_movgr2fcsr *a)
+{
+uint32_t mask = fcsr_mask[a->fcsrd];
+TCGv Rj = gpr_src(ctx, a->rj, EXT_NONE);
+
+if (mask == UINT32_MAX) {
+tcg_gen_extrl_i64_i32(cpu_fcsr0, Rj);
+} else {
+TCGv_i32 temp = tcg_temp_new_i32();
+
+tcg_gen_extrl_i64_i32(temp, Rj);
+tcg_gen_andi_i32(temp, temp, mask);
+tcg_gen_andi_i32(cpu_fcsr0, cpu_fcsr0, ~mask);
+tcg_gen_or_i32(cpu_fcsr0, cpu_fcsr0, temp);
+tcg_temp_free_i32(temp);
+
+/*
+ * Install the new rounding mode to fpu_status, if changed.
+ * Note that FCSR3 is exactly the rounding mode field.
+ */
+if (mask != FCSR0_M3) {
+return true;
+}
+}
+gen_helper_set_rounding_mode(cpu_env, cpu_fcsr0);
+
+return true;
+}
+
+static bool trans_movfcsr2gr(DisasContext *ctx, arg_movfcsr2gr *a)
+{
+TCGv_i32 temp = tcg_temp_new_i32();
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+
+tcg_gen_andi_i32(temp, cpu_fcsr0, fcsr_mask[a->fcsrs]);
+tcg_gen_ext_i32_i64(dest, temp);
+gen_set_gpr(a->rd, dest, EXT_NONE);
+tcg_temp_free_i32(temp);
+
+return true;
+}
+
+static void gen_movgr2fr_w(TCGv dest, TCGv src)
+{
+tcg_gen_deposit_i64(dest, dest, src, 0, 32);
+}
+
+static void gen_movgr2frh_w(TCGv dest, TCGv src)
+{
+tcg_gen_deposit_i64(dest, dest, src, 32, 32);
+}
+
+static void gen_movfrh2gr_s(TCGv dest, TCGv src)
+{
+tcg_gen_sextract_tl(dest, src, 32, 32);
+}
+
+static bool trans_movfr2cf(DisasContext *ctx, arg_movfr2cf *a)
+{
+TCGv t0 = tcg_temp_new();
+
+tcg_gen_andi_tl(t0, cpu_fpr[a->fj], 0x1);
+tcg_gen_st8_tl(t0, cpu_env, offsetof(CPULoongArchState, cf[a->cd & 0x7]));
+tcg_temp_free(t0);
+
+return true;
+}
+
+static bool

[PATCH v6 11/43] target/loongarch: Add floating point comparison instruction translation

2022-06-01 Thread Xiaojuan Yang
From: Song Gao 

This includes:
- FCMP.cond.{S/D}

Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
Reviewed-by: Richard Henderson 
---
 target/loongarch/fpu_helper.c| 60 
 target/loongarch/helper.h|  9 +++
 target/loongarch/insn_trans/trans_fcmp.c.inc | 56 ++
 target/loongarch/insns.decode|  8 +++
 target/loongarch/internals.h |  5 ++
 target/loongarch/translate.c |  1 +
 6 files changed, 139 insertions(+)
 create mode 100644 target/loongarch/insn_trans/trans_fcmp.c.inc

diff --git a/target/loongarch/fpu_helper.c b/target/loongarch/fpu_helper.c
index d7442cc188..1e514cce74 100644
--- a/target/loongarch/fpu_helper.c
+++ b/target/loongarch/fpu_helper.c
@@ -401,3 +401,63 @@ uint64_t helper_fmuladd_d(CPULoongArchState *env, uint64_t 
fj,
 update_fcsr0(env, GETPC());
 return fd;
 }
+
+static uint64_t fcmp_common(CPULoongArchState *env, FloatRelation cmp,
+uint32_t flags)
+{
+bool ret;
+
+switch (cmp) {
+case float_relation_less:
+ret = (flags & FCMP_LT);
+break;
+case float_relation_equal:
+ret = (flags & FCMP_EQ);
+break;
+case float_relation_greater:
+ret = (flags & FCMP_GT);
+break;
+case float_relation_unordered:
+ret = (flags & FCMP_UN);
+break;
+default:
+g_assert_not_reached();
+}
+update_fcsr0(env, GETPC());
+
+return ret;
+}
+
+/* fcmp_cXXX_s */
+uint64_t helper_fcmp_c_s(CPULoongArchState *env, uint64_t fj,
+ uint64_t fk, uint32_t flags)
+{
+FloatRelation cmp = float32_compare_quiet((uint32_t)fj,
+  (uint32_t)fk, &env->fp_status);
+return fcmp_common(env, cmp, flags);
+}
+
+/* fcmp_sXXX_s */
+uint64_t helper_fcmp_s_s(CPULoongArchState *env, uint64_t fj,
+ uint64_t fk, uint32_t flags)
+{
+FloatRelation cmp = float32_compare((uint32_t)fj,
+(uint32_t)fk, &env->fp_status);
+return fcmp_common(env, cmp, flags);
+}
+
+/* fcmp_cXXX_d */
+uint64_t helper_fcmp_c_d(CPULoongArchState *env, uint64_t fj,
+ uint64_t fk, uint32_t flags)
+{
+FloatRelation cmp = float64_compare_quiet(fj, fk, &env->fp_status);
+return fcmp_common(env, cmp, flags);
+}
+
+/* fcmp_sXXX_d */
+uint64_t helper_fcmp_s_d(CPULoongArchState *env, uint64_t fj,
+ uint64_t fk, uint32_t flags)
+{
+FloatRelation cmp = float64_compare(fj, fk, &env->fp_status);
+return fcmp_common(env, cmp, flags);
+}
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index 840bad9b2f..25a891bf8b 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -52,3 +52,12 @@ DEF_HELPER_FLAGS_2(frecip_d, TCG_CALL_NO_WG, i64, env, i64)
 
 DEF_HELPER_FLAGS_2(fclass_s, TCG_CALL_NO_RWG_SE, i64, env, i64)
 DEF_HELPER_FLAGS_2(fclass_d, TCG_CALL_NO_RWG_SE, i64, env, i64)
+
+/* fcmp.cXXX.s */
+DEF_HELPER_4(fcmp_c_s, i64, env, i64, i64, i32)
+/* fcmp.sXXX.s */
+DEF_HELPER_4(fcmp_s_s, i64, env, i64, i64, i32)
+/* fcmp.cXXX.d */
+DEF_HELPER_4(fcmp_c_d, i64, env, i64, i64, i32)
+/* fcmp.sXXX.d */
+DEF_HELPER_4(fcmp_s_d, i64, env, i64, i64, i32)
diff --git a/target/loongarch/insn_trans/trans_fcmp.c.inc 
b/target/loongarch/insn_trans/trans_fcmp.c.inc
new file mode 100644
index 00..93a6a2230f
--- /dev/null
+++ b/target/loongarch/insn_trans/trans_fcmp.c.inc
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+/* bit0(signaling/quiet) bit1(lt) bit2(eq) bit3(un) bit4(neq) */
+static uint32_t get_fcmp_flags(int cond)
+{
+uint32_t flags = 0;
+
+if (cond & 0x1) {
+flags |= FCMP_LT;
+}
+if (cond & 0x2) {
+flags |= FCMP_EQ;
+}
+if (cond & 0x4) {
+flags |= FCMP_UN;
+}
+if (cond & 0x8) {
+flags |= FCMP_GT | FCMP_LT;
+}
+return flags;
+}
+
+static bool trans_fcmp_cond_s(DisasContext *ctx, arg_fcmp_cond_s *a)
+{
+TCGv var = tcg_temp_new();
+uint32_t flags;
+void (*fn)(TCGv, TCGv_env, TCGv, TCGv, TCGv_i32);
+
+fn = (a->fcond & 1 ? gen_helper_fcmp_s_s : gen_helper_fcmp_c_s);
+flags = get_fcmp_flags(a->fcond >> 1);
+
+fn(var, cpu_env, cpu_fpr[a->fj], cpu_fpr[a->fk], tcg_constant_i32(flags));
+
+tcg_gen_st8_tl(var, cpu_env, offsetof(CPULoongArchState, cf[a->cd]));
+tcg_temp_free(var);
+return true;
+}
+
+static bool trans_fcmp_cond_d(DisasContext *ctx, arg_fcmp_cond_d *a)
+{
+TCGv var = tcg_temp_new();
+uint32_t flags;
+void (*fn)(TCGv, TCGv_env, TCGv, TCGv, TCGv_i32);
+fn = (a->fcond & 1 ? gen_helper_fcmp_s_d : gen_helper_fcmp_c_d);
+flags = get_fcmp_flags(a->fcond >> 1);
+
+fn(var, cpu_env, cpu_fpr[a->fj], cpu_fpr[a->fk], tcg_constant_i32(flags));
+
+tcg_gen_st8_tl(var

[PATCH v6 15/43] target/loongarch: Add branch instruction translation

2022-06-01 Thread Xiaojuan Yang
From: Song Gao 

This includes:
- BEQ, BNE, BLT[U], BGE[U]
- BEQZ, BNEZ
- B
- BL
- JIRL
- BCEQZ, BCNEZ

Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
Reviewed-by: Richard Henderson 
---
 .../loongarch/insn_trans/trans_branch.c.inc   | 83 +++
 target/loongarch/insns.decode | 28 +++
 target/loongarch/translate.c  |  1 +
 3 files changed, 112 insertions(+)
 create mode 100644 target/loongarch/insn_trans/trans_branch.c.inc

diff --git a/target/loongarch/insn_trans/trans_branch.c.inc 
b/target/loongarch/insn_trans/trans_branch.c.inc
new file mode 100644
index 00..65dbdff41e
--- /dev/null
+++ b/target/loongarch/insn_trans/trans_branch.c.inc
@@ -0,0 +1,83 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+static bool trans_b(DisasContext *ctx, arg_b *a)
+{
+gen_goto_tb(ctx, 0, ctx->base.pc_next + a->offs);
+ctx->base.is_jmp = DISAS_NORETURN;
+return true;
+}
+
+static bool trans_bl(DisasContext *ctx, arg_bl *a)
+{
+tcg_gen_movi_tl(cpu_gpr[1], ctx->base.pc_next + 4);
+gen_goto_tb(ctx, 0, ctx->base.pc_next + a->offs);
+ctx->base.is_jmp = DISAS_NORETURN;
+return true;
+}
+
+static bool trans_jirl(DisasContext *ctx, arg_jirl *a)
+{
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+
+tcg_gen_addi_tl(cpu_pc, src1, a->offs);
+tcg_gen_movi_tl(dest, ctx->base.pc_next + 4);
+gen_set_gpr(a->rd, dest, EXT_NONE);
+tcg_gen_lookup_and_goto_ptr();
+ctx->base.is_jmp = DISAS_NORETURN;
+return true;
+}
+
+static void gen_bc(DisasContext *ctx, TCGv src1, TCGv src2,
+   target_long offs, TCGCond cond)
+{
+TCGLabel *l = gen_new_label();
+tcg_gen_brcond_tl(cond, src1, src2, l);
+gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
+gen_set_label(l);
+gen_goto_tb(ctx, 0, ctx->base.pc_next + offs);
+ctx->base.is_jmp = DISAS_NORETURN;
+}
+
+static bool gen_rr_bc(DisasContext *ctx, arg_rr_offs *a, TCGCond cond)
+{
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv src2 = gpr_src(ctx, a->rd, EXT_NONE);
+
+gen_bc(ctx, src1, src2, a->offs, cond);
+return true;
+}
+
+static bool gen_rz_bc(DisasContext *ctx, arg_r_offs *a, TCGCond cond)
+{
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv src2 = tcg_constant_tl(0);
+
+gen_bc(ctx, src1, src2, a->offs, cond);
+return true;
+}
+
+static bool gen_cz_bc(DisasContext *ctx, arg_c_offs *a, TCGCond cond)
+{
+TCGv src1 = tcg_temp_new();
+TCGv src2 = tcg_constant_tl(0);
+
+tcg_gen_ld8u_tl(src1, cpu_env,
+offsetof(CPULoongArchState, cf[a->cj]));
+gen_bc(ctx, src1, src2, a->offs, cond);
+return true;
+}
+
+TRANS(beq, gen_rr_bc, TCG_COND_EQ)
+TRANS(bne, gen_rr_bc, TCG_COND_NE)
+TRANS(blt, gen_rr_bc, TCG_COND_LT)
+TRANS(bge, gen_rr_bc, TCG_COND_GE)
+TRANS(bltu, gen_rr_bc, TCG_COND_LTU)
+TRANS(bgeu, gen_rr_bc, TCG_COND_GEU)
+TRANS(beqz, gen_rz_bc, TCG_COND_EQ)
+TRANS(bnez, gen_rz_bc, TCG_COND_NE)
+TRANS(bceqz, gen_cz_bc, TCG_COND_EQ)
+TRANS(bcnez, gen_cz_bc, TCG_COND_NE)
diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode
index 8f286e7233..9b293dfdf9 100644
--- a/target/loongarch/insns.decode
+++ b/target/loongarch/insns.decode
@@ -10,6 +10,9 @@
 #
 %i14s2 10:s14   !function=shl_2
 %sa2p1 15:2 !function=plus_1
+%offs210:s5 10:16   !function=shl_2
+%offs1610:s16   !function=shl_2
+%offs260:s10 10:16  !function=shl_2
 
 #
 # Argument sets
@@ -38,6 +41,10 @@
 &rc   rd cj
 &frr  fd rj rk
 &fr_i fd rj imm
+&r_offs   rj offs
+&c_offs   cj offs
+&offs offs
+&rr_offs  rj rd offs
 
 #
 # Formats
@@ -74,6 +81,10 @@
 @rc  . . .. cj:3 rd:5&rc
 @frr     . rk:5 rj:5 fd:5&frr
 @fr_i12  .. imm:s12 rj:5 fd:5&fr_i
+@r_offs21  ..  rj:5 .&r_offs  
offs=%offs21
+@c_offs21   ..  .. cj:3 .&c_offs  
offs=%offs21
+@offs26 .. ..&offs
offs=%offs26
+@rr_offs16  ..  rj:5 rd:5&rr_offs 
offs=%offs16
 
 #
 # Fixed point arithmetic operation instruction
@@ -409,3 +420,20 @@ fstgt_s 0011 1111 01100 . . .
@frr
 fstgt_d 0011 1111 01101 . . .@frr
 fstle_s 0011 1111 01110 . . .@frr
 fstle_d 0011 1111 0 . . .@frr
+
+#
+# Branch instructions
+#
+beqz0100 00  . . @r_offs21
+bnez0100 01  . . @r_offs21
+bceqz   0100 10  00 ... .@c_offs21
+bcnez   0100 10  01 ... .@c_offs21
+jirl0100 11 

[PATCH v6 01/43] target/loongarch: Add README

2022-06-01 Thread Xiaojuan Yang
From: Song Gao 

This patch gives an introduction to the LoongArch target.

Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
Reviewed-by: Richard Henderson 
---
 MAINTAINERS |  6 ++
 target/loongarch/README | 10 ++
 2 files changed, 16 insertions(+)
 create mode 100644 target/loongarch/README

diff --git a/MAINTAINERS b/MAINTAINERS
index 00dc4a8ecb..64f2d6c235 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -212,6 +212,12 @@ S: Maintained
 F: target/hppa/
 F: disas/hppa.c
 
+LoongArch TCG CPUs
+M: Song Gao 
+M: Xiaojuan Yang 
+S: Maintained
+F: target/loongarch/
+
 M68K TCG CPUs
 M: Laurent Vivier 
 S: Maintained
diff --git a/target/loongarch/README b/target/loongarch/README
new file mode 100644
index 00..de141c1a58
--- /dev/null
+++ b/target/loongarch/README
@@ -0,0 +1,10 @@
+- Introduction
+
+  LoongArch is the general processor architecture of Loongson.
+
+  The following versions of the LoongArch core are supported
+core: 3A5000
+
https://github.com/loongson/LoongArch-Documentation/releases/download/2021.08.17/LoongArch-Vol1-v1.00-EN.pdf
+
+  We can get the latest loongarch documents at 
https://github.com/loongson/LoongArch-Documentation/tags.
+
-- 
2.31.1




[PATCH v6 23/43] target/loongarch: Add LoongArch interrupt and exception handle

2022-06-01 Thread Xiaojuan Yang
Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
Reviewed-by: Richard Henderson 
---
 target/loongarch/cpu.c   | 230 +++
 target/loongarch/cpu.h   |   2 +
 target/loongarch/internals.h |   2 +
 3 files changed, 234 insertions(+)

diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 8c8b10d601..8d8dfdd961 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -80,6 +80,215 @@ static void loongarch_cpu_set_pc(CPUState *cs, vaddr value)
 env->pc = value;
 }
 
+void loongarch_cpu_set_irq(void *opaque, int irq, int level)
+{
+LoongArchCPU *cpu = opaque;
+CPULoongArchState *env = &cpu->env;
+CPUState *cs = CPU(cpu);
+
+if (irq < 0 || irq >= N_IRQS) {
+return;
+}
+
+env->CSR_ESTAT = deposit64(env->CSR_ESTAT, irq, 1, level != 0);
+
+if (FIELD_EX64(env->CSR_ESTAT, CSR_ESTAT, IS)) {
+cpu_interrupt(cs, CPU_INTERRUPT_HARD);
+} else {
+cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
+}
+}
+
+static inline bool cpu_loongarch_hw_interrupts_enabled(CPULoongArchState *env)
+{
+bool ret = 0;
+
+ret = (FIELD_EX64(env->CSR_CRMD, CSR_CRMD, IE) &&
+  !(FIELD_EX64(env->CSR_DBG, CSR_DBG, DST)));
+
+return ret;
+}
+
+/* Check if there is pending and not masked out interrupt */
+static inline bool cpu_loongarch_hw_interrupts_pending(CPULoongArchState *env)
+{
+uint32_t pending;
+uint32_t status;
+bool r;
+
+pending = FIELD_EX64(env->CSR_ESTAT, CSR_ESTAT, IS);
+status  = FIELD_EX64(env->CSR_ECFG, CSR_ECFG, LIE);
+
+r = (pending & status) != 0;
+return r;
+}
+
+static void loongarch_cpu_do_interrupt(CPUState *cs)
+{
+LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+CPULoongArchState *env = &cpu->env;
+bool update_badinstr = 1;
+int cause = -1;
+const char *name;
+bool tlbfill = FIELD_EX64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR);
+uint32_t vec_size = FIELD_EX64(env->CSR_ECFG, CSR_ECFG, VS);
+
+if (cs->exception_index != EXCCODE_INT) {
+if (cs->exception_index < 0 ||
+cs->exception_index > ARRAY_SIZE(excp_names)) {
+name = "unknown";
+} else {
+name = excp_names[cs->exception_index];
+}
+
+qemu_log_mask(CPU_LOG_INT,
+ "%s enter: pc " TARGET_FMT_lx " ERA " TARGET_FMT_lx
+ " TLBRERA " TARGET_FMT_lx " %s exception\n", __func__,
+ env->pc, env->CSR_ERA, env->CSR_TLBRERA, name);
+}
+
+switch (cs->exception_index) {
+case EXCCODE_DBP:
+env->CSR_DBG = FIELD_DP64(env->CSR_DBG, CSR_DBG, DCL, 1);
+env->CSR_DBG = FIELD_DP64(env->CSR_DBG, CSR_DBG, ECODE, 0xC);
+goto set_DERA;
+set_DERA:
+env->CSR_DERA = env->pc;
+env->CSR_DBG = FIELD_DP64(env->CSR_DBG, CSR_DBG, DST, 1);
+env->pc = env->CSR_EENTRY + 0x480;
+break;
+case EXCCODE_INT:
+if (FIELD_EX64(env->CSR_DBG, CSR_DBG, DST)) {
+env->CSR_DBG = FIELD_DP64(env->CSR_DBG, CSR_DBG, DEI, 1);
+goto set_DERA;
+}
+QEMU_FALLTHROUGH;
+case EXCCODE_PIF:
+cause = cs->exception_index;
+update_badinstr = 0;
+break;
+case EXCCODE_ADEM:
+case EXCCODE_SYS:
+case EXCCODE_BRK:
+case EXCCODE_PIL:
+case EXCCODE_PIS:
+case EXCCODE_PME:
+case EXCCODE_PNR:
+case EXCCODE_PNX:
+case EXCCODE_PPI:
+case EXCCODE_INE:
+case EXCCODE_IPE:
+case EXCCODE_FPE:
+cause = cs->exception_index;
+break;
+default:
+qemu_log("Error: exception(%d) '%s' has not been supported\n",
+ cs->exception_index, excp_names[cs->exception_index]);
+abort();
+}
+
+if (update_badinstr) {
+env->CSR_BADI = cpu_ldl_code(env, env->pc);
+}
+
+/* Save PLV and IE */
+if (tlbfill) {
+env->CSR_TLBRPRMD = FIELD_DP64(env->CSR_TLBRPRMD, CSR_TLBRPRMD, PPLV,
+   FIELD_EX64(env->CSR_CRMD,
+   CSR_CRMD, PLV));
+env->CSR_TLBRPRMD = FIELD_DP64(env->CSR_TLBRPRMD, CSR_TLBRPRMD, PIE,
+   FIELD_EX64(env->CSR_CRMD, CSR_CRMD, 
IE));
+/* set the DA mode */
+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_TLBRERA = FIELD_DP64(env->CSR_TLBRERA, CSR_TLBRERA,
+  PC, (env->pc >> 2));
+} else {
+env->CSR_ESTAT = FIELD_DP64(env->CSR_ESTAT, CSR_ESTAT, ECODE, cause);
+env->CSR_PRMD = FIELD_DP64(env->CSR_PRMD, CSR_PRMD, PPLV,
+   FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV));
+env->CSR_PRMD = FIELD_DP64(env->CSR_PRMD, CSR_PRMD, PIE,
+   FIELD_EX64(env->CSR_CRMD, CSR_CRMD, IE));
+env->CSR_ERA = env->pc;
+}
+
+env->CSR_C

[PATCH v6 20/43] target/loongarch: Add basic vmstate description of CPU.

2022-06-01 Thread Xiaojuan Yang
Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
Reviewed-by: Richard Henderson 
---
 target/loongarch/cpu.c   |  1 +
 target/loongarch/internals.h |  2 +
 target/loongarch/machine.c   | 85 
 target/loongarch/meson.build |  6 +++
 4 files changed, 94 insertions(+)
 create mode 100644 target/loongarch/machine.c

diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index b863f495db..c44b2b16a9 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -331,6 +331,7 @@ static void loongarch_cpu_class_init(ObjectClass *c, void 
*data)
 cc->class_by_name = loongarch_cpu_class_by_name;
 cc->dump_state = loongarch_cpu_dump_state;
 cc->set_pc = loongarch_cpu_set_pc;
+dc->vmsd = &vmstate_loongarch_cpu;
 cc->disas_set_info = loongarch_cpu_disas_set_info;
 #ifdef CONFIG_TCG
 cc->tcg_ops = &loongarch_tcg_ops;
diff --git a/target/loongarch/internals.h b/target/loongarch/internals.h
index 1a3b39e0be..39960dee27 100644
--- a/target/loongarch/internals.h
+++ b/target/loongarch/internals.h
@@ -25,4 +25,6 @@ const char *loongarch_exception_name(int32_t exception);
 
 void restore_fp_status(CPULoongArchState *env);
 
+extern const VMStateDescription vmstate_loongarch_cpu;
+
 #endif
diff --git a/target/loongarch/machine.c b/target/loongarch/machine.c
new file mode 100644
index 00..49a06fdf28
--- /dev/null
+++ b/target/loongarch/machine.c
@@ -0,0 +1,85 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * QEMU LoongArch Machine State
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "migration/cpu.h"
+
+/* LoongArch CPU state */
+
+const VMStateDescription vmstate_loongarch_cpu = {
+.name = "cpu",
+.version_id = 0,
+.minimum_version_id = 0,
+.fields = (VMStateField[]) {
+
+VMSTATE_UINTTL_ARRAY(env.gpr, LoongArchCPU, 32),
+VMSTATE_UINTTL(env.pc, LoongArchCPU),
+VMSTATE_UINT64_ARRAY(env.fpr, LoongArchCPU, 32),
+VMSTATE_UINT32(env.fcsr0, LoongArchCPU),
+VMSTATE_BOOL_ARRAY(env.cf, LoongArchCPU, 8),
+
+/* Remaining CSRs */
+VMSTATE_UINT64(env.CSR_CRMD, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_PRMD, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_EUEN, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_MISC, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_ECFG, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_ESTAT, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_ERA, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_BADV, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_BADI, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_EENTRY, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TLBIDX, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TLBEHI, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TLBELO0, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TLBELO1, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_ASID, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_PGDL, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_PGDH, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_PGD, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_PWCL, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_PWCH, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_STLBPS, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_RVACFG, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_PRCFG1, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_PRCFG2, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_PRCFG3, LoongArchCPU),
+VMSTATE_UINT64_ARRAY(env.CSR_SAVE, LoongArchCPU, 16),
+VMSTATE_UINT64(env.CSR_TID, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TCFG, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TVAL, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_CNTC, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TICLR, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_LLBCTL, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_IMPCTL1, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_IMPCTL2, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TLBRENTRY, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TLBRBADV, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TLBRERA, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TLBRSAVE, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TLBRELO0, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TLBRELO1, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TLBREHI, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_TLBRPRMD, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_MERRCTL, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_MERRINFO1, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_MERRINFO2, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_MERRENTRY, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_MERRERA, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_MERRSAVE, LoongArchCPU),
+VMSTATE_UINT64(env.CSR_CTAG, LoongArchCPU),
+VMSTATE_UINT64_ARRAY(env.CSR_DMW, LoongArchCPU, 4),
+
+/* Debug CSRs */
+VMSTATE_UINT64(env.CSR_DBG, LoongArc

[PATCH v6 18/43] target/loongarch: Add system emulation introduction

2022-06-01 Thread Xiaojuan Yang
Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
Reviewed-by: Richard Henderson 
---
 MAINTAINERS |  8 +
 docs/system/loongarch/loongson3.rst | 41 ++
 target/loongarch/README | 54 +
 3 files changed, 103 insertions(+)
 create mode 100644 docs/system/loongarch/loongson3.rst

diff --git a/MAINTAINERS b/MAINTAINERS
index 64f2d6c235..896cfa54c6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1123,6 +1123,14 @@ F: include/hw/net/lasi_82596.h
 F: include/hw/pci-host/dino.h
 F: pc-bios/hppa-firmware.img
 
+LoongArch Machines
+--
+Virt
+M: Xiaojuan Yang 
+M: Song Gao 
+S: Maintained
+F: docs/system/loongarch/loongson3.rst
+
 M68K Machines
 -
 an5206
diff --git a/docs/system/loongarch/loongson3.rst 
b/docs/system/loongarch/loongson3.rst
new file mode 100644
index 00..fa3acd01c0
--- /dev/null
+++ b/docs/system/loongarch/loongson3.rst
@@ -0,0 +1,41 @@
+:orphan:
+
+==
+loongson3 virt generic platform (``virt``)
+==
+
+The ``virt`` machine use gpex host bridge, and there are some
+emulated devices on virt board, such as loongson7a RTC device,
+IOAPIC device, ACPI device and so on.
+
+Supported devices
+-
+
+The ``virt`` machine supports:
+- Gpex host bridge
+- Ls7a RTC device
+- Ls7a IOAPIC device
+- Ls7a ACPI device
+- Fw_cfg device
+- PCI/PCIe devices
+- Memory device
+- CPU device. Type: Loongson-3A5000.
+
+CPU and machine Type
+
+
+The ``qemu-system-loongarch64`` provides emulation for virt
+machine. You can specify the machine type ``virt`` and
+cpu type ``Loongson-3A5000``.
+
+Boot options
+
+
+Now the ``virt`` machine can run test program in ELF format and the
+method of compiling is in target/loongarch/README.
+
+.. code-block:: bash
+
+  $ qemu-system-loongarch64 -machine virt -m 4G -cpu Loongson-3A5000 \
+  -smp 1 -kernel hello -monitor none -display none \
+  -chardev file,path=hello.out,id=output -serial chardev:output
diff --git a/target/loongarch/README b/target/loongarch/README
index de141c1a58..4dcd0f1682 100644
--- a/target/loongarch/README
+++ b/target/loongarch/README
@@ -8,3 +8,57 @@
 
   We can get the latest loongarch documents at 
https://github.com/loongson/LoongArch-Documentation/tags.
 
+
+- System emulation
+
+  Mainly emulate a virt 3A5000 board and ls7a bridge that is not exactly the 
same as the host.
+  3A5000 support multiple interrupt cascading while here we just emulate the 
extioi interrupt
+  cascading. LS7A1000 host bridge support multiple devices, such as sata, 
gmac, uart, rtc
+  and so on. But we just realize the rtc. Others use the qemu common devices. 
It does not affect
+  the general use. We also introduced the emulation of devices at 
docs/system/loongarch/loongson3.rst.
+
+  This version only supports running binary files in ELF format, and does not 
depend on BIOS and kernel file.
+  You can compile the test program with 'make & make check-tcg' and run the 
test case with the following command:
+
+  1. Install LoongArch cross-tools on X86 machines.
+
+Download cross-tools.
+
+  wget 
https://github.com/loongson/build-tools/releases/latest/download/loongarch64-clfs-20211202-cross-tools.tar.xz
+
+  tar -vxf loongarch64-clfs-20211202-cross-tools.tar.xz -C /opt
+
+Config cross-tools env.
+
+  . setenv.sh
+
+  setenv.sh:
+
+  #!/bin/sh
+  set -x
+  CC_PREFIX=/opt/cross-tools
+
+  export PATH=$CC_PREFIX/bin:$PATH
+  export LD_LIBRARY_PATH=$CC_PREFIX/lib:$LD_LIBRARY_PATH
+  export 
LD_LIBRARY_PATH=$CC_PREFIX/loongarch64-unknown-linux-gnu/lib/:$LD_LIBRARY_PATH
+  set +x
+
+  2. Test tests/tcg/multiarch.
+
+./configure --disable-rdma --disable-pvrdma --prefix=/usr  \
+--target-list="loongarch64-softmmu"  \
+--disable-libiscsi --disable-libnfs --disable-libpmem \
+--disable-glusterfs --enable-libusb --enable-usb-redir \
+--disable-opengl --disable-xen --enable-spice --disable-werror \
+--enable-debug --disable-capstone --disable-kvm --enable-profiler
+
+cd  build/
+
+make && make check-tcg
+
+or
+
+./build/qemu-system-loongarch64 -machine virt -m 4G -cpu Loongson-3A5000 
-smp 1 -kernel build/tests/tcg/loongarch64-softmmu/hello -monitor none -display 
none -chardev file,path=hello.out,id=output -serial chardev:output
+
+- Note.
+  We can get the latest LoongArch documents or LoongArch tools at 
https://github.com/loongson/
-- 
2.31.1




[PATCH v6 06/43] target/loongarch: Add fixed point bit instruction translation

2022-06-01 Thread Xiaojuan Yang
From: Song Gao 

This includes:
- EXT.W.{B/H}
- CL{O/Z}.{W/D}, CT{O/Z}.{W/D}
- BYTEPICK.{W/D}
- REVB.{2H/4H/2W/D}
- REVH.{2W/D}
- BITREV.{4B/8B}, BITREV.{W/D}
- BSTRINS.{W/D}, BSTRPICK.{W/D}
- MASKEQZ, MASKNEZ

Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
Reviewed-by: Richard Henderson 
---
 target/loongarch/helper.h   |   4 +
 target/loongarch/insn_trans/trans_bit.c.inc | 212 
 target/loongarch/insns.decode   |  39 
 target/loongarch/op_helper.c|  21 ++
 target/loongarch/translate.c|   1 +
 5 files changed, 277 insertions(+)
 create mode 100644 target/loongarch/insn_trans/trans_bit.c.inc

diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index eb771c0628..04e0245d5e 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -4,3 +4,7 @@
  */
 
 DEF_HELPER_2(raise_exception, noreturn, env, i32)
+
+DEF_HELPER_FLAGS_1(bitrev_w, TCG_CALL_NO_RWG_SE, tl, tl)
+DEF_HELPER_FLAGS_1(bitrev_d, TCG_CALL_NO_RWG_SE, tl, tl)
+DEF_HELPER_FLAGS_1(bitswap, TCG_CALL_NO_RWG_SE, tl, tl)
diff --git a/target/loongarch/insn_trans/trans_bit.c.inc 
b/target/loongarch/insn_trans/trans_bit.c.inc
new file mode 100644
index 00..9337714ec4
--- /dev/null
+++ b/target/loongarch/insn_trans/trans_bit.c.inc
@@ -0,0 +1,212 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+static bool gen_rr(DisasContext *ctx, arg_rr *a,
+   DisasExtend src_ext, DisasExtend dst_ext,
+   void (*func)(TCGv, TCGv))
+{
+TCGv dest = gpr_dst(ctx, a->rd, dst_ext);
+TCGv src1 = gpr_src(ctx, a->rj, src_ext);
+
+func(dest, src1);
+gen_set_gpr(a->rd, dest, dst_ext);
+
+return true;
+}
+
+static void gen_bytepick_w(TCGv dest, TCGv src1, TCGv src2, target_long sa)
+{
+tcg_gen_concat_tl_i64(dest, src1, src2);
+tcg_gen_sextract_i64(dest, dest, (32 - sa * 8), 32);
+}
+
+static void gen_bytepick_d(TCGv dest, TCGv src1, TCGv src2, target_long sa)
+{
+tcg_gen_extract2_i64(dest, src1, src2, (64 - sa * 8));
+}
+
+static void gen_bstrins(TCGv dest, TCGv src1,
+unsigned int ls, unsigned int len)
+{
+tcg_gen_deposit_tl(dest, dest, src1, ls, len);
+}
+
+static bool gen_rr_ms_ls(DisasContext *ctx, arg_rr_ms_ls *a,
+ DisasExtend src_ext, DisasExtend dst_ext,
+ void (*func)(TCGv, TCGv, unsigned int, unsigned int))
+{
+TCGv dest = gpr_dst(ctx, a->rd, dst_ext);
+TCGv src1 = gpr_src(ctx, a->rj, src_ext);
+
+if (a->ls > a->ms) {
+return false;
+}
+
+func(dest, src1, a->ls, a->ms - a->ls + 1);
+gen_set_gpr(a->rd, dest, dst_ext);
+
+return true;
+}
+
+static void gen_clz_w(TCGv dest, TCGv src1)
+{
+tcg_gen_clzi_tl(dest, src1, TARGET_LONG_BITS);
+tcg_gen_subi_tl(dest, dest, TARGET_LONG_BITS - 32);
+}
+
+static void gen_clo_w(TCGv dest, TCGv src1)
+{
+tcg_gen_not_tl(dest, src1);
+tcg_gen_ext32u_tl(dest, dest);
+gen_clz_w(dest, dest);
+}
+
+static void gen_ctz_w(TCGv dest, TCGv src1)
+{
+tcg_gen_ori_tl(dest, src1, (target_ulong)MAKE_64BIT_MASK(32, 32));
+tcg_gen_ctzi_tl(dest, dest, TARGET_LONG_BITS);
+}
+
+static void gen_cto_w(TCGv dest, TCGv src1)
+{
+tcg_gen_not_tl(dest, src1);
+gen_ctz_w(dest, dest);
+}
+
+static void gen_clz_d(TCGv dest, TCGv src1)
+{
+tcg_gen_clzi_i64(dest, src1, TARGET_LONG_BITS);
+}
+
+static void gen_clo_d(TCGv dest, TCGv src1)
+{
+tcg_gen_not_tl(dest, src1);
+gen_clz_d(dest, dest);
+}
+
+static void gen_ctz_d(TCGv dest, TCGv src1)
+{
+tcg_gen_ctzi_tl(dest, src1, TARGET_LONG_BITS);
+}
+
+static void gen_cto_d(TCGv dest, TCGv src1)
+{
+tcg_gen_not_tl(dest, src1);
+gen_ctz_d(dest, dest);
+}
+
+static void gen_revb_2w(TCGv dest, TCGv src1)
+{
+tcg_gen_bswap64_i64(dest, src1);
+tcg_gen_rotri_i64(dest, dest, 32);
+}
+
+static void gen_revb_2h(TCGv dest, TCGv src1)
+{
+TCGv mask = tcg_constant_tl(0x00FF00FF);
+TCGv t0 = tcg_temp_new();
+TCGv t1 = tcg_temp_new();
+
+tcg_gen_shri_tl(t0, src1, 8);
+tcg_gen_and_tl(t0, t0, mask);
+tcg_gen_and_tl(t1, src1, mask);
+tcg_gen_shli_tl(t1, t1, 8);
+tcg_gen_or_tl(dest, t0, t1);
+
+tcg_temp_free(t0);
+tcg_temp_free(t1);
+}
+
+static void gen_revb_4h(TCGv dest, TCGv src1)
+{
+TCGv mask = tcg_constant_tl(0x00FF00FF00FF00FFULL);
+TCGv t0 = tcg_temp_new();
+TCGv t1 = tcg_temp_new();
+
+tcg_gen_shri_tl(t0, src1, 8);
+tcg_gen_and_tl(t0, t0, mask);
+tcg_gen_and_tl(t1, src1, mask);
+tcg_gen_shli_tl(t1, t1, 8);
+tcg_gen_or_tl(dest, t0, t1);
+
+tcg_temp_free(t0);
+tcg_temp_free(t1);
+}
+
+static void gen_revh_2w(TCGv dest, TCGv src1)
+{
+TCGv_i64 t0 = tcg_temp_new_i64();
+TCGv_i64 t1 = tcg_temp_new_i64();
+TCGv_i64 mask = tcg_constant_i64(0xull);
+
+tcg_gen_shri_i64(t0, src1, 16);
+tcg_gen_

[PATCH v6 09/43] target/loongarch: Add fixed point extra instruction translation

2022-06-01 Thread Xiaojuan Yang
From: Song Gao 

This includes:
- CRC[C].W.{B/H/W/D}.W
- SYSCALL
- BREAK
- ASRT{LE/GT}.D
- RDTIME{L/H}.W, RDTIME.D
- CPUCFG

Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
Reviewed-by: Richard Henderson 
---
 target/loongarch/helper.h |  4 ++
 target/loongarch/insn_trans/trans_extra.c.inc | 68 +++
 target/loongarch/insns.decode | 19 ++
 target/loongarch/op_helper.c  | 26 +++
 target/loongarch/translate.c  |  1 +
 5 files changed, 118 insertions(+)
 create mode 100644 target/loongarch/insn_trans/trans_extra.c.inc

diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index 100622bfc2..638c2efc51 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -11,3 +11,7 @@ DEF_HELPER_FLAGS_1(bitswap, TCG_CALL_NO_RWG_SE, tl, tl)
 
 DEF_HELPER_FLAGS_3(asrtle_d, TCG_CALL_NO_WG, void, env, tl, tl)
 DEF_HELPER_FLAGS_3(asrtgt_d, TCG_CALL_NO_WG, void, env, tl, tl)
+
+DEF_HELPER_FLAGS_3(crc32, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl)
+DEF_HELPER_FLAGS_3(crc32c, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl)
+DEF_HELPER_FLAGS_2(cpucfg, TCG_CALL_NO_RWG_SE, tl, env, tl)
diff --git a/target/loongarch/insn_trans/trans_extra.c.inc 
b/target/loongarch/insn_trans/trans_extra.c.inc
new file mode 100644
index 00..549f75a867
--- /dev/null
+++ b/target/loongarch/insn_trans/trans_extra.c.inc
@@ -0,0 +1,68 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+static bool trans_break(DisasContext *ctx, arg_break *a)
+{
+generate_exception(ctx, EXCCODE_BRK);
+return true;
+}
+
+static bool trans_syscall(DisasContext *ctx, arg_syscall *a)
+{
+generate_exception(ctx, EXCCODE_SYS);
+return true;
+}
+
+static bool trans_asrtle_d(DisasContext *ctx, arg_asrtle_d * a)
+{
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
+
+gen_helper_asrtle_d(cpu_env, src1, src2);
+return true;
+}
+
+static bool trans_asrtgt_d(DisasContext *ctx, arg_asrtgt_d * a)
+{
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
+
+gen_helper_asrtgt_d(cpu_env, src1, src2);
+return true;
+}
+
+static bool trans_cpucfg(DisasContext *ctx, arg_cpucfg *a)
+{
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+
+gen_helper_cpucfg(dest, cpu_env, src1);
+gen_set_gpr(a->rd, dest, EXT_NONE);
+
+return true;
+}
+
+static bool gen_crc(DisasContext *ctx, arg_rrr *a,
+void (*func)(TCGv, TCGv, TCGv, TCGv),
+TCGv tsz)
+{
+TCGv dest = gpr_dst(ctx, a->rd, EXT_SIGN);
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
+
+func(dest, src2, src1, tsz);
+gen_set_gpr(a->rd, dest, EXT_SIGN);
+
+return true;
+}
+
+TRANS(crc_w_b_w, gen_crc, gen_helper_crc32, tcg_constant_tl(1))
+TRANS(crc_w_h_w, gen_crc, gen_helper_crc32, tcg_constant_tl(2))
+TRANS(crc_w_w_w, gen_crc, gen_helper_crc32, tcg_constant_tl(4))
+TRANS(crc_w_d_w, gen_crc, gen_helper_crc32, tcg_constant_tl(8))
+TRANS(crcc_w_b_w, gen_crc, gen_helper_crc32c, tcg_constant_tl(1))
+TRANS(crcc_w_h_w, gen_crc, gen_helper_crc32c, tcg_constant_tl(2))
+TRANS(crcc_w_w_w, gen_crc, gen_helper_crc32c, tcg_constant_tl(4))
+TRANS(crcc_w_d_w, gen_crc, gen_helper_crc32c, tcg_constant_tl(8))
diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode
index 8d247aa68c..98774dbddb 100644
--- a/target/loongarch/insns.decode
+++ b/target/loongarch/insns.decode
@@ -17,6 +17,7 @@
 &iimm
 &r_i  rd imm
 &rr   rd rj
+&rr_jkrj rk
 &rrr  rd rj rk
 &rr_i rd rj imm
 &hint_r_i hint rj imm
@@ -28,6 +29,7 @@
 #
 @i15     . imm:15&i
 @rr     . . rj:5 rd:5&rr
+@rr_jk  . rk:5 rj:5 .&rr_jk
 @rrr     . rk:5 rj:5 rd:5&rrr
 @r_i20   ... imm:s20 rd:5&r_i
 @rr_ui5     . imm:5 rj:5 rd:5&rr_i
@@ -237,3 +239,20 @@ ammax_db_wu 0011 1111 0 . . .
@rrr
 ammax_db_du 0011 1111 1 . . .@rrr
 ammin_db_wu 0011 1111 00010 . . .@rrr
 ammin_db_du 0011 1111 00011 . . .@rrr
+
+#
+# Fixed point extra instruction
+#
+crc_w_b_w    0010 01000 . . .@rrr
+crc_w_h_w    0010 01001 . . .@rrr
+crc_w_w_w    0010 01010 . . .@rrr
+crc_w_d_w    0010 01011 . . .@rrr
+crcc_w_b_w   0010 01100 . . .@rrr
+crcc_w_h_w   0010 01101 . . .@rrr
+crcc_w_w_w   0010 01110 . . .@rrr
+crcc_w_d_w  0

[PATCH v6 21/43] target/loongarch: Implement qmp_query_cpu_definitions()

2022-06-01 Thread Xiaojuan Yang
Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
Reviewed-by: Richard Henderson 
---
 qapi/machine-target.json |  6 --
 target/loongarch/cpu.c   | 26 ++
 2 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/qapi/machine-target.json b/qapi/machine-target.json
index 06b0d2ca61..2e267fa458 100644
--- a/qapi/machine-target.json
+++ b/qapi/machine-target.json
@@ -323,7 +323,8 @@
'TARGET_ARM',
'TARGET_I386',
'TARGET_S390X',
-   'TARGET_MIPS' ] } }
+   'TARGET_MIPS',
+   'TARGET_LOONGARCH64' ] } }
 
 ##
 # @query-cpu-definitions:
@@ -339,4 +340,5 @@
'TARGET_ARM',
'TARGET_I386',
'TARGET_S390X',
-   'TARGET_MIPS' ] } }
+   'TARGET_MIPS',
+   'TARGET_LOONGARCH64' ] } }
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index c44b2b16a9..bb31502ff9 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -360,3 +360,29 @@ static const TypeInfo loongarch_cpu_type_infos[] = {
 };
 
 DEFINE_TYPES(loongarch_cpu_type_infos)
+
+static void loongarch_cpu_add_definition(gpointer data, gpointer user_data)
+{
+ObjectClass *oc = data;
+CpuDefinitionInfoList **cpu_list = user_data;
+CpuDefinitionInfo *info = g_new0(CpuDefinitionInfo, 1);
+const char *typename = object_class_get_name(oc);
+
+info->name = g_strndup(typename,
+   strlen(typename) - strlen("-" TYPE_LOONGARCH_CPU));
+info->q_typename = g_strdup(typename);
+
+QAPI_LIST_PREPEND(*cpu_list, info);
+}
+
+CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
+{
+CpuDefinitionInfoList *cpu_list = NULL;
+GSList *list;
+
+list = object_class_get_list(TYPE_LOONGARCH_CPU, false);
+g_slist_foreach(list, loongarch_cpu_add_definition, &cpu_list);
+g_slist_free(list);
+
+return cpu_list;
+}
-- 
2.31.1




[PATCH v6 25/43] target/loongarch: Add LoongArch CSR instruction

2022-06-01 Thread Xiaojuan Yang
This includes:
- CSRRD
- CSRWR
- CSRXCHG

Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
Reviewed-by: Richard Henderson 
---
 target/loongarch/csr_helper.c |  87 ++
 target/loongarch/disas.c  | 101 +++
 target/loongarch/helper.h |   8 +
 .../insn_trans/trans_privileged.c.inc | 264 ++
 target/loongarch/insns.decode |  13 +
 target/loongarch/meson.build  |   1 +
 target/loongarch/translate.c  |  11 +-
 7 files changed, 484 insertions(+), 1 deletion(-)
 create mode 100644 target/loongarch/csr_helper.c
 create mode 100644 target/loongarch/insn_trans/trans_privileged.c.inc

diff --git a/target/loongarch/csr_helper.c b/target/loongarch/csr_helper.c
new file mode 100644
index 00..24a9389364
--- /dev/null
+++ b/target/loongarch/csr_helper.c
@@ -0,0 +1,87 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * LoongArch emulation helpers for CSRs
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/main-loop.h"
+#include "cpu.h"
+#include "internals.h"
+#include "qemu/host-utils.h"
+#include "exec/helper-proto.h"
+#include "exec/exec-all.h"
+#include "exec/cpu_ldst.h"
+#include "hw/irq.h"
+#include "cpu-csr.h"
+#include "tcg/tcg-ldst.h"
+
+target_ulong helper_csrrd_pgd(CPULoongArchState *env)
+{
+int64_t v;
+
+if (env->CSR_TLBRERA & 0x1) {
+v = env->CSR_TLBRBADV;
+} else {
+v = env->CSR_BADV;
+}
+
+if ((v >> 63) & 0x1) {
+v = env->CSR_PGDH;
+} else {
+v = env->CSR_PGDL;
+}
+
+return v;
+}
+
+target_ulong helper_csrrd_tval(CPULoongArchState *env)
+{
+LoongArchCPU *cpu = env_archcpu(env);
+
+return cpu_loongarch_get_constant_timer_ticks(cpu);
+}
+
+target_ulong helper_csrwr_estat(CPULoongArchState *env, target_ulong val)
+{
+int64_t old_v = env->CSR_ESTAT;
+
+/* Only IS[1:0] can be written */
+env->CSR_ESTAT = deposit64(env->CSR_ESTAT, 0, 2, val);
+
+return old_v;
+}
+
+target_ulong helper_csrwr_asid(CPULoongArchState *env, target_ulong val)
+{
+int64_t old_v = env->CSR_ASID;
+
+/* Only ASID filed of CSR_ASID can be written */
+env->CSR_ASID = deposit64(env->CSR_ASID, 0, 10, val);
+if (old_v != env->CSR_ASID) {
+tlb_flush(env_cpu(env));
+}
+return old_v;
+}
+
+target_ulong helper_csrwr_tcfg(CPULoongArchState *env, target_ulong val)
+{
+LoongArchCPU *cpu = env_archcpu(env);
+int64_t old_v = env->CSR_TCFG;
+
+cpu_loongarch_store_constant_timer_config(cpu, val);
+
+return old_v;
+}
+
+target_ulong helper_csrwr_ticlr(CPULoongArchState *env, target_ulong val)
+{
+LoongArchCPU *cpu = env_archcpu(env);
+int64_t old_v = 0;
+
+if (val & 0x1) {
+loongarch_cpu_set_irq(cpu, IRQ_TIMER, 0);
+}
+return old_v;
+}
diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index 9454ebb8e9..11a704ff7c 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -8,6 +8,7 @@
 #include "qemu/osdep.h"
 #include "disas/dis-asm.h"
 #include "qemu/bitops.h"
+#include "cpu-csr.h"
 
 typedef struct {
 disassemble_info *info;
@@ -25,6 +26,90 @@ static inline int shl_2(DisasContext *ctx, int x)
 return x << 2;
 }
 
+#define CSR_NAME(REG) \
+[LOONGARCH_CSR_##REG] = (#REG)
+
+static const char * const csr_names[] = {
+CSR_NAME(CRMD),
+CSR_NAME(PRMD),
+CSR_NAME(EUEN),
+CSR_NAME(MISC),
+CSR_NAME(ECFG),
+CSR_NAME(ESTAT),
+CSR_NAME(ERA),
+CSR_NAME(BADV),
+CSR_NAME(BADI),
+CSR_NAME(EENTRY),
+CSR_NAME(TLBIDX),
+CSR_NAME(TLBEHI),
+CSR_NAME(TLBELO0),
+CSR_NAME(TLBELO1),
+CSR_NAME(ASID),
+CSR_NAME(PGDL),
+CSR_NAME(PGDH),
+CSR_NAME(PGD),
+CSR_NAME(PWCL),
+CSR_NAME(PWCH),
+CSR_NAME(STLBPS),
+CSR_NAME(RVACFG),
+CSR_NAME(CPUID),
+CSR_NAME(PRCFG1),
+CSR_NAME(PRCFG2),
+CSR_NAME(PRCFG3),
+CSR_NAME(SAVE(0)),
+CSR_NAME(SAVE(1)),
+CSR_NAME(SAVE(2)),
+CSR_NAME(SAVE(3)),
+CSR_NAME(SAVE(4)),
+CSR_NAME(SAVE(5)),
+CSR_NAME(SAVE(6)),
+CSR_NAME(SAVE(7)),
+CSR_NAME(SAVE(8)),
+CSR_NAME(SAVE(9)),
+CSR_NAME(SAVE(10)),
+CSR_NAME(SAVE(11)),
+CSR_NAME(SAVE(12)),
+CSR_NAME(SAVE(13)),
+CSR_NAME(SAVE(14)),
+CSR_NAME(SAVE(15)),
+CSR_NAME(TID),
+CSR_NAME(TCFG),
+CSR_NAME(TVAL),
+CSR_NAME(CNTC),
+CSR_NAME(TICLR),
+CSR_NAME(LLBCTL),
+CSR_NAME(IMPCTL1),
+CSR_NAME(IMPCTL2),
+CSR_NAME(TLBRENTRY),
+CSR_NAME(TLBRBADV),
+CSR_NAME(TLBRERA),
+CSR_NAME(TLBRSAVE),
+CSR_NAME(TLBRELO0),
+CSR_NAME(TLBRELO1),
+CSR_NAME(TLBREHI),
+CSR_NAME(TLBRPRMD),
+CSR_NAME(MERRCTL),
+CSR_NAME(MERRINFO1),
+CSR_NAME(MERRINFO2),
+CSR_NAME(MERRENTRY),
+CSR_NAME(MERRERA),
+CSR_NAME(MERRSAVE),
+CSR_NAME(CTAG),
+CSR_NAME(DMW(0)),
+CSR_NAME(DMW(1)),
+

[PATCH v6 05/43] target/loongarch: Add fixed point shift instruction translation

2022-06-01 Thread Xiaojuan Yang
From: Song Gao 

This includes:
- SLL.W, SRL.W, SRA.W, ROTR.W
- SLLI.W, SRLI.W, SRAI.W, ROTRI.W
- SLL.D, SRL.D, SRA.D, ROTR.D
- SLLI.D, SRLI.D, SRAI.D, ROTRI.D

Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
Reviewed-by: Richard Henderson 
---
 target/loongarch/insn_trans/trans_shift.c.inc | 106 ++
 target/loongarch/insns.decode |  22 
 target/loongarch/translate.c  |   1 +
 3 files changed, 129 insertions(+)
 create mode 100644 target/loongarch/insn_trans/trans_shift.c.inc

diff --git a/target/loongarch/insn_trans/trans_shift.c.inc 
b/target/loongarch/insn_trans/trans_shift.c.inc
new file mode 100644
index 00..5260af2337
--- /dev/null
+++ b/target/loongarch/insn_trans/trans_shift.c.inc
@@ -0,0 +1,106 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+static void gen_sll_w(TCGv dest, TCGv src1, TCGv src2)
+{
+TCGv t0 = tcg_temp_new();
+tcg_gen_andi_tl(t0, src2, 0x1f);
+tcg_gen_shl_tl(dest, src1, t0);
+tcg_temp_free(t0);
+}
+
+static void gen_srl_w(TCGv dest, TCGv src1, TCGv src2)
+{
+TCGv t0 = tcg_temp_new();
+tcg_gen_andi_tl(t0, src2, 0x1f);
+tcg_gen_shr_tl(dest, src1, t0);
+tcg_temp_free(t0);
+}
+
+static void gen_sra_w(TCGv dest, TCGv src1, TCGv src2)
+{
+TCGv t0 = tcg_temp_new();
+tcg_gen_andi_tl(t0, src2, 0x1f);
+tcg_gen_sar_tl(dest, src1, t0);
+tcg_temp_free(t0);
+}
+
+static void gen_sll_d(TCGv dest, TCGv src1, TCGv src2)
+{
+TCGv t0 = tcg_temp_new();
+tcg_gen_andi_tl(t0, src2, 0x3f);
+tcg_gen_shl_tl(dest, src1, t0);
+tcg_temp_free(t0);
+}
+
+static void gen_srl_d(TCGv dest, TCGv src1, TCGv src2)
+{
+TCGv t0 = tcg_temp_new();
+tcg_gen_andi_tl(t0, src2, 0x3f);
+tcg_gen_shr_tl(dest, src1, t0);
+tcg_temp_free(t0);
+}
+
+static void gen_sra_d(TCGv dest, TCGv src1, TCGv src2)
+{
+TCGv t0 = tcg_temp_new();
+tcg_gen_andi_tl(t0, src2, 0x3f);
+tcg_gen_sar_tl(dest, src1, t0);
+tcg_temp_free(t0);
+}
+
+static void gen_rotr_w(TCGv dest, TCGv src1, TCGv src2)
+{
+TCGv_i32 t1 = tcg_temp_new_i32();
+TCGv_i32 t2 = tcg_temp_new_i32();
+TCGv t0 = tcg_temp_new();
+
+tcg_gen_andi_tl(t0, src2, 0x1f);
+
+tcg_gen_trunc_tl_i32(t1, src1);
+tcg_gen_trunc_tl_i32(t2, t0);
+
+tcg_gen_rotr_i32(t1, t1, t2);
+tcg_gen_ext_i32_tl(dest, t1);
+
+tcg_temp_free_i32(t1);
+tcg_temp_free_i32(t2);
+tcg_temp_free(t0);
+}
+
+static void gen_rotr_d(TCGv dest, TCGv src1, TCGv src2)
+{
+TCGv t0 = tcg_temp_new();
+tcg_gen_andi_tl(t0, src2, 0x3f);
+tcg_gen_rotr_tl(dest, src1, t0);
+tcg_temp_free(t0);
+}
+
+static bool trans_srai_w(DisasContext *ctx, arg_srai_w *a)
+{
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+TCGv src1 = gpr_src(ctx, a->rj, EXT_ZERO);
+
+tcg_gen_sextract_tl(dest, src1, a->imm, 32 - a->imm);
+gen_set_gpr(a->rd, dest, EXT_NONE);
+
+return true;
+}
+
+TRANS(sll_w, gen_rrr, EXT_ZERO, EXT_NONE, EXT_SIGN, gen_sll_w)
+TRANS(srl_w, gen_rrr, EXT_ZERO, EXT_NONE, EXT_SIGN, gen_srl_w)
+TRANS(sra_w, gen_rrr, EXT_SIGN, EXT_NONE, EXT_SIGN, gen_sra_w)
+TRANS(sll_d, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_sll_d)
+TRANS(srl_d, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_srl_d)
+TRANS(sra_d, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_sra_d)
+TRANS(rotr_w, gen_rrr, EXT_ZERO, EXT_NONE, EXT_SIGN, gen_rotr_w)
+TRANS(rotr_d, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_rotr_d)
+TRANS(slli_w, gen_rri_c, EXT_NONE, EXT_SIGN, tcg_gen_shli_tl)
+TRANS(slli_d, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_shli_tl)
+TRANS(srli_w, gen_rri_c, EXT_ZERO, EXT_SIGN, tcg_gen_shri_tl)
+TRANS(srli_d, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_shri_tl)
+TRANS(srai_d, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_sari_tl)
+TRANS(rotri_w, gen_rri_v, EXT_NONE, EXT_NONE, gen_rotr_w)
+TRANS(rotri_d, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_rotri_tl)
diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode
index 8579c11984..673aee4be5 100644
--- a/target/loongarch/insns.decode
+++ b/target/loongarch/insns.decode
@@ -23,6 +23,8 @@
 #
 @rrr     . rk:5 rj:5 rd:5&rrr
 @r_i20   ... imm:s20 rd:5&r_i
+@rr_ui5     . imm:5 rj:5 rd:5&rr_i
+@rr_ui6   imm:6 rj:5 rd:5&rr_i
 @rr_i12  .. imm:s12 rj:5 rd:5&rr_i
 @rr_ui12  .. imm:12 rj:5 rd:5&rr_i
 @rr_i16  .. imm:s16 rj:5 rd:5&rr_i
@@ -77,3 +79,23 @@ addu16i_d   0001 00  . . 
@rr_i16
 andi 001101  . . @rr_ui12
 ori  001110  . . @rr_ui12
 xori 00  . . @rr_ui12
+
+#
+# Fixed point shift operation instruction
+#
+sll_w    0001 01110 . . .@rrr
+

[PATCH v6 33/43] hw/intc: Add LoongArch ls7a msi interrupt controller support(PCH-MSI)

2022-06-01 Thread Xiaojuan Yang
This patch realize PCH-MSI interrupt controller.

Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
Reviewed-by: Richard Henderson 
---
 hw/intc/Kconfig |  5 ++
 hw/intc/loongarch_pch_msi.c | 73 +
 hw/intc/meson.build |  1 +
 hw/intc/trace-events|  2 +
 hw/loongarch/Kconfig|  1 +
 include/hw/intc/loongarch_pch_msi.h | 20 
 include/hw/pci-host/ls7a.h  |  3 ++
 7 files changed, 105 insertions(+)
 create mode 100644 hw/intc/loongarch_pch_msi.c
 create mode 100644 include/hw/intc/loongarch_pch_msi.h

diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
index 362980ca8c..58f550b865 100644
--- a/hw/intc/Kconfig
+++ b/hw/intc/Kconfig
@@ -94,3 +94,8 @@ config LOONGARCH_IPI
 config LOONGARCH_PCH_PIC
 bool
 select UNIMP
+
+config LOONGARCH_PCH_MSI
+select MSI_NONBROKEN
+bool
+select UNIMP
diff --git a/hw/intc/loongarch_pch_msi.c b/hw/intc/loongarch_pch_msi.c
new file mode 100644
index 00..74bcdbdb48
--- /dev/null
+++ b/hw/intc/loongarch_pch_msi.c
@@ -0,0 +1,73 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * QEMU Loongson 7A1000 msi interrupt controller.
+ *
+ * Copyright (C) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "hw/sysbus.h"
+#include "hw/irq.h"
+#include "hw/intc/loongarch_pch_msi.h"
+#include "hw/intc/loongarch_pch_pic.h"
+#include "hw/pci/msi.h"
+#include "hw/misc/unimp.h"
+#include "migration/vmstate.h"
+#include "trace.h"
+
+static uint64_t loongarch_msi_mem_read(void *opaque, hwaddr addr, unsigned 
size)
+{
+return 0;
+}
+
+static void loongarch_msi_mem_write(void *opaque, hwaddr addr,
+uint64_t val, unsigned size)
+{
+LoongArchPCHMSI *s = LOONGARCH_PCH_MSI(opaque);
+int irq_num = val & 0xff;
+
+trace_loongarch_msi_set_irq(irq_num);
+assert(irq_num < PCH_MSI_IRQ_NUM);
+qemu_set_irq(s->pch_msi_irq[irq_num], 1);
+}
+
+static const MemoryRegionOps loongarch_pch_msi_ops = {
+.read  = loongarch_msi_mem_read,
+.write = loongarch_msi_mem_write,
+.endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+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);
+}
+
+static void loongarch_pch_msi_init(Object *obj)
+{
+LoongArchPCHMSI *s = LOONGARCH_PCH_MSI(obj);
+SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+
+memory_region_init_io(&s->msi_mmio, obj, &loongarch_pch_msi_ops,
+  s, TYPE_LOONGARCH_PCH_MSI, 0x8);
+sysbus_init_mmio(sbd, &s->msi_mmio);
+msi_nonbroken = true;
+
+qdev_init_gpio_out(DEVICE(obj), s->pch_msi_irq, PCH_MSI_IRQ_NUM);
+qdev_init_gpio_in(DEVICE(obj), pch_msi_irq_handler, PCH_MSI_IRQ_NUM);
+}
+
+static const TypeInfo loongarch_pch_msi_info = {
+.name  = TYPE_LOONGARCH_PCH_MSI,
+.parent= TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(LoongArchPCHMSI),
+.instance_init = loongarch_pch_msi_init,
+};
+
+static void loongarch_pch_msi_register_types(void)
+{
+type_register_static(&loongarch_pch_msi_info);
+}
+
+type_init(loongarch_pch_msi_register_types)
diff --git a/hw/intc/meson.build b/hw/intc/meson.build
index 03f13f1c49..1d407c046d 100644
--- a/hw/intc/meson.build
+++ b/hw/intc/meson.build
@@ -65,3 +65,4 @@ specific_ss.add(when: 'CONFIG_M68K_IRQC', if_true: 
files('m68k_irqc.c'))
 specific_ss.add(when: 'CONFIG_NIOS2_VIC', if_true: files('nios2_vic.c'))
 specific_ss.add(when: 'CONFIG_LOONGARCH_IPI', if_true: 
files('loongarch_ipi.c'))
 specific_ss.add(when: 'CONFIG_LOONGARCH_PCH_PIC', if_true: 
files('loongarch_pch_pic.c'))
+specific_ss.add(when: 'CONFIG_LOONGARCH_PCH_MSI', if_true: 
files('loongarch_pch_msi.c'))
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
index 2449b48e6d..63c9851923 100644
--- a/hw/intc/trace-events
+++ b/hw/intc/trace-events
@@ -301,3 +301,5 @@ loongarch_pch_pic_high_writew(unsigned size, uint64_t addr, 
uint64_t val) "size:
 loongarch_pch_pic_readb(unsigned size, uint64_t addr, uint64_t val) "size: %u 
addr: 0x%"PRIx64 "val: 0x%" PRIx64
 loongarch_pch_pic_writeb(unsigned size, uint64_t addr, uint64_t val) "size: %u 
addr: 0x%"PRIx64 "val: 0x%" PRIx64
 
+# loongarch_pch_msi.c
+loongarch_msi_set_irq(int irq_num) "set msi irq %d"
diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig
index 2df45f7e8f..d814fc6103 100644
--- a/hw/loongarch/Kconfig
+++ b/hw/loongarch/Kconfig
@@ -4,3 +4,4 @@ config LOONGARCH_VIRT
 select PCI_EXPRESS_GENERIC_BRIDGE
 select LOONGARCH_IPI
 select LOONGARCH_PCH_PIC
+select LOONGARCH_PCH_MSI
diff --git a/include/hw/intc/loongarch_pch_msi.h 
b/include/hw/intc/loongarch_pch_msi.h
new file mode 100644
index 00..f668bfca7a
--- /dev/null
+++ b/include/hw/intc/loongarch_pch_msi.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * LoongArch 7A1000 I/O inte

[PATCH v6 40/43] hw/loongarch: Add LoongArch power manager support

2022-06-01 Thread Xiaojuan Yang
Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
---
 hw/loongarch/loongson3.c | 45 +++-
 1 file changed, 44 insertions(+), 1 deletion(-)

diff --git a/hw/loongarch/loongson3.c b/hw/loongarch/loongson3.c
index 3c8fcb828c..658331f604 100644
--- a/hw/loongarch/loongson3.c
+++ b/hw/loongarch/loongson3.c
@@ -31,6 +31,44 @@
 
 #include "target/loongarch/cpu.h"
 
+#define PM_BASE 0x1008
+#define PM_SIZE 0x100
+#define PM_CTRL 0x10
+
+static uint64_t loongarch_virt_pm_read(void *opaque, hwaddr addr, unsigned 
size)
+{
+return 0;
+}
+
+static void loongarch_virt_pm_write(void *opaque, hwaddr addr,
+   uint64_t val, unsigned size)
+{
+if (addr != PM_CTRL) {
+return;
+}
+
+switch (val) {
+case 0x00:
+qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
+return;
+case 0xff:
+qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
+return;
+default:
+return;
+}
+}
+
+static const MemoryRegionOps loongarch_virt_pm_ops = {
+.read  = loongarch_virt_pm_read,
+.write = loongarch_virt_pm_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+.valid = {
+.min_access_size = 1,
+.max_access_size = 1
+}
+};
+
 static struct _loaderparams {
 uint64_t ram_size;
 const char *kernel_filename;
@@ -67,7 +105,7 @@ static void loongarch_devices_init(DeviceState *pch_pic)
 SysBusDevice *d;
 PCIBus *pci_bus;
 MemoryRegion *ecam_alias, *ecam_reg, *pio_alias, *pio_reg;
-MemoryRegion *mmio_alias, *mmio_reg;
+MemoryRegion *mmio_alias, *mmio_reg, *pm_mem;
 int i;
 
 gpex_dev = qdev_new(TYPE_GPEX_HOST);
@@ -132,6 +170,11 @@ static void loongarch_devices_init(DeviceState *pch_pic)
 sysbus_create_simple("ls7a_rtc", LS7A_RTC_REG_BASE,
  qdev_get_gpio_in(pch_pic,
  LS7A_RTC_IRQ - PCH_PIC_IRQ_OFFSET));
+
+pm_mem = g_new(MemoryRegion, 1);
+memory_region_init_io(pm_mem, NULL, &loongarch_virt_pm_ops,
+  NULL, "loongarch_virt_pm", PM_SIZE);
+memory_region_add_subregion(get_system_memory(), PM_BASE, pm_mem);
 }
 
 static void loongarch_irq_init(LoongArchMachineState *lams)
-- 
2.31.1




[PATCH v6 38/43] hw/loongarch: Add LoongArch ls7a rtc device support

2022-06-01 Thread Xiaojuan Yang
This patch add ls7a rtc device support.

Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
---
 MAINTAINERS|   1 +
 hw/loongarch/Kconfig   |   1 +
 hw/loongarch/loongson3.c   |   3 +
 hw/rtc/Kconfig |   3 +
 hw/rtc/ls7a_rtc.c  | 528 +
 hw/rtc/meson.build |   1 +
 include/hw/pci-host/ls7a.h |   4 +
 7 files changed, 541 insertions(+)
 create mode 100644 hw/rtc/ls7a_rtc.c

diff --git a/MAINTAINERS b/MAINTAINERS
index c22f95fb6a..9f4ee7978d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1137,6 +1137,7 @@ F: include/hw/loongarch/virt.h
 F: include/hw/intc/loongarch_*.h
 F: hw/intc/loongarch_*.c
 F: include/hw/pci-host/ls7a.h
+F: hw/rtc/ls7a_rtc.c
 
 M68K Machines
 -
diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig
index 8552ff4bee..35b6680772 100644
--- a/hw/loongarch/Kconfig
+++ b/hw/loongarch/Kconfig
@@ -13,3 +13,4 @@ config LOONGARCH_VIRT
 select LOONGARCH_PCH_PIC
 select LOONGARCH_PCH_MSI
 select LOONGARCH_EXTIOI
+select LS7A_RTC
diff --git a/hw/loongarch/loongson3.c b/hw/loongarch/loongson3.c
index 7bc17113dc..95984c9086 100644
--- a/hw/loongarch/loongson3.c
+++ b/hw/loongarch/loongson3.c
@@ -97,6 +97,9 @@ static void loongarch_devices_init(DeviceState *pch_pic)
  * Create some unimplemented devices to emulate this.
  */
 create_unimplemented_device("pci-dma-cfg", 0x1001041c, 0x4);
+sysbus_create_simple("ls7a_rtc", LS7A_RTC_REG_BASE,
+ qdev_get_gpio_in(pch_pic,
+ LS7A_RTC_IRQ - PCH_PIC_IRQ_OFFSET));
 }
 
 static void loongarch_irq_init(LoongArchMachineState *lams)
diff --git a/hw/rtc/Kconfig b/hw/rtc/Kconfig
index 730c272bc5..d0d8dda084 100644
--- a/hw/rtc/Kconfig
+++ b/hw/rtc/Kconfig
@@ -27,3 +27,6 @@ config SUN4V_RTC
 
 config GOLDFISH_RTC
 bool
+
+config LS7A_RTC
+bool
diff --git a/hw/rtc/ls7a_rtc.c b/hw/rtc/ls7a_rtc.c
new file mode 100644
index 00..fe6710310f
--- /dev/null
+++ b/hw/rtc/ls7a_rtc.c
@@ -0,0 +1,528 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Loongarch LS7A Real Time Clock emulation
+ *
+ * Copyright (C) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "hw/sysbus.h"
+#include "hw/irq.h"
+#include "include/hw/register.h"
+#include "qemu/timer.h"
+#include "sysemu/sysemu.h"
+#include "qemu/cutils.h"
+#include "qemu/log.h"
+#include "migration/vmstate.h"
+#include "hw/misc/unimp.h"
+#include "sysemu/rtc.h"
+#include "hw/registerfields.h"
+
+#define SYS_TOYTRIM0x20
+#define SYS_TOYWRITE0  0x24
+#define SYS_TOYWRITE1  0x28
+#define SYS_TOYREAD0   0x2C
+#define SYS_TOYREAD1   0x30
+#define SYS_TOYMATCH0  0x34
+#define SYS_TOYMATCH1  0x38
+#define SYS_TOYMATCH2  0x3C
+#define SYS_RTCCTRL0x40
+#define SYS_RTCTRIM0x60
+#define SYS_RTCWRTIE0  0x64
+#define SYS_RTCREAD0   0x68
+#define SYS_RTCMATCH0  0x6C
+#define SYS_RTCMATCH1  0x70
+#define SYS_RTCMATCH2  0x74
+
+#define LS7A_RTC_FREQ 32768
+#define TIMER_NUMS3
+/*
+ * Shift bits and filed mask
+ */
+
+FIELD(TOY, MON, 26, 6)
+FIELD(TOY, DAY, 21, 5)
+FIELD(TOY, HOUR, 16, 5)
+FIELD(TOY, MIN, 10, 6)
+FIELD(TOY, SEC, 4, 6)
+FIELD(TOY, MSEC, 0, 4)
+
+FIELD(TOY_MATCH, YEAR, 26, 6)
+FIELD(TOY_MATCH, MON, 22, 4)
+FIELD(TOY_MATCH, DAY, 17, 5)
+FIELD(TOY_MATCH, HOUR, 12, 5)
+FIELD(TOY_MATCH, MIN, 6, 6)
+FIELD(TOY_MATCH, SEC, 0, 6)
+
+FIELD(RTC_CTRL, RTCEN, 13, 1)
+FIELD(RTC_CTRL, TOYEN, 11, 1)
+FIELD(RTC_CTRL, EO, 8, 1)
+
+#define TYPE_LS7A_RTC "ls7a_rtc"
+OBJECT_DECLARE_SIMPLE_TYPE(LS7ARtcState, LS7A_RTC)
+
+struct LS7ARtcState {
+SysBusDevice parent_obj;
+
+MemoryRegion iomem;
+/*
+ * Needed to preserve the tick_count across migration, even if the
+ * absolute value of the rtc_clock is different on the source and
+ * destination.
+ */
+int64_t offset_toy;
+int64_t offset_rtc;
+uint64_t save_toy_mon;
+uint64_t save_toy_year;
+uint64_t save_rtc;
+int64_t data;
+int tidx;
+uint32_t toymatch[3];
+uint32_t toytrim;
+uint32_t cntrctl;
+uint32_t rtctrim;
+uint32_t rtccount;
+uint32_t rtcmatch[3];
+QEMUTimer *toy_timer[TIMER_NUMS];
+QEMUTimer *rtc_timer[TIMER_NUMS];
+qemu_irq irq;
+};
+
+/* switch nanoseconds time to rtc ticks */
+static inline uint64_t ls7a_rtc_ticks(void)
+{
+return qemu_clock_get_ns(rtc_clock) * LS7A_RTC_FREQ / 
NANOSECONDS_PER_SECOND;
+}
+
+/* switch rtc ticks to nanoseconds */
+static inline uint64_t ticks_to_ns(uint64_t ticks)
+{
+return ticks * NANOSECONDS_PER_SECOND / LS7A_RTC_FREQ;
+}
+
+static inline bool toy_enabled(LS7ARtcState *s)
+{
+return FIELD_EX32(s->cntrctl, RTC_CTRL, TOYEN) &&
+   FIELD_EX32(s->cntrctl, RTC_CTRL, EO);
+}
+
+static inline bool rtc_enabled(LS7ARtcState *s)
+{
+return FIELD_EX32(s->cntrctl, RTC_CTRL, RTCEN) &&
+   FIELD_EX32(s->cntrctl, RTC_CTRL, EO);
+}
+

[PATCH v6 36/43] Enable common virtio pci support for LoongArch

2022-06-01 Thread Xiaojuan Yang
Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
Reviewed-by: Richard Henderson 
---
 softmmu/qdev-monitor.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c
index 12fe60c467..bb5897fc76 100644
--- a/softmmu/qdev-monitor.c
+++ b/softmmu/qdev-monitor.c
@@ -60,7 +60,8 @@ typedef struct QDevAlias
   QEMU_ARCH_HPPA | QEMU_ARCH_I386 | \
   QEMU_ARCH_MIPS | QEMU_ARCH_PPC |  \
   QEMU_ARCH_RISCV | QEMU_ARCH_SH4 | \
-  QEMU_ARCH_SPARC | QEMU_ARCH_XTENSA)
+  QEMU_ARCH_SPARC | QEMU_ARCH_XTENSA | \
+  QEMU_ARCH_LOONGARCH)
 #define QEMU_ARCH_VIRTIO_CCW (QEMU_ARCH_S390X)
 #define QEMU_ARCH_VIRTIO_MMIO (QEMU_ARCH_M68K)
 
-- 
2.31.1




[PATCH v6 35/43] hw/loongarch: Add irq hierarchy for the system

2022-06-01 Thread Xiaojuan Yang
This patch add the irq hierarchy for the virt board.

Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
Reviewed-by: Richard Henderson 
---
 hw/loongarch/loongson3.c | 104 +++
 1 file changed, 104 insertions(+)

diff --git a/hw/loongarch/loongson3.c b/hw/loongarch/loongson3.c
index 7df32f777e..7a5c61e2df 100644
--- a/hw/loongarch/loongson3.c
+++ b/hw/loongarch/loongson3.c
@@ -16,8 +16,110 @@
 #include "sysemu/rtc.h"
 #include "hw/loongarch/virt.h"
 #include "exec/address-spaces.h"
+#include "hw/intc/loongarch_ipi.h"
+#include "hw/intc/loongarch_extioi.h"
+#include "hw/intc/loongarch_pch_pic.h"
+#include "hw/intc/loongarch_pch_msi.h"
+#include "hw/pci-host/ls7a.h"
+
 #include "target/loongarch/cpu.h"
 
+static void loongarch_irq_init(LoongArchMachineState *lams)
+{
+MachineState *ms = MACHINE(lams);
+DeviceState *pch_pic, *pch_msi, *cpudev;
+DeviceState *ipi, *extioi;
+SysBusDevice *d;
+LoongArchCPU *lacpu;
+CPULoongArchState *env;
+CPUState *cpu_state;
+int cpu, pin, i;
+
+ipi = qdev_new(TYPE_LOONGARCH_IPI);
+sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), &error_fatal);
+
+extioi = qdev_new(TYPE_LOONGARCH_EXTIOI);
+sysbus_realize_and_unref(SYS_BUS_DEVICE(extioi), &error_fatal);
+
+/*
+ * The connection of interrupts:
+ *   +-++-+ +---+
+ *   | IPI |--> | CPUINTC | <-- | Timer |
+ *   +-++-+ +---+
+ *  ^
+ *  |
+ *+-+
+ *| EIOINTC |
+ *+-+
+ * ^   ^
+ * |   |
+ *  +-+ +-+
+ *  | PCH-PIC | | PCH-MSI |
+ *  +-+ +-+
+ *^  ^  ^
+ *|  |  |
+ * ++ +-+ +-+
+ * | UARTs  | | Devices | | Devices |
+ * ++ +-+ +-+
+ */
+for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
+cpu_state = qemu_get_cpu(cpu);
+cpudev = DEVICE(cpu_state);
+lacpu = LOONGARCH_CPU(cpu_state);
+env = &(lacpu->env);
+
+/* connect ipi irq to cpu irq */
+qdev_connect_gpio_out(ipi, cpu, qdev_get_gpio_in(cpudev, IRQ_IPI));
+/* IPI iocsr memory region */
+memory_region_add_subregion(&env->system_iocsr, SMP_IPI_MAILBOX,
+sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi),
+cpu));
+/* extioi iocsr memory region */
+memory_region_add_subregion(&env->system_iocsr, APIC_BASE,
+sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi),
+cpu));
+}
+
+/*
+ * connect ext irq to the cpu irq
+ * cpu_pin[9:2] <= intc_pin[7:0]
+ */
+for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
+cpudev = DEVICE(qemu_get_cpu(cpu));
+for (pin = 0; pin < LS3A_INTC_IP; pin++) {
+qdev_connect_gpio_out(extioi, (cpu * 8 + pin),
+  qdev_get_gpio_in(cpudev, pin + 2));
+}
+}
+
+pch_pic = qdev_new(TYPE_LOONGARCH_PCH_PIC);
+d = SYS_BUS_DEVICE(pch_pic);
+sysbus_realize_and_unref(d, &error_fatal);
+memory_region_add_subregion(get_system_memory(), LS7A_IOAPIC_REG_BASE,
+sysbus_mmio_get_region(d, 0));
+memory_region_add_subregion(get_system_memory(),
+LS7A_IOAPIC_REG_BASE + PCH_PIC_ROUTE_ENTRY_OFFSET,
+sysbus_mmio_get_region(d, 1));
+memory_region_add_subregion(get_system_memory(),
+LS7A_IOAPIC_REG_BASE + PCH_PIC_INT_STATUS_LO,
+sysbus_mmio_get_region(d, 2));
+
+/* Connect 64 pch_pic irqs to extioi */
+for (int i = 0; i < PCH_PIC_IRQ_NUM; i++) {
+qdev_connect_gpio_out(DEVICE(d), i, qdev_get_gpio_in(extioi, i));
+}
+
+pch_msi = qdev_new(TYPE_LOONGARCH_PCH_MSI);
+d = SYS_BUS_DEVICE(pch_msi);
+sysbus_realize_and_unref(d, &error_fatal);
+sysbus_mmio_map(d, 0, LS7A_PCH_MSI_ADDR_LOW);
+for (i = 0; i < PCH_MSI_IRQ_NUM; i++) {
+/* Connect 192 pch_msi irqs to extioi */
+qdev_connect_gpio_out(DEVICE(d), i,
+  qdev_get_gpio_in(extioi, i + PCH_MSI_IRQ_START));
+}
+}
+
 static void loongarch_init(MachineState *machine)
 {
 const char *cpu_model = machine->cpu_type;
@@ -63,6 +165,8 @@ static void loongarch_init(MachineState *machine)
  get_system_io(), 0, LOONGARCH_ISA_IO_SIZE);
 memory_region_add_subregion(address_space_mem, LOONGARCH_ISA_IO_BASE,
 &lams->isa_io);
+/* Initialize the IO interrupt subsystem */
+loongarch_irq_init(lams);
 }
 
 static void loongarch_class_init(ObjectClass *oc, void *data)
-- 
2.31.1




[PATCH v6 34/43] hw/intc: Add LoongArch extioi interrupt controller(EIOINTC)

2022-06-01 Thread Xiaojuan Yang
This patch realize the EIOINTC interrupt controller.

Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
---
 hw/intc/Kconfig|   3 +
 hw/intc/loongarch_extioi.c | 298 +
 hw/intc/meson.build|   1 +
 hw/intc/trace-events   |   6 +
 hw/loongarch/Kconfig   |   1 +
 include/hw/intc/loongarch_extioi.h |  62 ++
 6 files changed, 371 insertions(+)
 create mode 100644 hw/intc/loongarch_extioi.c
 create mode 100644 include/hw/intc/loongarch_extioi.h

diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
index 58f550b865..ecd2883ceb 100644
--- a/hw/intc/Kconfig
+++ b/hw/intc/Kconfig
@@ -99,3 +99,6 @@ config LOONGARCH_PCH_MSI
 select MSI_NONBROKEN
 bool
 select UNIMP
+
+config LOONGARCH_EXTIOI
+bool
diff --git a/hw/intc/loongarch_extioi.c b/hw/intc/loongarch_extioi.c
new file mode 100644
index 00..6b6e99ec52
--- /dev/null
+++ b/hw/intc/loongarch_extioi.c
@@ -0,0 +1,298 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Loongson 3A5000 ext interrupt controller emulation
+ *
+ * Copyright (C) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/module.h"
+#include "qemu/log.h"
+#include "hw/irq.h"
+#include "hw/sysbus.h"
+#include "hw/loongarch/virt.h"
+#include "hw/qdev-properties.h"
+#include "exec/address-spaces.h"
+#include "hw/intc/loongarch_extioi.h"
+#include "migration/vmstate.h"
+#include "trace.h"
+
+
+static void extioi_update_irq(LoongArchExtIOI *s, int irq, int level)
+{
+int ipnum, cpu, found, irq_index, irq_mask;
+
+ipnum = s->sw_ipmap[irq / 32];
+cpu = s->sw_coremap[irq];
+irq_index = irq / 32;
+irq_mask = 1 << (irq & 0x1f);
+
+if (level) {
+/* if not enable return false */
+if (((s->enable[irq_index]) & irq_mask) == 0) {
+return;
+}
+s->coreisr[cpu][irq_index] |= irq_mask;
+found = find_first_bit(s->sw_isr[cpu][ipnum], EXTIOI_IRQS);
+set_bit(irq, s->sw_isr[cpu][ipnum]);
+if (found < EXTIOI_IRQS) {
+/* other irq is handling, need not update parent irq level */
+return;
+}
+} else {
+s->coreisr[cpu][irq_index] &= ~irq_mask;
+clear_bit(irq, s->sw_isr[cpu][ipnum]);
+found = find_first_bit(s->sw_isr[cpu][ipnum], EXTIOI_IRQS);
+if (found < EXTIOI_IRQS) {
+/* other irq is handling, need not update parent irq level */
+return;
+}
+}
+qemu_set_irq(s->parent_irq[cpu][ipnum], level);
+}
+
+static void extioi_setirq(void *opaque, int irq, int level)
+{
+LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque);
+trace_loongarch_extioi_setirq(irq, level);
+if (level) {
+/*
+ * s->isr should be used in vmstate structure,
+ * but it not support 'unsigned long',
+ * so we have to switch it.
+ */
+set_bit(irq, (unsigned long *)s->isr);
+} else {
+clear_bit(irq, (unsigned long *)s->isr);
+}
+extioi_update_irq(s, irq, level);
+}
+
+static uint64_t extioi_readw(void *opaque, hwaddr addr, unsigned size)
+{
+LoongArchExtIOI *s = LOONGARCH_EXTIOI(opaque);
+unsigned long offset = addr & 0x;
+uint32_t index, cpu, ret = 0;
+
+switch (offset) {
+case EXTIOI_NODETYPE_START ... EXTIOI_NODETYPE_END - 1:
+index = (offset - EXTIOI_NODETYPE_START) >> 2;
+ret = s->nodetype[index];
+break;
+case EXTIOI_IPMAP_START ... EXTIOI_IPMAP_END - 1:
+index = offset - EXTIOI_IPMAP_START;
+ret = *(uint32_t *)&s->ipmap[index];
+break;
+case EXTIOI_ENABLE_START ... EXTIOI_ENABLE_END - 1:
+index = (offset - EXTIOI_ENABLE_START) >> 2;
+ret = s->enable[index];
+break;
+case EXTIOI_BOUNCE_START ... EXTIOI_BOUNCE_END - 1:
+index = (offset - EXTIOI_BOUNCE_START) >> 2;
+ret = s->bounce[index];
+break;
+case EXTIOI_COREISR_START ... EXTIOI_COREISR_END - 1:
+index = ((offset - EXTIOI_COREISR_START) & 0x1f) >> 2;
+cpu = ((offset - EXTIOI_COREISR_START) >> 8) & 0x3;
+ret = s->coreisr[cpu][index];
+break;
+case EXTIOI_COREMAP_START ... EXTIOI_COREMAP_END - 1:
+index = offset - EXTIOI_COREMAP_START;
+ret = *(uint32_t *)&s->coremap[index];
+break;
+default:
+break;
+}
+
+trace_loongarch_extioi_readw(addr, ret);
+return ret;
+}
+
+static inline void extioi_enable_irq(LoongArchExtIOI *s, int index,\
+ uint32_t mask, int level)
+{
+uint32_t val;
+int irq;
+
+val = mask & s->isr[index];
+irq = ctz32(val);
+while (irq != 32) {
+/*
+ * enable bit change from 0 to 1,
+ * need to update irq by pending bits
+ */
+extioi_update_irq(s, irq + index * 32, level);
+val &= ~(1 << irq);
+irq = ctz32(val);
+}
+}
+
+static 

[PATCH v6 29/43] target/loongarch: Add timer related instructions support.

2022-06-01 Thread Xiaojuan Yang
This includes:
-RDTIME{L/H}.W
-RDTIME.D

Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
Reviewed-by: Richard Henderson 
---
 target/loongarch/disas.c  |  3 ++
 target/loongarch/helper.h |  2 ++
 target/loongarch/insn_trans/trans_extra.c.inc | 33 +++
 target/loongarch/insns.decode |  3 ++
 target/loongarch/op_helper.c  | 13 
 target/loongarch/translate.c  |  2 ++
 6 files changed, 56 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index 9d790b172c..858dfcc53a 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -352,6 +352,9 @@ INSN(bitrev_w, rr)
 INSN(bitrev_d, rr)
 INSN(ext_w_h,  rr)
 INSN(ext_w_b,  rr)
+INSN(rdtimel_w,rr)
+INSN(rdtimeh_w,rr)
+INSN(rdtime_d, rr)
 INSN(cpucfg,   rr)
 INSN(asrtle_d, rr_jk)
 INSN(asrtgt_d, rr_jk)
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index 626fc32e1e..85c11a60d4 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -93,6 +93,8 @@ DEF_HELPER_2(frint_d, i64, env, i64)
 
 DEF_HELPER_FLAGS_2(set_rounding_mode, TCG_CALL_NO_RWG, void, env, i32)
 
+DEF_HELPER_1(rdtime_d, i64, env)
+
 /* CSRs helper */
 DEF_HELPER_1(csrrd_pgd, i64, env)
 DEF_HELPER_1(csrrd_tval, i64, env)
diff --git a/target/loongarch/insn_trans/trans_extra.c.inc 
b/target/loongarch/insn_trans/trans_extra.c.inc
index 549f75a867..ad713cd61e 100644
--- a/target/loongarch/insn_trans/trans_extra.c.inc
+++ b/target/loongarch/insn_trans/trans_extra.c.inc
@@ -33,6 +33,39 @@ static bool trans_asrtgt_d(DisasContext *ctx, arg_asrtgt_d * 
a)
 return true;
 }
 
+static bool gen_rdtime(DisasContext *ctx, arg_rr *a,
+   bool word, bool high)
+{
+TCGv dst1 = gpr_dst(ctx, a->rd, EXT_NONE);
+TCGv dst2 = gpr_dst(ctx, a->rj, EXT_NONE);
+
+if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
+gen_io_start();
+}
+gen_helper_rdtime_d(dst1, cpu_env);
+if (word) {
+tcg_gen_sextract_tl(dst1, dst1, high ? 32 : 0, 32);
+}
+tcg_gen_ld_i64(dst2, cpu_env, offsetof(CPULoongArchState, CSR_TID));
+
+return true;
+}
+
+static bool trans_rdtimel_w(DisasContext *ctx, arg_rdtimel_w *a)
+{
+return gen_rdtime(ctx, a, 1, 0);
+}
+
+static bool trans_rdtimeh_w(DisasContext *ctx, arg_rdtimeh_w *a)
+{
+return gen_rdtime(ctx, a, 1, 1);
+}
+
+static bool trans_rdtime_d(DisasContext *ctx, arg_rdtime_d *a)
+{
+return gen_rdtime(ctx, a, 0, 0);
+}
+
 static bool trans_cpucfg(DisasContext *ctx, arg_cpucfg *a)
 {
 TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode
index ebd3d505fb..3fdc6e148c 100644
--- a/target/loongarch/insns.decode
+++ b/target/loongarch/insns.decode
@@ -309,6 +309,9 @@ break    0010 10100 ...  
@i15
 syscall  0010 10110 ...  @i15
 asrtle_d  00010 . . 0@rr_jk
 asrtgt_d  00011 . . 0@rr_jk
+rdtimel_w     0 11000 . .@rr
+rdtimeh_w     0 11001 . .@rr
+rdtime_d  0 11010 . .@rr
 cpucfg    0 11011 . .@rr
 
 #
diff --git a/target/loongarch/op_helper.c b/target/loongarch/op_helper.c
index a9ba72d5b2..d87049851f 100644
--- a/target/loongarch/op_helper.c
+++ b/target/loongarch/op_helper.c
@@ -84,6 +84,19 @@ target_ulong helper_cpucfg(CPULoongArchState *env, 
target_ulong rj)
 return rj > 21 ? 0 : env->cpucfg[rj];
 }
 
+uint64_t helper_rdtime_d(CPULoongArchState *env)
+{
+uint64_t plv;
+LoongArchCPU *cpu = env_archcpu(env);
+
+plv = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV);
+if (extract64(env->CSR_MISC, R_CSR_MISC_DRDTL_SHIFT + plv, 1)) {
+do_raise_exception(env, EXCCODE_IPE, GETPC());
+}
+
+return cpu_loongarch_get_constant_timer_counter(cpu);
+}
+
 void helper_ertn(CPULoongArchState *env)
 {
 uint64_t csr_pplv, csr_pie;
diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c
index 0f098924a3..c9afd11420 100644
--- a/target/loongarch/translate.c
+++ b/target/loongarch/translate.c
@@ -25,6 +25,8 @@ static TCGv cpu_lladdr, cpu_llval;
 TCGv_i32 cpu_fcsr0;
 TCGv_i64 cpu_fpr[32];
 
+#include "exec/gen-icount.h"
+
 #define DISAS_STOPDISAS_TARGET_0
 #define DISAS_EXITDISAS_TARGET_1
 #define DISAS_EXIT_UPDATE DISAS_TARGET_2
-- 
2.31.1




[PATCH v6 00/43] Add LoongArch softmmu support

2022-06-01 Thread Xiaojuan Yang
Hi All,

As this series only supports running binary files in ELF format, and 
does not depend on BIOS and kernel file. so this series are changed from
RFC to patch vX. 


The manual:
  - https://github.com/loongson/LoongArch-Documentation/releases/tag/2022.03.17

Old series:
  - https://patchew.org/QEMU/20220328125749.2918087-1-yangxiaoj...@loongson.cn/
  - https://patchew.org/QEMU/20220106094200.1801206-1-gaos...@loongson.cn/

This version we have done the following tests

configure with --enable-sanitizers

- make check  
   Ok: 117 
   Expected Fail:  0   
   Fail:   0   
   Unexpected Pass:0   
   Skipped:2   
   Timeout:0   
   
- make check-tcg

   GIT ui/keycodemapdb meson tests/fp/berkeley-testfloat-3
 tests/fp/berkeley-softfloat-3 dtc slirp
   BUILD   loongarch64-softmmu guest-tests
   RUN loongarch64-softmmu guest-tests
   TESThello on loongarch64
 ==559429==WARNING: ASan doesn't fully support makecontext/swapcontext
 functions and may produce false positives in some cases!
   TESTmemory on loongarch64
 ==559435==WARNING: ASan doesn't fully support makecontext/swapcontext
 functions and may produce false positives in some cases!


- IMAGES='fedora-i386-cross fedora-win32-cross fedora-win64-cross'
  make docker-test-build

  build success

- QTEST_QEMU_BINARY='./qemu-system-loongarch64'
   ./tests/qtest/device-introspect-test -v

  ok 6 /loongarch64/device/introspect/concrete/defaults/none
  # End of defaults tests
  # End of concrete tests
  # End of introspect tests
  # End of device tests
  # End of loongarch64 tests

Need review patches:

  no change
  0034-hw-intc-Add-LoongArch-extioi-interrupt-controller-EI.patch
  0038-hw-loongarch-Add-LoongArch-ls7a-rtc-device-support.patch

  new patch
  0040-hw-loongarch-Add-LoongArch-power-manager-support.patch


Thanks.
Xiaojuan

-
v6:
  - Fixed ipi device check errors when enabled sanitizers. (patch 31)

  - Removed acpi device emulation temporarily, and replaced it with virt
power manager. (patch 40)

v5:
  - Fixed loongarch extioi device emulation.
  - Fixed loongarch rtc device emulation.
  - Fixed 'make docker-test-build' error.

v4:
  - Use 'la464' cpu type.
  - Fixed loongarch extioi device emulation.
  - Fixed loongarch rtc device emulation.
  - Fixed loongarch load elf function.

v3:
  - Add Check csr_names.
  - Drop CSR_CPUID, use cpu->cpu_index.
  - Fixed loongarch extioi device emulation. ipmap and coremap register
change to 32bits.
  - Check_iocsr() function moved to loongarch_ipi_writel().
  - Pch_pic/msi use qdev_init_gpio_out() to init irq, and use
qdev_connect_gpio_out() to connect irq.
  - Load elf function moved to hw/loongarch/loongson.c

v2:
  - Improvents to CSR/IOCSR instructions translation.
  - Fixed extioi device emulation. It is represented by only one memory
region.
  - Fixed IPI device emulation. The registers are represented with
uint64_t.
  - Use do_cpu_reset() and cpu_set_pc() to specify the load address.

V4: https://patchew.org/QEMU/20220517113023.3051143-1-yangxiaoj...@loongson.cn/
v3: https://patchew.org/QEMU/20220429100729.1572481-1-yangxiaoj...@loongson.cn/
v2: https://patchew.org/QEMU/20220425091027.2877892-1-yangxiaoj...@loongson.cn/
v1: https://patchew.org/QEMU/20220415094058.3584233-1-yangxiaoj...@loongson.cn/


Song Gao (18):
  target/loongarch: Add README
  target/loongarch: Add core definition
  target/loongarch: Add main translation routines
  target/loongarch: Add fixed point arithmetic instruction translation
  target/loongarch: Add fixed point shift instruction translation
  target/loongarch: Add fixed point bit instruction translation
  target/loongarch: Add fixed point load/store instruction translation
  target/loongarch: Add fixed point atomic instruction translation
  target/loongarch: Add fixed point extra instruction translation
  target/loongarch: Add floating point arithmetic instruction
translation
  target/loongarch: Add floating point comparison instruction
translation
  target/loongarch: Add floating point conversion instruction
translation
  target/loongarch: Add floating point move instruction translation
  target/loongarch: Add floating point load/store instruction
translation
  target/loongarch: Add branch instruction translation
  target/loongarch: Add disassembler
  target/loongarch: Add target build suport
  target/loongarch: 'make check-tcg' support

Xiaojuan Yang (25):
  target/loongarch: Add system emulation introduction
  target/loongarch: Add CSRs definition
  target/loongarch: Add basic vmstate description of CPU.
  target/loongarch: Implement qmp_query_cpu_definitions()
  target/loongarch: Add MMU support for LoongArch CPU.
  target/loongarch: Add LoongArch interrupt and exception handle
  target/loongarch: Add constant timer support
  target/loongarch: Add LoongArch CSR instruction
  target/loongarch: Add LoongArch IOCSR instruction
  target/loongarch: Add TLB instr

[PATCH v6 02/43] target/loongarch: Add core definition

2022-06-01 Thread Xiaojuan Yang
From: Song Gao 

This patch adds target state header, target definitions
and initialization routines.

Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
---
 target/loongarch/cpu-param.h |  18 ++
 target/loongarch/cpu.c   | 324 +++
 target/loongarch/cpu.h   | 243 ++
 target/loongarch/internals.h |  21 +++
 4 files changed, 606 insertions(+)
 create mode 100644 target/loongarch/cpu-param.h
 create mode 100644 target/loongarch/cpu.c
 create mode 100644 target/loongarch/cpu.h
 create mode 100644 target/loongarch/internals.h

diff --git a/target/loongarch/cpu-param.h b/target/loongarch/cpu-param.h
new file mode 100644
index 00..9a769b67e0
--- /dev/null
+++ b/target/loongarch/cpu-param.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * LoongArch CPU parameters for QEMU.
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#ifndef LOONGARCH_CPU_PARAM_H
+#define LOONGARCH_CPU_PARAM_H
+
+#define TARGET_LONG_BITS 64
+#define TARGET_PHYS_ADDR_SPACE_BITS 48
+#define TARGET_VIRT_ADDR_SPACE_BITS 48
+
+#define TARGET_PAGE_BITS 14
+#define NB_MMU_MODES 4
+
+#endif
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
new file mode 100644
index 00..1f8e37906a
--- /dev/null
+++ b/target/loongarch/cpu.c
@@ -0,0 +1,324 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * QEMU LoongArch CPU
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qemu/qemu-print.h"
+#include "qapi/error.h"
+#include "qemu/module.h"
+#include "sysemu/qtest.h"
+#include "exec/exec-all.h"
+#include "qapi/qapi-commands-machine-target.h"
+#include "cpu.h"
+#include "internals.h"
+#include "fpu/softfloat-helpers.h"
+
+const char * const regnames[32] = {
+"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+};
+
+const char * const fregnames[32] = {
+"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
+"f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
+"f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
+"f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
+};
+
+static const char * const excp_names[] = {
+[EXCCODE_INT] = "Interrupt",
+[EXCCODE_PIL] = "Page invalid exception for load",
+[EXCCODE_PIS] = "Page invalid exception for store",
+[EXCCODE_PIF] = "Page invalid exception for fetch",
+[EXCCODE_PME] = "Page modified exception",
+[EXCCODE_PNR] = "Page Not Readable exception",
+[EXCCODE_PNX] = "Page Not Executable exception",
+[EXCCODE_PPI] = "Page Privilege error",
+[EXCCODE_ADEF] = "Address error for instruction fetch",
+[EXCCODE_ADEM] = "Address error for Memory access",
+[EXCCODE_SYS] = "Syscall",
+[EXCCODE_BRK] = "Break",
+[EXCCODE_INE] = "Instruction Non-Existent",
+[EXCCODE_IPE] = "Instruction privilege error",
+[EXCCODE_FPE] = "Floating Point Exception",
+[EXCCODE_DBP] = "Debug breakpoint",
+};
+
+const char *loongarch_exception_name(int32_t exception)
+{
+assert(excp_names[exception]);
+return excp_names[exception];
+}
+
+void G_NORETURN do_raise_exception(CPULoongArchState *env,
+   uint32_t exception,
+   uintptr_t pc)
+{
+CPUState *cs = env_cpu(env);
+
+qemu_log_mask(CPU_LOG_INT, "%s: %d (%s)\n",
+  __func__,
+  exception,
+  loongarch_exception_name(exception));
+cs->exception_index = exception;
+
+cpu_loop_exit_restore(cs, pc);
+}
+
+static void loongarch_cpu_set_pc(CPUState *cs, vaddr value)
+{
+LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+CPULoongArchState *env = &cpu->env;
+
+env->pc = value;
+}
+
+#ifdef CONFIG_TCG
+static void loongarch_cpu_synchronize_from_tb(CPUState *cs,
+  const TranslationBlock *tb)
+{
+LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+CPULoongArchState *env = &cpu->env;
+
+env->pc = tb->pc;
+}
+#endif /* CONFIG_TCG */
+
+static void loongarch_la464_initfn(Object *obj)
+{
+LoongArchCPU *cpu = LOONGARCH_CPU(obj);
+CPULoongArchState *env = &cpu->env;
+int i;
+
+for (i = 0; i < 21; i++) {
+env->cpucfg[i] = 0x0;
+}
+
+env->cpucfg[0] = 0x14c010;  /* PRID */
+
+uint32_t data = 0;
+data = FIELD_DP32(data, CPUCFG1, ARCH, 2);
+data = FIELD_DP32(data, CPUCFG1, PGMMU, 1);
+data = FIELD_DP32(data, CPUCFG1, IOCSR, 1);
+data = FIELD_DP32(data, CPUCFG1, PALEN, 0x2f);
+data = FIELD_DP32(data, CPUCFG1, VALEN, 0x2f);
+data = FIELD_DP32(data, CPUCFG1, UAL, 1);
+data = FIELD_DP32(data, CPUCFG1, RI, 1);
+data = FIELD_DP32(data

[PATCH v6 39/43] hw/loongarch: Add LoongArch load elf function.

2022-06-01 Thread Xiaojuan Yang
Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
Reviewed-by: Richard Henderson 
---
 hw/loongarch/loongson3.c | 61 ++--
 target/loongarch/cpu.h   |  2 ++
 2 files changed, 61 insertions(+), 2 deletions(-)

diff --git a/hw/loongarch/loongson3.c b/hw/loongarch/loongson3.c
index 95984c9086..3c8fcb828c 100644
--- a/hw/loongarch/loongson3.c
+++ b/hw/loongarch/loongson3.c
@@ -19,6 +19,8 @@
 #include "exec/address-spaces.h"
 #include "hw/irq.h"
 #include "net/net.h"
+#include "hw/loader.h"
+#include "elf.h"
 #include "hw/intc/loongarch_ipi.h"
 #include "hw/intc/loongarch_extioi.h"
 #include "hw/intc/loongarch_pch_pic.h"
@@ -29,6 +31,36 @@
 
 #include "target/loongarch/cpu.h"
 
+static struct _loaderparams {
+uint64_t ram_size;
+const char *kernel_filename;
+} loaderparams;
+
+static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr)
+{
+return addr & 0x1fffll;
+}
+
+static int64_t load_kernel_info(void)
+{
+uint64_t kernel_entry, kernel_low, kernel_high;
+ssize_t kernel_size;
+
+kernel_size = load_elf(loaderparams.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",
+ loaderparams.kernel_filename,
+ load_elf_strerror(kernel_size));
+exit(1);
+}
+return kernel_entry;
+}
+
 static void loongarch_devices_init(DeviceState *pch_pic)
 {
 DeviceState *gpex_dev;
@@ -200,15 +232,29 @@ static void loongarch_irq_init(LoongArchMachineState 
*lams)
 loongarch_devices_init(pch_pic);
 }
 
+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 loongarch_init(MachineState *machine)
 {
 const char *cpu_model = machine->cpu_type;
+const char *kernel_filename = machine->kernel_filename;
 ram_addr_t offset = 0;
 ram_addr_t ram_size = machine->ram_size;
 uint64_t highram_size = 0;
 MemoryRegion *address_space_mem = get_system_memory();
 LoongArchMachineState *lams = LOONGARCH_MACHINE(machine);
+LoongArchCPU *lacpu;
 int i;
+int64_t kernel_addr = 0;
 
 if (!cpu_model) {
 cpu_model = LOONGARCH_CPU_TYPE_NAME("la464");
@@ -234,17 +280,28 @@ static void loongarch_init(MachineState *machine)
  machine->ram, 0, 256 * MiB);
 memory_region_add_subregion(address_space_mem, offset, &lams->lowmem);
 offset += 256 * MiB;
-
 highram_size = ram_size - 256 * MiB;
 memory_region_init_alias(&lams->highmem, NULL, "loongarch.highmem",
  machine->ram, offset, highram_size);
 memory_region_add_subregion(address_space_mem, 0x9000, &lams->highmem);
-
 /* Add isa io region */
 memory_region_init_alias(&lams->isa_io, NULL, "isa-io",
  get_system_io(), 0, LOONGARCH_ISA_IO_SIZE);
 memory_region_add_subregion(address_space_mem, LOONGARCH_ISA_IO_BASE,
 &lams->isa_io);
+if (kernel_filename) {
+loaderparams.ram_size = ram_size;
+loaderparams.kernel_filename = kernel_filename;
+kernel_addr = load_kernel_info();
+if (!machine->firmware) {
+for (i = 0; i < machine->smp.cpus; i++) {
+lacpu = LOONGARCH_CPU(qemu_get_cpu(i));
+lacpu->env.load_elf = true;
+lacpu->env.elf_address = kernel_addr;
+qemu_register_reset(reset_load_elf, lacpu);
+}
+}
+}
 /* Initialize the IO interrupt subsystem */
 loongarch_irq_init(lams);
 }
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index 03cc96ee9b..71a5036c3c 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -308,6 +308,8 @@ typedef struct CPUArchState {
 AddressSpace address_space_iocsr;
 MemoryRegion system_iocsr;
 MemoryRegion iocsr_mem;
+bool load_elf;
+uint64_t elf_address;
 } CPULoongArchState;
 
 /**
-- 
2.31.1




[PATCH v6 31/43] hw/loongarch: Add LoongArch ipi interrupt support(IPI)

2022-06-01 Thread Xiaojuan Yang
This patch realize the IPI interrupt controller.

Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
Reviewed-by: Richard Henderson 
---
 MAINTAINERS |   2 +
 hw/intc/Kconfig |   3 +
 hw/intc/loongarch_ipi.c | 242 
 hw/intc/meson.build |   1 +
 hw/intc/trace-events|   5 +
 hw/loongarch/Kconfig|   1 +
 include/hw/intc/loongarch_ipi.h |  52 +++
 include/hw/loongarch/virt.h |   2 +
 8 files changed, 308 insertions(+)
 create mode 100644 hw/intc/loongarch_ipi.c
 create mode 100644 include/hw/intc/loongarch_ipi.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 898905ee1f..6872e9a2be 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1134,6 +1134,8 @@ F: configs/targets/loongarch64-softmmu.mak
 F: configs/devices/loongarch64-softmmu/default.mak
 F: hw/loongarch/
 F: include/hw/loongarch/virt.h
+F: include/hw/intc/loongarch_*.h
+F: hw/intc/loongarch_*.c
 
 M68K Machines
 -
diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
index eded1b557e..1122c33cec 100644
--- a/hw/intc/Kconfig
+++ b/hw/intc/Kconfig
@@ -87,3 +87,6 @@ config M68K_IRQC
 
 config NIOS2_VIC
 bool
+
+config LOONGARCH_IPI
+bool
diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c
new file mode 100644
index 00..66bee93675
--- /dev/null
+++ b/hw/intc/loongarch_ipi.c
@@ -0,0 +1,242 @@
+/* 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/sysbus.h"
+#include "hw/intc/loongarch_ipi.h"
+#include "hw/irq.h"
+#include "qapi/error.h"
+#include "qemu/log.h"
+#include "exec/address-spaces.h"
+#include "hw/loongarch/virt.h"
+#include "migration/vmstate.h"
+#include "target/loongarch/internals.h"
+#include "trace.h"
+
+static uint64_t loongarch_ipi_readl(void *opaque, hwaddr addr, unsigned size)
+{
+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_loongarch_ipi_read(size, (uint64_t)addr, ret);
+return ret;
+}
+
+static int get_ipi_data(target_ulong val)
+{
+int i, mask, data;
+
+data = val >> 32;
+mask = (val >> 27) & 0xf;
+
+for (i = 0; i < 4; i++) {
+if ((mask >> i) & 1) {
+data &= ~(0xff << (i * 8));
+}
+}
+return data;
+}
+
+static void ipi_send(uint64_t val)
+{
+int cpuid, data;
+CPULoongArchState *env;
+
+cpuid = (val >> 16) & 0x3ff;
+/* IPI status vector */
+data = 1 << (val & 0x1f);
+qemu_mutex_lock_iothread();
+CPUState *cs = qemu_get_cpu(cpuid);
+LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+env = &cpu->env;
+loongarch_cpu_set_irq(cpu, IRQ_IPI, 1);
+qemu_mutex_unlock_iothread();
+address_space_stl(&env->address_space_iocsr, 0x1008,
+  data, MEMTXATTRS_UNSPECIFIED, NULL);
+
+}
+
+static void mail_send(uint64_t val)
+{
+int cpuid, data;
+hwaddr addr;
+CPULoongArchState *env;
+
+cpuid = (val >> 16) & 0x3ff;
+addr = 0x1020 + (val & 0x1c);
+CPUState *cs = qemu_get_cpu(cpuid);
+LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+env = &cpu->env;
+data = get_ipi_data(val);
+address_space_stl(&env->address_space_iocsr, addr,
+  data, MEMTXATTRS_UNSPECIFIED, NULL);
+}
+
+static void any_send(uint64_t val)
+{
+int cpuid, data;
+hwaddr addr;
+CPULoongArchState *env;
+
+cpuid = (val >> 16) & 0x3ff;
+addr = val & 0x;
+CPUState *cs = qemu_get_cpu(cpuid);
+LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+env = &cpu->env;
+data = get_ipi_data(val);
+address_space_stl(&env->address_space_iocsr, addr,
+  data, MEMTXATTRS_UNSPECIFIED, NULL);
+}
+
+static void loongarch_ipi_writel(void *opaque, hwaddr addr, uint64_t val,
+ unsigned size)
+{
+IPICore *s = opaque;
+int index = 0;
+
+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:
+s->en = val;
+break;
+case CORE_SET_OFF:
+s->status |= val;
+if (s->status != 0 && (s->status & s->en) != 0) {
+qemu_irq_raise(s->irq);
+}
+break;
+case CORE_CLEAR_OFF:
+s->status &= ~val;
+ 

[PATCH v6 27/43] target/loongarch: Add TLB instruction support

2022-06-01 Thread Xiaojuan Yang
This includes:
- TLBSRCH
- TLBRD
- TLBWR
- TLBFILL
- TLBCLR
- TLBFLUSH
- INVTLB

Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
Reviewed-by: Richard Henderson 
---
 target/loongarch/disas.c  |  18 +
 target/loongarch/helper.h |  13 +
 .../insn_trans/trans_privileged.c.inc | 102 +
 target/loongarch/insns.decode |  11 +
 target/loongarch/tlb_helper.c | 355 ++
 5 files changed, 499 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index ea26aea728..6a56607302 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -303,6 +303,17 @@ static void output_rr_csr(DisasContext *ctx, arg_rr_csr *a,
a->rd, a->rj, a->csr, get_csr_name(a->csr));
 }
 
+static void output_empty(DisasContext *ctx, arg_empty *a,
+ const char *mnemonic)
+{
+output(ctx, mnemonic, "");
+}
+
+static void output_i_rr(DisasContext *ctx, arg_i_rr *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "%d, r%d, r%d", a->imm, a->rj, a->rk);
+}
+
 #define INSN(insn, type)\
 static bool trans_##insn(DisasContext *ctx, arg_##type * a) \
 {   \
@@ -623,6 +634,13 @@ INSN(iocsrwr_b,rr)
 INSN(iocsrwr_h,rr)
 INSN(iocsrwr_w,rr)
 INSN(iocsrwr_d,rr)
+INSN(tlbsrch,  empty)
+INSN(tlbrd,empty)
+INSN(tlbwr,empty)
+INSN(tlbfill,  empty)
+INSN(tlbclr,   empty)
+INSN(tlbflush, empty)
+INSN(invtlb,   i_rr)
 
 #define output_fcmp(C, PREFIX, SUFFIX) 
\
 {  
\
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index 4664a02dcf..b092ca75fe 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -108,3 +108,16 @@ DEF_HELPER_3(iocsrwr_b, void, env, tl, tl)
 DEF_HELPER_3(iocsrwr_h, void, env, tl, tl)
 DEF_HELPER_3(iocsrwr_w, void, env, tl, tl)
 DEF_HELPER_3(iocsrwr_d, void, env, tl, tl)
+
+/* TLB helper */
+DEF_HELPER_1(tlbwr, void, env)
+DEF_HELPER_1(tlbfill, void, env)
+DEF_HELPER_1(tlbsrch, void, env)
+DEF_HELPER_1(tlbrd, void, env)
+DEF_HELPER_1(tlbclr, void, env)
+DEF_HELPER_1(tlbflush, void, env)
+DEF_HELPER_1(invtlb_all, void, env)
+DEF_HELPER_2(invtlb_all_g, void, env, i32)
+DEF_HELPER_2(invtlb_all_asid, void, env, tl)
+DEF_HELPER_3(invtlb_page_asid, void, env, tl, tl)
+DEF_HELPER_3(invtlb_page_asid_or_g, void, env, tl, tl)
diff --git a/target/loongarch/insn_trans/trans_privileged.c.inc 
b/target/loongarch/insn_trans/trans_privileged.c.inc
index 3e50cd3ac6..d47918785b 100644
--- a/target/loongarch/insn_trans/trans_privileged.c.inc
+++ b/target/loongarch/insn_trans/trans_privileged.c.inc
@@ -297,3 +297,105 @@ TRANS(iocsrwr_b, gen_iocsrwr, gen_helper_iocsrwr_b)
 TRANS(iocsrwr_h, gen_iocsrwr, gen_helper_iocsrwr_h)
 TRANS(iocsrwr_w, gen_iocsrwr, gen_helper_iocsrwr_w)
 TRANS(iocsrwr_d, gen_iocsrwr, gen_helper_iocsrwr_d)
+
+static void check_mmu_idx(DisasContext *ctx)
+{
+if (ctx->mem_idx != MMU_DA_IDX) {
+tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next + 4);
+ctx->base.is_jmp = DISAS_EXIT;
+}
+}
+
+static bool trans_tlbsrch(DisasContext *ctx, arg_tlbsrch *a)
+{
+if (check_plv(ctx)) {
+return false;
+}
+gen_helper_tlbsrch(cpu_env);
+return true;
+}
+
+static bool trans_tlbrd(DisasContext *ctx, arg_tlbrd *a)
+{
+if (check_plv(ctx)) {
+return false;
+}
+gen_helper_tlbrd(cpu_env);
+return true;
+}
+
+static bool trans_tlbwr(DisasContext *ctx, arg_tlbwr *a)
+{
+if (check_plv(ctx)) {
+return false;
+}
+gen_helper_tlbwr(cpu_env);
+check_mmu_idx(ctx);
+return true;
+}
+
+static bool trans_tlbfill(DisasContext *ctx, arg_tlbfill *a)
+{
+if (check_plv(ctx)) {
+return false;
+}
+gen_helper_tlbfill(cpu_env);
+check_mmu_idx(ctx);
+return true;
+}
+
+static bool trans_tlbclr(DisasContext *ctx, arg_tlbclr *a)
+{
+if (check_plv(ctx)) {
+return false;
+}
+gen_helper_tlbclr(cpu_env);
+check_mmu_idx(ctx);
+return true;
+}
+
+static bool trans_tlbflush(DisasContext *ctx, arg_tlbflush *a)
+{
+if (check_plv(ctx)) {
+return false;
+}
+gen_helper_tlbflush(cpu_env);
+check_mmu_idx(ctx);
+return true;
+}
+
+static bool trans_invtlb(DisasContext *ctx, arg_invtlb *a)
+{
+TCGv rj = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv rk = gpr_src(ctx, a->rk, EXT_NONE);
+
+if (check_plv(ctx)) {
+return false;
+}
+
+switch (a->imm) {
+case 0:
+case 1:
+gen_helper_invtlb_all(cpu_env);
+break;
+case 2:
+gen_helper_invtlb_all_g(cpu_env, tcg_constant_i32(1));
+break;
+case 3:
+gen_helper_invtlb_all_g(cpu_env, tcg_constant_i32(0));
+break;
+case 4:
+gen_helper_invtlb_

[PATCH v6 28/43] target/loongarch: Add other core instructions support

2022-06-01 Thread Xiaojuan Yang
This includes:
-CACOP
-LDDIR
-LDPTE
-ERTN
-DBCL
-IDLE

Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
Reviewed-by: Richard Henderson 
---
 target/loongarch/disas.c  | 17 
 target/loongarch/helper.h |  5 +
 .../insn_trans/trans_privileged.c.inc | 65 +
 target/loongarch/insns.decode | 11 +++
 target/loongarch/internals.h  |  5 +
 target/loongarch/op_helper.c  | 37 
 target/loongarch/tlb_helper.c | 93 +++
 7 files changed, 233 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index 6a56607302..9d790b172c 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -314,6 +314,17 @@ static void output_i_rr(DisasContext *ctx, arg_i_rr *a, 
const char *mnemonic)
 output(ctx, mnemonic, "%d, r%d, r%d", a->imm, a->rj, a->rk);
 }
 
+static void output_cop_r_i(DisasContext *ctx, arg_cop_r_i *a,
+   const char *mnemonic)
+{
+output(ctx, mnemonic, "%d, r%d, %d", a->cop, a->rj, a->imm);
+}
+
+static void output_j_i(DisasContext *ctx, arg_j_i *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "r%d, %d", a->rj, a->imm);
+}
+
 #define INSN(insn, type)\
 static bool trans_##insn(DisasContext *ctx, arg_##type * a) \
 {   \
@@ -641,6 +652,12 @@ INSN(tlbfill,  empty)
 INSN(tlbclr,   empty)
 INSN(tlbflush, empty)
 INSN(invtlb,   i_rr)
+INSN(cacop,cop_r_i)
+INSN(lddir,rr_i)
+INSN(ldpte,j_i)
+INSN(ertn, empty)
+INSN(idle, i)
+INSN(dbcl, i)
 
 #define output_fcmp(C, PREFIX, SUFFIX) 
\
 {  
\
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index b092ca75fe..626fc32e1e 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -121,3 +121,8 @@ DEF_HELPER_2(invtlb_all_g, void, env, i32)
 DEF_HELPER_2(invtlb_all_asid, void, env, tl)
 DEF_HELPER_3(invtlb_page_asid, void, env, tl, tl)
 DEF_HELPER_3(invtlb_page_asid_or_g, void, env, tl, tl)
+
+DEF_HELPER_4(lddir, tl, env, tl, tl, i32)
+DEF_HELPER_4(ldpte, void, env, tl, tl, i32)
+DEF_HELPER_1(ertn, void, env)
+DEF_HELPER_1(idle, void, env)
diff --git a/target/loongarch/insn_trans/trans_privileged.c.inc 
b/target/loongarch/insn_trans/trans_privileged.c.inc
index d47918785b..53596c4f77 100644
--- a/target/loongarch/insn_trans/trans_privileged.c.inc
+++ b/target/loongarch/insn_trans/trans_privileged.c.inc
@@ -399,3 +399,68 @@ static bool trans_invtlb(DisasContext *ctx, arg_invtlb *a)
 ctx->base.is_jmp = DISAS_STOP;
 return true;
 }
+
+static bool trans_cacop(DisasContext *ctx, arg_cacop *a)
+{
+/* Treat the cacop as a nop */
+if (check_plv(ctx)) {
+return false;
+}
+return true;
+}
+
+static bool trans_ldpte(DisasContext *ctx, arg_ldpte *a)
+{
+TCGv_i32 mem_idx = tcg_constant_i32(ctx->mem_idx);
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+
+if (check_plv(ctx)) {
+return false;
+}
+gen_helper_ldpte(cpu_env, src1, tcg_constant_tl(a->imm), mem_idx);
+return true;
+}
+
+static bool trans_lddir(DisasContext *ctx, arg_lddir *a)
+{
+TCGv_i32 mem_idx = tcg_constant_i32(ctx->mem_idx);
+TCGv src = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+
+if (check_plv(ctx)) {
+return false;
+}
+gen_helper_lddir(dest, cpu_env, src, tcg_constant_tl(a->imm), mem_idx);
+return true;
+}
+
+static bool trans_ertn(DisasContext *ctx, arg_ertn *a)
+{
+if (check_plv(ctx)) {
+return false;
+}
+gen_helper_ertn(cpu_env);
+ctx->base.is_jmp = DISAS_EXIT;
+return true;
+}
+
+static bool trans_dbcl(DisasContext *ctx, arg_dbcl *a)
+{
+if (check_plv(ctx)) {
+return false;
+}
+generate_exception(ctx, EXCCODE_DBP);
+return true;
+}
+
+static bool trans_idle(DisasContext *ctx, arg_idle *a)
+{
+if (check_plv(ctx)) {
+return false;
+}
+
+tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next + 4);
+gen_helper_idle(cpu_env);
+ctx->base.is_jmp = DISAS_NORETURN;
+return true;
+}
diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode
index f8ed11d83e..ebd3d505fb 100644
--- a/target/loongarch/insns.decode
+++ b/target/loongarch/insns.decode
@@ -49,6 +49,8 @@
 &rr_csr   rd rj csr
 &empty
 &i_rr imm rj rk
+&cop_r_i  cop rj imm
+&j_i  rj imm
 
 #
 # Formats
@@ -60,6 +62,7 @@
 @r_i20   ... imm:s20 rd:5&r_i
 @rr_ui5     . imm:5 rj:5 rd:5&rr_i
 @rr_ui6   imm:6 rj:5 rd:5&rr_i
+@rr_ui8  ..   imm:8 rj:5 rd:5&rr_i
 @rr_i12  .. imm:s1

[PATCH v6 43/43] target/loongarch: 'make check-tcg' support

2022-06-01 Thread Xiaojuan Yang
From: Song Gao 

Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
Reviewed-by: Richard Henderson 
Acked-by: Alex Bennée 
Reviewed-by: Philippe Mathieu-Daudé 
---
 tests/tcg/configure.sh | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tests/tcg/configure.sh b/tests/tcg/configure.sh
index 691d90abac..331044c65d 100755
--- a/tests/tcg/configure.sh
+++ b/tests/tcg/configure.sh
@@ -51,6 +51,7 @@ fi
 : ${cross_cc_cflags_armeb="-mbig-endian"}
 : ${cross_cc_hexagon="hexagon-unknown-linux-musl-clang"}
 : ${cross_cc_cflags_hexagon="-mv67 -O2 -static"}
+: ${cross_cc_loongarch64="loongarch64-unknown-linux-gnu-gcc"}
 : ${cross_cc_hppa="hppa-linux-gnu-gcc"}
 : ${cross_cc_i386="i686-linux-gnu-gcc"}
 : ${cross_cc_cflags_i386="-m32"}
-- 
2.31.1




[PATCH v6 03/43] target/loongarch: Add main translation routines

2022-06-01 Thread Xiaojuan Yang
From: Song Gao 

This patch adds main translation routines and
basic functions for translation.

Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
Reviewed-by: Richard Henderson 
---
 target/loongarch/helper.h|   6 ++
 target/loongarch/op_helper.c |  21 +
 target/loongarch/translate.c | 161 +++
 target/loongarch/translate.h |  26 ++
 4 files changed, 214 insertions(+)
 create mode 100644 target/loongarch/helper.h
 create mode 100644 target/loongarch/op_helper.c
 create mode 100644 target/loongarch/translate.c
 create mode 100644 target/loongarch/translate.h

diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
new file mode 100644
index 00..eb771c0628
--- /dev/null
+++ b/target/loongarch/helper.h
@@ -0,0 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+DEF_HELPER_2(raise_exception, noreturn, env, i32)
diff --git a/target/loongarch/op_helper.c b/target/loongarch/op_helper.c
new file mode 100644
index 00..903810951e
--- /dev/null
+++ b/target/loongarch/op_helper.c
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * LoongArch emulation helpers for QEMU.
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/main-loop.h"
+#include "cpu.h"
+#include "qemu/host-utils.h"
+#include "exec/helper-proto.h"
+#include "exec/exec-all.h"
+#include "exec/cpu_ldst.h"
+#include "internals.h"
+
+/* Exceptions helpers */
+void helper_raise_exception(CPULoongArchState *env, uint32_t exception)
+{
+do_raise_exception(env, exception, GETPC());
+}
diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c
new file mode 100644
index 00..332a6d2d58
--- /dev/null
+++ b/target/loongarch/translate.c
@@ -0,0 +1,161 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * LoongArch emulation for QEMU - main translation routines.
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "tcg/tcg-op.h"
+#include "exec/translator.h"
+#include "exec/helper-proto.h"
+#include "exec/helper-gen.h"
+
+#include "exec/translator.h"
+#include "exec/log.h"
+#include "qemu/qemu-print.h"
+#include "translate.h"
+#include "internals.h"
+
+/* Global register indices */
+TCGv cpu_gpr[32], cpu_pc;
+static TCGv cpu_lladdr, cpu_llval;
+TCGv_i32 cpu_fcsr0;
+TCGv_i64 cpu_fpr[32];
+
+#define DISAS_STOP   DISAS_TARGET_0
+
+void generate_exception(DisasContext *ctx, int excp)
+{
+tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
+gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp));
+ctx->base.is_jmp = DISAS_NORETURN;
+}
+
+static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
+{
+if (translator_use_goto_tb(&ctx->base, dest)) {
+tcg_gen_goto_tb(n);
+tcg_gen_movi_tl(cpu_pc, dest);
+tcg_gen_exit_tb(ctx->base.tb, n);
+} else {
+tcg_gen_movi_tl(cpu_pc, dest);
+tcg_gen_lookup_and_goto_ptr();
+}
+}
+
+static void loongarch_tr_init_disas_context(DisasContextBase *dcbase,
+CPUState *cs)
+{
+int64_t bound;
+DisasContext *ctx = container_of(dcbase, DisasContext, base);
+
+ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
+ctx->mem_idx = ctx->base.tb->flags;
+
+/* Bound the number of insns to execute to those left on the page.  */
+bound = -(ctx->base.pc_first | TARGET_PAGE_MASK) / 4;
+ctx->base.max_insns = MIN(ctx->base.max_insns, bound);
+}
+
+static void loongarch_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
+{
+}
+
+static void loongarch_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
+{
+DisasContext *ctx = container_of(dcbase, DisasContext, base);
+
+tcg_gen_insn_start(ctx->base.pc_next);
+}
+
+static void loongarch_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
+{
+CPULoongArchState *env = cs->env_ptr;
+DisasContext *ctx = container_of(dcbase, DisasContext, base);
+
+ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
+
+if (!decode(ctx, ctx->opcode)) {
+qemu_log_mask(LOG_UNIMP, "Error: unknown opcode. "
+  TARGET_FMT_lx ": 0x%x\n",
+  ctx->base.pc_next, ctx->opcode);
+generate_exception(ctx, EXCCODE_INE);
+}
+
+ctx->base.pc_next += 4;
+}
+
+static void loongarch_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
+{
+DisasContext *ctx = container_of(dcbase, DisasContext, base);
+
+switch (ctx->base.is_jmp) {
+case DISAS_STOP:
+tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
+tcg_gen_lookup_and_goto_ptr();
+break;
+case DISAS_TOO_MANY:
+gen_goto_tb(ctx, 0, ctx->base.pc_next);
+break;
+case DISAS_NORETURN:
+break;
+default:
+g_assert_not_reached();
+}
+}
+
+static void loongar

[PATCH v6 17/43] target/loongarch: Add target build suport

2022-06-01 Thread Xiaojuan Yang
From: Song Gao 

Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
---
 target/loongarch/meson.build | 19 +++
 target/meson.build   |  1 +
 2 files changed, 20 insertions(+)
 create mode 100644 target/loongarch/meson.build

diff --git a/target/loongarch/meson.build b/target/loongarch/meson.build
new file mode 100644
index 00..bcb076e55f
--- /dev/null
+++ b/target/loongarch/meson.build
@@ -0,0 +1,19 @@
+gen = decodetree.process('insns.decode')
+
+loongarch_ss = ss.source_set()
+loongarch_ss.add(files(
+  'cpu.c',
+  'disas.c',
+))
+loongarch_tcg_ss = ss.source_set()
+loongarch_tcg_ss.add(gen)
+loongarch_tcg_ss.add(files(
+  'fpu_helper.c',
+  'op_helper.c',
+  'translate.c',
+))
+loongarch_tcg_ss.add(zlib)
+
+loongarch_ss.add_all(when: 'CONFIG_TCG', if_true: [loongarch_tcg_ss])
+
+target_arch += {'loongarch': loongarch_ss}
diff --git a/target/meson.build b/target/meson.build
index 2f6940255e..a53a60486f 100644
--- a/target/meson.build
+++ b/target/meson.build
@@ -5,6 +5,7 @@ subdir('cris')
 subdir('hexagon')
 subdir('hppa')
 subdir('i386')
+subdir('loongarch')
 subdir('m68k')
 subdir('microblaze')
 subdir('mips')
-- 
2.31.1




[PATCH v6 42/43] tests/tcg/loongarch64: Add hello/memory test in loongarch64 system

2022-06-01 Thread Xiaojuan Yang
- We write a very minimal softmmu harness.
- This is a very simple smoke test with no need to run a full Linux/kernel.
- The Makefile.softmmu-target record the rule to run.

Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
Reviewed-by: Richard Henderson 
---
 MAINTAINERS   |  1 +
 tests/tcg/loongarch64/Makefile.softmmu-target | 33 +++
 tests/tcg/loongarch64/system/boot.S   | 56 
 tests/tcg/loongarch64/system/kernel.ld| 30 +++
 tests/tcg/loongarch64/system/regdef.h | 86 +++
 5 files changed, 206 insertions(+)
 create mode 100644 tests/tcg/loongarch64/Makefile.softmmu-target
 create mode 100644 tests/tcg/loongarch64/system/boot.S
 create mode 100644 tests/tcg/loongarch64/system/kernel.ld
 create mode 100644 tests/tcg/loongarch64/system/regdef.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 492dbf64e0..86f6fea88e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -217,6 +217,7 @@ M: Song Gao 
 M: Xiaojuan Yang 
 S: Maintained
 F: target/loongarch/
+F: tests/tcg/loongarch64/
 
 M68K TCG CPUs
 M: Laurent Vivier 
diff --git a/tests/tcg/loongarch64/Makefile.softmmu-target 
b/tests/tcg/loongarch64/Makefile.softmmu-target
new file mode 100644
index 00..908f3a8c0f
--- /dev/null
+++ b/tests/tcg/loongarch64/Makefile.softmmu-target
@@ -0,0 +1,33 @@
+#
+# Loongarch64 system tests
+#
+
+LOONGARCH64_SYSTEM_SRC=$(SRC_PATH)/tests/tcg/loongarch64/system
+VPATH+=$(LOONGARCH64_SYSTEM_SRC)
+
+# These objects provide the basic boot code and helper functions for all tests
+CRT_OBJS=boot.o
+
+LOONGARCH64_TEST_SRCS=$(wildcard $(LOONGARCH64_SYSTEM_SRC)/*.c)
+LOONGARCH64_TESTS = $(patsubst $(LOONGARCH64_SYSTEM_SRC)/%.c, %, 
$(LOONGARCH64_TEST_SRCS))
+
+CRT_PATH=$(LOONGARCH64_SYSTEM_SRC)
+LINK_SCRIPT=$(LOONGARCH64_SYSTEM_SRC)/kernel.ld
+LDFLAGS=-Wl,-T$(LINK_SCRIPT)
+TESTS+=$(LOONGARCH64_TESTS) $(MULTIARCH_TESTS)
+CFLAGS+=-nostdlib -g -O1 -march=loongarch64 -mabi=lp64d $(MINILIB_INC)
+LDFLAGS+=-static -nostdlib $(CRT_OBJS) $(MINILIB_OBJS) -lgcc
+
+# building head blobs
+.PRECIOUS: $(CRT_OBJS)
+
+%.o: $(CRT_PATH)/%.S
+   $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -x assembler-with-cpp -c $< -o $@
+
+# Build and link the tests
+%: %.c $(LINK_SCRIPT) $(CRT_OBJS) $(MINILIB_OBJS)
+   $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS)
+
+memory: CFLAGS+=-DCHECK_UNALIGNED=0
+# Running
+QEMU_OPTS+=-serial chardev:output -kernel
diff --git a/tests/tcg/loongarch64/system/boot.S 
b/tests/tcg/loongarch64/system/boot.S
new file mode 100644
index 00..67eb1c04ce
--- /dev/null
+++ b/tests/tcg/loongarch64/system/boot.S
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Minimal LoongArch system boot code.
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "regdef.h"
+
+   .global _start
+   .align 16
+_start:
+   la.local t0, stack_end
+   move sp, t0
+   bl main
+
+   .type _start 2
+   .size _start, .-_start
+
+   .global _exit
+   .align 16
+_exit:
+2:  /* QEMU ACPI poweroff */
+   li.w  t0, 0xff
+   li.w  t1, 0x10080010
+   st.w  t0, t1, 0
+   idle  0
+   bl2b
+
+   .type _exit 2
+   .size _exit, .-_exit
+
+   .global __sys_outc
+__sys_outc:
+   li.d t1, 100
+loop:
+   lu12i.w t2, 0x1fe00
+   ori t0, t2, 0x1e5
+   ld.bu   t0, t0, 0
+   andit0, t0, 0x20
+   ext.w.b t0, t0
+   bnezt0, in
+   addi.w  t1, t1, -1
+   bnezt1, loop
+in:
+   ext.w.b a0, a0
+   lu12i.w t0, 0x1fe00
+   ori t0, t0, 0x1e0
+   st.ba0, t0, 0
+   jirl$r0, ra, 0
+
+   .data
+   .align 4
+stack:
+   .space  65536
+stack_end:
diff --git a/tests/tcg/loongarch64/system/kernel.ld 
b/tests/tcg/loongarch64/system/kernel.ld
new file mode 100644
index 00..f1a7c0168c
--- /dev/null
+++ b/tests/tcg/loongarch64/system/kernel.ld
@@ -0,0 +1,30 @@
+ENTRY(_start)
+
+SECTIONS
+{
+/* Linux kernel legacy start address.  */
+. = 0x9020;
+_text = .;
+.text : {
+*(.text)
+}
+.rodata : {
+*(.rodata)
+}
+_etext = .;
+
+. = ALIGN(8192);
+_data = .;
+.got : {
+*(.got)
+}
+.data : {
+   *(.sdata)
+*(.data)
+}
+_edata = .;
+.bss : {
+*(.bss)
+}
+_end = .;
+}
diff --git a/tests/tcg/loongarch64/system/regdef.h 
b/tests/tcg/loongarch64/system/regdef.h
new file mode 100644
index 00..faa09b2377
--- /dev/null
+++ b/tests/tcg/loongarch64/system/regdef.h
@@ -0,0 +1,86 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+#ifndef _ASM_REGDEF_H
+#define _ASM_REGDEF_H
+
+#define zero$r0 /* wired zero */
+#define ra  $r1 /* return address */
+#define tp  $r2
+#define sp  $r3 /* stack pointer */
+#define v0  $r4 /* return value - caller saved */
+#defin

[PATCH v6 04/43] target/loongarch: Add fixed point arithmetic instruction translation

2022-06-01 Thread Xiaojuan Yang
From: Song Gao 

This includes:
- ADD.{W/D}, SUB.{W/D}
- ADDI.{W/D}, ADDU16ID
- ALSL.{W[U]/D}
- LU12I.W, LU32I.D LU52I.D
- SLT[U], SLT[U]I
- PCADDI, PCADDU12I, PCADDU18I, PCALAU12I
- AND, OR, NOR, XOR, ANDN, ORN
- MUL.{W/D}, MULH.{W[U]/D[U]}
- MULW.D.W[U]
- DIV.{W[U]/D[U]}, MOD.{W[U]/D[U]}
- ANDI, ORI, XORI

Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
Reviewed-by: Richard Henderson 
---
 target/loongarch/insn_trans/trans_arith.c.inc | 304 ++
 target/loongarch/insns.decode |  79 +
 target/loongarch/translate.c  |  83 +
 target/loongarch/translate.h  |  19 ++
 4 files changed, 485 insertions(+)
 create mode 100644 target/loongarch/insn_trans/trans_arith.c.inc
 create mode 100644 target/loongarch/insns.decode

diff --git a/target/loongarch/insn_trans/trans_arith.c.inc 
b/target/loongarch/insn_trans/trans_arith.c.inc
new file mode 100644
index 00..8e45eadbc8
--- /dev/null
+++ b/target/loongarch/insn_trans/trans_arith.c.inc
@@ -0,0 +1,304 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+static bool gen_rrr(DisasContext *ctx, arg_rrr *a,
+DisasExtend src1_ext, DisasExtend src2_ext,
+DisasExtend dst_ext, void (*func)(TCGv, TCGv, TCGv))
+{
+TCGv dest = gpr_dst(ctx, a->rd, dst_ext);
+TCGv src1 = gpr_src(ctx, a->rj, src1_ext);
+TCGv src2 = gpr_src(ctx, a->rk, src2_ext);
+
+func(dest, src1, src2);
+gen_set_gpr(a->rd, dest, dst_ext);
+
+return true;
+}
+
+static bool gen_rri_v(DisasContext *ctx, arg_rr_i *a,
+  DisasExtend src_ext, DisasExtend dst_ext,
+  void (*func)(TCGv, TCGv, TCGv))
+{
+TCGv dest = gpr_dst(ctx, a->rd, dst_ext);
+TCGv src1 = gpr_src(ctx, a->rj, src_ext);
+TCGv src2 = tcg_constant_tl(a->imm);
+
+func(dest, src1, src2);
+gen_set_gpr(a->rd, dest, dst_ext);
+
+return true;
+}
+
+static bool gen_rri_c(DisasContext *ctx, arg_rr_i *a,
+  DisasExtend src_ext, DisasExtend dst_ext,
+  void (*func)(TCGv, TCGv, target_long))
+{
+TCGv dest = gpr_dst(ctx, a->rd, dst_ext);
+TCGv src1 = gpr_src(ctx, a->rj, src_ext);
+
+func(dest, src1, a->imm);
+gen_set_gpr(a->rd, dest, dst_ext);
+
+return true;
+}
+
+static bool gen_rrr_sa(DisasContext *ctx, arg_rrr_sa *a,
+   DisasExtend src_ext, DisasExtend dst_ext,
+   void (*func)(TCGv, TCGv, TCGv, target_long))
+{
+TCGv dest = gpr_dst(ctx, a->rd, dst_ext);
+TCGv src1 = gpr_src(ctx, a->rj, src_ext);
+TCGv src2 = gpr_src(ctx, a->rk, src_ext);
+
+func(dest, src1, src2, a->sa);
+gen_set_gpr(a->rd, dest, dst_ext);
+
+return true;
+}
+
+static bool trans_lu12i_w(DisasContext *ctx, arg_lu12i_w *a)
+{
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+
+tcg_gen_movi_tl(dest, a->imm << 12);
+gen_set_gpr(a->rd, dest, EXT_NONE);
+
+return true;
+}
+
+static bool gen_pc(DisasContext *ctx, arg_r_i *a,
+   target_ulong (*func)(target_ulong, int))
+{
+TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+target_ulong addr = func(ctx->base.pc_next, a->imm);
+
+tcg_gen_movi_tl(dest, addr);
+gen_set_gpr(a->rd, dest, EXT_NONE);
+
+return true;
+}
+
+static void gen_slt(TCGv dest, TCGv src1, TCGv src2)
+{
+tcg_gen_setcond_tl(TCG_COND_LT, dest, src1, src2);
+}
+
+static void gen_sltu(TCGv dest, TCGv src1, TCGv src2)
+{
+tcg_gen_setcond_tl(TCG_COND_LTU, dest, src1, src2);
+}
+
+static void gen_mulh_w(TCGv dest, TCGv src1, TCGv src2)
+{
+tcg_gen_mul_i64(dest, src1, src2);
+tcg_gen_sari_i64(dest, dest, 32);
+}
+
+static void gen_mulh_d(TCGv dest, TCGv src1, TCGv src2)
+{
+TCGv discard = tcg_temp_new();
+tcg_gen_muls2_tl(discard, dest, src1, src2);
+tcg_temp_free(discard);
+}
+
+static void gen_mulh_du(TCGv dest, TCGv src1, TCGv src2)
+{
+TCGv discard = tcg_temp_new();
+tcg_gen_mulu2_tl(discard, dest, src1, src2);
+tcg_temp_free(discard);
+}
+
+static void prep_divisor_d(TCGv ret, TCGv src1, TCGv src2)
+{
+TCGv t0 = tcg_temp_new();
+TCGv t1 = tcg_temp_new();
+TCGv zero = tcg_constant_tl(0);
+
+/*
+ * If min / -1, set the divisor to 1.
+ * This avoids potential host overflow trap and produces min.
+ * If x / 0, set the divisor to 1.
+ * This avoids potential host overflow trap;
+ * the required result is undefined.
+ */
+tcg_gen_setcondi_tl(TCG_COND_EQ, ret, src1, INT64_MIN);
+tcg_gen_setcondi_tl(TCG_COND_EQ, t0, src2, -1);
+tcg_gen_setcondi_tl(TCG_COND_EQ, t1, src2, 0);
+tcg_gen_and_tl(ret, ret, t0);
+tcg_gen_or_tl(ret, ret, t1);
+tcg_gen_movcond_tl(TCG_COND_NE, ret, ret, zero, ret, src2);
+
+tcg_temp_free(t0);
+tcg_temp_free(t1);
+}
+
+static void prep_divisor_du(TCGv ret, TCGv src2)
+{
+TCGv zero = tcg_constant_tl(0);
+TCGv one = t

[PATCH v6 26/43] target/loongarch: Add LoongArch IOCSR instruction

2022-06-01 Thread Xiaojuan Yang
This includes:
- IOCSR{RD/WR}.{B/H/W/D}

Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
Reviewed-by: Richard Henderson 
---
 target/loongarch/cpu.c| 44 
 target/loongarch/cpu.h| 25 +++
 target/loongarch/disas.c  |  8 +++
 target/loongarch/helper.h |  8 +++
 .../insn_trans/trans_privileged.c.inc | 35 ++
 target/loongarch/insns.decode |  9 +++
 target/loongarch/iocsr_helper.c   | 67 +++
 target/loongarch/meson.build  |  1 +
 8 files changed, 197 insertions(+)
 create mode 100644 target/loongarch/iocsr_helper.c

diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 18ac11db77..1d5b20bbfa 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -17,6 +17,8 @@
 #include "internals.h"
 #include "fpu/softfloat-helpers.h"
 #include "cpu-csr.h"
+#include "sysemu/reset.h"
+#include "hw/loader.h"
 
 const char * const regnames[32] = {
 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
@@ -484,14 +486,56 @@ static void loongarch_cpu_realizefn(DeviceState *dev, 
Error **errp)
 lacc->parent_realize(dev, errp);
 }
 
+static void loongarch_qemu_write(void *opaque, hwaddr addr,
+ uint64_t val, unsigned size)
+{
+}
+
+static uint64_t loongarch_qemu_read(void *opaque, hwaddr addr, unsigned size)
+{
+switch (addr) {
+case FEATURE_REG:
+return 1ULL << IOCSRF_MSI | 1ULL << IOCSRF_EXTIOI |
+   1ULL << IOCSRF_CSRIPI;
+case VENDOR_REG:
+return 0x6e6f73676e6f6f4cULL; /* "Loongson" */
+case CPUNAME_REG:
+return 0x303030354133ULL; /* "3A5000" */
+case MISC_FUNC_REG:
+return 1ULL << IOCSRM_EXTIOI_EN;
+}
+return 0ULL;
+}
+
+static const MemoryRegionOps loongarch_qemu_ops = {
+.read = loongarch_qemu_read,
+.write = loongarch_qemu_write,
+.endianness = DEVICE_LITTLE_ENDIAN,
+.valid = {
+.min_access_size = 4,
+.max_access_size = 8,
+},
+.impl = {
+.min_access_size = 8,
+.max_access_size = 8,
+},
+};
+
 static void loongarch_cpu_init(Object *obj)
 {
 LoongArchCPU *cpu = LOONGARCH_CPU(obj);
+CPULoongArchState *env = &cpu->env;
 
 cpu_set_cpustate_pointers(cpu);
 qdev_init_gpio_in(DEVICE(cpu), loongarch_cpu_set_irq, N_IRQS);
 timer_init_ns(&cpu->timer, QEMU_CLOCK_VIRTUAL,
   &loongarch_constant_timer_cb, cpu);
+memory_region_init_io(&env->system_iocsr, OBJECT(cpu), NULL,
+  env, "iocsr", UINT64_MAX);
+address_space_init(&env->address_space_iocsr, &env->system_iocsr, "IOCSR");
+memory_region_init_io(&env->iocsr_mem, OBJECT(cpu), &loongarch_qemu_ops,
+  NULL, "iocsr_misc", 0x428);
+memory_region_add_subregion(&env->system_iocsr, 0, &env->iocsr_mem);
 }
 
 static ObjectClass *loongarch_cpu_class_by_name(const char *cpu_model)
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index 2081902f2e..03cc96ee9b 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -12,6 +12,27 @@
 #include "fpu/softfloat-types.h"
 #include "hw/registerfields.h"
 #include "qemu/timer.h"
+#include "exec/memory.h"
+#include "hw/sysbus.h"
+
+#define IOCSRF_TEMP 0
+#define IOCSRF_NODECNT  1
+#define IOCSRF_MSI  2
+#define IOCSRF_EXTIOI   3
+#define IOCSRF_CSRIPI   4
+#define IOCSRF_FREQCSR  5
+#define IOCSRF_FREQSCALE6
+#define IOCSRF_DVFSV1   7
+#define IOCSRF_GMOD 9
+#define IOCSRF_VM   11
+
+#define FEATURE_REG 0x8
+#define VENDOR_REG  0x10
+#define CPUNAME_REG 0x20
+#define MISC_FUNC_REG   0x420
+#define IOCSRM_EXTIOI_EN48
+
+#define IOCSR_MEM_SIZE  0x428
 
 #define TCG_GUEST_DEFAULT_MO (0)
 
@@ -283,6 +304,10 @@ typedef struct CPUArchState {
 uint64_t CSR_DSAVE;
 
 LoongArchTLB  tlb[LOONGARCH_TLB_MAX];
+
+AddressSpace address_space_iocsr;
+MemoryRegion system_iocsr;
+MemoryRegion iocsr_mem;
 } CPULoongArchState;
 
 /**
diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index 11a704ff7c..ea26aea728 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -615,6 +615,14 @@ INSN(bgeu, rr_offs)
 INSN(csrrd,r_csr)
 INSN(csrwr,r_csr)
 INSN(csrxchg,  rr_csr)
+INSN(iocsrrd_b,rr)
+INSN(iocsrrd_h,rr)
+INSN(iocsrrd_w,rr)
+INSN(iocsrrd_d,rr)
+INSN(iocsrwr_b,rr)
+INSN(iocsrwr_h,rr)
+INSN(iocsrwr_w,rr)
+INSN(iocsrwr_d,rr)
 
 #define output_fcmp(C, PREFIX, SUFFIX) 
\
 {  
\
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index 5a6754eb65..4664a02dcf 100644
--- a/target/loongarch/helper.h
+++ b/

[PATCH v6 37/43] hw/loongarch: Add some devices support for 3A5000.

2022-06-01 Thread Xiaojuan Yang
1.Add uart,virtio-net,vga and usb for 3A5000.
2.Add irq set and map for the pci host. Non pci device
use irq 0-16, pci device use 16-64.
3.Add some unimplented device to emulate guest unused
memory space.

Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
Acked-by: Richard Henderson 
---
 hw/loongarch/Kconfig   |  7 
 hw/loongarch/loongson3.c   | 77 ++
 include/hw/pci-host/ls7a.h |  7 
 3 files changed, 91 insertions(+)

diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig
index f779087416..8552ff4bee 100644
--- a/hw/loongarch/Kconfig
+++ b/hw/loongarch/Kconfig
@@ -2,6 +2,13 @@ config LOONGARCH_VIRT
 bool
 select PCI
 select PCI_EXPRESS_GENERIC_BRIDGE
+imply VGA_PCI
+imply VIRTIO_VGA
+imply PCI_DEVICES
+select ISA_BUS
+select SERIAL
+select SERIAL_ISA
+select VIRTIO_PCI
 select LOONGARCH_IPI
 select LOONGARCH_PCH_PIC
 select LOONGARCH_PCH_MSI
diff --git a/hw/loongarch/loongson3.c b/hw/loongarch/loongson3.c
index 7a5c61e2df..7bc17113dc 100644
--- a/hw/loongarch/loongson3.c
+++ b/hw/loongarch/loongson3.c
@@ -9,6 +9,7 @@
 #include "qemu/datadir.h"
 #include "qapi/error.h"
 #include "hw/boards.h"
+#include "hw/char/serial.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/qtest.h"
 #include "sysemu/runstate.h"
@@ -16,14 +17,88 @@
 #include "sysemu/rtc.h"
 #include "hw/loongarch/virt.h"
 #include "exec/address-spaces.h"
+#include "hw/irq.h"
+#include "net/net.h"
 #include "hw/intc/loongarch_ipi.h"
 #include "hw/intc/loongarch_extioi.h"
 #include "hw/intc/loongarch_pch_pic.h"
 #include "hw/intc/loongarch_pch_msi.h"
 #include "hw/pci-host/ls7a.h"
+#include "hw/pci-host/gpex.h"
+#include "hw/misc/unimp.h"
 
 #include "target/loongarch/cpu.h"
 
+static void loongarch_devices_init(DeviceState *pch_pic)
+{
+DeviceState *gpex_dev;
+SysBusDevice *d;
+PCIBus *pci_bus;
+MemoryRegion *ecam_alias, *ecam_reg, *pio_alias, *pio_reg;
+MemoryRegion *mmio_alias, *mmio_reg;
+int i;
+
+gpex_dev = qdev_new(TYPE_GPEX_HOST);
+d = SYS_BUS_DEVICE(gpex_dev);
+sysbus_realize_and_unref(d, &error_fatal);
+pci_bus = PCI_HOST_BRIDGE(gpex_dev)->bus;
+
+/* Map only part size_ecam bytes of ECAM space */
+ecam_alias = g_new0(MemoryRegion, 1);
+ecam_reg = sysbus_mmio_get_region(d, 0);
+memory_region_init_alias(ecam_alias, OBJECT(gpex_dev), "pcie-ecam",
+ ecam_reg, 0, LS_PCIECFG_SIZE);
+memory_region_add_subregion(get_system_memory(), LS_PCIECFG_BASE,
+ecam_alias);
+
+/* Map PCI mem space */
+mmio_alias = g_new0(MemoryRegion, 1);
+mmio_reg = sysbus_mmio_get_region(d, 1);
+memory_region_init_alias(mmio_alias, OBJECT(gpex_dev), "pcie-mmio",
+ mmio_reg, LS7A_PCI_MEM_BASE, LS7A_PCI_MEM_SIZE);
+memory_region_add_subregion(get_system_memory(), LS7A_PCI_MEM_BASE,
+mmio_alias);
+
+/* Map PCI IO port space. */
+pio_alias = g_new0(MemoryRegion, 1);
+pio_reg = sysbus_mmio_get_region(d, 2);
+memory_region_init_alias(pio_alias, OBJECT(gpex_dev), "pcie-io", pio_reg,
+ LS7A_PCI_IO_OFFSET, LS7A_PCI_IO_SIZE);
+memory_region_add_subregion(get_system_memory(), LS7A_PCI_IO_BASE,
+pio_alias);
+
+for (i = 0; i < GPEX_NUM_IRQS; i++) {
+sysbus_connect_irq(d, i,
+   qdev_get_gpio_in(pch_pic, 16 + i));
+gpex_set_irq_num(GPEX_HOST(gpex_dev), i, 16 + i);
+}
+
+serial_mm_init(get_system_memory(), LS7A_UART_BASE, 0,
+   qdev_get_gpio_in(pch_pic,
+LS7A_UART_IRQ - PCH_PIC_IRQ_OFFSET),
+   115200, serial_hd(0), DEVICE_LITTLE_ENDIAN);
+
+/* Network init */
+for (i = 0; i < nb_nics; i++) {
+NICInfo *nd = &nd_table[i];
+
+if (!nd->model) {
+nd->model = g_strdup("virtio");
+}
+
+pci_nic_init_nofail(nd, pci_bus, nd->model, NULL);
+}
+
+/* VGA setup */
+pci_vga_init(pci_bus);
+
+/*
+ * There are some invalid guest memory access.
+ * Create some unimplemented devices to emulate this.
+ */
+create_unimplemented_device("pci-dma-cfg", 0x1001041c, 0x4);
+}
+
 static void loongarch_irq_init(LoongArchMachineState *lams)
 {
 MachineState *ms = MACHINE(lams);
@@ -118,6 +193,8 @@ static void loongarch_irq_init(LoongArchMachineState *lams)
 qdev_connect_gpio_out(DEVICE(d), i,
   qdev_get_gpio_in(extioi, i + PCH_MSI_IRQ_START));
 }
+
+loongarch_devices_init(pch_pic);
 }
 
 static void loongarch_init(MachineState *machine)
diff --git a/include/hw/pci-host/ls7a.h b/include/hw/pci-host/ls7a.h
index 089d3e5438..5c653527f0 100644
--- a/include/hw/pci-host/ls7a.h
+++ b/include/hw/pci-host/ls7a.h
@@ -17,6 +17,11 @@
 
 #define LS7A_PCI_MEM_BASE0x4000UL
 #define LS7A_

Re: [PATCH] target/ppc/cpu-models: Update max alias to power10

2022-06-01 Thread Daniel Henrique Barboza




On 6/1/22 07:03, Greg Kurz wrote:

On Wed, 1 Jun 2022 11:25:43 +0200
Thomas Huth  wrote:


On 01/06/2022 10.38, Greg Kurz wrote:

On Wed, 1 Jun 2022 09:27:31 +0200
Thomas Huth  wrote:


On 31/05/2022 19.27, Murilo Opsfelder Araujo wrote:

Update max alias to power10 so users can take advantage of a more
recent CPU model when '-cpu max' is provided.

...

We already have the concept of default CPU for the spapr
machine types, that is usually popped up to the newer
CPU model that is going to be supported in production.
This goes with a bump of the machine type version as
well for the sake of migration. This seems a lot more
reliable than the "max" thingy IMHO.

Unless there's a very important use case I'm missing,
I'd rather kill the thing instead of trying to resurrect
it.


It's about making ppc similar to other architectures, which
have "-cpu max" as well, see:

   https://gitlab.com/qemu-project/qemu/-/issues/1038

It would be nice to get something similar on ppc.



Problem is that on ppc, given the variety of models and boards,
the concept of "max" is quite fuzzy... i.e. a lot of cases to
consider for a benefit that is unclear to me. Hence my questioning.
If the idea is just to match what other targets do without a specific
use case in mind, this looks quite useless to me.


I mean, yes, the use case is that users/tooling are using -cpu max with x86
and arm. We'd rather not increase the gap between them and ppc64 because we
ended up removing -cpu max.

Even if the concept might not be applicable to every machine we have we can 
alias
-cpu max to the default machine CPU.




By the way, the warnings that you currently get when running with
TCG are quite ugly, too:

$ ./qemu-system-ppc64
qemu-system-ppc64: warning: TCG doesn't support requested feature,
cap-cfpc=workaround
qemu-system-ppc64: warning: TCG doesn't support requested feature,
cap-sbbc=workaround
qemu-system-ppc64: warning: TCG doesn't support requested feature,
cap-ibs=workaround
qemu-system-ppc64: warning: TCG doesn't support requested feature,
cap-ccf-assist=on

Maybe these could get fixed with a proper "max" CPU in TCG
mode, too?



I don't think so. These warnings are the consequence of pseries
being the default machine for ppc64, and the default pseries
machine decides on the default CPU model and default values for
features (in this case, these are mitigations for spectre/meltdown).
TCG doesn't support them but we certainly don't want to add more
divergence between TCG and KVM.


I sent a patch last year trying to suppress the warning:

https://lists.gnu.org/archive/html/qemu-devel/2021-01/msg05029.html

I proposed to suppress these warnings when the user didn't specifically
set those caps to true (which TCG doesn't support). David thought that
this was also a bad idea and we reached an impasse. Back then seemed like
I was the only one severely aggravated by these messages so I gave up :)


Thanks,


Daniel



Cheers,

--
Greg


   Thomas







[PATCH v6 32/43] hw/intc: Add LoongArch ls7a interrupt controller support(PCH-PIC)

2022-06-01 Thread Xiaojuan Yang
This patch realize the PCH-PIC interrupt controller.

Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
Reviewed-by: Richard Henderson 
---
 MAINTAINERS |   1 +
 hw/intc/Kconfig |   4 +
 hw/intc/loongarch_pch_pic.c | 431 
 hw/intc/meson.build |   1 +
 hw/intc/trace-events|   9 +
 hw/loongarch/Kconfig|   1 +
 include/hw/intc/loongarch_pch_pic.h |  69 +
 include/hw/pci-host/ls7a.h  |  30 ++
 8 files changed, 546 insertions(+)
 create mode 100644 hw/intc/loongarch_pch_pic.c
 create mode 100644 include/hw/intc/loongarch_pch_pic.h
 create mode 100644 include/hw/pci-host/ls7a.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 6872e9a2be..c22f95fb6a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1136,6 +1136,7 @@ F: hw/loongarch/
 F: include/hw/loongarch/virt.h
 F: include/hw/intc/loongarch_*.h
 F: hw/intc/loongarch_*.c
+F: include/hw/pci-host/ls7a.h
 
 M68K Machines
 -
diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
index 1122c33cec..362980ca8c 100644
--- a/hw/intc/Kconfig
+++ b/hw/intc/Kconfig
@@ -90,3 +90,7 @@ config NIOS2_VIC
 
 config LOONGARCH_IPI
 bool
+
+config LOONGARCH_PCH_PIC
+bool
+select UNIMP
diff --git a/hw/intc/loongarch_pch_pic.c b/hw/intc/loongarch_pch_pic.c
new file mode 100644
index 00..3c9814a3b4
--- /dev/null
+++ b/hw/intc/loongarch_pch_pic.c
@@ -0,0 +1,431 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * QEMU Loongson 7A1000 I/O interrupt controller.
+ *
+ * Copyright (C) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "hw/sysbus.h"
+#include "hw/loongarch/virt.h"
+#include "hw/irq.h"
+#include "hw/intc/loongarch_pch_pic.h"
+#include "migration/vmstate.h"
+#include "trace.h"
+
+static void pch_pic_update_irq(LoongArchPCHPIC *s, uint64_t mask, int level)
+{
+unsigned long val;
+int irq;
+
+if (level) {
+val = mask & s->intirr & ~s->int_mask;
+if (val) {
+irq = find_first_bit(&val, 64);
+s->intisr |= 0x1ULL << irq;
+qemu_set_irq(s->parent_irq[s->htmsi_vector[irq]], 1);
+}
+} else {
+val = mask & s->intisr;
+if (val) {
+irq = find_first_bit(&val, 64);
+s->intisr &= ~(0x1ULL << irq);
+qemu_set_irq(s->parent_irq[s->htmsi_vector[irq]], 0);
+}
+}
+}
+
+static void pch_pic_irq_handler(void *opaque, int irq, int level)
+{
+LoongArchPCHPIC *s = LOONGARCH_PCH_PIC(opaque);
+uint64_t mask = 1ULL << irq;
+
+assert(irq < PCH_PIC_IRQ_NUM);
+trace_loongarch_pch_pic_irq_handler(irq, level);
+
+if (s->intedge & mask) {
+/* Edge triggered */
+if (level) {
+if ((s->last_intirr & mask) == 0) {
+s->intirr |= mask;
+}
+s->last_intirr |= mask;
+} else {
+s->last_intirr &= ~mask;
+}
+} else {
+/* Level triggered */
+if (level) {
+s->intirr |= mask;
+s->last_intirr |= mask;
+} else {
+s->intirr &= ~mask;
+s->last_intirr &= ~mask;
+}
+}
+pch_pic_update_irq(s, mask, level);
+}
+
+static uint64_t loongarch_pch_pic_low_readw(void *opaque, hwaddr addr,
+unsigned size)
+{
+LoongArchPCHPIC *s = LOONGARCH_PCH_PIC(opaque);
+uint64_t val = 0;
+uint32_t offset = addr & 0xfff;
+
+switch (offset) {
+case PCH_PIC_INT_ID_LO:
+val = PCH_PIC_INT_ID_VAL;
+break;
+case PCH_PIC_INT_ID_HI:
+val = PCH_PIC_INT_ID_NUM;
+break;
+case PCH_PIC_INT_MASK_LO:
+val = (uint32_t)s->int_mask;
+break;
+case PCH_PIC_INT_MASK_HI:
+val = s->int_mask >> 32;
+break;
+case PCH_PIC_INT_EDGE_LO:
+val = (uint32_t)s->intedge;
+break;
+case PCH_PIC_INT_EDGE_HI:
+val = s->intedge >> 32;
+break;
+case PCH_PIC_HTMSI_EN_LO:
+val = (uint32_t)s->htmsi_en;
+break;
+case PCH_PIC_HTMSI_EN_HI:
+val = s->htmsi_en >> 32;
+break;
+case PCH_PIC_AUTO_CTRL0_LO:
+case PCH_PIC_AUTO_CTRL0_HI:
+case PCH_PIC_AUTO_CTRL1_LO:
+case PCH_PIC_AUTO_CTRL1_HI:
+break;
+default:
+break;
+}
+
+trace_loongarch_pch_pic_low_readw(size, addr, val);
+return val;
+}
+
+static uint64_t get_writew_val(uint64_t value, uint32_t target, bool hi)
+{
+uint64_t mask = 0x;
+uint64_t data = target;
+
+return hi ? (value & ~mask) | (data << 32) : (value & mask) | data;
+}
+
+static void loongarch_pch_pic_low_writew(void *opaque, hwaddr addr,
+ uint64_t value, unsigned size)
+{
+LoongArchPCHPIC *s = LOONGARCH_PCH_PIC(opaque);
+uint32_t offset, old_valid, data = (uint32_t)value;
+uint64_t old, int_mask;
+of

[PATCH v6 16/43] target/loongarch: Add disassembler

2022-06-01 Thread Xiaojuan Yang
From: Song Gao 

This patch adds support for disassembling via option '-d in_asm'.

Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
Reviewed-by: Richard Henderson 
---
 include/disas/dis-asm.h  |   2 +
 meson.build  |   1 +
 target/loongarch/disas.c | 610 +++
 3 files changed, 613 insertions(+)
 create mode 100644 target/loongarch/disas.c

diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h
index fc7cb7af5a..64247ecb11 100644
--- a/include/disas/dis-asm.h
+++ b/include/disas/dis-asm.h
@@ -253,6 +253,7 @@ enum bfd_architecture
 #define bfd_mach_rx0x75
 #define bfd_mach_rx_v2 0x76
 #define bfd_mach_rx_v3 0x77
+  bfd_arch_loongarch,
   bfd_arch_last
   };
 #define bfd_mach_s390_31 31
@@ -458,6 +459,7 @@ int print_insn_riscv64  (bfd_vma, 
disassemble_info*);
 int print_insn_riscv128 (bfd_vma, disassemble_info*);
 int print_insn_rx(bfd_vma, disassemble_info *);
 int print_insn_hexagon(bfd_vma, disassemble_info *);
+int print_insn_loongarch(bfd_vma, disassemble_info *);
 
 #ifdef CONFIG_CAPSTONE
 bool cap_disas_target(disassemble_info *info, uint64_t pc, size_t size);
diff --git a/meson.build b/meson.build
index bf318d9cbb..33f3a22a39 100644
--- a/meson.build
+++ b/meson.build
@@ -2349,6 +2349,7 @@ disassemblers = {
   'sh4' : ['CONFIG_SH4_DIS'],
   'sparc' : ['CONFIG_SPARC_DIS'],
   'xtensa' : ['CONFIG_XTENSA_DIS'],
+  'loongarch' : ['CONFIG_LOONGARCH_DIS'],
 }
 if link_language == 'cpp'
   disassemblers += {
diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
new file mode 100644
index 00..9454ebb8e9
--- /dev/null
+++ b/target/loongarch/disas.c
@@ -0,0 +1,610 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * QEMU LoongArch Disassembler
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited.
+ */
+
+#include "qemu/osdep.h"
+#include "disas/dis-asm.h"
+#include "qemu/bitops.h"
+
+typedef struct {
+disassemble_info *info;
+uint64_t pc;
+uint32_t insn;
+} DisasContext;
+
+static inline int plus_1(DisasContext *ctx, int x)
+{
+return x + 1;
+}
+
+static inline int shl_2(DisasContext *ctx, int x)
+{
+return x << 2;
+}
+
+#define output(C, INSN, FMT, ...)   \
+{   \
+(C)->info->fprintf_func((C)->info->stream, "%08x   %-9s\t" FMT, \
+(C)->insn, INSN, ##__VA_ARGS__);\
+}
+
+#include "decode-insns.c.inc"
+
+int print_insn_loongarch(bfd_vma memaddr, struct disassemble_info *info)
+{
+bfd_byte buffer[4];
+uint32_t insn;
+int status;
+
+status = (*info->read_memory_func)(memaddr, buffer, 4, info);
+if (status != 0) {
+(*info->memory_error_func)(status, memaddr, info);
+return -1;
+}
+insn = bfd_getl32(buffer);
+DisasContext ctx = {
+.info = info,
+.pc = memaddr,
+.insn = insn
+};
+
+if (!decode(&ctx, insn)) {
+output(&ctx, "illegal", "");
+}
+return 4;
+}
+
+static void output_r_i(DisasContext *ctx, arg_r_i *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "r%d, %d", a->rd, a->imm);
+}
+
+static void output_rrr(DisasContext *ctx, arg_rrr *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "r%d, r%d, r%d", a->rd, a->rj, a->rk);
+}
+
+static void output_rr_i(DisasContext *ctx, arg_rr_i *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "r%d, r%d, %d", a->rd, a->rj, a->imm);
+}
+
+static void output_rrr_sa(DisasContext *ctx, arg_rrr_sa *a,
+  const char *mnemonic)
+{
+output(ctx, mnemonic, "r%d, r%d, r%d, %d", a->rd, a->rj, a->rk, a->sa);
+}
+
+static void output_rr(DisasContext *ctx, arg_rr *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "r%d, r%d", a->rd, a->rj);
+}
+
+static void output_rr_ms_ls(DisasContext *ctx, arg_rr_ms_ls *a,
+  const char *mnemonic)
+{
+output(ctx, mnemonic, "r%d, r%d, %d, %d", a->rd, a->rj, a->ms, a->ls);
+}
+
+static void output_hint_r_i(DisasContext *ctx, arg_hint_r_i *a,
+const char *mnemonic)
+{
+output(ctx, mnemonic, "%d, r%d, %d", a->hint, a->rj, a->imm);
+}
+
+static void output_i(DisasContext *ctx, arg_i *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "%d", a->imm);
+}
+
+static void output_rr_jk(DisasContext *ctx, arg_rr_jk *a,
+ const char *mnemonic)
+{
+output(ctx, mnemonic, "r%d, r%d", a->rj, a->rk);
+}
+
+static void output_ff(DisasContext *ctx, arg_ff *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "f%d, f%d", a->fd, a->fj);
+}
+
+static void output_fff(DisasContext *ctx, arg_fff *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "f%d, f%d, f%d", a->fd, a->fj, a->fk);
+}
+
+static void output_(DisasContext *ctx, arg_ *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "f%d, f%d, f%d, f%d", a->fd, a->fj, a->fk, a->fa);
+

[PATCH v6 10/43] target/loongarch: Add floating point arithmetic instruction translation

2022-06-01 Thread Xiaojuan Yang
From: Song Gao 

This includes:
- F{ADD/SUB/MUL/DIV}.{S/D}
- F{MADD/MSUB/NMADD/NMSUB}.{S/D}
- F{MAX/MIN}.{S/D}
- F{MAXA/MINA}.{S/D}
- F{ABS/NEG}.{S/D}
- F{SQRT/RECIP/RSQRT}.{S/D}
- F{SCALEB/LOGB/COPYSIGN}.{S/D}
- FCLASS.{S/D}

Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
Reviewed-by: Richard Henderson 
---
 target/loongarch/cpu.c|   1 +
 target/loongarch/fpu_helper.c | 403 ++
 target/loongarch/helper.h |  37 ++
 .../loongarch/insn_trans/trans_farith.c.inc   | 105 +
 target/loongarch/insns.decode |  52 +++
 target/loongarch/internals.h  |   2 +
 target/loongarch/translate.c  |  11 +
 7 files changed, 611 insertions(+)
 create mode 100644 target/loongarch/fpu_helper.c
 create mode 100644 target/loongarch/insn_trans/trans_farith.c.inc

diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 1f8e37906a..95900be257 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -196,6 +196,7 @@ static void loongarch_cpu_reset(DeviceState *dev)
 env->fcsr0_mask = FCSR0_M1 | FCSR0_M2 | FCSR0_M3;
 env->fcsr0 = 0x0;
 
+restore_fp_status(env);
 cs->exception_index = -1;
 }
 
diff --git a/target/loongarch/fpu_helper.c b/target/loongarch/fpu_helper.c
new file mode 100644
index 00..d7442cc188
--- /dev/null
+++ b/target/loongarch/fpu_helper.c
@@ -0,0 +1,403 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * LoongArch float point emulation helpers for QEMU
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "exec/helper-proto.h"
+#include "exec/exec-all.h"
+#include "exec/cpu_ldst.h"
+#include "fpu/softfloat.h"
+#include "internals.h"
+
+#define FLOAT_TO_INT32_OVERFLOW 0x7fff
+#define FLOAT_TO_INT64_OVERFLOW 0x7fffULL
+
+static inline uint64_t nanbox_s(float32 fp)
+{
+return fp | MAKE_64BIT_MASK(32, 32);
+}
+
+/* Convert loongarch rounding mode in fcsr0 to IEEE library */
+static const FloatRoundMode ieee_rm[4] = {
+float_round_nearest_even,
+float_round_to_zero,
+float_round_up,
+float_round_down
+};
+
+void restore_fp_status(CPULoongArchState *env)
+{
+set_float_rounding_mode(ieee_rm[(env->fcsr0 >> FCSR0_RM) & 0x3],
+&env->fp_status);
+set_flush_to_zero(0, &env->fp_status);
+}
+
+static int ieee_ex_to_loongarch(int xcpt)
+{
+int ret = 0;
+if (xcpt & float_flag_invalid) {
+ret |= FP_INVALID;
+}
+if (xcpt & float_flag_overflow) {
+ret |= FP_OVERFLOW;
+}
+if (xcpt & float_flag_underflow) {
+ret |= FP_UNDERFLOW;
+}
+if (xcpt & float_flag_divbyzero) {
+ret |= FP_DIV0;
+}
+if (xcpt & float_flag_inexact) {
+ret |= FP_INEXACT;
+}
+return ret;
+}
+
+static void update_fcsr0_mask(CPULoongArchState *env, uintptr_t pc, int mask)
+{
+int flags = get_float_exception_flags(&env->fp_status);
+
+set_float_exception_flags(0, &env->fp_status);
+
+flags &= ~mask;
+
+if (!flags) {
+SET_FP_CAUSE(env->fcsr0, flags);
+return;
+} else {
+flags = ieee_ex_to_loongarch(flags);
+SET_FP_CAUSE(env->fcsr0, flags);
+}
+
+if (GET_FP_ENABLES(env->fcsr0) & flags) {
+do_raise_exception(env, EXCCODE_FPE, pc);
+} else {
+UPDATE_FP_FLAGS(env->fcsr0, flags);
+}
+}
+
+static void update_fcsr0(CPULoongArchState *env, uintptr_t pc)
+{
+update_fcsr0_mask(env, pc, 0);
+}
+
+uint64_t helper_fadd_s(CPULoongArchState *env, uint64_t fj, uint64_t fk)
+{
+uint64_t fd;
+
+fd = nanbox_s(float32_add((uint32_t)fj, (uint32_t)fk, &env->fp_status));
+update_fcsr0(env, GETPC());
+return fd;
+}
+
+uint64_t helper_fadd_d(CPULoongArchState *env, uint64_t fj, uint64_t fk)
+{
+uint64_t fd;
+
+fd = float64_add(fj, fk, &env->fp_status);
+update_fcsr0(env, GETPC());
+return fd;
+}
+
+uint64_t helper_fsub_s(CPULoongArchState *env, uint64_t fj, uint64_t fk)
+{
+uint64_t fd;
+
+fd = nanbox_s(float32_sub((uint32_t)fj, (uint32_t)fk, &env->fp_status));
+update_fcsr0(env, GETPC());
+return fd;
+}
+
+uint64_t helper_fsub_d(CPULoongArchState *env, uint64_t fj, uint64_t fk)
+{
+uint64_t fd;
+
+fd = float64_sub(fj, fk, &env->fp_status);
+update_fcsr0(env, GETPC());
+return fd;
+}
+
+uint64_t helper_fmul_s(CPULoongArchState *env, uint64_t fj, uint64_t fk)
+{
+uint64_t fd;
+
+fd = nanbox_s(float32_mul((uint32_t)fj, (uint32_t)fk, &env->fp_status));
+update_fcsr0(env, GETPC());
+return fd;
+}
+
+uint64_t helper_fmul_d(CPULoongArchState *env, uint64_t fj, uint64_t fk)
+{
+uint64_t fd;
+
+fd = float64_mul(fj, fk, &env->fp_status);
+update_fcsr0(env, GETPC());
+return fd;
+}
+
+uint64_t helper_fdiv_s(CPULoongArchState *env, uint64_t fj, uint64_t fk)
+{
+uint64_t fd;
+
+fd = nanbox_s(float32_div((uint32

[PATCH v6 12/43] target/loongarch: Add floating point conversion instruction translation

2022-06-01 Thread Xiaojuan Yang
From: Song Gao 

This includes:
- FCVT.S.D, FCVT.D.S
- FFINT.{S/D}.{W/L}, FTINT.{W/L}.{S/D}
- FTINT{RM/RP/RZ/RNE}.{W/L}.{S/D}
- FRINT.{S/D}

Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
Reviewed-by: Richard Henderson 
---
 target/loongarch/fpu_helper.c| 393 +++
 target/loongarch/helper.h|  29 ++
 target/loongarch/insn_trans/trans_fcnv.c.inc |  33 ++
 target/loongarch/insns.decode|  32 ++
 target/loongarch/translate.c |   1 +
 5 files changed, 488 insertions(+)
 create mode 100644 target/loongarch/insn_trans/trans_fcnv.c.inc

diff --git a/target/loongarch/fpu_helper.c b/target/loongarch/fpu_helper.c
index 1e514cce74..81466678eb 100644
--- a/target/loongarch/fpu_helper.c
+++ b/target/loongarch/fpu_helper.c
@@ -461,3 +461,396 @@ uint64_t helper_fcmp_s_d(CPULoongArchState *env, uint64_t 
fj,
 FloatRelation cmp = float64_compare(fj, fk, &env->fp_status);
 return fcmp_common(env, cmp, flags);
 }
+
+/* floating point conversion */
+uint64_t helper_fcvt_s_d(CPULoongArchState *env, uint64_t fj)
+{
+uint64_t fd;
+
+fd = nanbox_s(float64_to_float32(fj, &env->fp_status));
+update_fcsr0(env, GETPC());
+return fd;
+}
+
+uint64_t helper_fcvt_d_s(CPULoongArchState *env, uint64_t fj)
+{
+uint64_t fd;
+
+fd = float32_to_float64((uint32_t)fj, &env->fp_status);
+update_fcsr0(env, GETPC());
+return fd;
+}
+
+uint64_t helper_ffint_s_w(CPULoongArchState *env, uint64_t fj)
+{
+uint64_t fd;
+
+fd = nanbox_s(int32_to_float32((int32_t)fj, &env->fp_status));
+update_fcsr0(env, GETPC());
+return fd;
+}
+
+uint64_t helper_ffint_s_l(CPULoongArchState *env, uint64_t fj)
+{
+uint64_t fd;
+
+fd = nanbox_s(int64_to_float32(fj, &env->fp_status));
+update_fcsr0(env, GETPC());
+return fd;
+}
+
+uint64_t helper_ffint_d_w(CPULoongArchState *env, uint64_t fj)
+{
+uint64_t fd;
+
+fd = int32_to_float64((int32_t)fj, &env->fp_status);
+update_fcsr0(env, GETPC());
+return fd;
+}
+
+uint64_t helper_ffint_d_l(CPULoongArchState *env, uint64_t fj)
+{
+uint64_t fd;
+
+fd = int64_to_float64(fj, &env->fp_status);
+update_fcsr0(env, GETPC());
+return fd;
+}
+
+uint64_t helper_frint_s(CPULoongArchState *env, uint64_t fj)
+{
+uint64_t fd;
+
+fd = (uint64_t)(float32_round_to_int((uint32_t)fj, &env->fp_status));
+update_fcsr0(env, GETPC());
+return fd;
+}
+
+uint64_t helper_frint_d(CPULoongArchState *env, uint64_t fj)
+{
+uint64_t fd;
+
+fd = float64_round_to_int(fj, &env->fp_status);
+update_fcsr0(env, GETPC());
+return fd;
+}
+
+uint64_t helper_ftintrm_l_d(CPULoongArchState *env, uint64_t fj)
+{
+uint64_t fd;
+FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status);
+
+set_float_rounding_mode(float_round_down, &env->fp_status);
+fd = float64_to_int64(fj, &env->fp_status);
+set_float_rounding_mode(old_mode, &env->fp_status);
+
+if (get_float_exception_flags(&env->fp_status) &
+(float_flag_invalid | float_flag_overflow)) {
+fd = FLOAT_TO_INT64_OVERFLOW;
+}
+update_fcsr0(env, GETPC());
+return fd;
+}
+
+uint64_t helper_ftintrm_l_s(CPULoongArchState *env, uint64_t fj)
+{
+uint64_t fd;
+FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status);
+
+set_float_rounding_mode(float_round_down, &env->fp_status);
+fd = float32_to_int64((uint32_t)fj, &env->fp_status);
+set_float_rounding_mode(old_mode, &env->fp_status);
+
+if (get_float_exception_flags(&env->fp_status) &
+(float_flag_invalid | float_flag_overflow)) {
+fd = FLOAT_TO_INT64_OVERFLOW;
+}
+update_fcsr0(env, GETPC());
+return fd;
+}
+
+uint64_t helper_ftintrm_w_d(CPULoongArchState *env, uint64_t fj)
+{
+uint64_t fd;
+FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status);
+
+set_float_rounding_mode(float_round_down, &env->fp_status);
+fd = (uint64_t)float64_to_int32(fj, &env->fp_status);
+set_float_rounding_mode(old_mode, &env->fp_status);
+
+if (get_float_exception_flags(&env->fp_status) &
+(float_flag_invalid | float_flag_overflow)) {
+fd = FLOAT_TO_INT32_OVERFLOW;
+}
+update_fcsr0(env, GETPC());
+return fd;
+}
+
+uint64_t helper_ftintrm_w_s(CPULoongArchState *env, uint64_t fj)
+{
+uint64_t fd;
+FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status);
+
+set_float_rounding_mode(float_round_down, &env->fp_status);
+fd = (uint64_t)float32_to_int32((uint32_t)fj, &env->fp_status);
+set_float_rounding_mode(old_mode, &env->fp_status);
+
+if (get_float_exception_flags(&env->fp_status) &
+(float_flag_invalid | float_flag_overflow)) {
+fd = FLOAT_TO_INT32_OVERFLOW;
+}
+update_fcsr0(env, GETPC());
+return fd;
+}
+
+uint64_t helper_ftintrp_l_d(CPULoongArchState *env, uint64_t fj)
+{
+uint64_t fd;
+FloatRoundMode old_mode = get_float_rounding_

Re: [RFC PATCH v5 0/3] Sysbus device generic QAPI plug support

2022-06-01 Thread Mark Cave-Ayland

On 01/06/2022 09:39, Damien Hedde wrote:


On 5/31/22 22:43, Mark Cave-Ayland wrote:

On 31/05/2022 10:22, Damien Hedde wrote:


On 5/31/22 10:00, Mark Cave-Ayland wrote:

On 30/05/2022 15:05, Damien Hedde wrote:


On 5/30/22 12:25, Peter Maydell wrote:

On Mon, 30 May 2022 at 10:50, Damien Hedde  wrote:

TYPE_SYS_BUS_DEVICE also comes with reset support.
If a device is on not on any bus it is not reached by the root sysbus
reset which propagates to every device (and other sub-buses).
Even if we move all the mmio/sysbus-irq logic into TYPE_DEVICE, we will
still miss that. The bus is needed to handle the reset.
For devices created in machine init code, we have the option to do it in
the machine reset handler. But for user created device, this is an issue.


Yes, the missing reset support in TYPE_DEVICE is a design
flaw that we really should try to address.


I think the easiest way to handle this would be just after calling dc->realize; 
if the device has bus == NULL and dc->reset != NULL then manually call 
qemu_register_reset() for dc->reset. In a qdev world dc->reset is intended to be 
a bus-level reset, but I can't see an issue with manual registration for 
individual devices in this way, particularly as there are no reset ordering 
guarantees for sysbus.


I'm a bit afraid calling qemu_register_reset() outside dc->realize might modify 
the behavior for existing devices. Does any device end up having a non-NULL bus 
right now when using "-device" CLI ?


If you take a look at "info qtree" then that will show you all devices that are 
attached to a bus i.e. ones where bus is not NULL.



If we end up putting in TYPE_DEVICE support for mmios, interrupts and
some way to do the bus reset. What would be the difference between the
current TYPE_SYS_BUS_DEVICE ?


There would be none, and the idea would be to get rid of
TYPE_SYS_BUS_DEVICE entirely...

Do you expect the bus object to disappear in the process (bus-less system) or 
transforming the sysbus into a ~TYPE_BUS thing ?


I'd probably lean towards removing sysbus completely since in real life devices 
can exist outside of a bus. If a device needs a bus then it should already be 
modelled in QEMU, and anything that requires a hierarchy can already be 
represented via QOM children


For me, a "memory bus" is a bus. But I understand in QEMU, this is modeled by a 
memory region and we do not want to represent it anymore by a qdev/qbus hierarchy.




Assuming we manage to sort out this does cold plugging using the following 
scenario looks ok ? (regarding having to issue one command to create the device 
AND some commands to handle memory-region and interrupt lines)


 > device_add driver=ibex-uart id=uart chardev=serial0
 > sysbus-mmio-map device=uart addr=1073741824
 > qom-set path=uart property=sysbus-irq[0] value=plic/unnamed-gpio-in[1]

TYPE_DEVICE or TYPE_SYS_BUS_DEVICE, my goal is still to be able to cold-plug a 
"ibex-uart" define its memory map and choose which irq I wire where.


Anyhow getting back on topic: my main objection here is that you're adding a 
command "sysbus-mmio-map" when we don't want the concept of SysBusDevice to be 
exposed outside of QEMU at all. Referring back to my last email I think we should 
extend the device concept in the monitor to handle the additional functionality 
perhaps along the lines of:


- A monitor command such as "device_map" which is effectively a wrapper around
   memory_region_add_subregion(). Do we also want a "device_unmap"? We should
   consider allow mapping to other memory regions other than the system root.

- A monitor command such as "device_connect" which can be used to simplify your 
IRQ
   wiring, perhaps also with a "device_disconnect"?

- An outline of the monitor commands showing the complete workflow from 
introspection

   of a device to mapping its memory region(s) and connecting its gpios

Does that give you enough information to come up with a more detailed proposal?



Yes. Sorry for being not clear enough. I did not wanted to insist on specific 
command names. I've no issues regarding the modifications you request about having 
a device_connect or a device_map.


My question was more about the workflow which does not rely on issuing a single 
'device_add' command handling mapping/connection using parameters. Note that since 
we are talking supporting of map/connect for the base type TYPE_DEVICE, I don't 
really see how we could have parameters for these without impacting subtypes.


I'm not sure I understand what you are saying here? Can you give an example?


There are 2 possible workflows:
1. several commands
 > device_add ...
 > device_map ...
 > device_connect ...

2. single command
 > device_add ... map={...} connect={...}

The 2nd one is more like how we connect devices with '-device': all is done at once. 
But if this is supposed to apply to TYPE_DEVICE (versus TYPE_SYS_BUS_DEVICE), it 
becomes IMHO hard to prevent using them on devices where it does not makes sense (for 
examp

Re: [RFC PATCH v5 0/3] Sysbus device generic QAPI plug support

2022-06-01 Thread Mark Cave-Ayland

On 01/06/2022 10:07, David Hildenbrand wrote:


On 01.06.22 10:39, Damien Hedde wrote:



On 5/31/22 22:43, Mark Cave-Ayland wrote:

On 31/05/2022 10:22, Damien Hedde wrote:


On 5/31/22 10:00, Mark Cave-Ayland wrote:

On 30/05/2022 15:05, Damien Hedde wrote:


On 5/30/22 12:25, Peter Maydell wrote:

On Mon, 30 May 2022 at 10:50, Damien Hedde
 wrote:

TYPE_SYS_BUS_DEVICE also comes with reset support.
If a device is on not on any bus it is not reached by the root sysbus
reset which propagates to every device (and other sub-buses).
Even if we move all the mmio/sysbus-irq logic into TYPE_DEVICE, we
will
still miss that. The bus is needed to handle the reset.
For devices created in machine init code, we have the option to do
it in
the machine reset handler. But for user created device, this is an
issue.


Yes, the missing reset support in TYPE_DEVICE is a design
flaw that we really should try to address.


I think the easiest way to handle this would be just after calling
dc->realize; if the device has bus == NULL and dc->reset != NULL then
manually call qemu_register_reset() for dc->reset. In a qdev world
dc->reset is intended to be a bus-level reset, but I can't see an
issue with manual registration for individual devices in this way,
particularly as there are no reset ordering guarantees for sysbus.


I'm a bit afraid calling qemu_register_reset() outside dc->realize
might modify the behavior for existing devices. Does any device end up
having a non-NULL bus right now when using "-device" CLI ?


If you take a look at "info qtree" then that will show you all devices
that are attached to a bus i.e. ones where bus is not NULL.


If we end up putting in TYPE_DEVICE support for mmios, interrupts and
some way to do the bus reset. What would be the difference between
the
current TYPE_SYS_BUS_DEVICE ?


There would be none, and the idea would be to get rid of
TYPE_SYS_BUS_DEVICE entirely...


Do you expect the bus object to disappear in the process (bus-less
system) or transforming the sysbus into a ~TYPE_BUS thing ?


I'd probably lean towards removing sysbus completely since in real
life devices can exist outside of a bus. If a device needs a bus then
it should already be modelled in QEMU, and anything that requires a
hierarchy can already be represented via QOM children


For me, a "memory bus" is a bus. But I understand in QEMU, this is
modeled by a memory region and we do not want to represent it anymore
by a qdev/qbus hierarchy.




Assuming we manage to sort out this does cold plugging using the
following scenario looks ok ? (regarding having to issue one command
to create the device AND some commands to handle memory-region and
interrupt lines)

  > device_add driver=ibex-uart id=uart chardev=serial0
  > sysbus-mmio-map device=uart addr=1073741824
  > qom-set path=uart property=sysbus-irq[0]
value=plic/unnamed-gpio-in[1]

TYPE_DEVICE or TYPE_SYS_BUS_DEVICE, my goal is still to be able to
cold-plug a "ibex-uart" define its memory map and choose which irq I
wire where.


Anyhow getting back on topic: my main objection here is that you're
adding a command "sysbus-mmio-map" when we don't want the concept of
SysBusDevice to be exposed outside of QEMU at all. Referring back to
my last email I think we should extend the device concept in the
monitor to handle the additional functionality perhaps along the
lines of:

- A monitor command such as "device_map" which is effectively a
wrapper around
    memory_region_add_subregion(). Do we also want a "device_unmap"?
We should
    consider allow mapping to other memory regions other than the
system root.

- A monitor command such as "device_connect" which can be used to
simplify your IRQ
    wiring, perhaps also with a "device_disconnect"?

- An outline of the monitor commands showing the complete workflow
from introspection
    of a device to mapping its memory region(s) and connecting its gpios

Does that give you enough information to come up with a more detailed
proposal?



Yes. Sorry for being not clear enough. I did not wanted to insist on
specific command names. I've no issues regarding the modifications you
request about having a device_connect or a device_map.

My question was more about the workflow which does not rely on issuing
a single 'device_add' command handling mapping/connection using
parameters. Note that since we are talking supporting of map/connect
for the base type TYPE_DEVICE, I don't really see how we could have
parameters for these without impacting subtypes.


I'm not sure I understand what you are saying here? Can you give an
example?


There are 2 possible workflows:
1. several commands
  > device_add ...
  > device_map ...
  > device_connect ...

2. single command
  > device_add ... map={...} connect={...}

The 2nd one is more like how we connect devices with '-device': all is
done at once. But if this is supposed to apply to TYPE_DEVICE (versus
TYPE_SYS_BUS_DEVICE), it becomes IMHO hard to prevent using them on
devices where it does no

[PATCH v6 19/43] target/loongarch: Add CSRs definition

2022-06-01 Thread Xiaojuan Yang
Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
Reviewed-by: Richard Henderson 
---
 target/loongarch/cpu-csr.h | 208 +
 target/loongarch/cpu.c |  36 +++
 target/loongarch/cpu.h |  64 
 3 files changed, 308 insertions(+)
 create mode 100644 target/loongarch/cpu-csr.h

diff --git a/target/loongarch/cpu-csr.h b/target/loongarch/cpu-csr.h
new file mode 100644
index 00..4c8ce7fed5
--- /dev/null
+++ b/target/loongarch/cpu-csr.h
@@ -0,0 +1,208 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * QEMU LoongArch CSRs
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#ifndef LOONGARCH_CPU_CSR_H
+#define LOONGARCH_CPU_CSR_H
+
+#include "hw/registerfields.h"
+
+/* Base on kernal definitions: arch/loongarch/include/asm/loongarch.h */
+
+/* Basic CSRs */
+#define LOONGARCH_CSR_CRMD   0x0 /* Current mode info */
+
+#define LOONGARCH_CSR_PRMD   0x1 /* Prev-exception mode info */
+FIELD(CSR_PRMD, PPLV, 0, 2)
+FIELD(CSR_PRMD, PIE, 2, 1)
+FIELD(CSR_PRMD, PWE, 3, 1)
+
+#define LOONGARCH_CSR_EUEN   0x2 /* Extended unit enable */
+FIELD(CSR_EUEN, FPE, 0, 1)
+FIELD(CSR_EUEN, SXE, 1, 1)
+FIELD(CSR_EUEN, ASXE, 2, 1)
+FIELD(CSR_EUEN, BTE, 3, 1)
+
+#define LOONGARCH_CSR_MISC   0x3 /* Misc config */
+FIELD(CSR_MISC, VA32, 0, 4)
+FIELD(CSR_MISC, DRDTL, 4, 4)
+FIELD(CSR_MISC, RPCNTL, 8, 4)
+FIELD(CSR_MISC, ALCL, 12, 4)
+FIELD(CSR_MISC, DWPL, 16, 3)
+
+#define LOONGARCH_CSR_ECFG   0x4 /* Exception config */
+FIELD(CSR_ECFG, LIE, 0, 13)
+FIELD(CSR_ECFG, VS, 16, 3)
+
+#define LOONGARCH_CSR_ESTAT  0x5 /* Exception status */
+FIELD(CSR_ESTAT, IS, 0, 13)
+FIELD(CSR_ESTAT, ECODE, 16, 6)
+FIELD(CSR_ESTAT, ESUBCODE, 22, 9)
+
+#define LOONGARCH_CSR_ERA0x6 /* Exception return address */
+
+#define LOONGARCH_CSR_BADV   0x7 /* Bad virtual address */
+
+#define LOONGARCH_CSR_BADI   0x8 /* Bad instruction */
+
+#define LOONGARCH_CSR_EENTRY 0xc /* Exception entry address */
+
+/* TLB related CSRs */
+#define LOONGARCH_CSR_TLBIDX 0x10 /* TLB Index, EHINV, PageSize, NP */
+FIELD(CSR_TLBIDX, INDEX, 0, 12)
+FIELD(CSR_TLBIDX, PS, 24, 6)
+FIELD(CSR_TLBIDX, NE, 31, 1)
+
+#define LOONGARCH_CSR_TLBEHI 0x11 /* TLB EntryHi */
+FIELD(CSR_TLBEHI, VPPN, 13, 35)
+
+#define LOONGARCH_CSR_TLBELO00x12 /* TLB EntryLo0 */
+#define LOONGARCH_CSR_TLBELO10x13 /* TLB EntryLo1 */
+FIELD(TLBENTRY, V, 0, 1)
+FIELD(TLBENTRY, D, 1, 1)
+FIELD(TLBENTRY, PLV, 2, 2)
+FIELD(TLBENTRY, MAT, 4, 2)
+FIELD(TLBENTRY, G, 6, 1)
+FIELD(TLBENTRY, PPN, 12, 36)
+FIELD(TLBENTRY, NR, 61, 1)
+FIELD(TLBENTRY, NX, 62, 1)
+FIELD(TLBENTRY, RPLV, 63, 1)
+
+#define LOONGARCH_CSR_ASID   0x18 /* Address space identifier */
+FIELD(CSR_ASID, ASID, 0, 10)
+FIELD(CSR_ASID, ASIDBITS, 16, 8)
+
+/* Page table base address when badv[47] = 0 */
+#define LOONGARCH_CSR_PGDL   0x19
+/* Page table base address when badv[47] = 1 */
+#define LOONGARCH_CSR_PGDH   0x1a
+
+#define LOONGARCH_CSR_PGD0x1b /* Page table base address */
+
+/* Page walk controller's low addr */
+#define LOONGARCH_CSR_PWCL   0x1c
+FIELD(CSR_PWCL, PTBASE, 0, 5)
+FIELD(CSR_PWCL, PTWIDTH, 5, 5)
+FIELD(CSR_PWCL, DIR1_BASE, 10, 5)
+FIELD(CSR_PWCL, DIR1_WIDTH, 15, 5)
+FIELD(CSR_PWCL, DIR2_BASE, 20, 5)
+FIELD(CSR_PWCL, DIR2_WIDTH, 25, 5)
+FIELD(CSR_PWCL, PTEWIDTH, 30, 2)
+
+/* Page walk controller's high addr */
+#define LOONGARCH_CSR_PWCH   0x1d
+FIELD(CSR_PWCH, DIR3_BASE, 0, 6)
+FIELD(CSR_PWCH, DIR3_WIDTH, 6, 6)
+FIELD(CSR_PWCH, DIR4_BASE, 12, 6)
+FIELD(CSR_PWCH, DIR4_WIDTH, 18, 6)
+
+#define LOONGARCH_CSR_STLBPS 0x1e /* Stlb page size */
+FIELD(CSR_STLBPS, PS, 0, 5)
+
+#define LOONGARCH_CSR_RVACFG 0x1f /* Reduced virtual address config */
+FIELD(CSR_RVACFG, RBITS, 0, 4)
+
+/* Config CSRs */
+#define LOONGARCH_CSR_CPUID  0x20 /* CPU core id */
+
+#define LOONGARCH_CSR_PRCFG1 0x21 /* Config1 */
+FIELD(CSR_PRCFG1, SAVE_NUM, 0, 4)
+FIELD(CSR_PRCFG1, TIMER_BITS, 4, 8)
+FIELD(CSR_PRCFG1, VSMAX, 12, 3)
+
+#define LOONGARCH_CSR_PRCFG2 0x22 /* Config2 */
+
+#define LOONGARCH_CSR_PRCFG3 0x23 /* Config3 */
+FIELD(CSR_PRCFG3, TLB_TYPE, 0, 4)
+FIELD(CSR_PRCFG3, MTLB_ENTRY, 4, 8)
+FIELD(CSR_PRCFG3, STLB_WAYS, 12, 8)
+FIELD(CSR_PRCFG3, STLB_SETS, 20, 8)
+
+/*
+ * Save registers count can read from PRCFG1.SAVE_NUM
+ * The Min count is 1. Max count is 15.
+ */
+#define LOONGARCH_CSR_SAVE(N)(0x30 + N)
+
+/* Timer CSRs */
+#define LOONGARCH_CSR_TID0x40 /* Timer ID */
+
+#define LOONGARCH_CSR_TCFG   0x41 /* Timer config */
+FIELD(CSR_TCFG, EN, 0, 1)
+FIELD(CSR_TCFG, PERIODIC, 1, 1)
+FIELD(CSR_TCFG, INIT_VAL, 2, 46)
+
+#define LOONGARCH_CSR_TVAL   0x42 /* Timer ticks remain */
+
+#define LOONGARCH_CSR_CNTC   0x43 /* Timer offset */
+
+#define LOONGARCH_CSR_TICLR  0x44 /* Timer interrupt clear */
+
+/* LL

[PATCH v6 30/43] hw/loongarch: Add support loongson3 virt machine type.

2022-06-01 Thread Xiaojuan Yang
Emulate a 3A5000 board use the new loongarch instruction.
3A5000 belongs to the Loongson3 series processors.
The board consists of a 3A5000 cpu model and the virt
bridge. The host 3A5000 board is really complicated and
contains many functions.Now for the tcg softmmu mode
only part functions are emulated.

More detailed info you can see
https://github.com/loongson/LoongArch-Documentation

Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
Reviewed-by: Richard Henderson 
---
 MAINTAINERS   |  4 +
 .../devices/loongarch64-softmmu/default.mak   |  3 +
 configs/targets/loongarch64-softmmu.mak   |  3 +
 hw/Kconfig|  1 +
 hw/loongarch/Kconfig  |  4 +
 hw/loongarch/loongson3.c  | 94 +++
 hw/loongarch/meson.build  |  4 +
 hw/meson.build|  1 +
 include/exec/poison.h |  2 +
 include/hw/loongarch/virt.h   | 31 ++
 include/sysemu/arch_init.h|  1 +
 qapi/machine.json |  2 +-
 target/Kconfig|  1 +
 target/loongarch/Kconfig  |  2 +
 target/loongarch/cpu.c|  2 +
 15 files changed, 154 insertions(+), 1 deletion(-)
 create mode 100644 configs/devices/loongarch64-softmmu/default.mak
 create mode 100644 configs/targets/loongarch64-softmmu.mak
 create mode 100644 hw/loongarch/Kconfig
 create mode 100644 hw/loongarch/loongson3.c
 create mode 100644 hw/loongarch/meson.build
 create mode 100644 include/hw/loongarch/virt.h
 create mode 100644 target/loongarch/Kconfig

diff --git a/MAINTAINERS b/MAINTAINERS
index 896cfa54c6..898905ee1f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1130,6 +1130,10 @@ M: Xiaojuan Yang 
 M: Song Gao 
 S: Maintained
 F: docs/system/loongarch/loongson3.rst
+F: configs/targets/loongarch64-softmmu.mak
+F: configs/devices/loongarch64-softmmu/default.mak
+F: hw/loongarch/
+F: include/hw/loongarch/virt.h
 
 M68K Machines
 -
diff --git a/configs/devices/loongarch64-softmmu/default.mak 
b/configs/devices/loongarch64-softmmu/default.mak
new file mode 100644
index 00..928bc117ef
--- /dev/null
+++ b/configs/devices/loongarch64-softmmu/default.mak
@@ -0,0 +1,3 @@
+# Default configuration for loongarch64-softmmu
+
+CONFIG_LOONGARCH_VIRT=y
diff --git a/configs/targets/loongarch64-softmmu.mak 
b/configs/targets/loongarch64-softmmu.mak
new file mode 100644
index 00..666154022f
--- /dev/null
+++ b/configs/targets/loongarch64-softmmu.mak
@@ -0,0 +1,3 @@
+TARGET_ARCH=loongarch64
+TARGET_BASE_ARCH=loongarch
+TARGET_SUPPORTS_MTTCG=y
diff --git a/hw/Kconfig b/hw/Kconfig
index 50e0952889..38233bbb0f 100644
--- a/hw/Kconfig
+++ b/hw/Kconfig
@@ -50,6 +50,7 @@ source avr/Kconfig
 source cris/Kconfig
 source hppa/Kconfig
 source i386/Kconfig
+source loongarch/Kconfig
 source m68k/Kconfig
 source microblaze/Kconfig
 source mips/Kconfig
diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig
new file mode 100644
index 00..13e8501897
--- /dev/null
+++ b/hw/loongarch/Kconfig
@@ -0,0 +1,4 @@
+config LOONGARCH_VIRT
+bool
+select PCI
+select PCI_EXPRESS_GENERIC_BRIDGE
diff --git a/hw/loongarch/loongson3.c b/hw/loongarch/loongson3.c
new file mode 100644
index 00..7df32f777e
--- /dev/null
+++ b/hw/loongarch/loongson3.c
@@ -0,0 +1,94 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * QEMU loongson 3a5000 develop board emulation
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+#include "qemu/osdep.h"
+#include "qemu/units.h"
+#include "qemu/datadir.h"
+#include "qapi/error.h"
+#include "hw/boards.h"
+#include "sysemu/sysemu.h"
+#include "sysemu/qtest.h"
+#include "sysemu/runstate.h"
+#include "sysemu/reset.h"
+#include "sysemu/rtc.h"
+#include "hw/loongarch/virt.h"
+#include "exec/address-spaces.h"
+#include "target/loongarch/cpu.h"
+
+static void loongarch_init(MachineState *machine)
+{
+const char *cpu_model = machine->cpu_type;
+ram_addr_t offset = 0;
+ram_addr_t ram_size = machine->ram_size;
+uint64_t highram_size = 0;
+MemoryRegion *address_space_mem = get_system_memory();
+LoongArchMachineState *lams = LOONGARCH_MACHINE(machine);
+int i;
+
+if (!cpu_model) {
+cpu_model = LOONGARCH_CPU_TYPE_NAME("la464");
+}
+
+if (!strstr(cpu_model, "la464")) {
+error_report("LoongArch/TCG needs cpu type la464");
+exit(1);
+}
+
+if (ram_size < 1 * GiB) {
+error_report("ram_size must be greater than 1G.");
+exit(1);
+}
+
+/* Init CPUs */
+for (i = 0; i < machine->smp.cpus; i++) {
+cpu_create(machine->cpu_type);
+}
+
+/* Add memory region */
+memory_region_init_alias(&lams->lowmem, NULL, "loongarch.lowram",
+ machine->ram, 0, 256 * MiB);
+memory_region_add_subregion

Re: [PATCH v2 1/1] Fix the coredump when memory backend id conflicts with default_ram_id

2022-06-01 Thread lizhang



ping

On 2022-05-20 11:56, Li Zhang wrote:

When no memory backend is specified in machine options,
a default memory device will be added with default_ram_id.
However, if a memory backend object is added in QEMU options
and id is the same as default_ram_id, a coredump happens.

Command line:
qemu-system-x86_64 -name guest=vmtest,debug-threads=on \
-machine pc-q35-6.0,accel=kvm,usb=off,vmport=off \
-smp 16,sockets=16,cores=1,threads=1 \
-m 4G \
-object memory-backend-ram,id=pc.ram,size=4G \
-no-user-config -nodefaults -nographic

Stack trace of thread 16903:
#0  0x7fb109a9318b raise (libc.so.6 + 0x3a18b)
#1  0x7fb109a94585 abort (libc.so.6 + 0x3b585)
#2  0x558c34bc89be error_handle_fatal (qemu-system-x86_64 + 
0x9c89be)

#3  0x558c34bc8aee error_setv (qemu-system-x86_64 + 0x9c8aee)
#4  0x558c34bc8ccf error_setg_internal (qemu-system-x86_64 + 
0x9c8ccf)

#5  0x558c349f6899 object_property_try_add (qemu-system-x86_64
+ 0x7f6899)
#6  0x558c349f7df8 object_property_try_add_child
(qemu-system-x86_64 + 0x7f7df8)
#7  0x558c349f7e91 object_property_add_child
(qemu-system-x86_64 + 0x7f7e91)
#8  0x558c3454686d create_default_memdev (qemu-system-x86_64 + 
0x34686d)
#9  0x558c34546f58 qemu_init_board (qemu-system-x86_64 + 
0x346f58)
#10 0x558c345471b9 qmp_x_exit_preconfig (qemu-system-x86_64 + 
0x3471b9)

#11 0x558c345497d9 qemu_init (qemu-system-x86_64 + 0x3497d9)
#12 0x558c344e54c2 main (qemu-system-x86_64 + 0x2e54c2)
#13 0x7fb109a7e34d __libc_start_main (libc.so.6 + 0x2534d)
#14 0x558c344e53ba _start (qemu-system-x86_64 + 0x2e53ba)

Signed-off-by: Li Zhang 
---
 hw/core/machine.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/hw/core/machine.c b/hw/core/machine.c
index b03d9192ba..3867af7a8a 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -1290,9 +1290,17 @@ MemoryRegion
*machine_consume_memdev(MachineState *machine,
 static bool create_default_memdev(MachineState *ms, const char *path,
Error **errp)
 {
 Object *obj;
+ObjectProperty *prop;
 MachineClass *mc = MACHINE_GET_CLASS(ms);
 bool r = false;

+prop = object_property_find(object_get_objects_root(), 
mc->default_ram_id);

+if (prop) {
+error_report("Memory backend id conflicts with default_ram_id 
%s",

+ mc->default_ram_id);
+exit(EXIT_FAILURE);
+}
+
 obj = object_new(path ? TYPE_MEMORY_BACKEND_FILE :
TYPE_MEMORY_BACKEND_RAM);
 if (path) {
 if (!object_property_set_str(obj, "mem-path", path, errp)) {




[PATCH v6 22/43] target/loongarch: Add MMU support for LoongArch CPU.

2022-06-01 Thread Xiaojuan Yang
Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
Reviewed-by: Richard Henderson 
---
 target/loongarch/cpu-param.h  |   2 +-
 target/loongarch/cpu.c|  24 +++
 target/loongarch/cpu.h|  51 ++
 target/loongarch/internals.h  |   9 +
 target/loongarch/machine.c|  17 ++
 target/loongarch/meson.build  |   1 +
 target/loongarch/tlb_helper.c | 315 ++
 7 files changed, 418 insertions(+), 1 deletion(-)
 create mode 100644 target/loongarch/tlb_helper.c

diff --git a/target/loongarch/cpu-param.h b/target/loongarch/cpu-param.h
index 9a769b67e0..414d8fff46 100644
--- a/target/loongarch/cpu-param.h
+++ b/target/loongarch/cpu-param.h
@@ -13,6 +13,6 @@
 #define TARGET_VIRT_ADDR_SPACE_BITS 48
 
 #define TARGET_PAGE_BITS 14
-#define NB_MMU_MODES 4
+#define NB_MMU_MODES 5
 
 #endif
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index bb31502ff9..8c8b10d601 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -298,6 +298,21 @@ void loongarch_cpu_dump_state(CPUState *cs, FILE *f, int 
flags)
 }
 }
 
+qemu_fprintf(f, "CRMD=%016" PRIx64 "\n", env->CSR_CRMD);
+qemu_fprintf(f, "PRMD=%016" PRIx64 "\n", env->CSR_PRMD);
+qemu_fprintf(f, "EUEN=%016" PRIx64 "\n", env->CSR_EUEN);
+qemu_fprintf(f, "ESTAT=%016" PRIx64 "\n", env->CSR_ESTAT);
+qemu_fprintf(f, "ERA=%016" PRIx64 "\n", env->CSR_ERA);
+qemu_fprintf(f, "BADV=%016" PRIx64 "\n", env->CSR_BADV);
+qemu_fprintf(f, "BADI=%016" PRIx64 "\n", env->CSR_BADI);
+qemu_fprintf(f, "EENTRY=%016" PRIx64 "\n", env->CSR_EENTRY);
+qemu_fprintf(f, "PRCFG1=%016" PRIx64 ", PRCFG2=%016" PRIx64 ","
+ " PRCFG3=%016" PRIx64 "\n",
+ env->CSR_PRCFG1, env->CSR_PRCFG3, env->CSR_PRCFG3);
+qemu_fprintf(f, "TLBRENTRY=%016" PRIx64 "\n", env->CSR_TLBRENTRY);
+qemu_fprintf(f, "TLBRBADV=%016" PRIx64 "\n", env->CSR_TLBRBADV);
+qemu_fprintf(f, "TLBRERA=%016" PRIx64 "\n", env->CSR_TLBRERA);
+
 /* fpr */
 if (flags & CPU_DUMP_FPU) {
 for (i = 0; i < 32; i++) {
@@ -315,9 +330,17 @@ void loongarch_cpu_dump_state(CPUState *cs, FILE *f, int 
flags)
 static struct TCGCPUOps loongarch_tcg_ops = {
 .initialize = loongarch_translate_init,
 .synchronize_from_tb = loongarch_cpu_synchronize_from_tb,
+
+.tlb_fill = loongarch_cpu_tlb_fill,
 };
 #endif /* CONFIG_TCG */
 
+#include "hw/core/sysemu-cpu-ops.h"
+
+static const struct SysemuCPUOps loongarch_sysemu_ops = {
+.get_phys_page_debug = loongarch_cpu_get_phys_page_debug,
+};
+
 static void loongarch_cpu_class_init(ObjectClass *c, void *data)
 {
 LoongArchCPUClass *lacc = LOONGARCH_CPU_CLASS(c);
@@ -332,6 +355,7 @@ static void loongarch_cpu_class_init(ObjectClass *c, void 
*data)
 cc->dump_state = loongarch_cpu_dump_state;
 cc->set_pc = loongarch_cpu_set_pc;
 dc->vmsd = &vmstate_loongarch_cpu;
+cc->sysemu_ops = &loongarch_sysemu_ops;
 cc->disas_set_info = loongarch_cpu_disas_set_info;
 #ifdef CONFIG_TCG
 cc->tcg_ops = &loongarch_tcg_ops;
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index 3ec978f47c..e0415d8929 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -184,6 +184,26 @@ FIELD(CSR_CRMD, WE, 9, 1)
 extern const char * const regnames[32];
 extern const char * const fregnames[32];
 
+#define LOONGARCH_STLB 2048 /* 2048 STLB */
+#define LOONGARCH_MTLB 64   /* 64 MTLB */
+#define LOONGARCH_TLB_MAX  (LOONGARCH_STLB + LOONGARCH_MTLB)
+
+/*
+ * define the ASID PS E VPPN field of TLB
+ */
+FIELD(TLB_MISC, E, 0, 1)
+FIELD(TLB_MISC, ASID, 1, 10)
+FIELD(TLB_MISC, VPPN, 13, 35)
+FIELD(TLB_MISC, PS, 48, 6)
+
+struct LoongArchTLB {
+uint64_t tlb_misc;
+/* Fields corresponding to CSR_TLBELO0/1 */
+uint64_t tlb_entry0;
+uint64_t tlb_entry1;
+};
+typedef struct LoongArchTLB LoongArchTLB;
+
 typedef struct CPUArchState {
 uint64_t gpr[32];
 uint64_t pc;
@@ -256,6 +276,8 @@ typedef struct CPUArchState {
 uint64_t CSR_DBG;
 uint64_t CSR_DERA;
 uint64_t CSR_DSAVE;
+
+LoongArchTLB  tlb[LOONGARCH_TLB_MAX];
 } CPULoongArchState;
 
 /**
@@ -294,6 +316,35 @@ struct LoongArchCPUClass {
 DeviceReset parent_reset;
 };
 
+/*
+ * LoongArch CPUs has 4 privilege levels.
+ * 0 for kernel mode, 3 for user mode.
+ * Define an extra index for DA(direct addressing) mode.
+ */
+#define MMU_KERNEL_IDX   0
+#define MMU_USER_IDX 3
+#define MMU_DA_IDX   4
+
+static inline int cpu_mmu_index(CPULoongArchState *env, bool ifetch)
+{
+uint8_t pg = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PG);
+
+if (!pg) {
+return MMU_DA_IDX;
+}
+return FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV);
+}
+
+static inline void cpu_get_tb_cpu_state(CPULoongArchState *env,
+target_ulong *pc,
+target_ulong *cs_base,
+uint32_t *flags)
+{
+*pc = env->pc;
+*cs_base = 0

[PATCH v6 24/43] target/loongarch: Add constant timer support

2022-06-01 Thread Xiaojuan Yang
Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
Reviewed-by: Richard Henderson 
---
 target/loongarch/constant_timer.c | 64 +++
 target/loongarch/cpu.c|  2 +
 target/loongarch/cpu.h|  4 ++
 target/loongarch/internals.h  |  6 +++
 target/loongarch/meson.build  |  1 +
 5 files changed, 77 insertions(+)
 create mode 100644 target/loongarch/constant_timer.c

diff --git a/target/loongarch/constant_timer.c 
b/target/loongarch/constant_timer.c
new file mode 100644
index 00..1851f53fd6
--- /dev/null
+++ b/target/loongarch/constant_timer.c
@@ -0,0 +1,64 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * QEMU LoongArch constant timer support
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/timer.h"
+#include "cpu.h"
+#include "internals.h"
+#include "cpu-csr.h"
+
+#define TIMER_PERIOD10 /* 10 ns period for 100 MHz frequency */
+#define CONSTANT_TIMER_TICK_MASK0xfffcUL
+#define CONSTANT_TIMER_ENABLE   0x1UL
+
+uint64_t cpu_loongarch_get_constant_timer_counter(LoongArchCPU *cpu)
+{
+return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / TIMER_PERIOD;
+}
+
+uint64_t cpu_loongarch_get_constant_timer_ticks(LoongArchCPU *cpu)
+{
+uint64_t now, expire;
+
+now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+expire = timer_expire_time_ns(&cpu->timer);
+
+return (expire - now) / TIMER_PERIOD;
+}
+
+void cpu_loongarch_store_constant_timer_config(LoongArchCPU *cpu,
+   uint64_t value)
+{
+CPULoongArchState *env = &cpu->env;
+uint64_t now, next;
+
+env->CSR_TCFG = value;
+if (value & CONSTANT_TIMER_ENABLE) {
+now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+next = now + (value & CONSTANT_TIMER_TICK_MASK) * TIMER_PERIOD;
+timer_mod(&cpu->timer, next);
+} else {
+timer_del(&cpu->timer);
+}
+}
+
+void loongarch_constant_timer_cb(void *opaque)
+{
+LoongArchCPU *cpu  = opaque;
+CPULoongArchState *env = &cpu->env;
+uint64_t now, next;
+
+if (FIELD_EX64(env->CSR_TCFG, CSR_TCFG, PERIODIC)) {
+now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+next = now + (env->CSR_TCFG & CONSTANT_TIMER_TICK_MASK) * TIMER_PERIOD;
+timer_mod(&cpu->timer, next);
+} else {
+env->CSR_TCFG = FIELD_DP64(env->CSR_TCFG, CSR_TCFG, EN, 0);
+}
+
+loongarch_cpu_set_irq(opaque, IRQ_TIMER, 1);
+}
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 8d8dfdd961..18ac11db77 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -490,6 +490,8 @@ static void loongarch_cpu_init(Object *obj)
 
 cpu_set_cpustate_pointers(cpu);
 qdev_init_gpio_in(DEVICE(cpu), loongarch_cpu_set_irq, N_IRQS);
+timer_init_ns(&cpu->timer, QEMU_CLOCK_VIRTUAL,
+  &loongarch_constant_timer_cb, cpu);
 }
 
 static ObjectClass *loongarch_cpu_class_by_name(const char *cpu_model)
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index b983ce241c..2081902f2e 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -11,6 +11,7 @@
 #include "exec/cpu-defs.h"
 #include "fpu/softfloat-types.h"
 #include "hw/registerfields.h"
+#include "qemu/timer.h"
 
 #define TCG_GUEST_DEFAULT_MO (0)
 
@@ -185,6 +186,8 @@ extern const char * const regnames[32];
 extern const char * const fregnames[32];
 
 #define N_IRQS  13
+#define IRQ_TIMER   11
+#define IRQ_IPI 12
 
 #define LOONGARCH_STLB 2048 /* 2048 STLB */
 #define LOONGARCH_MTLB 64   /* 64 MTLB */
@@ -295,6 +298,7 @@ struct ArchCPU {
 
 CPUNegativeOffsetState neg;
 CPULoongArchState env;
+QEMUTimer timer;
 };
 
 #define TYPE_LOONGARCH_CPU "loongarch-cpu"
diff --git a/target/loongarch/internals.h b/target/loongarch/internals.h
index 69183e8bb5..4b1bcd7c0f 100644
--- a/target/loongarch/internals.h
+++ b/target/loongarch/internals.h
@@ -32,6 +32,12 @@ extern const VMStateDescription vmstate_loongarch_cpu;
 
 void loongarch_cpu_set_irq(void *opaque, int irq, int level);
 
+void loongarch_constant_timer_cb(void *opaque);
+uint64_t cpu_loongarch_get_constant_timer_counter(LoongArchCPU *cpu);
+uint64_t cpu_loongarch_get_constant_timer_ticks(LoongArchCPU *cpu);
+void cpu_loongarch_store_constant_timer_config(LoongArchCPU *cpu,
+   uint64_t value);
+
 bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
 MMUAccessType access_type, int mmu_idx,
 bool probe, uintptr_t retaddr);
diff --git a/target/loongarch/meson.build b/target/loongarch/meson.build
index 435cc75999..04e15ba1e3 100644
--- a/target/loongarch/meson.build
+++ b/target/loongarch/meson.build
@@ -18,6 +18,7 @@ loongarch_softmmu_ss = ss.source_set()
 loongarch_softmmu_ss.add(files(
   'machine.c',
   'tlb_helper.c',
+  'constant_timer.c',
 ))
 
 loongarch_ss.add

[PATCH v6 14/43] target/loongarch: Add floating point load/store instruction translation

2022-06-01 Thread Xiaojuan Yang
From: Song Gao 

This includes:
- FLD.{S/D}, FST.{S/D}
- FLDX.{S/D}, FSTX.{S/D}
- FLD{GT/LE}.{S/D}, FST{GT/LE}.{S/D}

Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
Reviewed-by: Richard Henderson 
---
 .../loongarch/insn_trans/trans_fmemory.c.inc  | 153 ++
 target/loongarch/insns.decode |  24 +++
 target/loongarch/translate.c  |   1 +
 3 files changed, 178 insertions(+)
 create mode 100644 target/loongarch/insn_trans/trans_fmemory.c.inc

diff --git a/target/loongarch/insn_trans/trans_fmemory.c.inc 
b/target/loongarch/insn_trans/trans_fmemory.c.inc
new file mode 100644
index 00..74ee98f63a
--- /dev/null
+++ b/target/loongarch/insn_trans/trans_fmemory.c.inc
@@ -0,0 +1,153 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+static void maybe_nanbox_load(TCGv freg, MemOp mop)
+{
+if ((mop & MO_SIZE) == MO_32) {
+gen_nanbox_s(freg, freg);
+}
+}
+
+static bool gen_fload_i(DisasContext *ctx, arg_fr_i *a, MemOp mop)
+{
+TCGv addr = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv temp = NULL;
+
+if (a->imm) {
+temp = tcg_temp_new();
+tcg_gen_addi_tl(temp, addr, a->imm);
+addr = temp;
+}
+
+tcg_gen_qemu_ld_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop);
+maybe_nanbox_load(cpu_fpr[a->fd], mop);
+
+if (temp) {
+tcg_temp_free(temp);
+}
+
+return true;
+}
+
+static bool gen_fstore_i(DisasContext *ctx, arg_fr_i *a, MemOp mop)
+{
+TCGv addr = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv temp = NULL;
+
+if (a->imm) {
+temp = tcg_temp_new();
+tcg_gen_addi_tl(temp, addr, a->imm);
+addr = temp;
+}
+
+tcg_gen_qemu_st_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop);
+
+if (temp) {
+tcg_temp_free(temp);
+}
+return true;
+}
+
+static bool gen_floadx(DisasContext *ctx, arg_frr *a, MemOp mop)
+{
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
+TCGv addr = tcg_temp_new();
+
+tcg_gen_add_tl(addr, src1, src2);
+tcg_gen_qemu_ld_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop);
+maybe_nanbox_load(cpu_fpr[a->fd], mop);
+tcg_temp_free(addr);
+
+return true;
+}
+
+static bool gen_fstorex(DisasContext *ctx, arg_frr *a, MemOp mop)
+{
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
+TCGv addr = tcg_temp_new();
+
+tcg_gen_add_tl(addr, src1, src2);
+tcg_gen_qemu_st_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop);
+tcg_temp_free(addr);
+
+return true;
+}
+
+static bool gen_fload_gt(DisasContext *ctx, arg_frr *a, MemOp mop)
+{
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
+TCGv addr = tcg_temp_new();
+
+gen_helper_asrtgt_d(cpu_env, src1, src2);
+tcg_gen_add_tl(addr, src1, src2);
+tcg_gen_qemu_ld_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop);
+maybe_nanbox_load(cpu_fpr[a->fd], mop);
+tcg_temp_free(addr);
+
+return true;
+}
+
+static bool gen_fstore_gt(DisasContext *ctx, arg_frr *a, MemOp mop)
+{
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
+TCGv addr = tcg_temp_new();
+
+gen_helper_asrtgt_d(cpu_env, src1, src2);
+tcg_gen_add_tl(addr, src1, src2);
+tcg_gen_qemu_st_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop);
+tcg_temp_free(addr);
+
+return true;
+}
+
+static bool gen_fload_le(DisasContext *ctx, arg_frr *a, MemOp mop)
+{
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
+TCGv addr = tcg_temp_new();
+
+gen_helper_asrtle_d(cpu_env, src1, src2);
+tcg_gen_add_tl(addr, src1, src2);
+tcg_gen_qemu_ld_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop);
+maybe_nanbox_load(cpu_fpr[a->fd], mop);
+tcg_temp_free(addr);
+
+return true;
+}
+
+static bool gen_fstore_le(DisasContext *ctx, arg_frr *a, MemOp mop)
+{
+TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE);
+TCGv addr = tcg_temp_new();
+
+gen_helper_asrtle_d(cpu_env, src1, src2);
+tcg_gen_add_tl(addr, src1, src2);
+tcg_gen_qemu_st_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop);
+tcg_temp_free(addr);
+
+return true;
+}
+
+TRANS(fld_s, gen_fload_i, MO_TEUL)
+TRANS(fst_s, gen_fstore_i, MO_TEUL)
+TRANS(fld_d, gen_fload_i, MO_TEUQ)
+TRANS(fst_d, gen_fstore_i, MO_TEUQ)
+TRANS(fldx_s, gen_floadx, MO_TEUL)
+TRANS(fldx_d, gen_floadx, MO_TEUQ)
+TRANS(fstx_s, gen_fstorex, MO_TEUL)
+TRANS(fstx_d, gen_fstorex, MO_TEUQ)
+TRANS(fldgt_s, gen_fload_gt, MO_TEUL)
+TRANS(fldgt_d, gen_fload_gt, MO_TEUQ)
+TRANS(fldle_s, gen_fload_le, MO_TEUL)
+TRANS(fldle_d, gen_fload_le, MO_TEUQ)
+TRANS(fstgt_s, gen_fstore_gt, MO_TEUL)
+TRANS(fstgt_d, gen_fstore_gt, MO_TEUQ)
+TRANS(fstle_s, gen_fstore_le, MO_TEUL)
+TRANS(fstle_d, gen_fstore_le, MO_TEUQ)
diff --git a/target/loongarch/

Re: Outreachy project task: Adding QEMU block layer APIs resembling Linux ZBD ioctls.

2022-06-01 Thread Stefan Hajnoczi
On Wed, 1 Jun 2022 at 11:19, Sam Li  wrote:
> Damien Le Moal  于2022年6月1日周三 13:47写道:
> > On 6/1/22 11:57, Sam Li wrote:
> > > Stefan Hajnoczi  于2022年5月30日周一 19:19写道:
> > >> On Mon, 30 May 2022 at 06:09, Sam Li  wrote:
> > For the zone struct: You may need to add a read-write lock per zone to be
> > able to write lock zones to ensure a sequential write pattern (virtio
> > devices can be multi-queue and so writes may be coming in from different
> > contexts) and to correctly emulate zone append operations with an atomic
> > update of the wp field.
> >
>
> Yes, I haven't thought through the thread-safety problem but I'll come
> up with an approach.

Operations in the I/O code path (as opposed to the control/management
code path) will probably be declared as coroutine_fn, which means that
they execute in a coroutine and can yield back to the event loop when
waiting for something to happen.

Coroutines can use CoMutex locks to serialize execution. This way only
one write request will be in flight at a time and the write pointer
can be updated atomically.

Here is a sketch of what the block/file-posix.c driver's write append
function would look like:

static int coroutine_fn raw_write_append_zone(BlockDriverState *bs,
uint64_t offset, uint64_t bytes, QEMUIOVector *qiov)
{
BDRVRawState *s = bs->opaque;
RawPosixAIOData acb = ...; /* fill in aio request state */

/* Serialize append requests */
QEMU_LOCK_GUARD(&s->append_locks[offset_to_lock_idx(offset)]);
return raw_thread_pool_submit(bs, handle_aiocb_append_zone, &acb);
}

The actual system call runs in a thread pool worker function
handle_aiocb_append_zone() that performs the write on the underlying
fd and updates the write pointer if the syscall succeeds.

Stefan



Re: Outreachy project task: Adding QEMU block layer APIs resembling Linux ZBD ioctls.

2022-06-01 Thread Stefan Hajnoczi
On Wed, 1 Jun 2022 at 06:47, Damien Le Moal
 wrote:
>
> On 6/1/22 11:57, Sam Li wrote:
> > Hi Stefan,
> >
> > Stefan Hajnoczi  于2022年5月30日周一 19:19写道:
> >
> >
> >>
> >> On Mon, 30 May 2022 at 06:09, Sam Li  wrote:
> >>>
> >>> Hi everyone,
> >>> I'm Sam Li, working on the Outreachy project which is to add zoned
> >>> device support to QEMU's virtio-blk emulation.
> >>>
> >>> For the first goal, adding QEMU block layer APIs resembling Linux ZBD
> >>> ioctls, I think the naive approach would be to introduce a new stable
> >>> struct zbd_zone descriptor for the library function interface. More
> >>> specifically, what I'd like to add to the BlockDriver struct are:
> >>> 1. zbd_info as zone block device information: includes numbers of
> >>> zones, size of logical blocks, and physical blocks.
> >>> 2. zbd_zone_type and zbd_zone_state
> >>> 3. zbd_dev_model: host-managed zbd, host-aware zbd
> >>> With those basic structs, we can start to implement new functions as
> >>> bdrv*() APIs for BLOCK*ZONE ioctls.
> >>>
> >>> I'll start to finish this task based on the above description. If
> >>> there is any problem or something I may miss in the design, please let
> >>> me know.
> >>
> >> Hi Sam,
> >> Can you propose function prototypes for the new BlockDriver callbacks
> >> needed for zoned devices?
> >
> > I have made some modifications based on Damien's device in design part
> > 1 and added the function prototypes in design part 2. If there is any
> > problem or part I missed, please let me know.
> >
> > Design of Block Layer APIs in BlockDriver:
> > 1. introduce a new stable struct zbd_zone descriptor for the library
> > function interface.
> >   a. zbd_info as zone block device information: includes numbers of
> > zones, size of blocks, write granularity in byte(minimal write size
> > and alignment
> > - write granularity: 512e SMRs: writes in units of physical block
> > size, 4096 bytes; NVMe ZNS write granularity is equal to the block
> > size.
> > - zone descriptor: start, length, capacity, write pointer, zone type
> >   b. zbd_zone_type
> > - zone type: conventional, sequential write required, sequential
> > write preferred
> >   c. zbd_dev_model: host-managed zbd, host-aware zbd
>
> This explanation is a little hard to understand. It seems to be mixing up
> device level information and per-zone information. I think it would be a
> lot simpler to write a struct definition to directly illustrate what you
> are planning.
>
> It is something like this ?
>
> struct zbd_zone {
> enum zone_type  type;
> enum zone_cond  cond;
> uint64_tstart;
> uint32_tlength;
> uint32_tcap;
> uint64_twp;
> };
>
> strcut zbd_dev {
> enum zone_model model;
> uint32_tblock_size;
> uint32_twrite_granularity;
> uint32_tnr_zones
> struct zbd_zone *zones; /* array of zones */
> };
>
> If yes, then my comments are as follows.
>
> For the device struct: It may be good to have also the maximum number of
> open zones and the maximum number of active zones.
>
> For the zone struct: You may need to add a read-write lock per zone to be
> able to write lock zones to ensure a sequential write pattern (virtio
> devices can be multi-queue and so writes may be coming in from different
> contexts) and to correctly emulate zone append operations with an atomic
> update of the wp field.
>
> These need to be integrated into the generic block driver interface in
> include/block/block_int-common.h or include/block/block-common.h.

QEMU's block layer has a few ways of exposing information about block devices:

int (*bdrv_get_info)(BlockDriverState *bs, BlockDriverInfo *bdi);
ImageInfoSpecific *(*bdrv_get_specific_info)(BlockDriverState *bs,
Error **errp);

These fetch information from the BlockDriver and are good when a small
amount of data is reported occassionally and consumed by the caller.

For data that is continuously accessed or that could be large, it may
be necessary for the data to reside inside BlockDriverState so that it
can be accessed in place (without copying):

void (*bdrv_refresh_limits)(BlockDriverState *bs, Error **errp);

QEMU uses this for the BlockLimits struct (BlockDriverState::bl) that
is continuously accessed by the block layer while processing I/O
requests. The "refresh" function updates the data in case the
underlying storage device has changed somehow. If no update function
is necessary then data can simply be populated during .bdrv_open() and
no new BlockDriver callback needs to be added.

So in the simplest case BlockDriverState can be extended with a struct
zbd_dev field that is populated during .bdrv_open(). If the
BlockDriver doesn't support zones then the zbd_dev.nr_zones field is 0
or the model field indicates that this is not a zoned storage device.

However, a BlockBackend (not BlockDriverState!) API will be needed to
expose this data to users like the hw/b

[PATCH v6 41/43] target/loongarch: Add gdb support.

2022-06-01 Thread Xiaojuan Yang
Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
Reviewed-by: Richard Henderson 
---
 MAINTAINERS |  1 +
 configs/targets/loongarch64-softmmu.mak |  1 +
 gdb-xml/loongarch-base64.xml| 44 ++
 gdb-xml/loongarch-fpu64.xml | 57 +
 target/loongarch/cpu.c  |  9 +++
 target/loongarch/gdbstub.c  | 81 +
 target/loongarch/internals.h|  4 ++
 target/loongarch/meson.build|  1 +
 8 files changed, 198 insertions(+)
 create mode 100644 gdb-xml/loongarch-base64.xml
 create mode 100644 gdb-xml/loongarch-fpu64.xml
 create mode 100644 target/loongarch/gdbstub.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 9f4ee7978d..492dbf64e0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1138,6 +1138,7 @@ F: include/hw/intc/loongarch_*.h
 F: hw/intc/loongarch_*.c
 F: include/hw/pci-host/ls7a.h
 F: hw/rtc/ls7a_rtc.c
+F: gdb-xml/loongarch*.xml
 
 M68K Machines
 -
diff --git a/configs/targets/loongarch64-softmmu.mak 
b/configs/targets/loongarch64-softmmu.mak
index 666154022f..7bc06c850c 100644
--- a/configs/targets/loongarch64-softmmu.mak
+++ b/configs/targets/loongarch64-softmmu.mak
@@ -1,3 +1,4 @@
 TARGET_ARCH=loongarch64
 TARGET_BASE_ARCH=loongarch
 TARGET_SUPPORTS_MTTCG=y
+TARGET_XML_FILES= gdb-xml/loongarch-base64.xml gdb-xml/loongarch-fpu64.xml
diff --git a/gdb-xml/loongarch-base64.xml b/gdb-xml/loongarch-base64.xml
new file mode 100644
index 00..4962bdbd28
--- /dev/null
+++ b/gdb-xml/loongarch-base64.xml
@@ -0,0 +1,44 @@
+
+
+
+
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
diff --git a/gdb-xml/loongarch-fpu64.xml b/gdb-xml/loongarch-fpu64.xml
new file mode 100644
index 00..e52cf89fbc
--- /dev/null
+++ b/gdb-xml/loongarch-fpu64.xml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+  
+
+
+  
+
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+  
+
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index fcd3ba4f35..2749297f74 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -482,6 +482,8 @@ static void loongarch_cpu_realizefn(DeviceState *dev, Error 
**errp)
 return;
 }
 
+loongarch_cpu_register_gdb_regs_for_features(cs);
+
 cpu_reset(cs);
 qemu_init_vcpu(cs);
 
@@ -635,6 +637,13 @@ static void loongarch_cpu_class_init(ObjectClass *c, void 
*data)
 dc->vmsd = &vmstate_loongarch_cpu;
 cc->sysemu_ops = &loongarch_sysemu_ops;
 cc->disas_set_info = loongarch_cpu_disas_set_info;
+cc->gdb_read_register = loongarch_cpu_gdb_read_register;
+cc->gdb_write_register = loongarch_cpu_gdb_write_register;
+cc->disas_set_info = loongarch_cpu_disas_set_info;
+cc->gdb_num_core_regs = 34;
+cc->gdb_core_xml_file = "loongarch-base64.xml";
+cc->gdb_stop_before_watchpoint = true;
+
 #ifdef CONFIG_TCG
 cc->tcg_ops = &loongarch_tcg_ops;
 #endif
diff --git a/target/loongarch/gdbstub.c b/target/loongarch/gdbstub.c
new file mode 100644
index 00..0c48834201
--- /dev/null
+++ b/target/loongarch/gdbstub.c
@@ -0,0 +1,81 @@
+/*
+ * LOONGARCH gdb server stub
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ *
+ * SPDX-License-Identifier: LGPL-2.1+
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "internals.h"
+#include "exec/gdbstub.h"
+
+int loongarch_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
+{
+LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+CPULoongArchState *env = &cpu->env;
+
+if (0 <= n && n < 32) {
+return gdb_get_regl(mem_buf, env->gpr[n]);
+} else if (n == 32) {
+return gdb_get_regl(mem_buf, env->pc);
+} else if (n == 33) {
+return gdb_get_regl(mem_buf, env->badaddr);
+}
+return 0;
+}
+
+int loongarch_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+CPULoongArchState *env = &cpu->env;
+target_ulong tmp = ldtul_p(mem_buf);
+int length = 0;
+
+if (0 <= n && n < 32) {
+env->gpr[n] = tmp;
+length = sizeof(target_ulong);
+} else if (n == 32) {
+env->pc = tmp;
+length = sizeof(target_ulong);
+}
+return length;
+}
+
+static int loongarch_gdb_get_fpu(CPULoongArchState *env,
+ GByteArray *mem_buf, int n)
+{
+if (0 <= n && n < 32) {
+return gdb_get_reg64(mem_buf, env->fpr[n]);
+} else if (32 <= n && n < 40) {
+return gdb_get_reg8(mem_buf, env->cf[n - 32]);
+} else if (n == 40) {
+return gdb_get_reg32(mem_buf, env->fcsr0);
+}
+return 0;
+}
+
+static int loongarch_gdb_set_fpu(CPULoongArchState *env,
+ uint8_t *mem_buf, int n)
+{
+int length = 0;
+
+if (0 <= n && n < 32

Re: [PATCH v2 1/1] Fix the coredump when memory backend id conflicts with default_ram_id

2022-06-01 Thread Philippe Mathieu-Daudé via
Cc'ing Igor

On Fri, May 20, 2022 at 11:56 AM Li Zhang  wrote:
>
> When no memory backend is specified in machine options,
> a default memory device will be added with default_ram_id.
> However, if a memory backend object is added in QEMU options
> and id is the same as default_ram_id, a coredump happens.
>
> Command line:
> qemu-system-x86_64 -name guest=vmtest,debug-threads=on \
> -machine pc-q35-6.0,accel=kvm,usb=off,vmport=off \
> -smp 16,sockets=16,cores=1,threads=1 \
> -m 4G \
> -object memory-backend-ram,id=pc.ram,size=4G \
> -no-user-config -nodefaults -nographic
>
> Stack trace of thread 16903:
> #0  0x7fb109a9318b raise (libc.so.6 + 0x3a18b)
> #1  0x7fb109a94585 abort (libc.so.6 + 0x3b585)
> #2  0x558c34bc89be error_handle_fatal (qemu-system-x86_64 + 0x9c89be)
> #3  0x558c34bc8aee error_setv (qemu-system-x86_64 + 0x9c8aee)
> #4  0x558c34bc8ccf error_setg_internal (qemu-system-x86_64 + 0x9c8ccf)
> #5  0x558c349f6899 object_property_try_add (qemu-system-x86_64 + 
> 0x7f6899)
> #6  0x558c349f7df8 object_property_try_add_child (qemu-system-x86_64 
> + 0x7f7df8)
> #7  0x558c349f7e91 object_property_add_child (qemu-system-x86_64 + 
> 0x7f7e91)
> #8  0x558c3454686d create_default_memdev (qemu-system-x86_64 + 
> 0x34686d)
> #9  0x558c34546f58 qemu_init_board (qemu-system-x86_64 + 0x346f58)
> #10 0x558c345471b9 qmp_x_exit_preconfig (qemu-system-x86_64 + 
> 0x3471b9)
> #11 0x558c345497d9 qemu_init (qemu-system-x86_64 + 0x3497d9)
> #12 0x558c344e54c2 main (qemu-system-x86_64 + 0x2e54c2)
> #13 0x7fb109a7e34d __libc_start_main (libc.so.6 + 0x2534d)
> #14 0x558c344e53ba _start (qemu-system-x86_64 + 0x2e53ba)
>
> Signed-off-by: Li Zhang 
> ---
>  hw/core/machine.c | 8 
>  1 file changed, 8 insertions(+)
>
> diff --git a/hw/core/machine.c b/hw/core/machine.c
> index b03d9192ba..3867af7a8a 100644
> --- a/hw/core/machine.c
> +++ b/hw/core/machine.c
> @@ -1290,9 +1290,17 @@ MemoryRegion *machine_consume_memdev(MachineState 
> *machine,
>  static bool create_default_memdev(MachineState *ms, const char *path, Error 
> **errp)
>  {
>  Object *obj;
> +ObjectProperty *prop;
>  MachineClass *mc = MACHINE_GET_CLASS(ms);
>  bool r = false;
>
> +prop = object_property_find(object_get_objects_root(), 
> mc->default_ram_id);
> +if (prop) {
> +error_report("Memory backend id conflicts with default_ram_id %s",
> + mc->default_ram_id);
> +exit(EXIT_FAILURE);
> +}
> +
>  obj = object_new(path ? TYPE_MEMORY_BACKEND_FILE : 
> TYPE_MEMORY_BACKEND_RAM);
>  if (path) {
>  if (!object_property_set_str(obj, "mem-path", path, errp)) {
> --
> 2.34.1
>



[PATCH] target/ppc: fix vbpermd in big endian hosts

2022-06-01 Thread matheus . ferst
From: Matheus Ferst 

The extract64 arguments are not endian dependent as they are only used
for bitwise operations. The current behavior in little-endian hosts is
correct; since the indexes in VRB are in PowerISA-ordering, we should
always invert the value before calling extract64. Also, using the VsrD
macro, we can have a single EXTRACT_BIT definition for big and
little-endian with the correct behavior.

Signed-off-by: Matheus Ferst 
---
Found this bug while refactoring VECTOR_FOR_INORDER_I uses. The
complete patch series will also use Vsr[DB] instead of VBPERM[DQ]_INDEX,
but it will need more testing. For now, we're just changing what is
necessary to fix the instruction.
---
 target/ppc/int_helper.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c
index 105b626d1b..4c5d3f03f8 100644
--- a/target/ppc/int_helper.c
+++ b/target/ppc/int_helper.c
@@ -1307,14 +1307,13 @@ XXGENPCV(XXGENPCVDM, 8)
 #define VBPERMQ_INDEX(avr, i) ((avr)->u8[(i)])
 #define VBPERMD_INDEX(i) (i)
 #define VBPERMQ_DW(index) (((index) & 0x40) != 0)
-#define EXTRACT_BIT(avr, i, index) (extract64((avr)->u64[i], index, 1))
 #else
 #define VBPERMQ_INDEX(avr, i) ((avr)->u8[15 - (i)])
 #define VBPERMD_INDEX(i) (1 - i)
 #define VBPERMQ_DW(index) (((index) & 0x40) == 0)
-#define EXTRACT_BIT(avr, i, index) \
-(extract64((avr)->u64[1 - i], 63 - index, 1))
 #endif
+#define EXTRACT_BIT(avr, i, index) \
+(extract64((avr)->VsrD(i), 63 - index, 1))
 
 void helper_vbpermd(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
 {
-- 
2.25.1




Re: [PATCH v2] vduse-blk: Add name option

2022-06-01 Thread Stefan Hajnoczi
On Tue, May 31, 2022 at 05:52:21PM +0800, Xie Yongji wrote:
> Currently we use 'id' option as the name of VDUSE device.
> It's a bit confusing since we use one value for two different
> purposes: the ID to identfy the export within QEMU (must be
> distinct from any other exports in the same QEMU process, but
> can overlap with names used by other processes), and the VDUSE
> name to uniquely identify it on the host (must be distinct from
> other VDUSE devices on the same host, but can overlap with other
> export types like NBD in the same process). To make it clear,
> this patch adds a separate 'name ' option to specify the VDUSE
> name for the vduse-blk export instead.
> 
> Signed-off-by: Xie Yongji 
> ---
>  block/export/vduse-blk.c | 9 ++---
>  docs/tools/qemu-storage-daemon.rst   | 5 +++--
>  qapi/block-export.json   | 7 ---
>  storage-daemon/qemu-storage-daemon.c | 8 
>  4 files changed, 17 insertions(+), 12 deletions(-)
> 
> diff --git a/block/export/vduse-blk.c b/block/export/vduse-blk.c
> index 3b10349173..d96993bdf5 100644
> --- a/block/export/vduse-blk.c
> +++ b/block/export/vduse-blk.c
> @@ -245,7 +245,7 @@ static int vduse_blk_exp_create(BlockExport *exp, 
> BlockExportOptions *opts,
>  }
>  vblk_exp->num_queues = num_queues;
>  vblk_exp->handler.blk = exp->blk;
> -vblk_exp->handler.serial = exp->id;
> +vblk_exp->handler.serial = g_strdup(vblk_opts->name);

Do we want to expose the VDUSE device name to the guest? Maybe the
serial string should be a separate parameter.

>  vblk_exp->handler.logical_block_size = logical_block_size;
>  vblk_exp->handler.writable = opts->writable;
>  
> @@ -279,22 +279,24 @@ static int vduse_blk_exp_create(BlockExport *exp, 
> BlockExportOptions *opts,
>  features |= 1ULL << VIRTIO_BLK_F_RO;
>  }
>  
> -vblk_exp->dev = vduse_dev_create(exp->id, VIRTIO_ID_BLOCK, 0,
> +vblk_exp->dev = vduse_dev_create(vblk_opts->name, VIRTIO_ID_BLOCK, 0,
>   features, num_queues,
>   sizeof(struct virtio_blk_config),
>   (char *)&config, &vduse_blk_ops,
>   vblk_exp);
>  if (!vblk_exp->dev) {
>  error_setg(errp, "failed to create vduse device");
> +g_free((void *)vblk_exp->handler.serial);

serial isn't const char * anymore, it's char *. Please update the struct
field and then these casts won't be necessary anymore.


signature.asc
Description: PGP signature


Re: [PATCH v6 3/8] mm/memfd: Introduce MFD_INACCESSIBLE flag

2022-06-01 Thread Gupta, Pankaj




Introduce a new memfd_create() flag indicating the content of the
created memfd is inaccessible from userspace through ordinary MMU
access (e.g., read/write/mmap). However, the file content can be
accessed via a different mechanism (e.g. KVM MMU) indirectly.



SEV, TDX, pkvm and software-only VMs seem to have usecases to set up
initial guest boot memory with the needed blobs.
TDX already supports a KVM IOCTL to transfer contents to private
memory using the TDX module but rest of the implementations will need
to invent
a way to do this.


There are some discussions in 
https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flkml.org%2Flkml%2F2022%2F5%2F9%2F1292&data=05%7C01%7Cpankaj.gupta%40amd.com%7Cb81ef334e2dd44c6143308da43b87d17%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637896756895977587%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=oQbM2Hj7GlhJTwnTM%2FPnwsfJlmTL7JR9ULBysAqm6V8%3D&reserved=0
already. I somehow agree with Sean. TDX is using an dedicated ioctl to
copy guest boot memory to private fd so the rest can do that similarly.
The concern is the performance (extra memcpy) but it's trivial since the
initial guest payload is usually optimized in size.



Is there a plan to support a common implementation for either allowing
initial write access from userspace to private fd or adding a KVM
IOCTL to transfer contents to such a file,
as part of this series through future revisions?


Indeed, adding pre-boot private memory populating on current design
isn't impossible, but there are still some opens, e.g. how to expose
private fd to userspace for access, pKVM and CC usages may have
different requirements. Before that's well-studied I would tend to not
add that and instead use an ioctl to copy. Whether we need a generic
ioctl or feature-specific ioctl, I don't have strong opinion here.
Current TDX uses a feature-specific ioctl so it's not covered in this
series.


Common function or ioctl to populate preboot private memory actually 
makes sense.


Sorry, did not follow much of TDX code yet, Is it possible to filter out
the current TDX specific ioctl to common function so that it can be used 
by other technologies?


Thanks,
Pankaj




Re: Accelerating non-standard disk types

2022-06-01 Thread Stefan Hajnoczi
On Tue, May 31, 2022 at 03:06:20AM +, Raphael Norwitz wrote:
> On Wed, May 25, 2022 at 05:00:04PM +0100, Stefan Hajnoczi wrote:
> > On Thu, May 19, 2022 at 06:39:39PM +, Raphael Norwitz wrote:
> > > On Tue, May 17, 2022 at 03:53:52PM +0200, Paolo Bonzini wrote:
> > > > On 5/16/22 19:38, Raphael Norwitz wrote:
> > > > > [1] Keep using the SCSI translation in QEMU but back vDisks with a
> > > > > vhost-user-scsi or vhost-user-blk backend device.
> > > > > [2] Implement SATA and IDE emulation with vfio-user (likely with an 
> > > > > SPDK
> > > > > client?).
> > > > > [3] We've also been looking at your libblkio library. From your
> > > > > description in
> > > > > https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.gnu.org_archive_html_qemu-2Ddevel_2021-2D04_msg06146.html&d=DwICaQ&c=s883GpUCOChKOHiocYtGcg&r=In4gmR1pGzKB8G5p6LUrWqkSMec2L5EtXZow_FZNJZk&m=wBSqcw0cal3wPP87YIKgFgmqMHjGCC3apYf4wCn1SIrX6GW_FR-J9wO68v-cyrpn&s=CP-6ZY-gqgQ2zLAJdR8WVTrMBoqmFHilGvW_qnf2myU&e=
> > > > >it
> > > > > sounds like it may definitely play a role here, and possibly provide 
> > > > > the
> > > > > nessesary abstractions to back I/O from these emulated disks to any
> > > > > backends we may want?
> > > > 
> > > > First of all: have you benchmarked it?  How much time is spent on MMIO 
> > > > vs.
> > > > disk I/O?
> > > >
> > > 
> > > Good point - we haven’t benchmarked the emulation, exit and translation
> > > overheads - it is very possible speeding up disk I/O may not have a huge
> > > impact. We would definitely benchmark this before exploring any of the
> > > options seriously, but as you rightly note, performance is not the only
> > > motivation here.
> > > 
> > > > Of the options above, the most interesting to me is to implement a
> > > > vhost-user-blk/vhost-user-scsi backend in QEMU, similar to the NVMe one,
> > > > that would translate I/O submissions to virtqueue (including polling 
> > > > and the
> > > > like) and could be used with SATA.
> > > >
> > > 
> > > We were certainly eyeing [1] as the most viable in the immediate future.
> > > That said, since a vhost-user-blk driver has been added to libblkio, [3]
> > > also sounds like a strong option. Do you see any long term benefit to
> > > translating SATA/IDE submissions to virtqueues in a world where libblkio
> > > is to be adopted?
> > >
> > > > For IDE specifically, I'm not sure how much it can be sped up since it 
> > > > has
> > > > only 1 in-flight operation.  I think using KVM coalesced I/O could 
> > > > provide
> > > > an interesting boost (assuming instant or near-instant reply from the
> > > > backend).  If all you're interested in however is not really 
> > > > performance,
> > > > but rather having a single "connection" to your back end, vhost-user is
> > > > certainly an option.
> > > > 
> > > 
> > > Interesting - I will take a look at KVM coalesced I/O.
> > > 
> > > You’re totally right though, performance is not our main interest for
> > > these disk types. I should have emphasized offload rather than
> > > acceleration and performance. We would prefer to QA and support as few
> > > data paths as possible, and a vhost-user offload mechanism would allow
> > > us to use the same path for all I/O. I imagine other QEMU users who
> > > offload to backends like SPDK and use SATA/IDE disk types may feel
> > > similarly?
> > 
> > It's nice to have a single target (e.g. vhost-user-blk in SPDK) that
> > handles all disk I/O. On the other hand, QEMU would still have the
> > IDE/SATA emulation and libblkio vhost-user-blk driver, so in the end it
> > may not reduce the amount of code that you need to support.
> > 
> 
> Apologies for the late reply - I was on PTO.
> 
> For us it’s not so much about the overall LOC we support. We have our
> own iSCSI client implementation with embedded business logic which we
> use for SCSI disks. Continuing to support SATA and IDE disks without our
> implementation has been really troublesome so, even if it means more
> LOC, we would really like to unify our data path at least at the iSCSI
> layer.
> 
> While the overall code may not be reduced so much for many others today,
> it may make a significant difference in the future. I can imagine some
> QEMU users may want to deprecate (or not implement) iSCSI target support
> in favor of NVMe over fabrics and still support these disk types. Being
> able to offload the transport layer via vhost-user-blk (either with some
> added logic on top of the existing SCSI translation layer or with
> libblkio) would make this easy.
> 
> Does that sound reasonable?

Yes.

Stefan


signature.asc
Description: PGP signature


Re: [PATCH v2] vduse-blk: Add name option

2022-06-01 Thread Yongji Xie
On Wed, Jun 1, 2022 at 9:03 PM Stefan Hajnoczi  wrote:
>
> On Tue, May 31, 2022 at 05:52:21PM +0800, Xie Yongji wrote:
> > Currently we use 'id' option as the name of VDUSE device.
> > It's a bit confusing since we use one value for two different
> > purposes: the ID to identfy the export within QEMU (must be
> > distinct from any other exports in the same QEMU process, but
> > can overlap with names used by other processes), and the VDUSE
> > name to uniquely identify it on the host (must be distinct from
> > other VDUSE devices on the same host, but can overlap with other
> > export types like NBD in the same process). To make it clear,
> > this patch adds a separate 'name ' option to specify the VDUSE
> > name for the vduse-blk export instead.
> >
> > Signed-off-by: Xie Yongji 
> > ---
> >  block/export/vduse-blk.c | 9 ++---
> >  docs/tools/qemu-storage-daemon.rst   | 5 +++--
> >  qapi/block-export.json   | 7 ---
> >  storage-daemon/qemu-storage-daemon.c | 8 
> >  4 files changed, 17 insertions(+), 12 deletions(-)
> >
> > diff --git a/block/export/vduse-blk.c b/block/export/vduse-blk.c
> > index 3b10349173..d96993bdf5 100644
> > --- a/block/export/vduse-blk.c
> > +++ b/block/export/vduse-blk.c
> > @@ -245,7 +245,7 @@ static int vduse_blk_exp_create(BlockExport *exp, 
> > BlockExportOptions *opts,
> >  }
> >  vblk_exp->num_queues = num_queues;
> >  vblk_exp->handler.blk = exp->blk;
> > -vblk_exp->handler.serial = exp->id;
> > +vblk_exp->handler.serial = g_strdup(vblk_opts->name);
>
> Do we want to expose the VDUSE device name to the guest? Maybe the
> serial string should be a separate parameter.
>

OK, it makes sense to me. But we might need a default value. Any suggestions?

> >  vblk_exp->handler.logical_block_size = logical_block_size;
> >  vblk_exp->handler.writable = opts->writable;
> >
> > @@ -279,22 +279,24 @@ static int vduse_blk_exp_create(BlockExport *exp, 
> > BlockExportOptions *opts,
> >  features |= 1ULL << VIRTIO_BLK_F_RO;
> >  }
> >
> > -vblk_exp->dev = vduse_dev_create(exp->id, VIRTIO_ID_BLOCK, 0,
> > +vblk_exp->dev = vduse_dev_create(vblk_opts->name, VIRTIO_ID_BLOCK, 0,
> >   features, num_queues,
> >   sizeof(struct virtio_blk_config),
> >   (char *)&config, &vduse_blk_ops,
> >   vblk_exp);
> >  if (!vblk_exp->dev) {
> >  error_setg(errp, "failed to create vduse device");
> > +g_free((void *)vblk_exp->handler.serial);
>
> serial isn't const char * anymore, it's char *. Please update the struct
> field and then these casts won't be necessary anymore.

OK.

Thanks,
Yongji



Re: [RESEND PATCH] hw/dma: fix crash caused by race condition

2022-06-01 Thread Stefan Hajnoczi
On Wed, Jun 01, 2022 at 10:00:50AM +0200, David Hildenbrand wrote:
> On 01.06.22 02:20, Tong Zhang wrote:
> > Hi David,
> > 
> > On Mon, May 30, 2022 at 9:19 AM David Hildenbrand  wrote:
> >>
> >> On 27.04.22 22:51, Tong Zhang wrote:
> >>> assert(dbs->acb) is meant to check the return value of io_func per
> >>> documented in commit 6bee44ea34 ("dma: the passed io_func does not
> >>> return NULL"). However, there is a chance that after calling
> >>> aio_context_release(dbs->ctx); the dma_blk_cb function is called before
> >>> the assertion and dbs->acb is set to NULL again at line 121. Thus when
> >>> we run assert at line 181 it will fail.
> >>>
> >>>   softmmu/dma-helpers.c:181: dma_blk_cb: Assertion `dbs->acb' failed.
> >>>
> >>> Reported-by: Francisco Londono 
> >>> Signed-off-by: Tong Zhang 
> >>> ---
> >>>  softmmu/dma-helpers.c | 2 +-
> >>>  1 file changed, 1 insertion(+), 1 deletion(-)
> >>>
> >>> diff --git a/softmmu/dma-helpers.c b/softmmu/dma-helpers.c
> >>> index 7820fec54c..cb81017928 100644
> >>> --- a/softmmu/dma-helpers.c
> >>> +++ b/softmmu/dma-helpers.c
> >>> @@ -177,8 +177,8 @@ static void dma_blk_cb(void *opaque, int ret)
> >>>  aio_context_acquire(dbs->ctx);
> >>>  dbs->acb = dbs->io_func(dbs->offset, &dbs->iov,
> >>>  dma_blk_cb, dbs, dbs->io_func_opaque);
> >>> -aio_context_release(dbs->ctx);
> >>>  assert(dbs->acb);
> >>> +aio_context_release(dbs->ctx);
> >>>  }
> >>>
> >>>  static void dma_aio_cancel(BlockAIOCB *acb)
> >>
> >> I'm fairly new to that code, but I wonder what prevents dma_blk_cb() to
> >> run after you reshuffled the code?
> >>
> > 
> > IMO if the assert is to test whether io_func returns a non-NULL value
> > shouldn't it be immediately after calling io_func.
> > Also... as suggested by commit 6bee44ea346aed24e12d525daf10542d695508db
> >   > dma: the passed io_func does not return NULL
> 
> Yes, but I just don't see how it would fix the assertion you document in
> the patch description. The locking change to fix the assertion doesn't
> make any sense to me, and most probably I am missing something important :)

The other thread will invoke dma_blk_cb(), which modifies dbs->acb, when
it can take the lock. Therefore dbs->acb may contain a value different
from our io_func()'s return value by the time we perform the assertion
check (that's the race).

This patch makes sense to me. Can you rephrase your concern?

Stefan


signature.asc
Description: PGP signature


Re: [PATCH v2] hw/nvme: clean up CC register write logic

2022-06-01 Thread Lukasz Maniak
On Wed, May 25, 2022 at 09:35:24AM +0200, Klaus Jensen wrote:
> 
> +stl_le_p(&n->bar.intms, 0);
> +stl_le_p(&n->bar.intmc, 0);
> +stl_le_p(&n->bar.cc, 0);

Looks fine, though it seems the NVMe spec says the above registers
should be cleared during each reset for VF as well.

> -- 
> 2.36.1
> 



Re: [RESEND PATCH] hw/dma: fix crash caused by race condition

2022-06-01 Thread David Hildenbrand
On 01.06.22 15:24, Stefan Hajnoczi wrote:
> On Wed, Jun 01, 2022 at 10:00:50AM +0200, David Hildenbrand wrote:
>> On 01.06.22 02:20, Tong Zhang wrote:
>>> Hi David,
>>>
>>> On Mon, May 30, 2022 at 9:19 AM David Hildenbrand  wrote:

 On 27.04.22 22:51, Tong Zhang wrote:
> assert(dbs->acb) is meant to check the return value of io_func per
> documented in commit 6bee44ea34 ("dma: the passed io_func does not
> return NULL"). However, there is a chance that after calling
> aio_context_release(dbs->ctx); the dma_blk_cb function is called before
> the assertion and dbs->acb is set to NULL again at line 121. Thus when
> we run assert at line 181 it will fail.
>
>   softmmu/dma-helpers.c:181: dma_blk_cb: Assertion `dbs->acb' failed.
>
> Reported-by: Francisco Londono 
> Signed-off-by: Tong Zhang 
> ---
>  softmmu/dma-helpers.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/softmmu/dma-helpers.c b/softmmu/dma-helpers.c
> index 7820fec54c..cb81017928 100644
> --- a/softmmu/dma-helpers.c
> +++ b/softmmu/dma-helpers.c
> @@ -177,8 +177,8 @@ static void dma_blk_cb(void *opaque, int ret)
>  aio_context_acquire(dbs->ctx);
>  dbs->acb = dbs->io_func(dbs->offset, &dbs->iov,
>  dma_blk_cb, dbs, dbs->io_func_opaque);
> -aio_context_release(dbs->ctx);
>  assert(dbs->acb);
> +aio_context_release(dbs->ctx);
>  }
>
>  static void dma_aio_cancel(BlockAIOCB *acb)

 I'm fairly new to that code, but I wonder what prevents dma_blk_cb() to
 run after you reshuffled the code?

>>>
>>> IMO if the assert is to test whether io_func returns a non-NULL value
>>> shouldn't it be immediately after calling io_func.
>>> Also... as suggested by commit 6bee44ea346aed24e12d525daf10542d695508db
>>>   > dma: the passed io_func does not return NULL
>>
>> Yes, but I just don't see how it would fix the assertion you document in
>> the patch description. The locking change to fix the assertion doesn't
>> make any sense to me, and most probably I am missing something important :)
> 
> The other thread will invoke dma_blk_cb(), which modifies dbs->acb, when
> it can take the lock. Therefore dbs->acb may contain a value different
> from our io_func()'s return value by the time we perform the assertion
> check (that's the race).
> 
> This patch makes sense to me. Can you rephrase your concern?

The locking is around dbs->io_func().

aio_context_acquire(dbs->ctx);
dbs->acb = dbs->io_func()
aio_context_release(dbs->ctx);


So where exactly would the lock that's now still held stop someone from
modifying dbs->acb = NULL at the beginning of the function, which seems
to be not protected by that lock?

Maybe I'm missing some locking magic due to the lock being a recursive lock.

-- 
Thanks,

David / dhildenb




Re: [PATCH v6 2/8] target/s390x: add zpci-interp to cpu models

2022-06-01 Thread Matthew Rosato

On 6/1/22 5:52 AM, David Hildenbrand wrote:

On 24.05.22 21:02, Matthew Rosato wrote:

The zpci-interp feature is used to specify whether zPCI interpretation is
to be used for this guest.


We have

DEF_FEAT(SIE_PFMFI, "pfmfi", SCLP_CONF_CHAR_EXT, 9, "SIE: PFMF
interpretation facility")

and

DEF_FEAT(SIE_SIGPIF, "sigpif", SCLP_CPU, 12, "SIE: SIGP interpretation
facility")


Should we call this simply "zpcii" or "zpciif" (if the official name
includes "Facility")



This actually controls the use of 2 facilities which really only make 
sense together - Maybe just zpcii




Signed-off-by: Matthew Rosato 
---
  hw/s390x/s390-virtio-ccw.c  | 1 +
  target/s390x/cpu_features_def.h.inc | 1 +
  target/s390x/gen-features.c | 2 ++
  target/s390x/kvm/kvm.c  | 1 +
  4 files changed, 5 insertions(+)

diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 047cca0487..b33310a135 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -806,6 +806,7 @@ static void ccw_machine_7_0_instance_options(MachineState 
*machine)
  static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V7_0 };
  
  ccw_machine_7_1_instance_options(machine);

+s390_cpudef_featoff_greater(14, 1, S390_FEAT_ZPCI_INTERP);
  s390_set_qemu_cpu_model(0x8561, 15, 1, qemu_cpu_feat);
  }
  
diff --git a/target/s390x/cpu_features_def.h.inc b/target/s390x/cpu_features_def.h.inc

index e86662bb3b..4ade3182aa 100644
--- a/target/s390x/cpu_features_def.h.inc
+++ b/target/s390x/cpu_features_def.h.inc
@@ -146,6 +146,7 @@ DEF_FEAT(SIE_CEI, "cei", SCLP_CPU, 43, "SIE: 
Conditional-external-interception f
  DEF_FEAT(DAT_ENH_2, "dateh2", MISC, 0, "DAT-enhancement facility 2")
  DEF_FEAT(CMM, "cmm", MISC, 0, "Collaborative-memory-management facility")
  DEF_FEAT(AP, "ap", MISC, 0, "AP instructions installed")
+DEF_FEAT(ZPCI_INTERP, "zpci-interp", MISC, 0, "zPCI interpretation")


How is this feature exposed to the guest, meaning, how can the guest
sense support?

Just a gut feeling: does this toggle enable the host to use
interpretation and the guest cannot really determine the difference
whether it's enabled or not? Then, it's not a guest CPU feature. But
let's hear first what this actually enables :)


This has changed a few times, but collectively we can determine on the 
host kernel if it is allowable based upon the availability of certain 
facility/sclp bits + the availability of an ioctl interface.


If all of these are available, the host kernel allows zPCI 
interpretation, with userspace able to toggle it on/off for the guest 
via this feature.  When allowed and enabled, 2 ECB bits then get set for 
each guest vcpu that enable the associated facilities.  The guest 
continues to use zPCI instructions in the same manner as before; the 
function handles it receives from CLP instructions will look different 
but are still used in the same manner.


We don't yet add vsie support of the facilities with this series, so the 
corresponding facility and sclp bits aren't forwarded to the guest.




  
  /* Features exposed via the PLO instruction. */

  DEF_FEAT(PLO_CL, "plo-cl", PLO, 0, "PLO Compare and load (32 bit in general 
registers)")
diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c
index c03ec2c9a9..f991646c01 100644
--- a/target/s390x/gen-features.c
+++ b/target/s390x/gen-features.c
@@ -554,6 +554,7 @@ static uint16_t full_GEN14_GA1[] = {
  S390_FEAT_HPMA2,
  S390_FEAT_SIE_KSS,
  S390_FEAT_GROUP_MULTIPLE_EPOCH_PTFF,
+S390_FEAT_ZPCI_INTERP,
  };
  
  #define full_GEN14_GA2 EmptyFeat

@@ -650,6 +651,7 @@ static uint16_t default_GEN14_GA1[] = {
  S390_FEAT_GROUP_MSA_EXT_8,
  S390_FEAT_MULTIPLE_EPOCH,
  S390_FEAT_GROUP_MULTIPLE_EPOCH_PTFF,
+S390_FEAT_ZPCI_INTERP,


I'm curious, should we really add this to the default model?

This implies that on any setup where we don't have zpci interpretation
support (including missing kernel support), that a basic "-cpu z14" will
no longer work with the new machine type.

If, OTOH, we expect this feature to be around in any sane installation,
then it's good to include it in the



From a hardware perspective, everything will be available on z14 and 
later so it's only a question of missing host kernel support (or, you 
aren't running in a z14 LPAR).  As far as host kernel support, the 
expectation is that for a distro release where this QEMU support lands 
the associated kernel support would also be backported.  I guess that 
leaves some awkwardness if one upgrades their distro qemu to a new 
release version without picking up the kernel upgrade for some reason.. 
In that case, you're not totally stuck, you could still use -cpu 
z14,zpcii=off (or better yet pick up the associated kernel upgrade...) 
The intent is for exploitation of interpretation facilities to become 
the default on z14 and later, with the ability to turn it off offered as 
a fall-back / backwards compatibility.


If th

Re: [RFC PATCH v1 0/8] qapi: add generator for Golang interface

2022-06-01 Thread Victor Toso
Hi,

On Wed, May 25, 2022 at 08:49:19AM -0500, Andrea Bolognani wrote:
> On Wed, May 18, 2022 at 02:30:11PM +0200, Markus Armbruster wrote:
> > Victor Toso  writes:
> > > IMHO, at this moment, qapi-go is targeting communicating with
> > > QEMU and handling multiple QEMU versions seems reasonable to me.
> >
> > It's targeting communicating in *QMP*.  QMP is designed to support
> > communicating with a range of QEMU versions.  Full compatibility is
> > promised for a narrow range.  Outside that range, graceful degradation.
> >
> > *If* you want to widen the full compatibility range, do it in *QMP*.  Or
> > do it on top of QEMU, e.g. in libvirt.
> >
> > > Perhaps libvirt can use qapi-go in the future or other generated
> > > interface. That would be cool.
> >
> > "Would be cool" and a dollar buys you a cup of bad coffee.
> >
> > Is it a good use of our limited resources?
> >
> > How much will it delay delivery of Go bindings compared to less
> > ambitious version?
> 
> Yeah, this thread has basically branched to cover three topics:
> 
>   1. what an MVP Go interface for QMP should look like;
>   2. how to make sure said interface uses pretty names;
>   3. how to make it work across multiple QEMU versions.
> 
> All of these are important in the long run, but as far as I'm
> concerned only 1. is an actual blocker to making progress.

I agree although (1) and (3) are holding hands a bit.

> If we get to the point where we can generate a reasonably
> complete and well-typed Go interface that can be used to
> communicate with a single version of QEMU, we should just
> plaster EXPERIMENTAL all over it and get it merged.
> 
> Basically get the MVP done and then iterate over it in-tree
> rather than trying to get everything perfect from the start.
>
> Sounds reasonable?

Yep. The whole discussion has been great as to clarify
limitations and possible goals but not aiming to get it perfect
all at once seems reasonable.

Cheers,
Victor


signature.asc
Description: PGP signature


Re: [RESEND PATCH] hw/dma: fix crash caused by race condition

2022-06-01 Thread Stefan Hajnoczi
On Wed, 1 Jun 2022 at 14:29, David Hildenbrand  wrote:
>
> On 01.06.22 15:24, Stefan Hajnoczi wrote:
> > On Wed, Jun 01, 2022 at 10:00:50AM +0200, David Hildenbrand wrote:
> >> On 01.06.22 02:20, Tong Zhang wrote:
> >>> Hi David,
> >>>
> >>> On Mon, May 30, 2022 at 9:19 AM David Hildenbrand  
> >>> wrote:
> 
>  On 27.04.22 22:51, Tong Zhang wrote:
> > assert(dbs->acb) is meant to check the return value of io_func per
> > documented in commit 6bee44ea34 ("dma: the passed io_func does not
> > return NULL"). However, there is a chance that after calling
> > aio_context_release(dbs->ctx); the dma_blk_cb function is called before
> > the assertion and dbs->acb is set to NULL again at line 121. Thus when
> > we run assert at line 181 it will fail.
> >
> >   softmmu/dma-helpers.c:181: dma_blk_cb: Assertion `dbs->acb' failed.
> >
> > Reported-by: Francisco Londono 
> > Signed-off-by: Tong Zhang 
> > ---
> >  softmmu/dma-helpers.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/softmmu/dma-helpers.c b/softmmu/dma-helpers.c
> > index 7820fec54c..cb81017928 100644
> > --- a/softmmu/dma-helpers.c
> > +++ b/softmmu/dma-helpers.c
> > @@ -177,8 +177,8 @@ static void dma_blk_cb(void *opaque, int ret)
> >  aio_context_acquire(dbs->ctx);
> >  dbs->acb = dbs->io_func(dbs->offset, &dbs->iov,
> >  dma_blk_cb, dbs, dbs->io_func_opaque);
> > -aio_context_release(dbs->ctx);
> >  assert(dbs->acb);
> > +aio_context_release(dbs->ctx);
> >  }
> >
> >  static void dma_aio_cancel(BlockAIOCB *acb)
> 
>  I'm fairly new to that code, but I wonder what prevents dma_blk_cb() to
>  run after you reshuffled the code?
> 
> >>>
> >>> IMO if the assert is to test whether io_func returns a non-NULL value
> >>> shouldn't it be immediately after calling io_func.
> >>> Also... as suggested by commit 6bee44ea346aed24e12d525daf10542d695508db
> >>>   > dma: the passed io_func does not return NULL
> >>
> >> Yes, but I just don't see how it would fix the assertion you document in
> >> the patch description. The locking change to fix the assertion doesn't
> >> make any sense to me, and most probably I am missing something important :)
> >
> > The other thread will invoke dma_blk_cb(), which modifies dbs->acb, when
> > it can take the lock. Therefore dbs->acb may contain a value different
> > from our io_func()'s return value by the time we perform the assertion
> > check (that's the race).
> >
> > This patch makes sense to me. Can you rephrase your concern?
>
> The locking is around dbs->io_func().
>
> aio_context_acquire(dbs->ctx);
> dbs->acb = dbs->io_func()
> aio_context_release(dbs->ctx);
>
>
> So where exactly would the lock that's now still held stop someone from
> modifying dbs->acb = NULL at the beginning of the function, which seems
> to be not protected by that lock?
>
> Maybe I'm missing some locking magic due to the lock being a recursive lock.

Tong Zhang: Can you share a backtrace of all threads when the
assertion failure occurs?

Stefan



Re: [External] [PATCH v13 3/8] QIOChannelSocket: Implement io_writev zero copy flag & io_flush for CONFIG_LINUX

2022-06-01 Thread Peter Xu
On Wed, Jun 01, 2022 at 05:37:10PM +0800, 徐闯 wrote:
> 
> On 2022/5/13 下午2:28, Leonardo Bras wrote:
> > For CONFIG_LINUX, implement the new zero copy flag and the optional callback
> > io_flush on QIOChannelSocket, but enables it only when MSG_ZEROCOPY
> > feature is available in the host kernel, which is checked on
> > qio_channel_socket_connect_sync()
> > 
> > qio_channel_socket_flush() was implemented by counting how many times
> > sendmsg(...,MSG_ZEROCOPY) was successfully called, and then reading the
> > socket's error queue, in order to find how many of them finished sending.
> > Flush will loop until those counters are the same, or until some error 
> > occurs.
> > 
> > Notes on using writev() with QIO_CHANNEL_WRITE_FLAG_ZERO_COPY:
> > 1: Buffer
> > - As MSG_ZEROCOPY tells the kernel to use the same user buffer to avoid 
> > copying,
> > some caution is necessary to avoid overwriting any buffer before it's sent.
> > If something like this happen, a newer version of the buffer may be sent 
> > instead.
> > - If this is a problem, it's recommended to call qio_channel_flush() before 
> > freeing
> > or re-using the buffer.
> > 
> > 2: Locked memory
> > - When using MSG_ZERCOCOPY, the buffer memory will be locked after queued, 
> > and
> > unlocked after it's sent.
> > - Depending on the size of each buffer, and how often it's sent, it may 
> > require
> > a larger amount of locked memory than usually available to non-root user.
> > - If the required amount of locked memory is not available, writev_zero_copy
> > will return an error, which can abort an operation like migration,
> > - Because of this, when an user code wants to add zero copy as a feature, it
> > requires a mechanism to disable it, so it can still be accessible to less
> > privileged users.
> > 
> > Signed-off-by: Leonardo Bras 
> > Reviewed-by: Peter Xu 
> > Reviewed-by: Daniel P. Berrangé 
> > Reviewed-by: Juan Quintela 
> > ---
> >   include/io/channel-socket.h |   2 +
> >   io/channel-socket.c | 116 ++--
> >   2 files changed, 114 insertions(+), 4 deletions(-)
> > 
> > diff --git a/include/io/channel-socket.h b/include/io/channel-socket.h
> > index e747e63514..513c428fe4 100644
> > --- a/include/io/channel-socket.h
> > +++ b/include/io/channel-socket.h
> > @@ -47,6 +47,8 @@ struct QIOChannelSocket {
> >   socklen_t localAddrLen;
> >   struct sockaddr_storage remoteAddr;
> >   socklen_t remoteAddrLen;
> > +ssize_t zero_copy_queued;
> > +ssize_t zero_copy_sent;
> >   };
> Hi, Leonardo. I'm also paying attention to the application of MSG_ZEROCOPY
> in live migration recently. I noticed that you defined a member
> `zero_copy_queued` in the struct QIOChannelSocket, but I can't find out
> where the value of this member has been changed in your patch. Can you
> answer it for me?
> 

Good point.. it should probably be increased when queuing the pages. We'd
better fix it up or it seems the flush() will be literally an no-op..

Two things in qio_channel_socket_flush() we can do to make sure it'll work
as expected, imo:

  1) make ret=-1 as initial value, rather than 1 - we only check negative
 errors in the caller so we could have missed a positive "1"

  2) add a tracepoint into the loop of updating zero_copy_sent

Leo, what's your take?

Thanks,

-- 
Peter Xu




Re: [PATCH] hw/intc: sifive_plic: Avoid overflowing the addr_config buffer

2022-06-01 Thread Philippe Mathieu-Daudé via

On 1/6/22 03:36, Alistair Francis wrote:

From: Alistair Francis 

Since commit ad40be27 "target/riscv: Support start kernel directly by
KVM" we have been overflowing the addr_config on "M,MS..."
configurations, as reported https://gitlab.com/qemu-project/qemu/-/issues/1050.

This commit changes the loop in sifive_plic_create() from iterating over
the number of harts to just iterating over the addr_config. The
addr_config is based on the hart_config, and will contain interrup details
for all harts. This way we can't iterate past the end of addr_config.

Fixes: ad40be27084536 ("target/riscv: Support start kernel directly by KVM")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1050
Signed-off-by: Alistair Francis 
---
  hw/intc/sifive_plic.c | 19 +--
  1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
index eebbcf33d4..56d60e9ac9 100644
--- a/hw/intc/sifive_plic.c
+++ b/hw/intc/sifive_plic.c
@@ -431,7 +431,7 @@ DeviceState *sifive_plic_create(hwaddr addr, char 
*hart_config,
  uint32_t context_stride, uint32_t aperture_size)
  {
  DeviceState *dev = qdev_new(TYPE_SIFIVE_PLIC);
-int i, j = 0;
+int i;
  SiFivePLICState *plic;
  
  assert(enable_stride == (enable_stride & -enable_stride));

@@ -451,18 +451,17 @@ DeviceState *sifive_plic_create(hwaddr addr, char 
*hart_config,
  sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
  
  plic = SIFIVE_PLIC(dev);

-for (i = 0; i < num_harts; i++) {
-CPUState *cpu = qemu_get_cpu(hartid_base + i);
  
-if (plic->addr_config[j].mode == PLICMode_M) {

-j++;
-qdev_connect_gpio_out(dev, num_harts + i,
+for (i = 0; i < plic->num_addrs; i++) {
+int cpu_num = plic->addr_config[i].hartid;
+CPUState *cpu = qemu_get_cpu(hartid_base + cpu_num);
+
+if (plic->addr_config[i].mode == PLICMode_M) {
+qdev_connect_gpio_out(dev, num_harts + cpu_num,
qdev_get_gpio_in(DEVICE(cpu), IRQ_M_EXT));
  }
-
-if (plic->addr_config[j].mode == PLICMode_S) {
-j++;
-qdev_connect_gpio_out(dev, i,
+if (plic->addr_config[i].mode == PLICMode_S) {
+qdev_connect_gpio_out(dev, cpu_num,
qdev_get_gpio_in(DEVICE(cpu), IRQ_S_EXT));
  }
  }


The logic is much easier to follow now, thanks.

Reviewed-by: Philippe Mathieu-Daudé 



Re: [PATCH v6 2/8] target/s390x: add zpci-interp to cpu models

2022-06-01 Thread David Hildenbrand
On 01.06.22 15:48, Matthew Rosato wrote:
> On 6/1/22 5:52 AM, David Hildenbrand wrote:
>> On 24.05.22 21:02, Matthew Rosato wrote:
>>> The zpci-interp feature is used to specify whether zPCI interpretation is
>>> to be used for this guest.
>>
>> We have
>>
>> DEF_FEAT(SIE_PFMFI, "pfmfi", SCLP_CONF_CHAR_EXT, 9, "SIE: PFMF
>> interpretation facility")
>>
>> and
>>
>> DEF_FEAT(SIE_SIGPIF, "sigpif", SCLP_CPU, 12, "SIE: SIGP interpretation
>> facility")
>>
>>
>> Should we call this simply "zpcii" or "zpciif" (if the official name
>> includes "Facility")
>>
> 
> This actually controls the use of 2 facilities which really only make 
> sense together - Maybe just zpcii
> 
>>>
>>> Signed-off-by: Matthew Rosato 
>>> ---
>>>   hw/s390x/s390-virtio-ccw.c  | 1 +
>>>   target/s390x/cpu_features_def.h.inc | 1 +
>>>   target/s390x/gen-features.c | 2 ++
>>>   target/s390x/kvm/kvm.c  | 1 +
>>>   4 files changed, 5 insertions(+)
>>>
>>> diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
>>> index 047cca0487..b33310a135 100644
>>> --- a/hw/s390x/s390-virtio-ccw.c
>>> +++ b/hw/s390x/s390-virtio-ccw.c
>>> @@ -806,6 +806,7 @@ static void 
>>> ccw_machine_7_0_instance_options(MachineState *machine)
>>>   static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V7_0 
>>> };
>>>   
>>>   ccw_machine_7_1_instance_options(machine);
>>> +s390_cpudef_featoff_greater(14, 1, S390_FEAT_ZPCI_INTERP);
>>>   s390_set_qemu_cpu_model(0x8561, 15, 1, qemu_cpu_feat);
>>>   }
>>>   
>>> diff --git a/target/s390x/cpu_features_def.h.inc 
>>> b/target/s390x/cpu_features_def.h.inc
>>> index e86662bb3b..4ade3182aa 100644
>>> --- a/target/s390x/cpu_features_def.h.inc
>>> +++ b/target/s390x/cpu_features_def.h.inc
>>> @@ -146,6 +146,7 @@ DEF_FEAT(SIE_CEI, "cei", SCLP_CPU, 43, "SIE: 
>>> Conditional-external-interception f
>>>   DEF_FEAT(DAT_ENH_2, "dateh2", MISC, 0, "DAT-enhancement facility 2")
>>>   DEF_FEAT(CMM, "cmm", MISC, 0, "Collaborative-memory-management facility")
>>>   DEF_FEAT(AP, "ap", MISC, 0, "AP instructions installed")
>>> +DEF_FEAT(ZPCI_INTERP, "zpci-interp", MISC, 0, "zPCI interpretation")
>>
>> How is this feature exposed to the guest, meaning, how can the guest
>> sense support?
>>
>> Just a gut feeling: does this toggle enable the host to use
>> interpretation and the guest cannot really determine the difference
>> whether it's enabled or not? Then, it's not a guest CPU feature. But
>> let's hear first what this actually enables :)
> 
> This has changed a few times, but collectively we can determine on the 
> host kernel if it is allowable based upon the availability of certain 
> facility/sclp bits + the availability of an ioctl interface.
> 
> If all of these are available, the host kernel allows zPCI 
> interpretation, with userspace able to toggle it on/off for the guest 
> via this feature.  When allowed and enabled, 2 ECB bits then get set for 
> each guest vcpu that enable the associated facilities.  The guest 
> continues to use zPCI instructions in the same manner as before; the 
> function handles it receives from CLP instructions will look different 
> but are still used in the same manner.
> 
> We don't yet add vsie support of the facilities with this series, so the 
> corresponding facility and sclp bits aren't forwarded to the guest.

That's exactly my point:

sigpif and pfmfi are actually vsie features. I'd have expected that
zpcii would be a vsie feature as well.

If interpretation is really more an implementation detail in the
hypervisor to implement zpci, than an actual guest feature (meaning, the
guest is able to observe it as if it were a real CPU feature), then we
most probably want some other way to toggle it (maybe via the machine?).

Example: KVM uses SIGP interpretation based on availability. However, we
don't toggle it via sigpif. sigpif actually tells the guest that it can
use the SIGP interpretation facility along with vsie.

You mention "CLP instructions will look different", I'm not sure if that
should actually be handled via the CPU model. From my gut feeling, zpcii
should actually be the vsie zpcii support to be implemented in the future.


So I wonder if we could simply always enable zPCI interpretation if
HW+kernel support is around and we're on a new compat machine? I there
is a way that migration could break (from old kernel to new kernel),
we'd have to think about alternatives.


-- 
Thanks,

David / dhildenb




Re: [PATCH] tcg: Add tcg_gen_mov_ptr

2022-06-01 Thread Matheus K. Ferst

On 31/05/2022 00:21, Richard Henderson wrote:

Add an interface to perform moves between TCGv_ptr.

Signed-off-by: Richard Henderson 
---

This will be required for target/arm FEAT_SME.

r~

---
  include/tcg/tcg-op.h | 5 +
  1 file changed, 5 insertions(+)

diff --git a/include/tcg/tcg-op.h b/include/tcg/tcg-op.h
index b09b8b4a05..209e168305 100644
--- a/include/tcg/tcg-op.h
+++ b/include/tcg/tcg-op.h
@@ -1288,6 +1288,11 @@ static inline void tcg_gen_addi_ptr(TCGv_ptr r, TCGv_ptr 
a, intptr_t b)
  glue(tcg_gen_addi_,PTR)((NAT)r, (NAT)a, b);
  }

+static inline void tcg_gen_mov_ptr(TCGv_ptr d, TCGv_ptr s)
+{
+glue(tcg_gen_mov_,PTR)((NAT)d, (NAT)s);
+}
+
  static inline void tcg_gen_brcondi_ptr(TCGCond cond, TCGv_ptr a,
 intptr_t b, TCGLabel *label)
  {
--
2.34.1




Reviewed-by: Matheus Ferst 

--
Matheus K. Ferst
Instituto de Pesquisas ELDORADO 
Analista de Software
Aviso Legal - Disclaimer 



Re: Types?

2022-06-01 Thread Philippe Mathieu-Daudé via

Hi Kenneth,

On 1/6/22 11:28, Kenneth Adam Miller wrote:

Hello,

I am working on a qemu target under development. and I am wondering how 
I should differentiate the MachineState from the MachineClass.


Look at QOM documentation:
https://qemu.readthedocs.io/en/latest/devel/qom.html

MachineClass is the interface to create a MachineState object instance.

There is at most one FooClass registered. This class can create multiple
FooState instances.

FooClass fields are usually read-only, as modifying them would affect
all FooState instances.

Maybe start looking at hw/avr/arduino.c, which should be quite easy to
follow.

Regards,

Phil.



Re: [PATCH] target/ppc: fix vbpermd in big endian hosts

2022-06-01 Thread Philippe Mathieu-Daudé via

+Mark for commit ef96e3ae96.

On 1/6/22 14:53, matheus.fe...@eldorado.org.br wrote:

From: Matheus Ferst 

The extract64 arguments are not endian dependent as they are only used
for bitwise operations. The current behavior in little-endian hosts is
correct; since the indexes in VRB are in PowerISA-ordering, we should
always invert the value before calling extract64. Also, using the VsrD
macro, we can have a single EXTRACT_BIT definition for big and
little-endian with the correct behavior.

Signed-off-by: Matheus Ferst 
---
Found this bug while refactoring VECTOR_FOR_INORDER_I uses. The
complete patch series will also use Vsr[DB] instead of VBPERM[DQ]_INDEX,
but it will need more testing. For now, we're just changing what is
necessary to fix the instruction.
---
  target/ppc/int_helper.c | 5 ++---
  1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c
index 105b626d1b..4c5d3f03f8 100644
--- a/target/ppc/int_helper.c
+++ b/target/ppc/int_helper.c
@@ -1307,14 +1307,13 @@ XXGENPCV(XXGENPCVDM, 8)
  #define VBPERMQ_INDEX(avr, i) ((avr)->u8[(i)])
  #define VBPERMD_INDEX(i) (i)
  #define VBPERMQ_DW(index) (((index) & 0x40) != 0)
-#define EXTRACT_BIT(avr, i, index) (extract64((avr)->u64[i], index, 1))
  #else
  #define VBPERMQ_INDEX(avr, i) ((avr)->u8[15 - (i)])
  #define VBPERMD_INDEX(i) (1 - i)
  #define VBPERMQ_DW(index) (((index) & 0x40) == 0)
-#define EXTRACT_BIT(avr, i, index) \
-(extract64((avr)->u64[1 - i], 63 - index, 1))
  #endif
+#define EXTRACT_BIT(avr, i, index) \
+(extract64((avr)->VsrD(i), 63 - index, 1))
  
  void helper_vbpermd(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)

  {





Re: [PATCH v1 31/33] gitlab: convert build/container jobs to .base_job_template

2022-06-01 Thread Alex Bennée


Thomas Huth  writes:

> On 27/05/2022 17.36, Alex Bennée wrote:
>> From: Daniel P. Berrangé 
>> This converts the main build and container jobs to use the
>> base job rules, defining the following new variables
>>   - QEMU_JOB_SKIPPED - jobs that are known to be currently
>> broken and should not be run. Can still be manually
>> launched if desired.
>>   - QEMU_JOB_AVOCADO - jobs that run the Avocado integration
>> test harness.
>>   - QEMU_JOB_PUBLISH - jobs that publish content after the
>> branch is merged upstream
>> Signed-off-by: Daniel P. Berrangé 
>> Message-Id: <20220526110705.59952-5-berra...@redhat.com>
>> Signed-off-by: Alex Bennée 
>> ---
> ...
>> diff --git a/.gitlab-ci.d/buildtest.yml b/.gitlab-ci.d/buildtest.yml
>> index e9620c3074..ecac3ec50c 100644
>> --- a/.gitlab-ci.d/buildtest.yml
>> +++ b/.gitlab-ci.d/buildtest.yml
>> @@ -360,12 +360,11 @@ build-cfi-aarch64:
>>   expire_in: 2 days
>>   paths:
>> - build
>> -  rules:
>> +  variables:
>>   # FIXME: This job is often failing, likely due to out-of-memory 
>> problems in
>>   # the constrained containers of the shared runners. Thus this is 
>> marked as
>> -# manual until the situation has been solved.
>> -- when: manual
>> -  allow_failure: true
>> +# skipped until the situation has been solved.
>> +QEMU_JOB_SKIPPED: 1
>> check-cfi-aarch64:
>> extends: .native_test_job_template
>> @@ -402,12 +401,11 @@ build-cfi-ppc64-s390x:
>>   expire_in: 2 days
>>   paths:
>> - build
>> -  rules:
>> +  variables:
>>   # FIXME: This job is often failing, likely due to out-of-memory 
>> problems in
>>   # the constrained containers of the shared runners. Thus this is 
>> marked as
>> -# manual until the situation has been solved.
>> -- when: manual
>> -  allow_failure: true
>> +# skipped until the situation has been solved.
>> +QEMU_JOB_SKIPPED: 1
>> check-cfi-ppc64-s390x:
>> extends: .native_test_job_template
>> @@ -579,6 +577,7 @@ build-without-default-features:
>>   MAKE_CHECK_ARGS: check-unit check-qtest SPEED=slow
>> build-libvhost-user:
>> +  extends: .base_job_template
>> stage: build
>> image: $CI_REGISTRY_IMAGE/qemu/fedora:latest
>> needs:
>> @@ -595,10 +594,13 @@ build-tools-and-docs-debian:
>> extends: .native_build_job_template
>> needs:
>>   job: amd64-debian-container
>> +# when running on 'master' we use pre-existing container
>> +optional: true
>
> This change doesn't look like it's related to the other changes in
> here? Maybe mention it in the patch description at least?

It is because the QEMU_JOB_PUBLISH stage is run on master so we don't
really need to rebuild the container from staging to run it. I've
mentioned it in the commit.

>
> Apart from that:
> Reviewed-by: Thomas Huth 


-- 
Alex Bennée



Re: [PATCH v6 2/8] target/s390x: add zpci-interp to cpu models

2022-06-01 Thread Matthew Rosato

On 6/1/22 10:10 AM, David Hildenbrand wrote:

On 01.06.22 15:48, Matthew Rosato wrote:

On 6/1/22 5:52 AM, David Hildenbrand wrote:

On 24.05.22 21:02, Matthew Rosato wrote:

The zpci-interp feature is used to specify whether zPCI interpretation is
to be used for this guest.


We have

DEF_FEAT(SIE_PFMFI, "pfmfi", SCLP_CONF_CHAR_EXT, 9, "SIE: PFMF
interpretation facility")

and

DEF_FEAT(SIE_SIGPIF, "sigpif", SCLP_CPU, 12, "SIE: SIGP interpretation
facility")


Should we call this simply "zpcii" or "zpciif" (if the official name
includes "Facility")



This actually controls the use of 2 facilities which really only make
sense together - Maybe just zpcii



Signed-off-by: Matthew Rosato 
---
   hw/s390x/s390-virtio-ccw.c  | 1 +
   target/s390x/cpu_features_def.h.inc | 1 +
   target/s390x/gen-features.c | 2 ++
   target/s390x/kvm/kvm.c  | 1 +
   4 files changed, 5 insertions(+)

diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 047cca0487..b33310a135 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -806,6 +806,7 @@ static void ccw_machine_7_0_instance_options(MachineState 
*machine)
   static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V7_0 };
   
   ccw_machine_7_1_instance_options(machine);

+s390_cpudef_featoff_greater(14, 1, S390_FEAT_ZPCI_INTERP);
   s390_set_qemu_cpu_model(0x8561, 15, 1, qemu_cpu_feat);
   }
   
diff --git a/target/s390x/cpu_features_def.h.inc b/target/s390x/cpu_features_def.h.inc

index e86662bb3b..4ade3182aa 100644
--- a/target/s390x/cpu_features_def.h.inc
+++ b/target/s390x/cpu_features_def.h.inc
@@ -146,6 +146,7 @@ DEF_FEAT(SIE_CEI, "cei", SCLP_CPU, 43, "SIE: 
Conditional-external-interception f
   DEF_FEAT(DAT_ENH_2, "dateh2", MISC, 0, "DAT-enhancement facility 2")
   DEF_FEAT(CMM, "cmm", MISC, 0, "Collaborative-memory-management facility")
   DEF_FEAT(AP, "ap", MISC, 0, "AP instructions installed")
+DEF_FEAT(ZPCI_INTERP, "zpci-interp", MISC, 0, "zPCI interpretation")


How is this feature exposed to the guest, meaning, how can the guest
sense support?

Just a gut feeling: does this toggle enable the host to use
interpretation and the guest cannot really determine the difference
whether it's enabled or not? Then, it's not a guest CPU feature. But
let's hear first what this actually enables :)


This has changed a few times, but collectively we can determine on the
host kernel if it is allowable based upon the availability of certain
facility/sclp bits + the availability of an ioctl interface.

If all of these are available, the host kernel allows zPCI
interpretation, with userspace able to toggle it on/off for the guest
via this feature.  When allowed and enabled, 2 ECB bits then get set for
each guest vcpu that enable the associated facilities.  The guest
continues to use zPCI instructions in the same manner as before; the
function handles it receives from CLP instructions will look different
but are still used in the same manner.

We don't yet add vsie support of the facilities with this series, so the
corresponding facility and sclp bits aren't forwarded to the guest.


That's exactly my point:

sigpif and pfmfi are actually vsie features. I'd have expected that
zpcii would be a vsie feature as well.

If interpretation is really more an implementation detail in the
hypervisor to implement zpci, than an actual guest feature (meaning, the
guest is able to observe it as if it were a real CPU feature), then we
most probably want some other way to toggle it (maybe via the machine?).

Example: KVM uses SIGP interpretation based on availability. However, we
don't toggle it via sigpif. sigpif actually tells the guest that it can
use the SIGP interpretation facility along with vsie.

You mention "CLP instructions will look different", I'm not sure if that
should actually be handled via the CPU model. From my gut feeling, zpcii
should actually be the vsie zpcii support to be implemented in the future.



Well, what I meant was that the CLP response data looks different, 
primarily because when interpretation is enabled the guest would get 
passthrough of the function handle (which in turn has bits turned off 
that force hypervisor intercepts) rather than one that QEMU fabricated.


As far as a machine option, well we still need a mechanism by which 
userspace can decide whether it's OK to enable interpretation in the 
first place.  I guess we can take advantage of the fact that the 
capability associated with the ioctl interface can indicate both that 
the kernel interface is available + all of the necessary hardware 
facilities are available to that host kernel.


So I guess we could use that to make a decision to default a machine 
setting based upon that (yes if everything is available, no if not).




So I wonder if we could simply always enable zPCI interpretation if
HW+kernel support is around and we're on a new compat machine? I there
is a way that migration could break (

Re: [PATCH] MAINTAINERS: Update s390 vhost entries

2022-06-01 Thread Thomas Huth

On 25/05/2022 16.58, Eric Farman wrote:

Commit 7a523d96a0 ("virtio-ccw: move vhost_ccw_scsi to a separate file")
introduced a new file hw/s390x/vhost-scsi-ccw.c, which received a
couple comments [1][2] to update MAINTAINERS that were missed.

Fix that by making the vhost CCW entries a wildcard.

[1] 
https://lore.kernel.org/r/d8d2bbd5021076bdba444d31a6da74f507baede3.ca...@linux.ibm.com/
[2] https://lore.kernel.org/r/87k0c4gb9f@redhat.com/

Signed-off-by: Eric Farman 
---


Thanks, queued to s390x-next now:

 https://gitlab.com/thuth/qemu/-/commits/s390x-next/

 Thomas





Re: [PATCH v2] tests/tcg/s390x: Test overflow conditions

2022-06-01 Thread Thomas Huth

On 31/05/2022 20.35, Gautam Agrawal wrote:

Add a test to check for overflow conditions in s390x.
This patch is based on the following patches :
* https://git.qemu.org/?p=qemu.git;a=commitdiff;h=5a2e67a691501
* https://git.qemu.org/?p=qemu.git;a=commitdiff;h=fc6e0d0f2db51

Signed-off-by: Gautam Agrawal 
---


Thank you very much, queued to my s390x-next branch now:

 https://gitlab.com/thuth/qemu/-/commits/s390x-next/

 Thomas





  1   2   3   >