Re: [PATCH v5 00/19] Reconstruct loongson ipi driver

2024-07-19 Thread Jiaxun Yang



在2024年7月18日七月 下午9:32,Philippe Mathieu-Daudé写道:
> Since v4:
> - Fix build failure due to rebase (Song)
> - Loongarch -> LoongArch (Song)
> - Added Song's tags
>
> Since v3:
> - Use DEFINE_TYPES() macro (unreviewed patch #1)
> - Update MAINTAINERS
> - Added Bibo's tags

For the whole series:

Reviewed-by: Jiaxun Yang 
Tested-by: Jiaxun Yang 

Thanks! Tested on MIPS loongson3-virt with 2, 4 CPUs, all working fine.

I'll get this covered by CI later.
- Jiaxun

>
> Thanks,
>
> Phil.
>
> Bibo Mao (16):
>   hw/intc/loongson_ipi: Access memory in little endian
>   hw/intc/loongson_ipi: Rename LoongsonIPI -> LoongsonIPIState
>   hw/intc/loongson_ipi: Extract loongson_ipi_common_finalize()
>   hw/intc/loongson_ipi: Extract loongson_ipi_common_realize()
>   hw/intc/loongson_ipi: Add TYPE_LOONGSON_IPI_COMMON stub
>   hw/intc/loongson_ipi: Move common definitions to loongson_ipi_common.h
>   hw/intc/loongson_ipi: Move IPICore::mmio_mem to LoongsonIPIState
>   hw/intc/loongson_ipi: Move IPICore structure to loongson_ipi_common.h
>   hw/intc/loongson_ipi: Pass LoongsonIPICommonState to send_ipi_data()
>   hw/intc/loongson_ipi: Add LoongsonIPICommonClass::get_iocsr_as handler
>   hw/intc/loongson_ipi: Add LoongsonIPICommonClass::cpu_by_arch_id
> handler
>   hw/intc/loongson_ipi: Expose loongson_ipi_core_read/write helpers
>   hw/intc/loongson_ipi: Move common code to loongson_ipi_common.c
>   hw/intc/loongarch_ipi: Add loongarch IPI support
>   hw/loongarch/virt: Replace Loongson IPI with LoongArch IPI
>   hw/intc/loongson_ipi: Restrict to MIPS
>
> Philippe Mathieu-Daudé (3):
>   hw/intc/loongson_ipi: Declare QOM types using DEFINE_TYPES() macro
>   hw/intc/loongson_ipi: Remove unused headers
>   docs: Correct Loongarch -> LoongArch
>
>  MAINTAINERS   |   6 +-
>  docs/about/emulation.rst  |   2 +-
>  include/hw/intc/loongarch_ipi.h   |  25 ++
>  include/hw/intc/loongson_ipi.h|  50 +---
>  include/hw/intc/loongson_ipi_common.h |  72 ++
>  include/hw/loongarch/virt.h   |   1 -
>  hw/intc/loongarch_ipi.c   |  68 +
>  hw/intc/loongson_ipi.c| 355 +++---
>  hw/intc/loongson_ipi_common.c | 344 +
>  hw/loongarch/virt.c   |   4 +-
>  hw/rtc/ls7a_rtc.c |   2 +-
>  hw/intc/Kconfig   |   8 +
>  hw/intc/meson.build   |   2 +
>  hw/loongarch/Kconfig  |   2 +-
>  14 files changed, 570 insertions(+), 371 deletions(-)
>  create mode 100644 include/hw/intc/loongarch_ipi.h
>  create mode 100644 include/hw/intc/loongson_ipi_common.h
>  create mode 100644 hw/intc/loongarch_ipi.c
>  create mode 100644 hw/intc/loongson_ipi_common.c
>
> -- 
> 2.41.0

-- 
- Jiaxun



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

2024-07-17 Thread Jiaxun Yang



在2024年7月17日七月 下午5:22,maobibo写道:
> On 2024/7/16 下午2:40, Philippe Mathieu-Daudé wrote:
>> On 16/7/24 03:29, maobibo wrote:
>>>
>>>
>>> On 2024/7/16 上午9:04, maobibo wrote:


 On 2024/7/15 下午11:17, Philippe Mathieu-Daudé wrote:
> On 4/7/24 05:37, Bibo Mao wrote:
>> Now loongson ipi and loongarch ipi share the same code with different
>> macro, loongson ipi has its separate function such mmio region,
>> loongarch ipi has other requirement such as irqchip in kernel.
>>
>> Interrupt irqchip has strong relationship with architecture, since
>> it sends irq to vcpu and interfaces to get irqchip register is also
>> architecture specific.
>>
>> Here like other architectures, base class TYPE_LOONGSON_IPI_COMMON
>> is added, it comes from loongson ipi mostly. And it defined four 
>> abstract
>> interfaces which can be used for MIPS 3A4000 and Loongarch 3A5000 
>> machine,
>> also can be used for 3A5000 irqchip in kernel mode soon.
>>
>> Also Loongarch ipi and loongson ipi device are added here, it inherits
>> from base class TYPE_LOONGSON_IPI_COMMON. Loongarch ipi is tested,
>> loongson ipi device only passes to compile and make check, it is not
>> tested.
>>
>> Bibo Mao (4):
>>    hw/intc/loongson_ipi_common: Add loongson ipi common class
>>    hw/intc/loongarch_ipi: Add loongarch ipi support
>>    hw/loongarch/virt: Replace loongson ipi with loongarch ipi
>>    hw/intc/loongson_ipi: reconstruct driver inherit from common class
>
> I'll try to respin a clearer v3.
 I am ok with it since it solve the problem, and it is suitable for 
 9.1 release. Only that in the long time we hope that intc emulation 
 driver has common base class + tcg/kvm driver, similar with other 
 architecture.

>>> Sorry for the confusion, I had thought it was another topic.
>>>
>>> Thanks for pointing out the problem and welcome the v3 version.
>> 
>> Please do not post v3, let me post it.
> Hi Philippe,
>
> QEMU 9.1 is coming to soft frozen stage, do you have enough time working 
> on it?  Is it ok to use bugfix patch for 9.1 release version?

Bug fix is always qualified between soft freeze and release.

I tested the series for MIPS yesterday and can confirm it do work.

Will give my tags on v3.

Thanks

> https://lore.kernel.org/all/20240627125819.62779-2-phi...@linaro.org/
>
> After 9.1 is released, there will be enough time for patch v3.
>
> Regards
> Bibo, Mao

-- 
- Jiaxun



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

2024-07-09 Thread Jiaxun Yang



在2024年7月9日七月 下午8:04,maobibo写道:
> Hi Philippe/Jiaxun,
>
> Could you do me a favor giving a review about this patch?

Hi Bibo,

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

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

Thanks

>
> Regards
> Bibo Mao
>
> On 2024/7/4 上午11:37, Bibo Mao wrote:
>> Now loongson ipi and loongarch ipi share the same code with different
>> macro, loongson ipi has its separate function such mmio region,
>> loongarch ipi has other requirement such as irqchip in kernel.
>> 
>> Interrupt irqchip has strong relationship with architecture, since
>> it sends irq to vcpu and interfaces to get irqchip register is also
>> architecture specific.
>> 
>> Here like other architectures, base class TYPE_LOONGSON_IPI_COMMON
>> is added, it comes from loongson ipi mostly. And it defined four abstract
>> interfaces which can be used for MIPS 3A4000 and Loongarch 3A5000 machine,
>> also can be used for 3A5000 irqchip in kernel mode soon.
>> 
>> Also Loongarch ipi and loongson ipi device are added here, it inherits
>> from base class TYPE_LOONGSON_IPI_COMMON. Loongarch ipi is tested,
>> loongson ipi device only passes to compile and make check, it is not
>> tested.
>> 
>> Bibo Mao (4):
>>hw/intc/loongson_ipi_common: Add loongson ipi common class
>>hw/intc/loongarch_ipi: Add loongarch ipi support
>>hw/loongarch/virt: Replace loongson ipi with loongarch ipi
>>hw/intc/loongson_ipi: reconstruct driver inherit from common class
>> 
>>   hw/intc/Kconfig   |   3 +
>>   hw/intc/loongarch_ipi.c   |  80 ++
>>   hw/intc/loongson_ipi.c| 330 ++---
>>   hw/intc/loongson_ipi_common.c | 394 ++
>>   hw/intc/meson.build   |   3 +-
>>   hw/loongarch/Kconfig  |   2 +-
>>   hw/loongarch/virt.c   |   4 +-
>>   include/hw/intc/loongarch_ipi.h   |  33 +++
>>   include/hw/intc/loongson_ipi.h|  54 ++--
>>   include/hw/intc/loongson_ipi_common.h |  77 +
>>   include/hw/loongarch/virt.h   |   1 -
>>   11 files changed, 632 insertions(+), 349 deletions(-)
>>   create mode 100644 hw/intc/loongarch_ipi.c
>>   create mode 100644 hw/intc/loongson_ipi_common.c
>>   create mode 100644 include/hw/intc/loongarch_ipi.h
>>   create mode 100644 include/hw/intc/loongson_ipi_common.h
>> 
>> 
>> base-commit: 6746482d12da3b6e4d3cdf06481a0027a797f719
>>

-- 
- Jiaxun



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

2024-07-03 Thread Jiaxun Yang



在2024年7月3日七月 下午6:10,maobibo写道:
[...]
>>>
>>> Huacai, would you agree with me?
>> For me the important thing is consistency, all vm-features or all
>> vcpu-features are both accepted.
> To understand features immediately is difficult job for me. There is 
> supported features/used features usages etc, overall feature detection 
> should be VM relative by my knowledge.
>
> Maybe after host machine type and migration feature detection and 
> checking is finished, there will be further upstanding -:(

Do you agree with the scratch_vcpu approach? This seems to be the only
straight forward way to make some progress here.

Thanks
-- 
- Jiaxun



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

2024-07-03 Thread Jiaxun Yang



在2024年7月1日七月 下午2:57,Jiaxun Yang写道:
> 在2024年5月30日五月 上午7:49,Bibo Mao写道:
>> Loongson Binary Translation (LBT) is used to accelerate binary
>> translation, which contains 4 scratch registers (scr0 to scr3), x86/ARM
>> eflags (eflags) and x87 fpu stack pointer (ftop).
>>
>> Now LBT feature is added in kvm mode, not supported in TCG mode since
>> it is not emulated. Feature variable lbt is added with OnOffAuto type,
>> If lbt feature is not supported with KVM host, it reports error if there
>> is lbt=on command line.
>>
>> If there is no any command line about lbt parameter, it checks whether
>> KVM host supports lbt feature and set the corresponding value in cpucfg.
>>
>> Signed-off-by: Bibo Mao 
> Hi Bibo,
>
> I was going across recent LoongArch changes and this comes into my attention: 
>
>> ---
>>  target/loongarch/cpu.c| 53 +++
>>  target/loongarch/cpu.h|  6 +++
>>  target/loongarch/kvm/kvm.c| 26 +
>>  target/loongarch/kvm/kvm_loongarch.h  | 16 
>>  target/loongarch/loongarch-qmp-cmds.c |  2 +-
>>  5 files changed, 102 insertions(+), 1 deletion(-)
>>
>> diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
>> index b5c1ec94af..14265b6667 100644
>> --- a/target/loongarch/cpu.c
>> +++ b/target/loongarch/cpu.c
>> @@ -571,6 +571,30 @@ static void loongarch_cpu_disas_set_info(CPUState 
>> *s, disassemble_info *info)
>>  info->print_insn = print_insn_loongarch;
>>  }
>> 
>> +static void loongarch_cpu_check_lbt(CPUState *cs, Error **errp)
>> +{
>> +CPULoongArchState *env = cpu_env(cs);
>> +LoongArchCPU *cpu = LOONGARCH_CPU(cs);
>> +bool kvm_supported;
>> +
>> +kvm_supported = kvm_feature_supported(cs, LOONGARCH_FEATURE_LBT);
>
> IMHO if there is no global states that should be saved/restored VM wise,
> this should be handled at per CPU level, preferably with CPUCFG flags hint.
>
> We should minimize non-privilege KVM feature bits to prevent hindering
> asymmetry ISA system.

+ Huacai for further discussion

Hi Bibo, Huacai,

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

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

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

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

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

Huacai, would you agree with me?

Thanks
- Jiaxun

>
> Thanks
> - Jiaxun
>
> -- 
> - Jiaxun

-- 
- Jiaxun



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

2024-07-03 Thread Jiaxun Yang



在2024年7月3日七月 下午2:40,maobibo写道:
[...]
Hi Bobo,
>
> MMIO is loongson ipi specific, it is not necessary to put into common 
> function. Functions loongson_ipi_core_readl/loongson_ipi_core_writel can 
> be exported in header file include/hw/intc/loongson_ipi_common.h, or get 
> MemoryRegionOps of first memoryregion of loongson_ipi instance.
>
> There is pseudo code:

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

Do you mind to finish conversion of loongson_ipi as well? Since you are 
drafting the
design.

>
> static void loongson_ipi_realize(DeviceState *dev, Error **errp)
> {
>  LoongarchIPIState *s = LOONGARCH_IPI(dev);
>  LoongarchIPIClass *lic = LOONGARCH_IPI_GET_CLASS(s);
>  Error *local_err = NULL;
>
>  lic->parent_realize(dev, _err);
>  if (local_err) {
>  error_propagate(errp, local_err);
>  return;
>  }
>
>  
>  *do mmio specific implematation in loongson ipi itself*
> }
>
> static void loongson_ipi_class_init(ObjectClass *klass, void *data)
> {
>  DeviceClass *dc = DEVICE_CLASS(klass);
>  LoongsonIPICommonClass *licc = LOONGSON_IPI_COMMON_CLASS(klass);
>  LoongarchIPIClass *lic = LOONGARCH_IPI_CLASS(klass);
>
>  device_class_set_parent_realize(dc, loongson_ipi_realize, 
> >parent_realize);
>  licc->get_iocsr_as = get_iocsr_as;
> }
>
>> 
>> If current implementation is hindering your future plan can you elaborate so 
>> we
>> can work on a resolution.
>> 
>> I'm happy to help with devlopment and testing.
>> 
>>>   3. Interace cpu_by_arch_id is added, by default generic function
>>> cpu_by_arch_id() is used to search vcpu from physical cpuid, it is
>>> generic searching method. Different machine may define another search
>>> method such binary searching method.
>> 
>> If you are going to implement some faster searching algorithm why don't we
>>   make it generic for all architectures?
> It depends on the detailed physical id layout, is physical id is growing 
> up with logic cpu id or irrelative with logic cpu id? Different 
> architecture has different logic definition about physical id.

For x86' APIC id and RISC-V's hardid they are all somehow linear.
I'd suggest you to post a RFC patch regarding better algorithm.

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

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

2024-07-03 Thread Jiaxun Yang



在2024年7月3日七月 上午10:12,Bibo Mao写道:
> Loongson ipi common class and instance is created here, it comes
> from file loongson_ipi mostly. For the new added loongson ipi
> common class, there is four interfaces defined here:
>  1. Interfaces pre_save/post_load are used for future kvm child class
>  2. Interface get_iocsr_as can be used for different architectures,
> now MIPS 3A4000 and LoongArch 3A5000 machine use this ip, can inherit
> this common class.

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

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

I'm happy to help with devlopment and testing.

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

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

Thanks
- Jiaxun

>
> Signed-off-by: Bibo Mao 
> ---
>  hw/intc/loongson_ipi_common.c | 394 ++
>  include/hw/intc/loongson_ipi_common.h |  71 +
>  2 files changed, 465 insertions(+)
>  create mode 100644 hw/intc/loongson_ipi_common.c
>  create mode 100644 include/hw/intc/loongson_ipi_common.h
>
> diff --git a/hw/intc/loongson_ipi_common.c 
> b/hw/intc/loongson_ipi_common.c
> new file mode 100644
> index 00..f462f24f32
> --- /dev/null
> +++ b/hw/intc/loongson_ipi_common.c
> @@ -0,0 +1,394 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * Loongson ipi interrupt support
> + *
> + * Copyright (C) 2021 Loongson Technology Corporation Limited
> + */
> +
> +#include "qemu/osdep.h"
> +#include "hw/boards.h"
> +#include "hw/sysbus.h"
> +#include "hw/intc/loongson_ipi_common.h"
> +#include "hw/irq.h"
> +#include "hw/qdev-properties.h"
> +#include "qapi/error.h"
> +#include "qemu/log.h"
> +#include "exec/address-spaces.h"
> +#include "exec/memory.h"
> +#include "migration/vmstate.h"
> +#include "trace.h"
> +
> +static MemTxResult loongson_ipi_core_readl(void *opaque, hwaddr addr,
> +   uint64_t *data,
> +   unsigned size, MemTxAttrs 
> attrs)
> +{
> +IPICore *s = opaque;
> +uint64_t ret = 0;
> +int index = 0;
> +
> +addr &= 0xff;
> +switch (addr) {
> +case CORE_STATUS_OFF:
> +ret = s->status;
> +break;
> +case CORE_EN_OFF:
> +ret = s->en;
> +break;
> +case CORE_SET_OFF:
> +ret = 0;
> +break;
> +case CORE_CLEAR_OFF:
> +ret = 0;
> +break;
> +case CORE_BUF_20 ... CORE_BUF_38 + 4:
> +index = (addr - CORE_BUF_20) >> 2;
> +ret = s->buf[index];
> +break;
> +default:
> +qemu_log_mask(LOG_UNIMP, "invalid read: %x", (uint32_t)addr);
> +break;
> +}
> +
> +trace_loongson_ipi_read(size, (uint64_t)addr, ret);
> +*data = ret;
> +return MEMTX_OK;
> +}
> +
> +static MemTxResult loongson_ipi_iocsr_readl(void *opaque, hwaddr addr,
> +uint64_t *data,
> +unsigned size, MemTxAttrs 
> attrs)
> +{
> +LoongsonIPICommonState *ipi = opaque;
> +IPICore *s;
> +
> +if (attrs.requester_id >= ipi->num_cpu) {
> +return MEMTX_DECODE_ERROR;
> +}
> +
> +s = >cpu[attrs.requester_id];
> +return loongson_ipi_core_readl(s, addr, data, size, attrs);
> +}
> +
> +static MemTxResult send_ipi_data(LoongsonIPICommonState *ipi, CPUState 
> *cpu,
> + uint64_t val,
> + hwaddr addr, MemTxAttrs attrs)
> +{
> +int i, mask = 0, data = 0;
> +AddressSpace *iocsr_as;
> +LoongsonIPICommonClass *licc = LOONGSON_IPI_COMMON_GET_CLASS(ipi);
> +
> +iocsr_as = NULL;
> +if (licc->get_iocsr_as) {
> +iocsr_as = licc->get_iocsr_as(cpu);
> +}
> +
> +if (!iocsr_as) {
> +return MEMTX_DECODE_ERROR;
> +}
> +
> +/*
> + * bit 27-30 is mask for byte writing,
> + * if the mask is 0, we need not to do anything.
> + */
> +if ((val >> 27) & 0xf) {
> +data = address_space_ldl_le(iocsr_as, addr, attrs, NULL);
> +for (i = 0; i < 4; i++) {
> +/* get mask for byte writing */
> +if (val & (0x1 << (27 + i))) {
> +mask |= 0xff << (i * 8);
> +}
> +}
> +}
> +
> +data &= mask;
> +data |= (val >> 32) & ~mask;
> +address_space_stl_le(iocsr_as, addr, data, attrs, NULL);
> +
> +return MEMTX_OK;
> +}
> +
> +static CPUState *get_cpu_by_arch_id(LoongsonIPICommonState *ipi, 
> 

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

2024-07-01 Thread Jiaxun Yang



在2024年7月1日七月 上午8:32,maobibo写道:
[...]
>>>
>>> +static void loongarch_cpu_check_lbt(CPUState *cs, Error **errp)
>>> +{
>>> +CPULoongArchState *env = cpu_env(cs);
>>> +LoongArchCPU *cpu = LOONGARCH_CPU(cs);
>>> +bool kvm_supported;
>>> +
>>> +kvm_supported = kvm_feature_supported(cs, LOONGARCH_FEATURE_LBT);
>> 
>> IMHO if there is no global states that should be saved/restored VM wise,
>> this should be handled at per CPU level, preferably with CPUCFG flags hint.
>> 
>> We should minimize non-privilege KVM feature bits to prevent hindering
>> asymmetry ISA system.
> For "asymmetry ISA system", do you meaning some vcpus have LBT feature, 
> however some vcpus does have LBT features? That does not exists at all.

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

>From Weiwu's presentations, I believe LASX asymmetry product is already on the
roadmap. So for LBT it's also a possibility.

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

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

Affinity placement etc, there are many possibilities.

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

See: arm64: Allow mismatched 32-bit EL0 support

Thanks
>
> Regards
> Bibo
>> 
>> Thanks
>> - Jiaxun
>>

-- 
- Jiaxun



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

2024-07-01 Thread Jiaxun Yang



在2024年7月1日七月 上午8:22,maobibo写道:
> On 2024/7/1 下午3:01, Jiaxun Yang wrote:
>> 
>> 
>> 在2024年7月1日七月 上午7:44,maobibo写道:
>>> Also this patch is problematic on LoongArch.
>>>
>>> The original patch is to search physical cpuid rather than logic cpuid.
>>>
>>> We want to make ipi module better and better, however now it comes back
>>> to initial state at the beginning :(
>> 
>> Isn't arch_id the "physical id" you want? "cs->cpu_index" is the logical ID
>> for QEMU.
>> 
>> arch_id is setup by arch code, like APIC ID for x86.
>> 
>> I had come across the old ipi_getcpu  implementation, and I'm sure we were
>> looking at arch_id as well.
> So, where is implementation code for function get_arch_id() looking for 
> vcpu with physical index?

Hi Bibo,

cpu_by_arch_id will be redirected to:

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

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

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

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

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

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

Thanks

>
> Regards
> Bibo Mao
>
>> 
>> Thanks
>> - Jiaxun
>>>
>>> commit 03ca348b6b9038ce284916b36c19f700ac0ce7a6
>>> Author: Jiaxun Yang 
>>> Date:   Wed Jun 5 10:04:27 2024
>>>
>>>   hw/intc/loongson_ipi: Replace ipi_getcpu with cpu_by_arch_id
>>>
>>>   cpu_by_arch_id is doing the same thing as our ipi_getcpu logic.
>>>
>>>   Signed-off-by: Jiaxun Yang 
>>>   Reviewed-by: Song Gao 
>>>   Message-ID: <20240605-loongson3-ipi-v3-4-ddd2c0e03...@flygoat.com>
>>>   Signed-off-by: Philippe Mathieu-Daudé 
>>>
>>>
>>> Regards
>>> Bibo Mao
>>>

-- 
- Jiaxun



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

2024-07-01 Thread Jiaxun Yang



在2024年7月1日七月 上午2:35,maobibo写道:
[...]
>
> How about split loongson_ipi.c into 
> loongson_ipi_base.c/loongson_ipi_loongson.c/loongson_ipi_loongarch.c,
>
> File loongson_ipi_base.c contains the common code, loongson_ipi_xxx.c 
> contains arch specific. Soon we will submit irqchip in kernel function,
> it will be much different for architectures, since ioctl command is 
> different for two architectures to save/restore ipi registers.

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

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

Thanks
>
> Regards
> Bibo Mao

-- 
- Jiaxun



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

2024-07-01 Thread Jiaxun Yang



在2024年7月1日七月 上午7:44,maobibo写道:
> Also this patch is problematic on LoongArch.
>
> The original patch is to search physical cpuid rather than logic cpuid.
>
> We want to make ipi module better and better, however now it comes back 
> to initial state at the beginning :(

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

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

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

Thanks
- Jiaxun
>
> commit 03ca348b6b9038ce284916b36c19f700ac0ce7a6
> Author: Jiaxun Yang 
> Date:   Wed Jun 5 10:04:27 2024
>
>  hw/intc/loongson_ipi: Replace ipi_getcpu with cpu_by_arch_id
>
>  cpu_by_arch_id is doing the same thing as our ipi_getcpu logic.
>
>  Signed-off-by: Jiaxun Yang 
>  Reviewed-by: Song Gao 
>  Message-ID: <20240605-loongson3-ipi-v3-4-ddd2c0e03...@flygoat.com>
>  Signed-off-by: Philippe Mathieu-Daudé 
>
>
> Regards
> Bibo Mao
>
-- 
- Jiaxun



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

2024-07-01 Thread Jiaxun Yang



在2024年5月30日五月 上午7:49,Bibo Mao写道:
> Loongson Binary Translation (LBT) is used to accelerate binary
> translation, which contains 4 scratch registers (scr0 to scr3), x86/ARM
> eflags (eflags) and x87 fpu stack pointer (ftop).
>
> Now LBT feature is added in kvm mode, not supported in TCG mode since
> it is not emulated. Feature variable lbt is added with OnOffAuto type,
> If lbt feature is not supported with KVM host, it reports error if there
> is lbt=on command line.
>
> If there is no any command line about lbt parameter, it checks whether
> KVM host supports lbt feature and set the corresponding value in cpucfg.
>
> Signed-off-by: Bibo Mao 
Hi Bibo,

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

> ---
>  target/loongarch/cpu.c| 53 +++
>  target/loongarch/cpu.h|  6 +++
>  target/loongarch/kvm/kvm.c| 26 +
>  target/loongarch/kvm/kvm_loongarch.h  | 16 
>  target/loongarch/loongarch-qmp-cmds.c |  2 +-
>  5 files changed, 102 insertions(+), 1 deletion(-)
>
> diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
> index b5c1ec94af..14265b6667 100644
> --- a/target/loongarch/cpu.c
> +++ b/target/loongarch/cpu.c
> @@ -571,6 +571,30 @@ static void loongarch_cpu_disas_set_info(CPUState 
> *s, disassemble_info *info)
>  info->print_insn = print_insn_loongarch;
>  }
> 
> +static void loongarch_cpu_check_lbt(CPUState *cs, Error **errp)
> +{
> +CPULoongArchState *env = cpu_env(cs);
> +LoongArchCPU *cpu = LOONGARCH_CPU(cs);
> +bool kvm_supported;
> +
> +kvm_supported = kvm_feature_supported(cs, LOONGARCH_FEATURE_LBT);

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

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

Thanks
- Jiaxun

-- 
- Jiaxun



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

2024-06-27 Thread Jiaxun Yang



在2024年6月27日六月 下午4:13,gaosong写道:
> 在 2024/6/27 下午2:38, Philippe Mathieu-Daudé 写道:
>> On 27/6/24 06:13, Jiaxun Yang wrote:
>>> Signed-off-by: Jiaxun Yang 
>>> ---
>>> Jiaxun Yang (2):
>>>    hw/intc/loongson_ipi: Gate MMIO regions creation with property
>>>    MAINTAINERS: Add myself as a reviewer of LoongArch virt machine
>>
>> Maybe s/has-mmio/use-mmio/? Otherwise series:
>> Reviewed-by: Philippe Mathieu-Daudé 
>>
> Hi,
>
> If we had done a simple test, we should have found the following 
> problem, but obviously we didn't .

My bad, I’m currently traveling and sent that in rush.

I do boot tested with CI and I trust CI can catch those issues.


>
> root@loongson-KVM:~/work/code/clean/github/qemu# . /kernel.sh
> Unexpected error in object_property_find_err() at . /qom/object.c:1357.
> qemu-system-loongarch64: Property 'loongson_ipi.unnamed-gpio-out[0]' not 
> found
> . /kernel.sh: line 16: 117708 Aborted (core dumped) . 
> /build/qemu-system-loongarch64 -machine virt -m 8G -cpu la464 -smp 8 
> -kernel ~/vmlinux -initrd ramdisk -serial stdio -monitor 
> telnet:localhost. 4418,server,nowait -net nic -net user -device 
> virtio-gpu-pci -device nec-usb-xhci,id=xhci,addr=0x1b -device 
> usb-tablet,id=tablet,bus=xhci.0, port=1 -device 
> usb-tablet,id=tablet,bus=xhci.0, -device usb-tablet,id=tablet,bus=xhci. 
> port=1 -device usb-kbd,id=keyboard,bus=xhci.0,port=2 -append 
> "root=/dev/ram rdinit=/sbin/init console=ttyS0,115200 
> earlycon=uart,mmio. 0x1fe001e0" --nographic
>
>
> So to minimize interactions with the MIPS architecture, I'll submit a 
> patch to restore loongarch_ipi for LoongArch.
>
> Thanks.
> Song Gao

-- 
- Jiaxun



[PATCH 0/2] hw/intc/loongson_ipi: Fix for LoongArch

2024-06-26 Thread Jiaxun Yang
Signed-off-by: Jiaxun Yang 
---
Jiaxun Yang (2):
  hw/intc/loongson_ipi: Gate MMIO regions creation with property
  MAINTAINERS: Add myself as a reviewer of LoongArch virt machine

 MAINTAINERS|  1 +
 hw/intc/loongson_ipi.c | 23 ++-
 hw/mips/loongson3_virt.c   |  1 +
 include/hw/intc/loongson_ipi.h |  1 +
 4 files changed, 17 insertions(+), 9 deletions(-)
---
base-commit: 3f044554b94fc0756d5b3cdbf84501e0eea0e629
change-id: 20240627-ipi-fixes-13eaf1b8815a

Best regards,
-- 
Jiaxun Yang 




[PATCH 1/2] hw/intc/loongson_ipi: Gate MMIO regions creation with property

2024-06-26 Thread Jiaxun Yang
Commit 49eba52a52fe ("hw/intc/loongson_ipi: Provide per core MMIO address
spaces") implemented per core MMIO spaces for IPI registers.

However on LoongArch system emulation with high core count it may exhaust
QDEV_MAX_MMIO and trigger assertion.

Given that MMIO region is unused for LoongArch system emulation (we do have
it on hardware but kernel is in favor of IOCSR), gate MMIO regions creation
with "has-mmio" property and only set if for loongson3-virt machine to avoid
such limitation on LoongArch.

Reported-by: maobibo 
Signed-off-by: Jiaxun Yang 
---
 hw/intc/loongson_ipi.c | 23 ++-
 hw/mips/loongson3_virt.c   |  1 +
 include/hw/intc/loongson_ipi.h |  1 +
 3 files changed, 16 insertions(+), 9 deletions(-)

diff --git a/hw/intc/loongson_ipi.c b/hw/intc/loongson_ipi.c
index e6a7142480c6..6e92a503499a 100644
--- a/hw/intc/loongson_ipi.c
+++ b/hw/intc/loongson_ipi.c
@@ -305,15 +305,19 @@ static void loongson_ipi_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 
-for (i = 0; i < s->num_cpu; i++) {
-s->cpu[i].ipi = s;
-s->cpu[i].ipi_mmio_mem = g_new0(MemoryRegion, 1);
-g_autofree char *name = g_strdup_printf("loongson_ipi_cpu%d_mmio", i);
-memory_region_init_io(s->cpu[i].ipi_mmio_mem, OBJECT(dev),
-  _ipi_core_ops, >cpu[i], name, 0x48);
-sysbus_init_mmio(sbd, s->cpu[i].ipi_mmio_mem);
-
-qdev_init_gpio_out(dev, >cpu[i].irq, 1);
+if (s->has_mmio) {
+for (i = 0; i < s->num_cpu; i++) {
+s->cpu[i].ipi = s;
+s->cpu[i].ipi_mmio_mem = g_new0(MemoryRegion, 1);
+g_autofree char *name =
+g_strdup_printf("loongson_ipi_cpu%d_mmio", i);
+memory_region_init_io(s->cpu[i].ipi_mmio_mem, OBJECT(dev),
+  _ipi_core_ops, >cpu[i],
+  name, 0x48);
+sysbus_init_mmio(sbd, s->cpu[i].ipi_mmio_mem);
+
+qdev_init_gpio_out(dev, >cpu[i].irq, 1);
+}
 }
 }
 
@@ -344,6 +348,7 @@ static const VMStateDescription vmstate_loongson_ipi = {
 
 static Property ipi_properties[] = {
 DEFINE_PROP_UINT32("num-cpu", LoongsonIPI, num_cpu, 1),
+DEFINE_PROP_BOOL("has-mmio", LoongsonIPI, has_mmio, false),
 DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/mips/loongson3_virt.c b/hw/mips/loongson3_virt.c
index 4ad36f0c5b64..a27b30ab318c 100644
--- a/hw/mips/loongson3_virt.c
+++ b/hw/mips/loongson3_virt.c
@@ -537,6 +537,7 @@ static void mips_loongson3_virt_init(MachineState *machine)
 if (!kvm_enabled()) {
 ipi = qdev_new(TYPE_LOONGSON_IPI);
 qdev_prop_set_uint32(ipi, "num-cpu", machine->smp.cpus);
+qdev_prop_set_bit(ipi, "has-mmio", true);
 sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), _fatal);
 memory_region_add_subregion(iocsr, SMP_IPI_MAILBOX,
 sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 
0));
diff --git a/include/hw/intc/loongson_ipi.h b/include/hw/intc/loongson_ipi.h
index 3f795edbf3cd..0e35674e7aaf 100644
--- a/include/hw/intc/loongson_ipi.h
+++ b/include/hw/intc/loongson_ipi.h
@@ -50,6 +50,7 @@ struct LoongsonIPI {
 MemoryRegion ipi_iocsr_mem;
 MemoryRegion ipi64_iocsr_mem;
 uint32_t num_cpu;
+bool has_mmio;
 IPICore *cpu;
 };
 

-- 
2.43.0




[PATCH 2/2] MAINTAINERS: Add myself as a reviewer of LoongArch virt machine

2024-06-26 Thread Jiaxun Yang
I would like to be informed on changes made to the LoongArch virt machine.

I'm fairly familiar with Loongson-3 series platform hardware and doing
firmwre (U-Boot) development as hobbyist on LoongArch virt platform,
so I believe I can give positive review input to changes on that machine.

Signed-off-by: Jiaxun Yang 
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 19f67dc5d215..9a646ea58483 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1239,6 +1239,7 @@ LoongArch Machines
 --
 Virt
 M: Song Gao 
+R: Jiaxun Yang 
 S: Maintained
 F: docs/system/loongarch/virt.rst
 F: configs/targets/loongarch64-softmmu.mak

-- 
2.43.0




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

2024-06-26 Thread Jiaxun Yang



在2024年6月26日六月 上午8:51,maobibo写道:
> On 2024/6/26 下午3:40, Jiaxun Yang wrote:
>> 
>> 
>> 在2024年6月26日六月 上午5:11,maobibo写道:
>> [...]
>>> It is different with existing implementation.
>> What do you mean? Isn't this the actual hardware behaviour?
>> 
>>>
>>> With hw/intc/loongson_ipi.c, every vcpu has one ipi_mmio_mem, however on
>>> loongarch ipi machine, there is no ipi_mmio_mem memory region.
>>> So if machine has 256 vcpus, there will be 256 ipi_mmio_mem memory
>>> regions. In function sysbus_init_mmio(), memory region can not exceed
>>> QDEV_MAX_MMIO (32).  With so many memory regions, it slows down memory
>>> region search speed also.
>> Ouch, never thought about that before, but I think we can control the
>> registration of sysbus_mmio with a device property or even ifdef so LoongArch
>> machine won't be affected.
>> 
>> For MIPS loongson3-virt machine, our CPU number is capped, so that won't
>> be a problem.
>> 
>> I'm currently travelling without access to my PC, I'll prepare a patch
>> as soon as I gain access again. Feel free to send a patch before me with
>> this approach if you desperately want to fix it.
>> 
>>>
>>> void sysbus_init_mmio(SysBusDevice *dev, MemoryRegion *memory)
>>> {
>>>   int n;
>>>
>>>   assert(dev->num_mmio < QDEV_MAX_MMIO);
>>>   n = dev->num_mmio++;
>>>   dev->mmio[n].addr = -1;
>>>   dev->mmio[n].memory = memory;
>>> }
>>>
>>> Can we revert this patch? We want to do production usable by real users
>>> rather than show pure technology.
>> 
>> I don't really get your point, we have at leat 4 real users requesting SMP
>> support for loongson3-virt on gitlab issues, plus I need this to test
>> MIPS/Loongson64 SMP kernel.
>> 
>> If there is a problem with your use case, we can fix it. Why we do want to
>> remove the functionality when there is an easy fix?
> I do not think we have the ability to abstract hw and continuous 
> maintenance for two different architecture, including you and me.

After all it’s the same IP block, I fail to see any reason to implement it 
separately.

I perfectly understand that piece of hardware IP and I fix broken stuff in this 
driver time by time.

I understand how does it work on LoongArch systems so I make my best effort to 
cover LoongArch part.

There might be some edge cases that I missed, and I’ll be thankful for reports 
or assistance.

The approach of shared drivers for LoongArch/MIPS works so well in kernel 
development, for QEMU I believe it’s also desirable.

I’m not asking you or Loongson to maintain any MIPS/Loongson related features, 
I’ll take care of them if things go wrong.

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

If there is anything not clear to you on both MIPS and LoongArch side please 
let me know, I’m happy to help.

We promote code reuse in QEMU to minimize maintenance burden.

Thanks

>
> Regards
> Bibo Mao
>> 
>> It’s not only the features necessary for you that made QEMU an outstanding
>> project; it’s everything coming together that completes it.
>> 
>> Thanks
>> - Jiaxun
>>>
>>> Regards
>>> Bibo Mao
>>>
>>>> -
>>>> -s->cpu = g_new0(IPICore, s->num_cpu);
>>>> -if (s->cpu == NULL) {
>>>> -error_setg(errp, "Memory allocation for ExtIOICore faile");
>>>> -return;
>>>> -}
>>>> -
>>>> -for (i = 0; i < s->num_cpu; i++) {
>>>> -qdev_init_gpio_out(dev, >cpu[i].irq, 1);
>>>> -}
>>>> -}
>>>> -
>>>> -static const VMStateDescription vmstate_ipi_core = {
>>>> -.name = "ipi-single",
>>>> -.version_id = 2,
>>>> -.minimum_version_id = 2,
>>>> -.fields = (const VMStateField[]) {
>>>> -VMSTATE_UINT32(status, IPICore),
>>>> -VMSTATE_UINT32(en, IPICore),
>>>> -VMSTATE_UINT32(set, IPICore),
>>>> -VMSTATE_UINT32(clear, IPICore),
>>>> -VMSTATE_UINT32_ARRAY(buf, IPICore, IPI_MBX_NUM * 2),
>>>> -VMSTATE_END_OF_LIST()
>>>> -}
>>>> -};
>>>> -
>>>> -static const VMStateDescription vmstate_loongarch_ipi = {
>>>> -.name = TYPE_LOONGAR

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

2024-06-26 Thread Jiaxun Yang



在2024年6月26日六月 上午5:11,maobibo写道:
[...]
> It is different with existing implementation.
What do you mean? Isn't this the actual hardware behaviour?

>
> With hw/intc/loongson_ipi.c, every vcpu has one ipi_mmio_mem, however on 
> loongarch ipi machine, there is no ipi_mmio_mem memory region.
> So if machine has 256 vcpus, there will be 256 ipi_mmio_mem memory 
> regions. In function sysbus_init_mmio(), memory region can not exceed
> QDEV_MAX_MMIO (32).  With so many memory regions, it slows down memory
> region search speed also.
Ouch, never thought about that before, but I think we can control the
registration of sysbus_mmio with a device property or even ifdef so LoongArch
machine won't be affected.

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

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

>
> void sysbus_init_mmio(SysBusDevice *dev, MemoryRegion *memory)
> {
>  int n;
>
>  assert(dev->num_mmio < QDEV_MAX_MMIO);
>  n = dev->num_mmio++;
>  dev->mmio[n].addr = -1;
>  dev->mmio[n].memory = memory;
> }
>
> Can we revert this patch? We want to do production usable by real users 
> rather than show pure technology.

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

If there is a problem with your use case, we can fix it. Why we do want to
remove the functionality when there is an easy fix?

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

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

-- 
- Jiaxun



[PATCH v2 2/3] hw/mips/loongson3_virt: Fix condition of IPI IOCSR connection

2024-06-21 Thread Jiaxun Yang
This fixes Coverity CID-1547264.

Link: 
https://lore.kernel.org/qemu-devel/752417ad-ab72-4fed-8d1f-af41f15bc...@app.fastmail.com/
Signed-off-by: Jiaxun Yang 
---
 hw/mips/loongson3_virt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/mips/loongson3_virt.c b/hw/mips/loongson3_virt.c
index 69c1f2275838..24aa4dd04b18 100644
--- a/hw/mips/loongson3_virt.c
+++ b/hw/mips/loongson3_virt.c
@@ -574,7 +574,7 @@ static void mips_loongson3_virt_init(MachineState *machine)
 cpu_mips_clock_init(cpu);
 qemu_register_reset(main_cpu_reset, cpu);
 
-if (ipi) {
+if (!kvm_enabled()) {
 hwaddr base = ((hwaddr)node << 44) + virt_memmap[VIRT_IPI].base;
 base += core * 0x100;
 qdev_connect_gpio_out(ipi, i, cpu->env.irq[6]);

-- 
2.43.0




[PATCH v2 1/3] hw/mips/loongson3_virt: Store core_iocsr into LoongsonMachineState

2024-06-21 Thread Jiaxun Yang
Link: 
https://lore.kernel.org/qemu-devel/972034d6-23b3-415a-b401-b8bc1cc51...@linaro.org/
Suggested-by: Philippe Mathieu-Daudé 
Signed-off-by: Jiaxun Yang 
---
 hw/mips/loongson3_virt.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/hw/mips/loongson3_virt.c b/hw/mips/loongson3_virt.c
index 4ad36f0c5b64..69c1f2275838 100644
--- a/hw/mips/loongson3_virt.c
+++ b/hw/mips/loongson3_virt.c
@@ -97,6 +97,7 @@ struct LoongsonMachineState {
 MemoryRegion *pio_alias;
 MemoryRegion *mmio_alias;
 MemoryRegion *ecam_alias;
+MemoryRegion *core_iocsr[LOONGSON_MAX_VCPUS];
 };
 typedef struct LoongsonMachineState LoongsonMachineState;
 
@@ -493,6 +494,7 @@ static void mips_loongson3_virt_init(MachineState *machine)
 const char *kernel_filename = machine->kernel_filename;
 const char *initrd_filename = machine->initrd_filename;
 ram_addr_t ram_size = machine->ram_size;
+LoongsonMachineState *s = LOONGSON_MACHINE(machine);
 MemoryRegion *address_space_mem = get_system_memory();
 MemoryRegion *ram = g_new(MemoryRegion, 1);
 MemoryRegion *bios = g_new(MemoryRegion, 1);
@@ -586,6 +588,7 @@ static void mips_loongson3_virt_init(MachineState *machine)
  iocsr, 0, UINT32_MAX);
 memory_region_add_subregion(_CPU(cpu)->env.iocsr.mr,
 0, core_iocsr);
+s->core_iocsr[i] = core_iocsr;
 }
 
 if (node > 0) {

-- 
2.43.0




[PATCH v2 3/3] linux-user/mips64: Use MIPS64R2-generic as default CPU type

2024-06-21 Thread Jiaxun Yang
5KEf is some what not standard compliant by having non-functional
FCSR condition fields. This is causing glibc test failure in
qemu-user.

Use MIPS64R2-generic as our default type, which have maximum CPU
features.

Cc: sta...@vger.kernel.org
Signed-off-by: Jiaxun Yang 
---
 linux-user/mips64/target_elf.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/linux-user/mips64/target_elf.h b/linux-user/mips64/target_elf.h
index 5f2f2df29f7f..82bb7e8b1cbf 100644
--- a/linux-user/mips64/target_elf.h
+++ b/linux-user/mips64/target_elf.h
@@ -15,6 +15,6 @@ static inline const char *cpu_get_model(uint32_t eflags)
 if ((eflags & EF_MIPS_MACH) == EF_MIPS_MACH_5900) {
 return "R5900";
 }
-return "5KEf";
+return "MIPS64R2-generic";
 }
 #endif

-- 
2.43.0




[PATCH v2 0/3] MIPS misc patches

2024-06-21 Thread Jiaxun Yang
Signed-off-by: Jiaxun Yang 
---
Changes in v2:
- v1 was sent in mistake, b4 messed up with QEMU again
- Link to v1: 
https://lore.kernel.org/r/20240621-loongson3-ipi-follow-v1-0-c6e73f2b2...@flygoat.com

---
Jiaxun Yang (3):
  hw/mips/loongson3_virt: Store core_iocsr into LoongsonMachineState
  hw/mips/loongson3_virt: Fix condition of IPI IOCSR connection
  linux-user/mips64: Use MIPS64R2-generic as default CPU type

 hw/mips/loongson3_virt.c   | 5 -
 linux-user/mips64/target_elf.h | 2 +-
 2 files changed, 5 insertions(+), 2 deletions(-)
---
base-commit: 02d9c38236cf8c9826e5c5be61780ccb4ae0
change-id: 20240621-loongson3-ipi-follow-1f4919621882

Best regards,
-- 
Jiaxun Yang 




[PATCH 2/3] hw/mips/loongson3_virt: Fix condition of IPI IOCSR connection

2024-06-21 Thread Jiaxun Yang
This fixes Coverity CID-1547264.

Link: 
https://lore.kernel.org/qemu-devel/752417ad-ab72-4fed-8d1f-af41f15bc...@app.fastmail.com/
Signed-off-by: Jiaxun Yang 
---
 hw/mips/loongson3_virt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/mips/loongson3_virt.c b/hw/mips/loongson3_virt.c
index 528be84bf970..80e953512a85 100644
--- a/hw/mips/loongson3_virt.c
+++ b/hw/mips/loongson3_virt.c
@@ -575,7 +575,7 @@ static void mips_loongson3_virt_init(MachineState *machine)
 cpu_mips_clock_init(cpu);
 qemu_register_reset(main_cpu_reset, cpu);
 
-if (ipi) {
+if (!kvm_enabled()) {
 hwaddr base = ((hwaddr)node << 44) + virt_memmap[VIRT_IPI].base;
 base += core * 0x100;
 qdev_connect_gpio_out(ipi, i, cpu->env.irq[6]);

-- 
2.43.0




[PATCH 1/3] hw/mips/loongson3_virt: Store core_iocsr into LoongsonMachineState

2024-06-21 Thread Jiaxun Yang
Link: 
https://lore.kernel.org/qemu-devel/972034d6-23b3-415a-b401-b8bc1cc51...@linaro.org/
Suggested-by: Philippe Mathieu-Daudé 
Signed-off-by: Jiaxun Yang 
---
 hw/mips/loongson3_virt.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/hw/mips/loongson3_virt.c b/hw/mips/loongson3_virt.c
index 4ad36f0c5b64..528be84bf970 100644
--- a/hw/mips/loongson3_virt.c
+++ b/hw/mips/loongson3_virt.c
@@ -97,6 +97,7 @@ struct LoongsonMachineState {
 MemoryRegion *pio_alias;
 MemoryRegion *mmio_alias;
 MemoryRegion *ecam_alias;
+MemoryRegion *core_iocsr[LOONGSON_MAX_VCPUS];
 };
 typedef struct LoongsonMachineState LoongsonMachineState;
 
@@ -493,6 +494,8 @@ static void mips_loongson3_virt_init(MachineState *machine)
 const char *kernel_filename = machine->kernel_filename;
 const char *initrd_filename = machine->initrd_filename;
 ram_addr_t ram_size = machine->ram_size;
+MachineClass *mc = MACHINE_GET_CLASS(machine);
+LoongsonMachineState *s = LOONGSON_MACHINE(machine);
 MemoryRegion *address_space_mem = get_system_memory();
 MemoryRegion *ram = g_new(MemoryRegion, 1);
 MemoryRegion *bios = g_new(MemoryRegion, 1);
@@ -586,6 +589,7 @@ static void mips_loongson3_virt_init(MachineState *machine)
  iocsr, 0, UINT32_MAX);
 memory_region_add_subregion(_CPU(cpu)->env.iocsr.mr,
 0, core_iocsr);
+s->core_iocsr[i] = core_iocsr;
 }
 
 if (node > 0) {

-- 
2.43.0




[PATCH 3/3] linux-user/mips64: Use MIPS64R2-generic as default CPU type

2024-06-21 Thread Jiaxun Yang
5KEf is some what not standard compliant by having non-functional
FCSR condition fields. This is causing glibc test failure in
qemu-user.

Use MIPS64R2-generic as our default type, which have maximum CPU
features.

Cc: sta...@vger.kernel.org
Signed-off-by: Jiaxun Yang 
---
 linux-user/mips64/target_elf.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/linux-user/mips64/target_elf.h b/linux-user/mips64/target_elf.h
index 5f2f2df29f7f..82bb7e8b1cbf 100644
--- a/linux-user/mips64/target_elf.h
+++ b/linux-user/mips64/target_elf.h
@@ -15,6 +15,6 @@ static inline const char *cpu_get_model(uint32_t eflags)
 if ((eflags & EF_MIPS_MACH) == EF_MIPS_MACH_5900) {
 return "R5900";
 }
-return "5KEf";
+return "MIPS64R2-generic";
 }
 #endif

-- 
2.43.0




[PATCH 0/3] MIPS misc patches

2024-06-21 Thread Jiaxun Yang
Signed-off-by: Jiaxun Yang 
---
Jiaxun Yang (3):
  hw/mips/loongson3_virt: Store core_iocsr into LoongsonMachineState
  hw/mips/loongson3_virt: Fix condition of IPI IOCSR connection
  linux-user/mips64: Use MIPS64R2-generic as default CPU type

 hw/mips/loongson3_virt.c   | 6 +-
 linux-user/mips64/target_elf.h | 2 +-
 2 files changed, 6 insertions(+), 2 deletions(-)
---
base-commit: 02d9c38236cf8c9826e5c5be61780ccb4ae0
change-id: 20240621-loongson3-ipi-follow-1f4919621882

Best regards,
-- 
Jiaxun Yang 




Re: [PULL 65/76] hw/mips/loongson3_virt: Wire up loongson_ipi device

2024-06-20 Thread Jiaxun Yang



在2024年6月20日六月 下午8:50,Philippe Mathieu-Daudé写道:
[...]
> Do you mind posting a patch fixing it?

I'll prepare a series tomorrow with your comments on this patch before.

Thanks
- Jiaxun
>
>> +hwaddr base = ((hwaddr)node << 44) + virt_memmap[VIRT_IPI].base;
>> +base += core * 0x100;
>> +qdev_connect_gpio_out(ipi, i, cpu->env.irq[6]);
>> +sysbus_mmio_map(SYS_BUS_DEVICE(ipi), i + 2, base);
>> +}
>> +
>> +if (ase_lcsr_available(_CPU(cpu)->env)) {
>> +MemoryRegion *core_iocsr = g_new(MemoryRegion, 1);
>> +g_autofree char *name = g_strdup_printf("core%d_iocsr", i);
>> +memory_region_init_alias(core_iocsr, OBJECT(cpu), name,
>> + iocsr, 0, UINT32_MAX);
>> +memory_region_add_subregion(_CPU(cpu)->env.iocsr.mr,
>> +0, core_iocsr);
>> +}
>> +
>> +if (node > 0) {
>>   continue; /* Only node-0 can be connected to LIOINTC */
>>   }
>>   
>>   for (ip = 0; ip < 4 ; ip++) {
>> -int pin = i * 4 + ip;
>> +int pin = core * LOONGSON3_CORE_PER_NODE + ip;
>>   sysbus_connect_irq(SYS_BUS_DEVICE(liointc),
>>  pin, cpu->env.irq[ip + 2]);
>>   }

-- 
- Jiaxun



Re: [PATCH 3/4] hw/m68k/virt: Add a pflash controller for BIOS firmware

2024-06-18 Thread Jiaxun Yang



在2024年6月18日六月 下午12:47,Philippe Mathieu-Daudé写道:
> Hi Jiaxun,
>
> On 27/5/24 19:15, Jiaxun Yang wrote:
>> Add a 8 MiB pflash controller for BIOS firmware, and boot
>> from it if possible.
>> 
>> Signed-off-by: Jiaxun Yang 
>> ---
>>   hw/m68k/Kconfig   |  1 +
>>   hw/m68k/virt.c| 44 
>> +++
>>   include/standard-headers/asm-m68k/bootinfo-virt.h |  1 +
>>   3 files changed, 46 insertions(+)
>> 
>> diff --git a/hw/m68k/Kconfig b/hw/m68k/Kconfig
>> index 4501da56ff6d..f233a5948f19 100644
>> --- a/hw/m68k/Kconfig
>> +++ b/hw/m68k/Kconfig
>> @@ -42,6 +42,7 @@ config M68K_VIRT
>>   select M68K_IRQC
>>   select FW_CFG_DMA
>>   select VIRT_CTRL
>> +select PFLASH_CFI01
>>   select GOLDFISH_PIC
>>   select GOLDFISH_TTY
>>   select GOLDFISH_RTC
>> diff --git a/hw/m68k/virt.c b/hw/m68k/virt.c
>> index 7590e6515ac3..a2eebc0f2243 100644
>> --- a/hw/m68k/virt.c
>> +++ b/hw/m68k/virt.c
>> @@ -8,6 +8,7 @@
>>*/
>>   
>>   #include "qemu/osdep.h"
>> +#include "qemu/datadir.h"
>>   #include "qemu/units.h"
>>   #include "qemu/guest-random.h"
>>   #include "sysemu/sysemu.h"
>> @@ -28,6 +29,7 @@
>>   #include "sysemu/runstate.h"
>>   #include "sysemu/reset.h"
>>   
>> +#include "hw/block/flash.h"
>>   #include "hw/intc/m68k_irqc.h"
>>   #include "hw/misc/virt_ctrl.h"
>>   #include "hw/char/goldfish_tty.h"
>> @@ -97,6 +99,10 @@
>>   #define VIRT_XHCI_MMIO_BASE 0xff02/* MMIO: 0xff02 - 0xff023fff 
>> */
>>   #define VIRT_XHCI_IRQ_BASE  PIC_IRQ(1, 2) /* PIC: #1, IRQ: #2 */
>>   
>> +#define VIRT_PFLASH_MMIO_BASE 0xff80  /* MMIO: 0xff80 - 
>> 0x */
>> +#define VIRT_PFLASH_SIZE  0x80/* 8 MiB */
>
> Do you need a real RW pflash or a ROM would be enough?

U-Boot needs somewhere to store env vars :-(
Probably a NVRAM would fit the purpose?

Thanks

>

-- 
- Jiaxun



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

2024-06-14 Thread Jiaxun Yang



在2024年6月14日六月 上午6:17,maobibo写道:
> On 2024/6/14 下午12:27, Jiaxun Yang wrote:
>> 
>> 
>> 在2024年6月14日六月 上午4:32,maobibo写道:
>>> It is interesting.
>>>
>>> How to wakeup VM if it sleeps in S3/S4, from emulated keyboard or
>>> ethernet magic packet or qemu monitor command in background?
>> 
>> Hi Bibo,
>> 
>> The best way to wake the guest is system_wakeup command in monitor.
> Ok, I see.
>
> It is useful and it can be used to test S3/S4 in TCG mode at least.
>
> Can we add feature capability, enabled in TCG mode, disabled in KVM mode 
> by default? If vm deploys in cloud, users in general help it is power-on 
> always.

Well, I think we should align both machines as much as possible.

It's also enabled for KVM on x86 piix4 and q35 machines.

Thanks
>
> Regards
> Bibo Mao
-- 
- Jiaxun



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

2024-06-13 Thread Jiaxun Yang



在2024年6月14日六月 上午4:32,maobibo写道:
> It is interesting.
>
> How to wakeup VM if it sleeps in S3/S4, from emulated keyboard or 
> ethernet magic packet or qemu monitor command in background?

Hi Bibo,

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

Thanks
- Jiaxun

>
> Regards
> Bibo Mao
>
>
> On 2024/6/14 上午1:30, Jiaxun Yang wrote:
>> Hi all,
>> 
>> This series implemented S3 and S4 sleep for loongarch virt machine
>> and microvm.
>> 
>> For loongarch/virt a kernel patch is requried [1].
>> 
>> [1]: 
>> https://lore.kernel.org/loongarch/20240613-loongarch64-sleep-v1-0-a245232af...@flygoat.com/
>> 
>> Please review.
>> Thanks
>> 
>> Signed-off-by: Jiaxun Yang 
>> ---
>> Jiaxun Yang (3):
>>acpi/ged: Implement S3 and S4 sleep
>>hw/loongarch/virt: Wire up S3 and S4 sleep
>>hw/i386/microvm: Wire up S3 and S4 sleep
>> 
>>   hw/acpi/generic_event_device.c | 70 
>> ++
>>   hw/i386/acpi-microvm.c | 18 +
>>   hw/i386/microvm.c  |  3 ++
>>   hw/loongarch/acpi-build.c  | 18 +
>>   hw/loongarch/virt.c|  3 ++
>>   include/hw/acpi/generic_event_device.h | 12 +-
>>   6 files changed, 115 insertions(+), 9 deletions(-)
>> ---
>> base-commit: f3e8cc47de2bc537d4991e883a85208e4e1c0f98
>> change-id: 20240613-loongarch64-sleep-37b2466b8d76
>> 
>> Best regards,
>>

-- 
- Jiaxun



[PATCH 1/3] acpi/ged: Implement S3 and S4 sleep

2024-06-13 Thread Jiaxun Yang
Implement S3 and S4 sleep with ACPI_GED_REG_SLEEP_CTL.SLP_TYP
writes.

Implement wakeup callback and WAK_STS register to inform guest
about current states.

All new functions are gated by "slp-typs" property, it is defaulted
to S5 only and machines can opt-in for S3 and S4.

Signed-off-by: Jiaxun Yang 
---
 hw/acpi/generic_event_device.c | 70 ++
 include/hw/acpi/generic_event_device.h | 12 +-
 2 files changed, 73 insertions(+), 9 deletions(-)

diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
index 2d6e91b124e5..f1fc99c04011 100644
--- a/hw/acpi/generic_event_device.c
+++ b/hw/acpi/generic_event_device.c
@@ -11,6 +11,7 @@
 
 #include "qemu/osdep.h"
 #include "qapi/error.h"
+#include "qapi/qapi-events-run-state.h"
 #include "hw/acpi/acpi.h"
 #include "hw/acpi/generic_event_device.h"
 #include "hw/irq.h"
@@ -186,24 +187,53 @@ static const MemoryRegionOps ged_evt_ops = {
 
 static uint64_t ged_regs_read(void *opaque, hwaddr addr, unsigned size)
 {
+GEDState *ged_st = opaque;
+
+switch (addr) {
+case ACPI_GED_REG_SLEEP_STS:
+return ged_st->sleep_sts;
+default:
+break;
+}
+
 return 0;
 }
 
 static void ged_regs_write(void *opaque, hwaddr addr, uint64_t data,
unsigned int size)
 {
-bool slp_en;
-int slp_typ;
+GEDState *ged_st = opaque;
+AcpiGedState *s = container_of(ged_st, AcpiGedState, ged_state);
 
 switch (addr) {
 case ACPI_GED_REG_SLEEP_CTL:
-slp_typ = (data >> 2) & 0x07;
-slp_en  = (data >> 5) & 0x01;
-if (slp_en && slp_typ == 5) {
-qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
+if (data & ACPI_GED_SLP_EN) {
+switch (extract8(data, 2, 3)) {
+case ACPI_GED_SLP_TYP_S3:
+if (s->slp_typs_bitmap & (1 << ACPI_GED_SLP_TYP_S3)) {
+qemu_system_suspend_request();
+}
+break;
+case ACPI_GED_SLP_TYP_S4:
+if (s->slp_typs_bitmap & (1 << ACPI_GED_SLP_TYP_S4)) {
+qapi_event_send_suspend_disk();
+
qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
+}
+break;
+case ACPI_GED_SLP_TYP_S5:
+if (s->slp_typs_bitmap & (1 << ACPI_GED_SLP_TYP_S5)) {
+
qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
+}
+break;
+default:
+break;
+}
 }
 return;
 case ACPI_GED_REG_SLEEP_STS:
+if (data & ACPI_GED_WAK_STS) {
+ged_st->sleep_sts &= ~ACPI_GED_WAK_STS;
+}
 return;
 case ACPI_GED_REG_RESET:
 if (data == ACPI_GED_RESET_VALUE) {
@@ -223,6 +253,14 @@ static const MemoryRegionOps ged_regs_ops = {
 },
 };
 
+static void acpi_ged_notify_wakeup(Notifier *notifier, void *data)
+{
+GEDState *ged_st = container_of(notifier, GEDState, wakeup);
+
+ged_st->sleep_sts |= ACPI_GED_WAK_STS;
+}
+
+
 static void acpi_ged_device_plug_cb(HotplugHandler *hotplug_dev,
 DeviceState *dev, Error **errp)
 {
@@ -305,6 +343,8 @@ static void acpi_ged_send_event(AcpiDeviceIf *adev, 
AcpiEventStatusBits ev)
 
 static Property acpi_ged_properties[] = {
 DEFINE_PROP_UINT32("ged-event", AcpiGedState, ged_event_bitmap, 0),
+DEFINE_PROP_UINT32("slp-typs", AcpiGedState, slp_typs_bitmap,
+(1 << ACPI_GED_SLP_TYP_S5)),
 DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -320,10 +360,11 @@ static const VMStateDescription vmstate_memhp_state = {
 
 static const VMStateDescription vmstate_ged_state = {
 .name = "acpi-ged-state",
-.version_id = 1,
-.minimum_version_id = 1,
+.version_id = 2,
+.minimum_version_id = 2,
 .fields = (const VMStateField[]) {
 VMSTATE_UINT32(sel, GEDState),
+VMSTATE_UINT8(sleep_sts, GEDState),
 VMSTATE_END_OF_LIST()
 }
 };
@@ -371,6 +412,18 @@ static const VMStateDescription vmstate_acpi_ged = {
 }
 };
 
+static void acpi_ged_realize(DeviceState *dev, Error **errp)
+{
+AcpiGedState *s = ACPI_GED(dev);
+GEDState *ged_st = >ged_state;
+
+if (s->slp_typs_bitmap & (1 << ACPI_GED_SLP_TYP_S3)) {
+ged_st->wakeup.notify = acpi_ged_notify_wakeup;
+qemu_register_wakeup_notifier(_st->wakeup);
+qemu_register_wakeup_support();
+}
+}
+
 static void acpi_ged_initfn(Object *obj)
 {
 DeviceState *dev = DEVICE(obj);
@@ -409,6 +462,7 @@ static void acpi_ged_class_init(ObjectClass *class, void 
*data)
 AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_CLASS(class);
 
 dc->desc = 

[PATCH 2/3] hw/loongarch/virt: Wire up S3 and S4 sleep

2024-06-13 Thread Jiaxun Yang
Wire up S3 and S4 sleep by setting relevant slp-typs bits for
GED and generate _S3 and _S4 methods in acpi table.

Signed-off-by: Jiaxun Yang 
---
 hw/loongarch/acpi-build.c | 18 ++
 hw/loongarch/virt.c   |  3 +++
 2 files changed, 21 insertions(+)

diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c
index af45ce526d6e..2cb1696b579b 100644
--- a/hw/loongarch/acpi-build.c
+++ b/hw/loongarch/acpi-build.c
@@ -416,6 +416,24 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, 
MachineState *machine)
 acpi_dsdt_add_tpm(dsdt, lvms);
 #endif
 /* System State Package */
+scope = aml_scope("\\");
+pkg = aml_package(4);
+aml_append(pkg, aml_int(ACPI_GED_SLP_TYP_S3));
+aml_append(pkg, aml_int(0)); /* ignored */
+aml_append(pkg, aml_int(0)); /* reserved */
+aml_append(pkg, aml_int(0)); /* reserved */
+aml_append(scope, aml_name_decl("_S3", pkg));
+aml_append(dsdt, scope);
+
+scope = aml_scope("\\");
+pkg = aml_package(4);
+aml_append(pkg, aml_int(ACPI_GED_SLP_TYP_S4));
+aml_append(pkg, aml_int(0)); /* ignored */
+aml_append(pkg, aml_int(0)); /* reserved */
+aml_append(pkg, aml_int(0)); /* reserved */
+aml_append(scope, aml_name_decl("_S4", pkg));
+aml_append(dsdt, scope);
+
 scope = aml_scope("\\");
 pkg = aml_package(4);
 aml_append(pkg, aml_int(ACPI_GED_SLP_TYP_S5));
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 66cef201abe0..a4b55f00a32b 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -615,6 +615,9 @@ static DeviceState *create_acpi_ged(DeviceState *pch_pic,
 }
 dev = qdev_new(TYPE_ACPI_GED);
 qdev_prop_set_uint32(dev, "ged-event", event);
+qdev_prop_set_uint32(dev, "slp-typs", (1 << ACPI_GED_SLP_TYP_S3) |
+ (1 << ACPI_GED_SLP_TYP_S4) |
+ (1 << ACPI_GED_SLP_TYP_S5));
 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), _fatal);
 
 /* ged event */

-- 
2.43.0




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

2024-06-13 Thread Jiaxun Yang
Hi all,

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

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

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

Please review.
Thanks

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

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

Best regards,
-- 
Jiaxun Yang 




[PATCH 3/3] hw/i386/microvm: Wire up S3 and S4 sleep

2024-06-13 Thread Jiaxun Yang
Wire up S3 and S4 sleep by setting relevant slp-typs bits for
GED and generate _S3 and _S4 methods in acpi table.

Signed-off-by: Jiaxun Yang 
---
 hw/i386/acpi-microvm.c | 18 ++
 hw/i386/microvm.c  |  3 +++
 2 files changed, 21 insertions(+)

diff --git a/hw/i386/acpi-microvm.c b/hw/i386/acpi-microvm.c
index 279da6b4aa2f..7564de2b343b 100644
--- a/hw/i386/acpi-microvm.c
+++ b/hw/i386/acpi-microvm.c
@@ -129,6 +129,24 @@ build_dsdt_microvm(GArray *table_data, BIOSLinker *linker,
 aml_append(dsdt, sb_scope);
 
 /* ACPI 5.0: Table 7-209 System State Package */
+scope = aml_scope("\\");
+pkg = aml_package(4);
+aml_append(pkg, aml_int(ACPI_GED_SLP_TYP_S3));
+aml_append(pkg, aml_int(0)); /* ignored */
+aml_append(pkg, aml_int(0)); /* reserved */
+aml_append(pkg, aml_int(0)); /* reserved */
+aml_append(scope, aml_name_decl("_S3", pkg));
+aml_append(dsdt, scope);
+
+scope = aml_scope("\\");
+pkg = aml_package(4);
+aml_append(pkg, aml_int(ACPI_GED_SLP_TYP_S4));
+aml_append(pkg, aml_int(0)); /* ignored */
+aml_append(pkg, aml_int(0)); /* reserved */
+aml_append(pkg, aml_int(0)); /* reserved */
+aml_append(scope, aml_name_decl("_S4", pkg));
+aml_append(dsdt, scope);
+
 scope = aml_scope("\\");
 pkg = aml_package(4);
 aml_append(pkg, aml_int(ACPI_GED_SLP_TYP_S5));
diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c
index fec63cacfa88..b9fb2d28e570 100644
--- a/hw/i386/microvm.c
+++ b/hw/i386/microvm.c
@@ -206,6 +206,9 @@ static void microvm_devices_init(MicrovmMachineState *mms)
 if (x86_machine_is_acpi_enabled(x86ms)) {
 DeviceState *dev = qdev_new(TYPE_ACPI_GED);
 qdev_prop_set_uint32(dev, "ged-event", ACPI_GED_PWR_DOWN_EVT);
+qdev_prop_set_uint32(dev, "slp-typs", (1 << ACPI_GED_SLP_TYP_S3) |
+ (1 << ACPI_GED_SLP_TYP_S4) |
+ (1 << ACPI_GED_SLP_TYP_S5));
 sysbus_realize(SYS_BUS_DEVICE(dev), _fatal);
 sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, GED_MMIO_BASE);
 /* sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, GED_MMIO_BASE_MEMHP); */

-- 
2.43.0




Re: [PATCH v3 0/4] hw/mips/loongson3_virt: Implement IPI support

2024-06-12 Thread Jiaxun Yang
在2024年6月5日六月 上午3:15,Jiaxun Yang写道:
> Hi all,
>
> This series enabled IPI support for loongson3 virt board, loosely
> based on my previous work[1].
> It generalized loongarch_ipi device to share among both loongarch
> and MIPS machines. 
>
> Thanks

A genttle ping :-)

Thanks
- Jiaxun

>
> [1]: 
> https://lore.kernel.org/all/20230521102307.87081-1-jiaxun.y...@flygoat.com/
>
> To: qemu-devel@nongnu.org
> Cc: Song Gao 
>
> Signed-off-by: Jiaxun Yang 
> ---
> Changes in v3:
> - Fix up sign off lines.
> - Link to v2: 
> https://lore.kernel.org/r/20240605-loongson3-ipi-v2-0-da26282e0...@flygoat.com
>
> Changes in v2:
> - Add a patch to remove loongarch_ipi.c (Gao)
> - Change iocsr alias owner to CPU (philmd)
> - New patch to remove ipi_getcpu
> - Link to v1: 
> https://lore.kernel.org/r/20240508-loongson3-ipi-v1-0-1a7b67704...@flygoat.com
>
> ---
> Jiaxun Yang (4):
>   hw/intc: Remove loongarch_ipi.c
>   hw/intc/loongson_ipi: Provide per core MMIO address spaces
>   hw/mips/loongson3_virt: Wire up loongson_ipi device
>   hw/intc/loongson_ipi: Replace ipi_getcpu with cpu_by_arch_id
>
>  hw/intc/loongarch_ipi.c| 347 
> -
>  hw/intc/loongson_ipi.c | 120 +++---
>  hw/mips/Kconfig|   1 +
>  hw/mips/loongson3_bootp.c  |   2 -
>  hw/mips/loongson3_bootp.h  |   3 +
>  hw/mips/loongson3_virt.c   |  39 -
>  include/hw/intc/loongson_ipi.h |   2 +
>  7 files changed, 108 insertions(+), 406 deletions(-)
> ---
> base-commit: d67a6e054b92e5e1cbb7b0bd5782a670cc7f0df7
> change-id: 20240508-loongson3-ipi-65e99b47c400
>
> Best regards,
> -- 
> Jiaxun Yang 

-- 
- Jiaxun



Re: [PATCH] mips64el-softmmu: Enable MTTCG

2024-06-07 Thread Jiaxun Yang



在2024年6月5日六月 下午1:47,Jiaxun Yang写道:
[...]
> I'll try to upgrade kernel used in this test.

Unfortunately, we don't have kernel build from reliable source
for that test.

I requested Debian project to build kernel for us[1].

[1]: https://salsa.debian.org/kernel-team/linux/-/merge_requests/1074

Thanks
>
> Thanks
> - Jiaxun
>>
[...]
>
> -- 
> - Jiaxun

-- 
- Jiaxun



Re: [PATCH] mips64el-softmmu: Enable MTTCG

2024-06-05 Thread Jiaxun Yang



在2024年6月4日六月 下午1:43,Alex Bennée写道:
[...]
>
> I'm a little uncomfortable about making the success of MTTCG depend on
> the user options passed to the kernel.

Yes, I agree, it sounds awkward.

>
> How come a non-icount run depends on how many instructions are being run
> on each core? Why is time not based on the wallclock time and by
> definition synced between all cores?

That's the problem of Guest Kernel, the synchronisation mechanism is poorly
written that relies on instruction latency too much. I have patch pending to
improve it at guest side, but we can't fix it in existing binary.

This clock, CP0_Counter, as per ISA spec, is independent between cores and
needs to be synchronized by software. We can emulate it as a monotonic clock
source and Linux should be happy with it, but that is violating ISA spec.

>
>> In non-MTTCG build, the execution is slow enough so kernel won't
>> observe back drifts.
>>
>> Test results:
>>
>> With clocksource=MIPS
>> ```
>>  ~/tmp/retry/retry.py -n 100 -c -- ./qemu-system-mips64el \
>> -display none -vga none -serial mon:stdio \
>> -machine malta -kernel ./vmlinux-4.7.0-rc1.I6400 \
>> -cpu I6400 -smp 8 -vga std \
>> -append "printk.time=0 clocksource=MIPS console=tty0 console=ttyS0 
>> panic=-1" \
>> --no-reboot
>>
>> 100, 0, PASS, 5.258126, 100, 100, -
>> Results summary:
>> 0: 100 times (100.00%), avg time 6.508 (55.53 varience/7.45 deviation)
>> Ran command 100 times, 100 passes
>> ```
>>
>> With linux-next:
>> ```
>>  ~/tmp/retry/retry.py -n 100 -c -- ./qemu-system-mips64el \
>> -display none -vga none -serial mon:stdio \
>> -machine malta -kernel ~/linux-next/vmlinux \
>> -cpu I6400 -smp 8 -vga std \
>> -append "printk.time=0 console=tty0 console=ttyS0 panic=-1" \
>> --no-reboot
>>
>> 100, 0, PASS, 4.507921, 100, 100, -
>> Results summary:
>> 0: 100 times (100.00%), avg time 4.233 (0.04 varience/0.21 deviation)
>> Ran command 100 times, 100 passes
>> ```
>>
>> Signed-off-by: Jiaxun Yang 
>> ---
>> I'll leave the test case alone as it's already marked as
>> QEMU_TEST_FLAKY_TESTS
>
> We should ensure we have some testing enabled if we switch this on. Was
> the FLAKY test marked for MTTCG issues or something else?

Tracking history, I think it was because this issue is still popping up after
disabling MTTCG.

I'll try to upgrade kernel used in this test.

Thanks
- Jiaxun
>
>> ---
>>  configs/targets/mips64el-softmmu.mak | 1 +
>>  1 file changed, 1 insertion(+)
>>
>> diff --git a/configs/targets/mips64el-softmmu.mak 
>> b/configs/targets/mips64el-softmmu.mak
>> index 8d9ab3ddc4b1..199b1d909a7d 100644
>> --- a/configs/targets/mips64el-softmmu.mak
>> +++ b/configs/targets/mips64el-softmmu.mak
>> @@ -1,3 +1,4 @@
>>  TARGET_ARCH=mips64
>>  TARGET_BASE_ARCH=mips
>> +TARGET_SUPPORTS_MTTCG=y
>>  TARGET_NEED_FDT=y
>>
>> ---
>> base-commit: 248f6f62df073a3b4158fd0093863ab885feabb5
>> change-id: 20240511-mips_mttcg-47a6b19074b3
>>
>> Best regards,
>
> -- 
> Alex Bennée
> Virtualisation Tech Lead @ Linaro

-- 
- Jiaxun



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

2024-06-04 Thread Jiaxun Yang
It was missed out in previous commit.

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

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

[PATCH v3 4/4] hw/intc/loongson_ipi: Replace ipi_getcpu with cpu_by_arch_id

2024-06-04 Thread Jiaxun Yang
cpu_by_arch_id is doing the same thing as our ipi_getcpu logic.

Signed-off-by: Jiaxun Yang 
---
 hw/intc/loongson_ipi.c | 39 +++
 1 file changed, 3 insertions(+), 36 deletions(-)

diff --git a/hw/intc/loongson_ipi.c b/hw/intc/loongson_ipi.c
index c8a25b4eb8e2..b3cda5972793 100644
--- a/hw/intc/loongson_ipi.c
+++ b/hw/intc/loongson_ipi.c
@@ -118,39 +118,6 @@ static MemTxResult send_ipi_data(CPUState *cpu, uint64_t 
val, hwaddr addr,
 return MEMTX_OK;
 }
 
-static int archid_cmp(const void *a, const void *b)
-{
-   CPUArchId *archid_a = (CPUArchId *)a;
-   CPUArchId *archid_b = (CPUArchId *)b;
-
-   return archid_a->arch_id - archid_b->arch_id;
-}
-
-static CPUArchId *find_cpu_by_archid(MachineState *ms, uint32_t id)
-{
-CPUArchId apic_id, *found_cpu;
-
-apic_id.arch_id = id;
-found_cpu = bsearch(_id, ms->possible_cpus->cpus,
-ms->possible_cpus->len, sizeof(*ms->possible_cpus->cpus),
-archid_cmp);
-
-return found_cpu;
-}
-
-static CPUState *ipi_getcpu(int arch_id)
-{
-MachineState *machine = MACHINE(qdev_get_machine());
-CPUArchId *archid;
-
-archid = find_cpu_by_archid(machine, arch_id);
-if (archid) {
-return CPU(archid->cpu);
-}
-
-return NULL;
-}
-
 static MemTxResult mail_send(uint64_t val, MemTxAttrs attrs)
 {
 uint32_t cpuid;
@@ -158,7 +125,7 @@ static MemTxResult mail_send(uint64_t val, MemTxAttrs attrs)
 CPUState *cs;
 
 cpuid = extract32(val, 16, 10);
-cs = ipi_getcpu(cpuid);
+cs = cpu_by_arch_id(cpuid);
 if (cs == NULL) {
 return MEMTX_DECODE_ERROR;
 }
@@ -176,7 +143,7 @@ static MemTxResult any_send(uint64_t val, MemTxAttrs attrs)
 CPUState *cs;
 
 cpuid = extract32(val, 16, 10);
-cs = ipi_getcpu(cpuid);
+cs = cpu_by_arch_id(cpuid);
 if (cs == NULL) {
 return MEMTX_DECODE_ERROR;
 }
@@ -227,7 +194,7 @@ static MemTxResult loongson_ipi_core_writel(void *opaque, 
hwaddr addr,
 cpuid = extract32(val, 16, 10);
 /* IPI status vector */
 vector = extract8(val, 0, 5);
-cs = ipi_getcpu(cpuid);
+cs = cpu_by_arch_id(cpuid);
 if (cs == NULL || cs->cpu_index >= ipi->num_cpu) {
 return MEMTX_DECODE_ERROR;
 }

-- 
2.43.0




[PATCH v3 3/4] hw/mips/loongson3_virt: Wire up loongson_ipi device

2024-06-04 Thread Jiaxun Yang
Wire up loongson_ipi device for loongson3_virt machine, so we
can have SMP support for TCG backend as well.

Signed-off-by: Jiaxun Yang 
---
 hw/mips/Kconfig   |  1 +
 hw/mips/loongson3_bootp.c |  2 --
 hw/mips/loongson3_bootp.h |  3 +++
 hw/mips/loongson3_virt.c  | 39 +--
 4 files changed, 41 insertions(+), 4 deletions(-)

diff --git a/hw/mips/Kconfig b/hw/mips/Kconfig
index a7f26edebe84..692bede538ee 100644
--- a/hw/mips/Kconfig
+++ b/hw/mips/Kconfig
@@ -67,6 +67,7 @@ config LOONGSON3V
 imply USB_OHCI_PCI
 select SERIAL
 select GOLDFISH_RTC
+select LOONGSON_IPI
 select LOONGSON_LIOINTC
 select PCI_EXPRESS_GENERIC_BRIDGE
 select MSI_NONBROKEN
diff --git a/hw/mips/loongson3_bootp.c b/hw/mips/loongson3_bootp.c
index 03a10b63c1b4..b97b81903b74 100644
--- a/hw/mips/loongson3_bootp.c
+++ b/hw/mips/loongson3_bootp.c
@@ -25,8 +25,6 @@
 #include "hw/boards.h"
 #include "hw/mips/loongson3_bootp.h"
 
-#define LOONGSON3_CORE_PER_NODE 4
-
 static void init_cpu_info(void *g_cpuinfo, uint64_t cpu_freq)
 {
 struct efi_cpuinfo_loongson *c = g_cpuinfo;
diff --git a/hw/mips/loongson3_bootp.h b/hw/mips/loongson3_bootp.h
index 1b0dd3b59171..9091265df7fc 100644
--- a/hw/mips/loongson3_bootp.h
+++ b/hw/mips/loongson3_bootp.h
@@ -200,6 +200,8 @@ struct boot_params {
 struct efi_reset_system_t reset_system;
 };
 
+#define LOONGSON3_CORE_PER_NODE 4
+
 /* Overall MMIO & Memory layout */
 enum {
 VIRT_LOWMEM,
@@ -211,6 +213,7 @@ enum {
 VIRT_BIOS_ROM,
 VIRT_UART,
 VIRT_LIOINTC,
+VIRT_IPI,
 VIRT_PCIE_MMIO,
 VIRT_HIGHMEM
 };
diff --git a/hw/mips/loongson3_virt.c b/hw/mips/loongson3_virt.c
index 440268a07430..3a4105228c1d 100644
--- a/hw/mips/loongson3_virt.c
+++ b/hw/mips/loongson3_virt.c
@@ -36,6 +36,7 @@
 #include "hw/mips/loongson3_bootp.h"
 #include "hw/misc/unimp.h"
 #include "hw/intc/i8259.h"
+#include "hw/intc/loongson_ipi.h"
 #include "hw/loader.h"
 #include "hw/isa/superio.h"
 #include "hw/pci/msi.h"
@@ -74,6 +75,7 @@ const MemMapEntry virt_memmap[] = {
 [VIRT_PCIE_ECAM] =   { 0x1a00, 0x200 },
 [VIRT_BIOS_ROM] ={ 0x1fc0,  0x20 },
 [VIRT_UART] ={ 0x1fe001e0,   0x8 },
+[VIRT_IPI] = { 0x3ff01000, 0x400 },
 [VIRT_LIOINTC] = { 0x3ff01400,  0x64 },
 [VIRT_PCIE_MMIO] =   { 0x4000,0x4000 },
 [VIRT_HIGHMEM] = { 0x8000,   0x0 }, /* Variable */
@@ -485,6 +487,7 @@ static void mips_loongson3_virt_init(MachineState *machine)
 Clock *cpuclk;
 CPUMIPSState *env;
 DeviceState *liointc;
+DeviceState *ipi = NULL;
 char *filename;
 const char *kernel_cmdline = machine->kernel_cmdline;
 const char *kernel_filename = machine->kernel_filename;
@@ -494,6 +497,7 @@ static void mips_loongson3_virt_init(MachineState *machine)
 MemoryRegion *ram = g_new(MemoryRegion, 1);
 MemoryRegion *bios = g_new(MemoryRegion, 1);
 MemoryRegion *iomem = g_new(MemoryRegion, 1);
+MemoryRegion *iocsr = g_new(MemoryRegion, 1);
 
 /* TODO: TCG will support all CPU types */
 if (!kvm_enabled()) {
@@ -527,6 +531,19 @@ static void mips_loongson3_virt_init(MachineState *machine)
 create_unimplemented_device("mmio fallback 0", 0x1000, 256 * MiB);
 create_unimplemented_device("mmio fallback 1", 0x3000, 256 * MiB);
 
+memory_region_init(iocsr, OBJECT(machine), "loongson3.iocsr", UINT32_MAX);
+
+/* IPI controller is in kernel for KVM */
+if (!kvm_enabled()) {
+ipi = qdev_new(TYPE_LOONGSON_IPI);
+qdev_prop_set_uint32(ipi, "num-cpu", machine->smp.cpus);
+sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), _fatal);
+memory_region_add_subregion(iocsr, SMP_IPI_MAILBOX,
+sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 0));
+memory_region_add_subregion(iocsr, MAIL_SEND_ADDR,
+sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 1));
+}
+
 liointc = qdev_new("loongson.liointc");
 sysbus_realize_and_unref(SYS_BUS_DEVICE(liointc), _fatal);
 
@@ -543,6 +560,8 @@ static void mips_loongson3_virt_init(MachineState *machine)
 clock_set_hz(cpuclk, DEF_LOONGSON3_FREQ);
 
 for (i = 0; i < machine->smp.cpus; i++) {
+int node = i / LOONGSON3_CORE_PER_NODE;
+int core = i % LOONGSON3_CORE_PER_NODE;
 int ip;
 
 /* init CPUs */
@@ -553,12 +572,28 @@ static void mips_loongson3_virt_init(MachineState 
*machine)
 cpu_mips_clock_init(cpu);
 qemu_register_reset(main_cpu_reset, cpu);
 
-if (i >= 4) {
+if (ipi) {
+hwaddr base = ((hwaddr)node << 44) + virt_memmap[VIRT_IPI].base;
+base += core * 0x100;
+qdev_connect_gpio_out(ipi, i, cpu->env.irq[6]);
+sysbu

[PATCH v3 2/4] hw/intc/loongson_ipi: Provide per core MMIO address spaces

2024-06-04 Thread Jiaxun Yang
The real IPI hardware have dedicated MMIO registers mapped into
memory address space for every core. This is not used by LoongArch
guest software but it is essential for CPU without IOCSR such as
Loongson-3A1000.

Implement it with existing infrastructure.

Acked-by: Song Gao 
Signed-off-by: Jiaxun Yang 
---
 hw/intc/loongson_ipi.c | 81 --
 include/hw/intc/loongson_ipi.h |  2 ++
 2 files changed, 64 insertions(+), 19 deletions(-)

diff --git a/hw/intc/loongson_ipi.c b/hw/intc/loongson_ipi.c
index 93cc50a37a11..c8a25b4eb8e2 100644
--- a/hw/intc/loongson_ipi.c
+++ b/hw/intc/loongson_ipi.c
@@ -23,16 +23,14 @@
 #endif
 #include "trace.h"
 
-static MemTxResult loongson_ipi_readl(void *opaque, hwaddr addr,
+static MemTxResult loongson_ipi_core_readl(void *opaque, hwaddr addr,
uint64_t *data,
unsigned size, MemTxAttrs attrs)
 {
-IPICore *s;
-LoongsonIPI *ipi = opaque;
+IPICore *s = opaque;
 uint64_t ret = 0;
 int index = 0;
 
-s = >cpu[attrs.requester_id];
 addr &= 0xff;
 switch (addr) {
 case CORE_STATUS_OFF:
@@ -61,6 +59,21 @@ static MemTxResult loongson_ipi_readl(void *opaque, hwaddr 
addr,
 return MEMTX_OK;
 }
 
+static MemTxResult loongson_ipi_iocsr_readl(void *opaque, hwaddr addr,
+   uint64_t *data,
+   unsigned size, MemTxAttrs attrs)
+{
+LoongsonIPI *ipi = opaque;
+IPICore *s;
+
+if (attrs.requester_id >= ipi->num_cpu) {
+return MEMTX_DECODE_ERROR;
+}
+
+s = >cpu[attrs.requester_id];
+return loongson_ipi_core_readl(s, addr, data, size, attrs);
+}
+
 static AddressSpace *get_cpu_iocsr_as(CPUState *cpu)
 {
 #ifdef TARGET_LOONGARCH64
@@ -174,17 +187,17 @@ static MemTxResult any_send(uint64_t val, MemTxAttrs 
attrs)
 return send_ipi_data(cs, val, addr, attrs);
 }
 
-static MemTxResult loongson_ipi_writel(void *opaque, hwaddr addr, uint64_t val,
-unsigned size, MemTxAttrs attrs)
+static MemTxResult loongson_ipi_core_writel(void *opaque, hwaddr addr,
+uint64_t val, unsigned size,
+MemTxAttrs attrs)
 {
-LoongsonIPI *ipi = opaque;
-IPICore *s;
+IPICore *s = opaque;
+LoongsonIPI *ipi = s->ipi;
 int index = 0;
 uint32_t cpuid;
 uint8_t vector;
 CPUState *cs;
 
-s = >cpu[attrs.requester_id];
 addr &= 0xff;
 trace_loongson_ipi_write(size, (uint64_t)addr, val);
 switch (addr) {
@@ -215,13 +228,11 @@ static MemTxResult loongson_ipi_writel(void *opaque, 
hwaddr addr, uint64_t val,
 /* IPI status vector */
 vector = extract8(val, 0, 5);
 cs = ipi_getcpu(cpuid);
-if (cs == NULL) {
+if (cs == NULL || cs->cpu_index >= ipi->num_cpu) {
 return MEMTX_DECODE_ERROR;
 }
-
-/* override requester_id */
-attrs.requester_id = cs->cpu_index;
-loongson_ipi_writel(ipi, CORE_SET_OFF, BIT(vector), 4, attrs);
+loongson_ipi_core_writel(>cpu[cs->cpu_index], CORE_SET_OFF,
+ BIT(vector), 4, attrs);
 break;
 default:
 qemu_log_mask(LOG_UNIMP, "invalid write: %x", (uint32_t)addr);
@@ -231,9 +242,34 @@ static MemTxResult loongson_ipi_writel(void *opaque, 
hwaddr addr, uint64_t val,
 return MEMTX_OK;
 }
 
-static const MemoryRegionOps loongson_ipi_ops = {
-.read_with_attrs = loongson_ipi_readl,
-.write_with_attrs = loongson_ipi_writel,
+static MemTxResult loongson_ipi_iocsr_writel(void *opaque, hwaddr addr,
+uint64_t val, unsigned size,
+MemTxAttrs attrs)
+{
+LoongsonIPI *ipi = opaque;
+IPICore *s;
+
+if (attrs.requester_id >= ipi->num_cpu) {
+return MEMTX_DECODE_ERROR;
+}
+
+s = >cpu[attrs.requester_id];
+return loongson_ipi_core_writel(s, addr, val, size, attrs);
+}
+
+static const MemoryRegionOps loongson_ipi_core_ops = {
+.read_with_attrs = loongson_ipi_core_readl,
+.write_with_attrs = loongson_ipi_core_writel,
+.impl.min_access_size = 4,
+.impl.max_access_size = 4,
+.valid.min_access_size = 4,
+.valid.max_access_size = 8,
+.endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static const MemoryRegionOps loongson_ipi_iocsr_ops = {
+.read_with_attrs = loongson_ipi_iocsr_readl,
+.write_with_attrs = loongson_ipi_iocsr_writel,
 .impl.min_access_size = 4,
 .impl.max_access_size = 4,
 .valid.min_access_size = 4,
@@ -282,7 +318,7 @@ static void loongson_ipi_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 
-memory_region_init_io(>ipi_iocsr_mem, OBJECT(dev), _ipi_ops,
+memory_region_init_i

[PATCH v3 0/4] hw/mips/loongson3_virt: Implement IPI support

2024-06-04 Thread Jiaxun Yang
Hi all,

This series enabled IPI support for loongson3 virt board, loosely
based on my previous work[1].
It generalized loongarch_ipi device to share among both loongarch
and MIPS machines. 

Thanks

[1]: https://lore.kernel.org/all/20230521102307.87081-1-jiaxun.y...@flygoat.com/

To: qemu-devel@nongnu.org
Cc: Song Gao 

Signed-off-by: Jiaxun Yang 
---
Changes in v3:
- Fix up sign off lines.
- Link to v2: 
https://lore.kernel.org/r/20240605-loongson3-ipi-v2-0-da26282e0...@flygoat.com

Changes in v2:
- Add a patch to remove loongarch_ipi.c (Gao)
- Change iocsr alias owner to CPU (philmd)
- New patch to remove ipi_getcpu
- Link to v1: 
https://lore.kernel.org/r/20240508-loongson3-ipi-v1-0-1a7b67704...@flygoat.com

---
Jiaxun Yang (4):
  hw/intc: Remove loongarch_ipi.c
  hw/intc/loongson_ipi: Provide per core MMIO address spaces
  hw/mips/loongson3_virt: Wire up loongson_ipi device
  hw/intc/loongson_ipi: Replace ipi_getcpu with cpu_by_arch_id

 hw/intc/loongarch_ipi.c| 347 -
 hw/intc/loongson_ipi.c | 120 +++---
 hw/mips/Kconfig|   1 +
 hw/mips/loongson3_bootp.c  |   2 -
 hw/mips/loongson3_bootp.h  |   3 +
 hw/mips/loongson3_virt.c   |  39 -
 include/hw/intc/loongson_ipi.h |   2 +
 7 files changed, 108 insertions(+), 406 deletions(-)
---
base-commit: d67a6e054b92e5e1cbb7b0bd5782a670cc7f0df7
change-id: 20240508-loongson3-ipi-65e99b47c400

Best regards,
-- 
Jiaxun Yang 




[PATCH v2 4/4] hw/intc/loongson_ipi: Replace ipi_getcpu with cpu_by_arch_id

2024-06-04 Thread Jiaxun Yang
cpu_by_arch_id is doing the same thing as our ipi_getcpu logic.

Signed-off-by: jiaxun.y...@flygoat.com 
---
 hw/intc/loongson_ipi.c | 39 +++
 1 file changed, 3 insertions(+), 36 deletions(-)

diff --git a/hw/intc/loongson_ipi.c b/hw/intc/loongson_ipi.c
index c8a25b4eb8e2..b3cda5972793 100644
--- a/hw/intc/loongson_ipi.c
+++ b/hw/intc/loongson_ipi.c
@@ -118,39 +118,6 @@ static MemTxResult send_ipi_data(CPUState *cpu, uint64_t 
val, hwaddr addr,
 return MEMTX_OK;
 }
 
-static int archid_cmp(const void *a, const void *b)
-{
-   CPUArchId *archid_a = (CPUArchId *)a;
-   CPUArchId *archid_b = (CPUArchId *)b;
-
-   return archid_a->arch_id - archid_b->arch_id;
-}
-
-static CPUArchId *find_cpu_by_archid(MachineState *ms, uint32_t id)
-{
-CPUArchId apic_id, *found_cpu;
-
-apic_id.arch_id = id;
-found_cpu = bsearch(_id, ms->possible_cpus->cpus,
-ms->possible_cpus->len, sizeof(*ms->possible_cpus->cpus),
-archid_cmp);
-
-return found_cpu;
-}
-
-static CPUState *ipi_getcpu(int arch_id)
-{
-MachineState *machine = MACHINE(qdev_get_machine());
-CPUArchId *archid;
-
-archid = find_cpu_by_archid(machine, arch_id);
-if (archid) {
-return CPU(archid->cpu);
-}
-
-return NULL;
-}
-
 static MemTxResult mail_send(uint64_t val, MemTxAttrs attrs)
 {
 uint32_t cpuid;
@@ -158,7 +125,7 @@ static MemTxResult mail_send(uint64_t val, MemTxAttrs attrs)
 CPUState *cs;
 
 cpuid = extract32(val, 16, 10);
-cs = ipi_getcpu(cpuid);
+cs = cpu_by_arch_id(cpuid);
 if (cs == NULL) {
 return MEMTX_DECODE_ERROR;
 }
@@ -176,7 +143,7 @@ static MemTxResult any_send(uint64_t val, MemTxAttrs attrs)
 CPUState *cs;
 
 cpuid = extract32(val, 16, 10);
-cs = ipi_getcpu(cpuid);
+cs = cpu_by_arch_id(cpuid);
 if (cs == NULL) {
 return MEMTX_DECODE_ERROR;
 }
@@ -227,7 +194,7 @@ static MemTxResult loongson_ipi_core_writel(void *opaque, 
hwaddr addr,
 cpuid = extract32(val, 16, 10);
 /* IPI status vector */
 vector = extract8(val, 0, 5);
-cs = ipi_getcpu(cpuid);
+cs = cpu_by_arch_id(cpuid);
 if (cs == NULL || cs->cpu_index >= ipi->num_cpu) {
 return MEMTX_DECODE_ERROR;
 }

-- 
2.43.0




[PATCH v2 3/4] hw/mips/loongson3_virt: Wire up loongson_ipi device

2024-06-04 Thread Jiaxun Yang
Wire up loongson_ipi device for loongson3_virt machine, so we
can have SMP support for TCG backend as well.

Signed-off-by: Jiaxun Yang 
---
 hw/mips/Kconfig   |  1 +
 hw/mips/loongson3_bootp.c |  2 --
 hw/mips/loongson3_bootp.h |  3 +++
 hw/mips/loongson3_virt.c  | 39 +--
 4 files changed, 41 insertions(+), 4 deletions(-)

diff --git a/hw/mips/Kconfig b/hw/mips/Kconfig
index a7f26edebe84..692bede538ee 100644
--- a/hw/mips/Kconfig
+++ b/hw/mips/Kconfig
@@ -67,6 +67,7 @@ config LOONGSON3V
 imply USB_OHCI_PCI
 select SERIAL
 select GOLDFISH_RTC
+select LOONGSON_IPI
 select LOONGSON_LIOINTC
 select PCI_EXPRESS_GENERIC_BRIDGE
 select MSI_NONBROKEN
diff --git a/hw/mips/loongson3_bootp.c b/hw/mips/loongson3_bootp.c
index 03a10b63c1b4..b97b81903b74 100644
--- a/hw/mips/loongson3_bootp.c
+++ b/hw/mips/loongson3_bootp.c
@@ -25,8 +25,6 @@
 #include "hw/boards.h"
 #include "hw/mips/loongson3_bootp.h"
 
-#define LOONGSON3_CORE_PER_NODE 4
-
 static void init_cpu_info(void *g_cpuinfo, uint64_t cpu_freq)
 {
 struct efi_cpuinfo_loongson *c = g_cpuinfo;
diff --git a/hw/mips/loongson3_bootp.h b/hw/mips/loongson3_bootp.h
index 1b0dd3b59171..9091265df7fc 100644
--- a/hw/mips/loongson3_bootp.h
+++ b/hw/mips/loongson3_bootp.h
@@ -200,6 +200,8 @@ struct boot_params {
 struct efi_reset_system_t reset_system;
 };
 
+#define LOONGSON3_CORE_PER_NODE 4
+
 /* Overall MMIO & Memory layout */
 enum {
 VIRT_LOWMEM,
@@ -211,6 +213,7 @@ enum {
 VIRT_BIOS_ROM,
 VIRT_UART,
 VIRT_LIOINTC,
+VIRT_IPI,
 VIRT_PCIE_MMIO,
 VIRT_HIGHMEM
 };
diff --git a/hw/mips/loongson3_virt.c b/hw/mips/loongson3_virt.c
index 440268a07430..3a4105228c1d 100644
--- a/hw/mips/loongson3_virt.c
+++ b/hw/mips/loongson3_virt.c
@@ -36,6 +36,7 @@
 #include "hw/mips/loongson3_bootp.h"
 #include "hw/misc/unimp.h"
 #include "hw/intc/i8259.h"
+#include "hw/intc/loongson_ipi.h"
 #include "hw/loader.h"
 #include "hw/isa/superio.h"
 #include "hw/pci/msi.h"
@@ -74,6 +75,7 @@ const MemMapEntry virt_memmap[] = {
 [VIRT_PCIE_ECAM] =   { 0x1a00, 0x200 },
 [VIRT_BIOS_ROM] ={ 0x1fc0,  0x20 },
 [VIRT_UART] ={ 0x1fe001e0,   0x8 },
+[VIRT_IPI] = { 0x3ff01000, 0x400 },
 [VIRT_LIOINTC] = { 0x3ff01400,  0x64 },
 [VIRT_PCIE_MMIO] =   { 0x4000,0x4000 },
 [VIRT_HIGHMEM] = { 0x8000,   0x0 }, /* Variable */
@@ -485,6 +487,7 @@ static void mips_loongson3_virt_init(MachineState *machine)
 Clock *cpuclk;
 CPUMIPSState *env;
 DeviceState *liointc;
+DeviceState *ipi = NULL;
 char *filename;
 const char *kernel_cmdline = machine->kernel_cmdline;
 const char *kernel_filename = machine->kernel_filename;
@@ -494,6 +497,7 @@ static void mips_loongson3_virt_init(MachineState *machine)
 MemoryRegion *ram = g_new(MemoryRegion, 1);
 MemoryRegion *bios = g_new(MemoryRegion, 1);
 MemoryRegion *iomem = g_new(MemoryRegion, 1);
+MemoryRegion *iocsr = g_new(MemoryRegion, 1);
 
 /* TODO: TCG will support all CPU types */
 if (!kvm_enabled()) {
@@ -527,6 +531,19 @@ static void mips_loongson3_virt_init(MachineState *machine)
 create_unimplemented_device("mmio fallback 0", 0x1000, 256 * MiB);
 create_unimplemented_device("mmio fallback 1", 0x3000, 256 * MiB);
 
+memory_region_init(iocsr, OBJECT(machine), "loongson3.iocsr", UINT32_MAX);
+
+/* IPI controller is in kernel for KVM */
+if (!kvm_enabled()) {
+ipi = qdev_new(TYPE_LOONGSON_IPI);
+qdev_prop_set_uint32(ipi, "num-cpu", machine->smp.cpus);
+sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), _fatal);
+memory_region_add_subregion(iocsr, SMP_IPI_MAILBOX,
+sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 0));
+memory_region_add_subregion(iocsr, MAIL_SEND_ADDR,
+sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 1));
+}
+
 liointc = qdev_new("loongson.liointc");
 sysbus_realize_and_unref(SYS_BUS_DEVICE(liointc), _fatal);
 
@@ -543,6 +560,8 @@ static void mips_loongson3_virt_init(MachineState *machine)
 clock_set_hz(cpuclk, DEF_LOONGSON3_FREQ);
 
 for (i = 0; i < machine->smp.cpus; i++) {
+int node = i / LOONGSON3_CORE_PER_NODE;
+int core = i % LOONGSON3_CORE_PER_NODE;
 int ip;
 
 /* init CPUs */
@@ -553,12 +572,28 @@ static void mips_loongson3_virt_init(MachineState 
*machine)
 cpu_mips_clock_init(cpu);
 qemu_register_reset(main_cpu_reset, cpu);
 
-if (i >= 4) {
+if (ipi) {
+hwaddr base = ((hwaddr)node << 44) + virt_memmap[VIRT_IPI].base;
+base += core * 0x100;
+qdev_connect_gpio_out(ipi, i, cpu->env.irq[6]);
+sysbu

[PATCH v2 2/4] hw/intc/loongson_ipi: Provide per core MMIO address spaces

2024-06-04 Thread Jiaxun Yang
The real IPI hardware have dedicated MMIO registers mapped into
memory address space for every core. This is not used by LoongArch
guest software but it is essential for CPU without IOCSR such as
Loongson-3A1000.

Implement it with existing infrastructure.

Acked-by: Song Gao 
Signed-off-by: Jiaxun Yang 
---
 hw/intc/loongson_ipi.c | 81 --
 include/hw/intc/loongson_ipi.h |  2 ++
 2 files changed, 64 insertions(+), 19 deletions(-)

diff --git a/hw/intc/loongson_ipi.c b/hw/intc/loongson_ipi.c
index 93cc50a37a11..c8a25b4eb8e2 100644
--- a/hw/intc/loongson_ipi.c
+++ b/hw/intc/loongson_ipi.c
@@ -23,16 +23,14 @@
 #endif
 #include "trace.h"
 
-static MemTxResult loongson_ipi_readl(void *opaque, hwaddr addr,
+static MemTxResult loongson_ipi_core_readl(void *opaque, hwaddr addr,
uint64_t *data,
unsigned size, MemTxAttrs attrs)
 {
-IPICore *s;
-LoongsonIPI *ipi = opaque;
+IPICore *s = opaque;
 uint64_t ret = 0;
 int index = 0;
 
-s = >cpu[attrs.requester_id];
 addr &= 0xff;
 switch (addr) {
 case CORE_STATUS_OFF:
@@ -61,6 +59,21 @@ static MemTxResult loongson_ipi_readl(void *opaque, hwaddr 
addr,
 return MEMTX_OK;
 }
 
+static MemTxResult loongson_ipi_iocsr_readl(void *opaque, hwaddr addr,
+   uint64_t *data,
+   unsigned size, MemTxAttrs attrs)
+{
+LoongsonIPI *ipi = opaque;
+IPICore *s;
+
+if (attrs.requester_id >= ipi->num_cpu) {
+return MEMTX_DECODE_ERROR;
+}
+
+s = >cpu[attrs.requester_id];
+return loongson_ipi_core_readl(s, addr, data, size, attrs);
+}
+
 static AddressSpace *get_cpu_iocsr_as(CPUState *cpu)
 {
 #ifdef TARGET_LOONGARCH64
@@ -174,17 +187,17 @@ static MemTxResult any_send(uint64_t val, MemTxAttrs 
attrs)
 return send_ipi_data(cs, val, addr, attrs);
 }
 
-static MemTxResult loongson_ipi_writel(void *opaque, hwaddr addr, uint64_t val,
-unsigned size, MemTxAttrs attrs)
+static MemTxResult loongson_ipi_core_writel(void *opaque, hwaddr addr,
+uint64_t val, unsigned size,
+MemTxAttrs attrs)
 {
-LoongsonIPI *ipi = opaque;
-IPICore *s;
+IPICore *s = opaque;
+LoongsonIPI *ipi = s->ipi;
 int index = 0;
 uint32_t cpuid;
 uint8_t vector;
 CPUState *cs;
 
-s = >cpu[attrs.requester_id];
 addr &= 0xff;
 trace_loongson_ipi_write(size, (uint64_t)addr, val);
 switch (addr) {
@@ -215,13 +228,11 @@ static MemTxResult loongson_ipi_writel(void *opaque, 
hwaddr addr, uint64_t val,
 /* IPI status vector */
 vector = extract8(val, 0, 5);
 cs = ipi_getcpu(cpuid);
-if (cs == NULL) {
+if (cs == NULL || cs->cpu_index >= ipi->num_cpu) {
 return MEMTX_DECODE_ERROR;
 }
-
-/* override requester_id */
-attrs.requester_id = cs->cpu_index;
-loongson_ipi_writel(ipi, CORE_SET_OFF, BIT(vector), 4, attrs);
+loongson_ipi_core_writel(>cpu[cs->cpu_index], CORE_SET_OFF,
+ BIT(vector), 4, attrs);
 break;
 default:
 qemu_log_mask(LOG_UNIMP, "invalid write: %x", (uint32_t)addr);
@@ -231,9 +242,34 @@ static MemTxResult loongson_ipi_writel(void *opaque, 
hwaddr addr, uint64_t val,
 return MEMTX_OK;
 }
 
-static const MemoryRegionOps loongson_ipi_ops = {
-.read_with_attrs = loongson_ipi_readl,
-.write_with_attrs = loongson_ipi_writel,
+static MemTxResult loongson_ipi_iocsr_writel(void *opaque, hwaddr addr,
+uint64_t val, unsigned size,
+MemTxAttrs attrs)
+{
+LoongsonIPI *ipi = opaque;
+IPICore *s;
+
+if (attrs.requester_id >= ipi->num_cpu) {
+return MEMTX_DECODE_ERROR;
+}
+
+s = >cpu[attrs.requester_id];
+return loongson_ipi_core_writel(s, addr, val, size, attrs);
+}
+
+static const MemoryRegionOps loongson_ipi_core_ops = {
+.read_with_attrs = loongson_ipi_core_readl,
+.write_with_attrs = loongson_ipi_core_writel,
+.impl.min_access_size = 4,
+.impl.max_access_size = 4,
+.valid.min_access_size = 4,
+.valid.max_access_size = 8,
+.endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static const MemoryRegionOps loongson_ipi_iocsr_ops = {
+.read_with_attrs = loongson_ipi_iocsr_readl,
+.write_with_attrs = loongson_ipi_iocsr_writel,
 .impl.min_access_size = 4,
 .impl.max_access_size = 4,
 .valid.min_access_size = 4,
@@ -282,7 +318,7 @@ static void loongson_ipi_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 
-memory_region_init_io(>ipi_iocsr_mem, OBJECT(dev), _ipi_ops,
+memory_region_init_i

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

2024-06-04 Thread Jiaxun Yang
It was missed out in previous commit.

Fixes: b4a12dfc2132 ("hw/intc/loongarch_ipi: Rename as loongson_ipi")
Signed-off-by: jiaxun.y...@flygoat.com 
---
 hw/intc/loongarch_ipi.c | 347 
 1 file changed, 347 deletions(-)

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

[PATCH v2 0/4] hw/mips/loongson3_virt: Implement IPI support

2024-06-04 Thread Jiaxun Yang
Hi all,

This series enabled IPI support for loongson3 virt board, loosely
based on my previous work[1].
It generalized loongarch_ipi device to share among both loongarch
and MIPS machines. 

Thanks

[1]: https://lore.kernel.org/all/20230521102307.87081-1-jiaxun.y...@flygoat.com/

To: qemu-devel@nongnu.org
Cc: Song Gao 

Signed-off-by: Jiaxun Yang 
---
Changes in v2:
- Add a patch to remove loongarch_ipi.c (Gao)
- Change iocsr alias owner to CPU (philmd)
- New patch to remove ipi_getcpu
- Link to v1: 
https://lore.kernel.org/r/20240508-loongson3-ipi-v1-0-1a7b67704...@flygoat.com

---
Jiaxun Yang (4):
  hw/intc: Remove loongarch_ipi.c
  hw/intc/loongson_ipi: Provide per core MMIO address spaces
  hw/mips/loongson3_virt: Wire up loongson_ipi device
  hw/intc/loongson_ipi: Replace ipi_getcpu with cpu_by_arch_id

 hw/intc/loongarch_ipi.c| 347 -
 hw/intc/loongson_ipi.c | 120 +++---
 hw/mips/Kconfig|   1 +
 hw/mips/loongson3_bootp.c  |   2 -
 hw/mips/loongson3_bootp.h  |   3 +
 hw/mips/loongson3_virt.c   |  39 -
 include/hw/intc/loongson_ipi.h |   2 +
 7 files changed, 108 insertions(+), 406 deletions(-)
---
base-commit: d67a6e054b92e5e1cbb7b0bd5782a670cc7f0df7
change-id: 20240508-loongson3-ipi-65e99b47c400

Best regards,
-- 
Jiaxun Yang 




Re: [PATCH 3/5] hw/intc/loongson_ipi: Implement IOCSR address space for MIPS

2024-06-04 Thread Jiaxun Yang



在2024年6月3日六月 下午4:45,Philippe Mathieu-Daudé写道:
[...]
>
> LoongsonIPI should have an array of CPUState[] and MemoryRegion[].
> (Or maybe add them to IPICore.)
> Expose them as QOM link properties.
>
> Caller wire them while creating the LoongsonIPI.
> Then loongson_ipi_realize() resolves them once.
> No need to call get_cpu_iocsr_as() and ipi_getcpu() for each MMIO
> access IMO.

I was tempted to do so but realized that arch_id might be discontinuous
for LoongArch.

@Song, can you confirm if it's viable?

Thanks
- Jiaxun
>
>> +
>> +if (!iocsr_as) {
>> +return MEMTX_DECODE_ERROR;
>> +}

-- 
- Jiaxun



Re: [PATCH] mips64el-softmmu: Enable MTTCG

2024-06-04 Thread Jiaxun Yang



在2024年6月3日六月 下午7:15,Pierrick Bouvier写道:
> On 5/11/24 13:26, Jiaxun Yang wrote:
>> MTTCG was disabled in a092a9554771 ("configure: disable MTTCG
>> for MIPS guests") due to test case instability.
>> 
>> I was able to reproduce this issue with in latest QEMU and look
>> into reason behind that.
>> 
>> What actually happend is kernel's CP0 timer synchronisation
>> mechanism assumed a consistent latency in memory access between
>> cores, which TCG can't guarantee. Thus there is a huge drift in
>> count value between cores, and in early kernel versions CP0 timer
>> is always used as sched_clock.
>> 
>> sched_clock drift back on some cores triggered RCU watchdog in
>> some extreme cases.
>> 
>> This can be resolved by setting clocksource to MIPS, which allows
>> clocksource to drift together with sched_clock. However this will
>> leed to other problems after boot.
>> 
>> Another option would beupdating kernel to later version, which
>> will use GIC as sched_clock.
>> 
>> In non-MTTCG build, the execution is slow enough so kernel won't
>> observe back drifts.
>> 
>> Test results:
>> 
>> With clocksource=MIPS
>> ```
>>   ~/tmp/retry/retry.py -n 100 -c -- ./qemu-system-mips64el \
>>  -display none -vga none -serial mon:stdio \
>>  -machine malta -kernel ./vmlinux-4.7.0-rc1.I6400 \
>>  -cpu I6400 -smp 8 -vga std \
>>  -append "printk.time=0 clocksource=MIPS console=tty0 console=ttyS0 
>> panic=-1" \
>>  --no-reboot
>> 
>> 100, 0, PASS, 5.258126, 100, 100, -
>> Results summary:
>> 0: 100 times (100.00%), avg time 6.508 (55.53 varience/7.45 deviation)
>> Ran command 100 times, 100 passes
>> ```
>> 
>> With linux-next:
>> ```
>>   ~/tmp/retry/retry.py -n 100 -c -- ./qemu-system-mips64el \
>>  -display none -vga none -serial mon:stdio \
>>  -machine malta -kernel ~/linux-next/vmlinux \
>>  -cpu I6400 -smp 8 -vga std \
>>  -append "printk.time=0 console=tty0 console=ttyS0 panic=-1" \
>>  --no-reboot
>> 
>> 100, 0, PASS, 4.507921, 100, 100, -
>> Results summary:
>> 0: 100 times (100.00%), avg time 4.233 (0.04 varience/0.21 deviation)
>> Ran command 100 times, 100 passes
>> ```
>> 
>> Signed-off-by: Jiaxun Yang 
>> ---
>> I'll leave the test case alone as it's already marked as 
>> QEMU_TEST_FLAKY_TESTS
>> ---
>>   configs/targets/mips64el-softmmu.mak | 1 +
>>   1 file changed, 1 insertion(+)
>> 
>> diff --git a/configs/targets/mips64el-softmmu.mak 
>> b/configs/targets/mips64el-softmmu.mak
>> index 8d9ab3ddc4b1..199b1d909a7d 100644
>> --- a/configs/targets/mips64el-softmmu.mak
>> +++ b/configs/targets/mips64el-softmmu.mak
>> @@ -1,3 +1,4 @@
>>   TARGET_ARCH=mips64
>>   TARGET_BASE_ARCH=mips
>> +TARGET_SUPPORTS_MTTCG=y
>>   TARGET_NEED_FDT=y
>> 
>> ---
>> base-commit: 248f6f62df073a3b4158fd0093863ab885feabb5
>> change-id: 20240511-mips_mttcg-47a6b19074b3
>> 
>> Best regards,
>
> Hi Jiaxun,
> Thanks for your analysis!
>
> We should see to update concerned test in another series.
> I'm not sure which way is preferred between updating kernel used or 
> changing current command line.
>
> Reviewed-by: Pierrick Bouvier 

I think updating kernel can prevent further problems.
Will test with latest Debian kernel.

Thanks!
-- 
- Jiaxun



Re: tests/avocado: Add LoongArch machine start test

2024-05-30 Thread Jiaxun Yang



在2024年5月31日五月 上午2:52,gaosong写道:
> 在 2024/5/30 下午9:16, Jiaxun Yang 写道:
>>
>> 在2024年5月30日五月 下午2:00,gaosong写道:
>> [...]
>>>> FYI, the test does not seem to work anymore - apparently the binaries
>>>> have changed and now the hashes do not match anymore. Could you please
>>>> update it? (preferably with some versioned binaries that do not change
>>>> in the course of time?)
>>>>
>>> Thank you,  I had send a patch to fix it.
>> Hi Song,
>>
>> As LoongArch EDK2 support has been merged long ago, do you to make a clean
>> build and add it to pc-bios directory?
> EDK2 LoongArchVirt under OvmfPkg is being committed to upstream.
>
> PR:
> https://github.com/tianocore/edk2/pull/5208

I meant here:

https://gitlab.com/qemu-project/qemu/-/tree/master/pc-bios?ref_type=heads

Thanks
>
> Thanks
> Song Gao
>>
>> Thanks
>> - Jiaxun

-- 
- Jiaxun



Re: tests/avocado: Add LoongArch machine start test

2024-05-30 Thread Jiaxun Yang



在2024年5月30日五月 下午2:00,gaosong写道:
[...]
>> FYI, the test does not seem to work anymore - apparently the binaries 
>> have changed and now the hashes do not match anymore. Could you please 
>> update it? (preferably with some versioned binaries that do not change 
>> in the course of time?)
>>
> Thank you,  I had send a patch to fix it.

Hi Song,

As LoongArch EDK2 support has been merged long ago, do you to make a clean
build and add it to pc-bios directory?

Thanks
- Jiaxun

>
> Thanks.
> Song Gao

-- 
- Jiaxun



Re: [PATCH] target/mips: Remove unused 'hw/misc/mips_itu.h' header

2024-05-29 Thread Jiaxun Yang



在2024年5月29日五月 下午4:52,Philippe Mathieu-Daudé写道:
> Since commit e1152f8166 ("target/mips: Remove helpers accessing
> SAAR registers") this header is not needed.
>
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Jiaxun Yang 

> ---
>  target/mips/tcg/sysemu/cp0_helper.c | 1 -
>  1 file changed, 1 deletion(-)
>
> diff --git a/target/mips/tcg/sysemu/cp0_helper.c 
> b/target/mips/tcg/sysemu/cp0_helper.c
> index ded6c78e9a..79a5c833ce 100644
> --- a/target/mips/tcg/sysemu/cp0_helper.c
> +++ b/target/mips/tcg/sysemu/cp0_helper.c
> @@ -28,7 +28,6 @@
>  #include "qemu/host-utils.h"
>  #include "exec/helper-proto.h"
>  #include "exec/exec-all.h"
> -#include "hw/misc/mips_itu.h"
> 
> 
>  /* SMP helpers.  */
> -- 
> 2.41.0

-- 
- Jiaxun



[PATCH 2/4] hw/m68k/virt: Add fw_cfg controller

2024-05-27 Thread Jiaxun Yang
Add a fw_cfg controller to pass essential information
to firmware.

Signed-off-by: Jiaxun Yang 
---
 hw/m68k/Kconfig   |  1 +
 hw/m68k/virt.c| 25 ++-
 include/standard-headers/asm-m68k/bootinfo-virt.h |  1 +
 3 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/hw/m68k/Kconfig b/hw/m68k/Kconfig
index 66e63cd60b57..4501da56ff6d 100644
--- a/hw/m68k/Kconfig
+++ b/hw/m68k/Kconfig
@@ -40,6 +40,7 @@ config M68K_VIRT
 default y
 depends on M68K
 select M68K_IRQC
+select FW_CFG_DMA
 select VIRT_CTRL
 select GOLDFISH_PIC
 select GOLDFISH_TTY
diff --git a/hw/m68k/virt.c b/hw/m68k/virt.c
index 7b3917dcbd2b..7590e6515ac3 100644
--- a/hw/m68k/virt.c
+++ b/hw/m68k/virt.c
@@ -42,7 +42,8 @@
  * CPU IRQ #1 -> PIC #1
  *   IRQ #1 -> virt-ctrl
  *   IRQ #2 -> xhci
- *   IRQ #3 to IRQ #31 -> unused
+ *   IRQ #3 -> fw_cfg
+ *   IRQ #4 to IRQ #31 -> unused
  *   IRQ #32 -> goldfish-tty
  * CPU IRQ #2 -> PIC #2
  *   IRQ #1 to IRQ #32 -> virtio-mmio from 1 to 32
@@ -80,6 +81,10 @@
 #define VIRT_CTRL_MMIO_BASE 0xff009000/* MMIO: 0xff009000 - 0xff009fff */
 #define VIRT_CTRL_IRQ_BASE  PIC_IRQ(1, 1) /* PIC: #1, IRQ: #1 */
 
+/* 1 fw_cfg */
+#define VIRT_FW_CFG_MMIO_BASE 0xff00a000/* MMIO: 0xff00a000 - 0xff00afff */
+#define VIRT_FW_CFG_IRQ_BASE  PIC_IRQ(1, 3) /* PIC: #1, IRQ: #3 */
+
 /*
  * virtio-mmio size is 0x200 bytes
  * we use 4 goldfish-pic to attach them,
@@ -116,6 +121,12 @@ static void rerandomize_rng_seed(void *opaque)
 be16_to_cpu(*(uint16_t *)rng_seed->data));
 }
 
+static void fw_cfg_boot_set(void *opaque, const char *boot_device,
+Error **errp)
+{
+fw_cfg_modify_i16(opaque, FW_CFG_BOOT_DEVICE, boot_device[0]);
+}
+
 static void virt_init(MachineState *machine)
 {
 M68kCPU *cpu = NULL;
@@ -134,6 +145,7 @@ static void virt_init(MachineState *machine)
 SysBusDevice *sysbus;
 hwaddr io_base;
 int i;
+FWCfgState *fw_cfg;
 ResetInfo *reset_info;
 uint8_t rng_seed[32];
 
@@ -210,6 +222,15 @@ static void virt_init(MachineState *machine)
 dev = sysbus_create_simple(TYPE_VIRT_CTRL, VIRT_CTRL_MMIO_BASE,
PIC_GPIO(VIRT_CTRL_IRQ_BASE));
 
+/* fw_cfg */
+fw_cfg = fw_cfg_init_mem_wide(VIRT_FW_CFG_MMIO_BASE + 8,
+  VIRT_FW_CFG_MMIO_BASE, 8,
+  VIRT_FW_CFG_MMIO_BASE + 16,
+  _space_memory);
+fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
+qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
+rom_set_fw(fw_cfg);
+
 /* virtio-mmio */
 io_base = VIRT_VIRTIO_MMIO_BASE;
 for (i = 0; i < 128; i++) {
@@ -288,6 +309,8 @@ static void virt_init(MachineState *machine)
 BOOTINFO2(param_ptr, BI_VIRT_XHCI_BASE,
 VIRT_XHCI_MMIO_BASE, VIRT_XHCI_IRQ_BASE);
 }
+BOOTINFO2(param_ptr, BI_VIRT_FW_CFG_BASE,
+  VIRT_FW_CFG_MMIO_BASE, VIRT_FW_CFG_IRQ_BASE);
 
 if (kernel_cmdline) {
 BOOTINFOSTR(param_ptr, BI_COMMAND_LINE,
diff --git a/include/standard-headers/asm-m68k/bootinfo-virt.h 
b/include/standard-headers/asm-m68k/bootinfo-virt.h
index 1700c3ada765..7f90be1aa7bd 100644
--- a/include/standard-headers/asm-m68k/bootinfo-virt.h
+++ b/include/standard-headers/asm-m68k/bootinfo-virt.h
@@ -17,6 +17,7 @@
  * #define BI_VIRT_RNG_SEED0x8006 */
 
 #define BI_VIRT_XHCI_BASE  0x8007
+#define BI_VIRT_FW_CFG_BASE0x8008
 
 #define VIRT_BOOTI_VERSION MK_BI_VERSION(2, 0)
 

-- 
2.43.0




[PATCH 3/4] hw/m68k/virt: Add a pflash controller for BIOS firmware

2024-05-27 Thread Jiaxun Yang
Add a 8 MiB pflash controller for BIOS firmware, and boot
from it if possible.

Signed-off-by: Jiaxun Yang 
---
 hw/m68k/Kconfig   |  1 +
 hw/m68k/virt.c| 44 +++
 include/standard-headers/asm-m68k/bootinfo-virt.h |  1 +
 3 files changed, 46 insertions(+)

diff --git a/hw/m68k/Kconfig b/hw/m68k/Kconfig
index 4501da56ff6d..f233a5948f19 100644
--- a/hw/m68k/Kconfig
+++ b/hw/m68k/Kconfig
@@ -42,6 +42,7 @@ config M68K_VIRT
 select M68K_IRQC
 select FW_CFG_DMA
 select VIRT_CTRL
+select PFLASH_CFI01
 select GOLDFISH_PIC
 select GOLDFISH_TTY
 select GOLDFISH_RTC
diff --git a/hw/m68k/virt.c b/hw/m68k/virt.c
index 7590e6515ac3..a2eebc0f2243 100644
--- a/hw/m68k/virt.c
+++ b/hw/m68k/virt.c
@@ -8,6 +8,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu/datadir.h"
 #include "qemu/units.h"
 #include "qemu/guest-random.h"
 #include "sysemu/sysemu.h"
@@ -28,6 +29,7 @@
 #include "sysemu/runstate.h"
 #include "sysemu/reset.h"
 
+#include "hw/block/flash.h"
 #include "hw/intc/m68k_irqc.h"
 #include "hw/misc/virt_ctrl.h"
 #include "hw/char/goldfish_tty.h"
@@ -97,6 +99,10 @@
 #define VIRT_XHCI_MMIO_BASE 0xff02/* MMIO: 0xff02 - 0xff023fff */
 #define VIRT_XHCI_IRQ_BASE  PIC_IRQ(1, 2) /* PIC: #1, IRQ: #2 */
 
+#define VIRT_PFLASH_MMIO_BASE 0xff80  /* MMIO: 0xff80 - 0x 
*/
+#define VIRT_PFLASH_SIZE  0x80/* 8 MiB */
+#define VIRT_PFLASH_SECTOR_SIZE (128 * KiB)   /* 64 KiB */
+
 typedef struct {
 M68kCPU *cpu;
 hwaddr initial_pc;
@@ -139,6 +145,7 @@ static void virt_init(MachineState *machine)
 const char *initrd_filename = machine->initrd_filename;
 const char *kernel_cmdline = machine->kernel_cmdline;
 hwaddr parameters_base;
+DriveInfo *dinfo;
 DeviceState *dev;
 DeviceState *irqc_dev;
 DeviceState *pic_dev[VIRT_GF_PIC_NB];
@@ -165,6 +172,8 @@ static void virt_init(MachineState *machine)
 cpu = M68K_CPU(cpu_create(machine->cpu_type));
 
 reset_info->cpu = cpu;
+reset_info->initial_pc = VIRT_PFLASH_MMIO_BASE;
+reset_info->initial_stack = ram_size;
 qemu_register_reset(main_cpu_reset, reset_info);
 
 /* RAM */
@@ -253,6 +262,39 @@ static void virt_init(MachineState *machine)
 PIC_GPIO(VIRT_XHCI_IRQ_BASE));
 }
 
+/* pflash */
+dinfo = drive_get(IF_PFLASH, 0, 0);
+pflash_cfi01_register(VIRT_PFLASH_MMIO_BASE,
+  "virt.pflash0",
+   VIRT_PFLASH_SIZE,
+   dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
+   VIRT_PFLASH_SECTOR_SIZE, 4,
+   0x89, 0x18, 0, 0, 1);
+
+if (machine->firmware) {
+char *fn;
+int image_size;
+
+if (drive_get(IF_PFLASH, 0, 0)) {
+error_report("The contents of the first flash device may be "
+ "specified with -bios or with -drive if=pflash... "
+ "but you cannot use both options at once");
+exit(1);
+}
+fn = qemu_find_file(QEMU_FILE_TYPE_BIOS, machine->firmware);
+if (!fn) {
+error_report("Could not find ROM image '%s'", machine->firmware);
+exit(1);
+}
+image_size = load_image_targphys(fn, VIRT_PFLASH_MMIO_BASE,
+ VIRT_PFLASH_SIZE);
+g_free(fn);
+if (image_size < 0) {
+error_report("Could not load ROM image '%s'", machine->firmware);
+exit(1);
+}
+}
+
 if (kernel_filename) {
 CPUState *cs = CPU(cpu);
 uint64_t high;
@@ -311,6 +353,8 @@ static void virt_init(MachineState *machine)
 }
 BOOTINFO2(param_ptr, BI_VIRT_FW_CFG_BASE,
   VIRT_FW_CFG_MMIO_BASE, VIRT_FW_CFG_IRQ_BASE);
+BOOTINFO2(param_ptr, BI_VIRT_PFLASH_BASE,
+VIRT_PFLASH_MMIO_BASE, 0);
 
 if (kernel_cmdline) {
 BOOTINFOSTR(param_ptr, BI_COMMAND_LINE,
diff --git a/include/standard-headers/asm-m68k/bootinfo-virt.h 
b/include/standard-headers/asm-m68k/bootinfo-virt.h
index 7f90be1aa7bd..21c9a98d2912 100644
--- a/include/standard-headers/asm-m68k/bootinfo-virt.h
+++ b/include/standard-headers/asm-m68k/bootinfo-virt.h
@@ -18,6 +18,7 @@
 
 #define BI_VIRT_XHCI_BASE  0x8007
 #define BI_VIRT_FW_CFG_BASE0x8008
+#define BI_VIRT_PFLASH_BASE0x8009
 
 #define VIRT_BOOTI_VERSION MK_BI_VERSION(2, 0)
 

-- 
2.43.0




[PATCH 1/4] hw/m68k/virt: Add a XHCI controller

2024-05-27 Thread Jiaxun Yang
VirtIO is somewhat limited on the diversity of devices.
We lack proper audio, webcam and so on support on m68k virt machine.

This can be improved by providing a XHCI controller, which enables
provision of many different discoverable devices.

Signed-off-by: Jiaxun Yang 
---
 hw/m68k/Kconfig   |  1 +
 hw/m68k/virt.c| 22 +-
 include/standard-headers/asm-m68k/bootinfo-virt.h |  2 ++
 3 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/hw/m68k/Kconfig b/hw/m68k/Kconfig
index 0092cda4e9c8..66e63cd60b57 100644
--- a/hw/m68k/Kconfig
+++ b/hw/m68k/Kconfig
@@ -44,4 +44,5 @@ config M68K_VIRT
 select GOLDFISH_PIC
 select GOLDFISH_TTY
 select GOLDFISH_RTC
+select USB_XHCI_SYSBUS
 select VIRTIO_MMIO
diff --git a/hw/m68k/virt.c b/hw/m68k/virt.c
index 09bc9bdfefb2..7b3917dcbd2b 100644
--- a/hw/m68k/virt.c
+++ b/hw/m68k/virt.c
@@ -33,13 +33,16 @@
 #include "hw/char/goldfish_tty.h"
 #include "hw/rtc/goldfish_rtc.h"
 #include "hw/intc/goldfish_pic.h"
+#include "hw/usb/hcd-xhci-sysbus.h"
 #include "hw/virtio/virtio-mmio.h"
 #include "hw/virtio/virtio-blk.h"
 
 /*
  * 6 goldfish-pic for CPU IRQ #1 to IRQ #6
  * CPU IRQ #1 -> PIC #1
- *   IRQ #1 to IRQ #31 -> unused
+ *   IRQ #1 -> virt-ctrl
+ *   IRQ #2 -> xhci
+ *   IRQ #3 to IRQ #31 -> unused
  *   IRQ #32 -> goldfish-tty
  * CPU IRQ #2 -> PIC #2
  *   IRQ #1 to IRQ #32 -> virtio-mmio from 1 to 32
@@ -86,6 +89,9 @@
 #define VIRT_VIRTIO_MMIO_BASE 0xff01 /* MMIO: 0xff01 - 0xff01 
*/
 #define VIRT_VIRTIO_IRQ_BASE  PIC_IRQ(2, 1)  /* PIC: 2, 3, 4, 5, IRQ: ALL */
 
+#define VIRT_XHCI_MMIO_BASE 0xff02/* MMIO: 0xff02 - 0xff023fff */
+#define VIRT_XHCI_IRQ_BASE  PIC_IRQ(1, 2) /* PIC: #1, IRQ: #2 */
+
 typedef struct {
 M68kCPU *cpu;
 hwaddr initial_pc;
@@ -216,6 +222,16 @@ static void virt_init(MachineState *machine)
 io_base += 0x200;
 }
 
+/* xhci */
+if (machine_usb(machine)) {
+dev = qdev_new(TYPE_XHCI_SYSBUS);
+qdev_prop_set_uint32(dev, "intrs", 1);
+sysbus_realize(SYS_BUS_DEVICE(dev), _fatal);
+sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, VIRT_XHCI_MMIO_BASE);
+sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,
+PIC_GPIO(VIRT_XHCI_IRQ_BASE));
+}
+
 if (kernel_filename) {
 CPUState *cs = CPU(cpu);
 uint64_t high;
@@ -268,6 +284,10 @@ static void virt_init(MachineState *machine)
   VIRT_CTRL_MMIO_BASE, VIRT_CTRL_IRQ_BASE);
 BOOTINFO2(param_ptr, BI_VIRT_VIRTIO_BASE,
   VIRT_VIRTIO_MMIO_BASE, VIRT_VIRTIO_IRQ_BASE);
+if (machine_usb(machine)) {
+BOOTINFO2(param_ptr, BI_VIRT_XHCI_BASE,
+VIRT_XHCI_MMIO_BASE, VIRT_XHCI_IRQ_BASE);
+}
 
 if (kernel_cmdline) {
 BOOTINFOSTR(param_ptr, BI_COMMAND_LINE,
diff --git a/include/standard-headers/asm-m68k/bootinfo-virt.h 
b/include/standard-headers/asm-m68k/bootinfo-virt.h
index 75ac6bbd7d73..1700c3ada765 100644
--- a/include/standard-headers/asm-m68k/bootinfo-virt.h
+++ b/include/standard-headers/asm-m68k/bootinfo-virt.h
@@ -16,6 +16,8 @@
 /* No longer used -- replaced with BI_RNG_SEED -- but don't reuse this index:
  * #define BI_VIRT_RNG_SEED0x8006 */
 
+#define BI_VIRT_XHCI_BASE  0x8007
+
 #define VIRT_BOOTI_VERSION MK_BI_VERSION(2, 0)
 
 #endif /* _UAPI_ASM_M68K_BOOTINFO_MAC_H */

-- 
2.43.0




[PATCH 0/4] hw/m68k/virt: Add some devices

2024-05-27 Thread Jiaxun Yang
Hi all,

This series added some devices that I found lacking when
I was trying to port U-Boot to m68k virt machine.

Please review.
Thanks

Signed-off-by: Jiaxun Yang 
---
Jiaxun Yang (4):
  hw/m68k/virt: Add a XHCI controller
  hw/m68k/virt: Add fw_cfg controller
  hw/m68k/virt: Add a pflash controller for BIOS firmware
  hw/m68k/virt: Supply bootinfo for BIOS

 hw/m68k/Kconfig   |   3 +
 hw/m68k/virt.c| 231 --
 include/standard-headers/asm-m68k/bootinfo-virt.h |   4 +
 3 files changed, 176 insertions(+), 62 deletions(-)
---
base-commit: 60b54b67c63d8f076152e0f7dccf39854dfc6a77
change-id: 20240527-m68k-bios-a0a2370181f5

Best regards,
-- 
Jiaxun Yang 




[PATCH 4/4] hw/m68k/virt: Supply bootinfo for BIOS

2024-05-27 Thread Jiaxun Yang
We follow common function split between BIOS and QEMU loader,
When BIOS firmware is available QEMU does not load kernel/initrd
binary to memory, instead BIOS retrieve those binaries from fw_cfg.

A stripped version of bootinfo is placed at 1 KiB position of memory.
This allows BIOS to probe board level information. It does not contain
any booting related information (kernel, initrd, cmdline, random).

Signed-off-by: Jiaxun Yang 
---
 hw/m68k/virt.c | 160 -
 1 file changed, 90 insertions(+), 70 deletions(-)

diff --git a/hw/m68k/virt.c b/hw/m68k/virt.c
index a2eebc0f2243..ea7a1bb430fc 100644
--- a/hw/m68k/virt.c
+++ b/hw/m68k/virt.c
@@ -138,13 +138,16 @@ static void virt_init(MachineState *machine)
 M68kCPU *cpu = NULL;
 int32_t kernel_size;
 uint64_t elf_entry;
-ram_addr_t initrd_base;
-int32_t initrd_size;
+ram_addr_t initrd_base = 0;
+int32_t initrd_size = 0;
+int32_t bootinfo_size;
+bool bios_loaded = false;
 ram_addr_t ram_size = machine->ram_size;
 const char *kernel_filename = machine->kernel_filename;
 const char *initrd_filename = machine->initrd_filename;
 const char *kernel_cmdline = machine->kernel_cmdline;
-hwaddr parameters_base;
+void *param_blob, *param_ptr, *param_rng_seed = NULL;
+hwaddr parameters_base = 1 * KiB;
 DriveInfo *dinfo;
 DeviceState *dev;
 DeviceState *irqc_dev;
@@ -264,6 +267,9 @@ static void virt_init(MachineState *machine)
 
 /* pflash */
 dinfo = drive_get(IF_PFLASH, 0, 0);
+if (dinfo) {
+bios_loaded = true;
+}
 pflash_cfi01_register(VIRT_PFLASH_MMIO_BASE,
   "virt.pflash0",
VIRT_PFLASH_SIZE,
@@ -293,18 +299,12 @@ static void virt_init(MachineState *machine)
 error_report("Could not load ROM image '%s'", machine->firmware);
 exit(1);
 }
+
+bios_loaded = true;
 }
 
-if (kernel_filename) {
-CPUState *cs = CPU(cpu);
+if (kernel_filename && !bios_loaded) {
 uint64_t high;
-void *param_blob, *param_ptr, *param_rng_seed;
-
-if (kernel_cmdline) {
-param_blob = g_malloc(strlen(kernel_cmdline) + 1024);
-} else {
-param_blob = g_malloc(1024);
-}
 
 kernel_size = load_elf(kernel_filename, NULL, NULL, NULL,
_entry, NULL, , NULL, 1,
@@ -315,57 +315,6 @@ static void virt_init(MachineState *machine)
 }
 reset_info->initial_pc = elf_entry;
 parameters_base = (high + 1) & ~1;
-param_ptr = param_blob;
-
-BOOTINFO1(param_ptr, BI_MACHTYPE, MACH_VIRT);
-if (m68k_feature(>env, M68K_FEATURE_M68020)) {
-BOOTINFO1(param_ptr, BI_CPUTYPE, CPU_68020);
-} else if (m68k_feature(>env, M68K_FEATURE_M68030)) {
-BOOTINFO1(param_ptr, BI_MMUTYPE, MMU_68030);
-BOOTINFO1(param_ptr, BI_CPUTYPE, CPU_68030);
-} else if (m68k_feature(>env, M68K_FEATURE_M68040)) {
-BOOTINFO1(param_ptr, BI_FPUTYPE, FPU_68040);
-BOOTINFO1(param_ptr, BI_MMUTYPE, MMU_68040);
-BOOTINFO1(param_ptr, BI_CPUTYPE, CPU_68040);
-} else if (m68k_feature(>env, M68K_FEATURE_M68060)) {
-BOOTINFO1(param_ptr, BI_FPUTYPE, FPU_68060);
-BOOTINFO1(param_ptr, BI_MMUTYPE, MMU_68060);
-BOOTINFO1(param_ptr, BI_CPUTYPE, CPU_68060);
-}
-BOOTINFO2(param_ptr, BI_MEMCHUNK, 0, ram_size);
-
-BOOTINFO1(param_ptr, BI_VIRT_QEMU_VERSION,
-  ((QEMU_VERSION_MAJOR << 24) | (QEMU_VERSION_MINOR << 16) |
-   (QEMU_VERSION_MICRO << 8)));
-BOOTINFO2(param_ptr, BI_VIRT_GF_PIC_BASE,
-  VIRT_GF_PIC_MMIO_BASE, VIRT_GF_PIC_IRQ_BASE);
-BOOTINFO2(param_ptr, BI_VIRT_GF_RTC_BASE,
-  VIRT_GF_RTC_MMIO_BASE, VIRT_GF_RTC_IRQ_BASE);
-BOOTINFO2(param_ptr, BI_VIRT_GF_TTY_BASE,
-  VIRT_GF_TTY_MMIO_BASE, VIRT_GF_TTY_IRQ_BASE);
-BOOTINFO2(param_ptr, BI_VIRT_CTRL_BASE,
-  VIRT_CTRL_MMIO_BASE, VIRT_CTRL_IRQ_BASE);
-BOOTINFO2(param_ptr, BI_VIRT_VIRTIO_BASE,
-  VIRT_VIRTIO_MMIO_BASE, VIRT_VIRTIO_IRQ_BASE);
-if (machine_usb(machine)) {
-BOOTINFO2(param_ptr, BI_VIRT_XHCI_BASE,
-VIRT_XHCI_MMIO_BASE, VIRT_XHCI_IRQ_BASE);
-}
-BOOTINFO2(param_ptr, BI_VIRT_FW_CFG_BASE,
-  VIRT_FW_CFG_MMIO_BASE, VIRT_FW_CFG_IRQ_BASE);
-BOOTINFO2(param_ptr, BI_VIRT_PFLASH_BASE,
-VIRT_PFLASH_MMIO_BASE, 0);
-
-if (kernel_cmdline) {
-BOOTINFOSTR(param_ptr, BI_COMMAND_LINE,
-kernel_cmdline);
-}
-
-/* Pass seed to RNG. */
-param_rng_seed = param_ptr;
-  

Re: [PULL 10/10] hw/loongarch/virt: Fix FDT memory node address width

2024-05-24 Thread Jiaxun Yang



在2024年5月24日五月 上午11:10,Michael Tokarev写道:
> 23.05.2024 04:46, Song Gao wrote:
>> From: Jiaxun Yang 
>> 
>> Higher bits for memory nodes were omitted at qemu_fdt_setprop_cells.
>> 
>> Cc: qemu-sta...@nongnu.org
>> Signed-off-by: Jiaxun Yang 
>> Reviewed-by: Song Gao 
>> Message-Id: <20240520-loongarch-fdt-memnode-v1-1-5ea9be939...@flygoat.com>
>> Signed-off-by: Song Gao 
>> ---
>>   hw/loongarch/virt.c | 3 ++-
>>   1 file changed, 2 insertions(+), 1 deletion(-)
>> 
>> diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
>> index e3bdf085b5..3e6e93edf3 100644
>> --- a/hw/loongarch/virt.c
>> +++ b/hw/loongarch/virt.c
>> @@ -464,7 +464,8 @@ static void fdt_add_memory_node(MachineState *ms,
>>   char *nodename = g_strdup_printf("/memory@%" PRIx64, base);
>>   
>>   qemu_fdt_add_subnode(ms->fdt, nodename);
>> -qemu_fdt_setprop_cells(ms->fdt, nodename, "reg", 0, base, 0, size);
>> +qemu_fdt_setprop_cells(ms->fdt, nodename, "reg", base >> 32, base,
>> +   size >> 32, size);
>>   qemu_fdt_setprop_string(ms->fdt, nodename, "device_type", "memory");
>>   
>>   if (ms->numa_state && ms->numa_state->num_nodes) {
>
> This commit changes exactly the same place as the previous commit,
> v9.0.0-274-gb11f981452, "hw/loongarch: Fix fdt memory node wrong 'reg'".
>
> Was it the wrong fix?

Yes, I believe previous commit is the wrong fix on the same problem.

>
> Note the previous commit isn't in any released version of qemu.  So
> when picking up for any stable release, both needs to be picked up :)

Please go ahead!

Thanks
- Jiaxun

>
> Thanks,
>
> /mjt
> -- 
> GPG Key transition (from rsa2048 to rsa4096) since 2024-04-24.
> New key: rsa4096/61AD3D98ECDF2C8E  9D8B E14E 3F2A 9DD7 9199  28F1 61AD 
> 3D98 ECDF 2C8E
> Old key: rsa2048/457CE0A0804465C5  6EE1 95D1 886E 8FFB 810D  4324 457C 
> E0A0 8044 65C5
> Transition statement: http://www.corpit.ru/mjt/gpg-transition-2024.txt

-- 
- Jiaxun



Re: [PATCH v3 0/3] Add extioi virt extension support

2024-05-23 Thread Jiaxun Yang



在2024年5月21日五月 下午1:32,Song Gao写道:
> On LoongArch, IRQs can be routed to four vcpus with hardware extioi.
> This patch adds the extioi virt extension support so that the IRQ can
> route to 256 vcpus.

Hi Song,

Sorry for chime in here, I'm a little bit confused by this series, can
you give me a little bit of context behind?

I don't see this functionality on 3A5000/3A6000's user manual, so is this
some sort of undocumented hardware feature?

I checked openEuler kernel patch you referred, it seems like this applies to
hypervisor mode only. I suppose it should be handled by KVM subsystem in
kernel, why do we need this in user mode device emulation?

Currently, LoongArch's in-kernel irqchip functionality does not include such
feature, can we see KVM side support for this, or at least a draft 
specification?

Thanks
- Jiaxun

>
> v3:
> - Split patch2 to two small patch.
> - remove unused code.
> - loongarch_extioi_reset() clear status without checking virt extioi
>   features.
> - Link to v2: 
> https://patchew.org/QEMU/20240514090756.988096-1-gaos...@loongson.cn/
>
> v2:
> - Split the patch to two small patch.
> - Drop 'RFC' title. extioi virt extension suport only enable on kvm
>   mode and  the extioi driver need patch[1].
>   but this series do not affect the old codes in any way.
> - Link to v1: 
> https://lore.kernel.org/all/20240116022526.498613-1-gaos...@loongson.cn/#r
>
> [1]: 
> https://gitee.com/openeuler/kernel/commit/5d97cff72f91f4f20a536efd60eca75bfcb78a64
>
> Thanks.
> Song Gao
>
> Song Gao (3):
>   hw/intc/loongarch_extioi: Add extioi virt extension definition
>   hw/loongarch/virt: Enable extioi virt extension
>   hw/loongarch/virt: Use MemTxAttrs interface for misc ops
>
>  include/hw/intc/loongarch_extioi.h |  21 ++
>  include/hw/loongarch/virt.h|   2 +
>  target/loongarch/cpu.h |   1 +
>  hw/intc/loongarch_extioi.c |  88 +-
>  hw/loongarch/virt.c| 116 +
>  5 files changed, 210 insertions(+), 18 deletions(-)
>
> -- 
> 2.34.1

-- 
- Jiaxun



[PATCH] hw/loongarch/virt: Fix FDT memory node address width

2024-05-20 Thread Jiaxun Yang
Higher bits for memory nodes were omitted at qemu_fdt_setprop_cells.

Signed-off-by: Jiaxun Yang 
---
This should be stable backported, otherwise DT boot is totally broken.
---
 hw/loongarch/virt.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index f0640d2d8035..f97626bacf65 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -463,7 +463,8 @@ static void fdt_add_memory_node(MachineState *ms,
 char *nodename = g_strdup_printf("/memory@%" PRIx64, base);
 
 qemu_fdt_add_subnode(ms->fdt, nodename);
-qemu_fdt_setprop_cells(ms->fdt, nodename, "reg", 0, base, 0, size);
+qemu_fdt_setprop_cells(ms->fdt, nodename, "reg", base >> 32, base,
+   size >> 32, size);
 qemu_fdt_setprop_string(ms->fdt, nodename, "device_type", "memory");
 
 if (ms->numa_state && ms->numa_state->num_nodes) {

---
base-commit: 85ef20f1673feaa083f4acab8cf054df77b0dbed
change-id: 20240520-loongarch-fdt-memnode-e36c01ae9b6e

Best regards,
-- 
Jiaxun Yang 




Re: [PATCH 0/5] hw/mips/loongson3_virt: Implement IPI support

2024-05-16 Thread Jiaxun Yang



在2024年5月8日五月 下午10:41,Philippe Mathieu-Daudé写道:
> On 8/5/24 15:06, Jiaxun Yang wrote:
>> Hi all,
>> 
>> This series enabled IPI support for loongson3 virt board, loosely
>> based on my previous work[1].
>> It generalized loongarch_ipi device to share among both loongarch
>> and MIPS machines.
>
>
>> Signed-off-by: Jiaxun Yang 
>> ---
>> Jiaxun Yang (5):
>>hw/intc/loongarch_ipi: Remove pointless MAX_CPU check
>>hw/intc/loongarch_ipi: Rename as loongson_ipi
>>hw/intc/loongson_ipi: Implement IOCSR address space for MIPS
>
> So far patches 1-3 queued to hw-misc tree, thanks.

Hi Philippe,

Thanks! What's your plan with the rest of the series and earlier MIPS
CPS SMP series?

Let me know if you need help on testing etc.

Thanks
-- 
- Jiaxun



[PATCH] hw/mips/loongson3_virt: Implement node counter timer

2024-05-12 Thread Jiaxun Yang
Node counter is a timer presents on Loongson-3 chips, which runs
as fast as CPU clock. It's being mapped into a MMIO location.

Emulate this for loongson3_virt machine, in hope that kernel can
use it as a better clock source.

Hardware's behavior on 32-bit read/write is also emulated in case
legacy kernel is trying to use it with hi/lo splitted read.

Signed-off-by: Jiaxun Yang 
---
 hw/mips/loongson3_bootp.h |  1 +
 hw/mips/loongson3_virt.c  | 38 ++
 2 files changed, 35 insertions(+), 4 deletions(-)

diff --git a/hw/mips/loongson3_bootp.h b/hw/mips/loongson3_bootp.h
index 1b0dd3b59171..c6a435397d2c 100644
--- a/hw/mips/loongson3_bootp.h
+++ b/hw/mips/loongson3_bootp.h
@@ -210,6 +210,7 @@ enum {
 VIRT_PCIE_ECAM,
 VIRT_BIOS_ROM,
 VIRT_UART,
+VIRT_NODECNT,
 VIRT_LIOINTC,
 VIRT_PCIE_MMIO,
 VIRT_HIGHMEM
diff --git a/hw/mips/loongson3_virt.c b/hw/mips/loongson3_virt.c
index b10a611a98f4..b78ac8032096 100644
--- a/hw/mips/loongson3_virt.c
+++ b/hw/mips/loongson3_virt.c
@@ -74,6 +74,7 @@ const MemMapEntry virt_memmap[] = {
 [VIRT_PCIE_ECAM] =   { 0x1a00, 0x200 },
 [VIRT_BIOS_ROM] ={ 0x1fc0,  0x20 },
 [VIRT_UART] ={ 0x1fe001e0,   0x8 },
+[VIRT_NODECNT] = { 0x3ff00408,   0x8 },
 [VIRT_LIOINTC] = { 0x3ff01400,  0x64 },
 [VIRT_PCIE_MMIO] =   { 0x4000,0x4000 },
 [VIRT_HIGHMEM] = { 0x8000,   0x0 }, /* Variable */
@@ -92,6 +93,7 @@ static const MemMapEntry loader_rommap[] = {
 
 struct LoongsonMachineState {
 MachineState parent_obj;
+Clock *cpuclk;
 MemoryRegion *pio_alias;
 MemoryRegion *mmio_alias;
 MemoryRegion *ecam_alias;
@@ -145,6 +147,29 @@ static const MemoryRegionOps loongson3_pm_ops = {
 }
 };
 
+static uint64_t loongson3_nodecnt_read(void *opaque,
+hwaddr addr, unsigned size)
+{
+LoongsonMachineState *s = opaque;
+int64_t now_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+uint64_t ticks = clock_ns_to_ticks(s->cpuclk, now_ns);
+
+if (addr == 0x4) {
+return ticks >> 32;
+}
+
+return ticks;
+}
+
+static const MemoryRegionOps loongson3_nodecnt_ops = {
+.read  = loongson3_nodecnt_read,
+.endianness = DEVICE_NATIVE_ENDIAN,
+.valid.min_access_size = 4,
+.valid.max_access_size = 8,
+.impl.min_access_size = 4,
+.impl.max_access_size = 8,
+};
+
 #define DEF_LOONGSON3_FREQ (800 * 1000 * 1000)
 
 static uint64_t get_cpu_freq_hz(void)
@@ -463,7 +488,6 @@ static void mips_loongson3_virt_init(MachineState *machine)
 int i;
 long bios_size;
 MIPSCPU *cpu;
-Clock *cpuclk;
 CPUMIPSState *env;
 DeviceState *liointc;
 char *filename;
@@ -471,10 +495,12 @@ static void mips_loongson3_virt_init(MachineState 
*machine)
 const char *kernel_filename = machine->kernel_filename;
 const char *initrd_filename = machine->initrd_filename;
 ram_addr_t ram_size = machine->ram_size;
+LoongsonMachineState *ms = LOONGSON_MACHINE(machine);
 MemoryRegion *address_space_mem = get_system_memory();
 MemoryRegion *ram = g_new(MemoryRegion, 1);
 MemoryRegion *bios = g_new(MemoryRegion, 1);
 MemoryRegion *iomem = g_new(MemoryRegion, 1);
+MemoryRegion *nodecnt = g_new(MemoryRegion, 1);
 
 /* TODO: TCG will support all CPU types */
 if (!kvm_enabled()) {
@@ -520,14 +546,14 @@ static void mips_loongson3_virt_init(MachineState 
*machine)
 sysbus_create_simple("goldfish_rtc", virt_memmap[VIRT_RTC].base,
  qdev_get_gpio_in(liointc, RTC_IRQ));
 
-cpuclk = clock_new(OBJECT(machine), "cpu-refclk");
-clock_set_hz(cpuclk, DEF_LOONGSON3_FREQ);
+ms->cpuclk = clock_new(OBJECT(machine), "cpu-refclk");
+clock_set_hz(ms->cpuclk, DEF_LOONGSON3_FREQ);
 
 for (i = 0; i < machine->smp.cpus; i++) {
 int ip;
 
 /* init CPUs */
-cpu = mips_cpu_create_with_clock(machine->cpu_type, cpuclk);
+cpu = mips_cpu_create_with_clock(machine->cpu_type, ms->cpuclk);
 
 /* Init internal devices */
 cpu_mips_irq_init_cpu(cpu);
@@ -553,6 +579,8 @@ static void mips_loongson3_virt_init(MachineState *machine)
machine->ram, 0, virt_memmap[VIRT_LOWMEM].size);
 memory_region_init_io(iomem, NULL, _pm_ops,
NULL, "loongson3_pm", virt_memmap[VIRT_PM].size);
+memory_region_init_io(nodecnt, NULL, _nodecnt_ops, ms,
+  "loongson3_nodecnt", virt_memmap[VIRT_NODECNT].size);
 
 memory_region_add_subregion(address_space_mem,
   virt_memmap[VIRT_LOWMEM].base, ram);
@@ -562,6 +590,8 @@ static void mips_loongson3_virt_init(MachineState *machine)
   virt_memmap[VIRT_HIGHMEM].base, machine->ram);
 memory_

[PATCH] mips64el-softmmu: Enable MTTCG

2024-05-11 Thread Jiaxun Yang
MTTCG was disabled in a092a9554771 ("configure: disable MTTCG
for MIPS guests") due to test case instability.

I was able to reproduce this issue with in latest QEMU and look
into reason behind that.

What actually happend is kernel's CP0 timer synchronisation
mechanism assumed a consistent latency in memory access between
cores, which TCG can't guarantee. Thus there is a huge drift in
count value between cores, and in early kernel versions CP0 timer
is always used as sched_clock.

sched_clock drift back on some cores triggered RCU watchdog in
some extreme cases.

This can be resolved by setting clocksource to MIPS, which allows
clocksource to drift together with sched_clock. However this will
leed to other problems after boot.

Another option would beupdating kernel to later version, which
will use GIC as sched_clock.

In non-MTTCG build, the execution is slow enough so kernel won't
observe back drifts.

Test results:

With clocksource=MIPS
```
 ~/tmp/retry/retry.py -n 100 -c -- ./qemu-system-mips64el \
-display none -vga none -serial mon:stdio \
-machine malta -kernel ./vmlinux-4.7.0-rc1.I6400 \
-cpu I6400 -smp 8 -vga std \
-append "printk.time=0 clocksource=MIPS console=tty0 console=ttyS0 
panic=-1" \
--no-reboot

100, 0, PASS, 5.258126, 100, 100, -
Results summary:
0: 100 times (100.00%), avg time 6.508 (55.53 varience/7.45 deviation)
Ran command 100 times, 100 passes
```

With linux-next:
```
 ~/tmp/retry/retry.py -n 100 -c -- ./qemu-system-mips64el \
-display none -vga none -serial mon:stdio \
-machine malta -kernel ~/linux-next/vmlinux \
-cpu I6400 -smp 8 -vga std \
-append "printk.time=0 console=tty0 console=ttyS0 panic=-1" \
--no-reboot

100, 0, PASS, 4.507921, 100, 100, -
Results summary:
0: 100 times (100.00%), avg time 4.233 (0.04 varience/0.21 deviation)
Ran command 100 times, 100 passes
```

Signed-off-by: Jiaxun Yang 
---
I'll leave the test case alone as it's already marked as QEMU_TEST_FLAKY_TESTS
---
 configs/targets/mips64el-softmmu.mak | 1 +
 1 file changed, 1 insertion(+)

diff --git a/configs/targets/mips64el-softmmu.mak 
b/configs/targets/mips64el-softmmu.mak
index 8d9ab3ddc4b1..199b1d909a7d 100644
--- a/configs/targets/mips64el-softmmu.mak
+++ b/configs/targets/mips64el-softmmu.mak
@@ -1,3 +1,4 @@
 TARGET_ARCH=mips64
 TARGET_BASE_ARCH=mips
+TARGET_SUPPORTS_MTTCG=y
 TARGET_NEED_FDT=y

---
base-commit: 248f6f62df073a3b4158fd0093863ab885feabb5
change-id: 20240511-mips_mttcg-47a6b19074b3

Best regards,
-- 
Jiaxun Yang 




Re: [PATCH] hw/mips/loongson3_virt: Emulate suspend function

2024-05-08 Thread Jiaxun Yang



在2024年5月8日五月 下午5:48,Philippe Mathieu-Daudé写道:
> On 8/5/24 17:35, Philippe Mathieu-Daudé wrote:
>> On 8/5/24 11:31, Jiaxun Yang wrote:
>>> Suspend function is emulated as what hardware actually do.
>>> Doorbell register fields are updates to include suspend value,
>>> suspend vector is encoded in firmware blob and fw_cfg is updated
>>> to include S3 bits as what x86 did.
>>>
>>> Signed-off-by: Jiaxun Yang 
>>> ---
>>>   hw/mips/loongson3_bootp.c |  1 +
>>>   hw/mips/loongson3_virt.c  | 19 +++
>>>   2 files changed, 20 insertions(+)
>> 
>> Thanks, patch queued.
>
> Fixed:
>
> ERROR: use g_memdup2() instead of unsafe g_memdup()
> #76: FILE: hw/mips/loongson3_virt.c:293:
> +fw_cfg_add_file(fw_cfg, "etc/system-states", g_memdup(suspend, 6), 6);

Thanks, I omitted this one as it is copied from hw/acpi/core.c

Should we fix that one as well?

-- 
- Jiaxun



[PATCH 0/5] hw/mips/loongson3_virt: Implement IPI support

2024-05-08 Thread Jiaxun Yang
Hi all,

This series enabled IPI support for loongson3 virt board, loosely
based on my previous work[1].
It generalized loongarch_ipi device to share among both loongarch
and MIPS machines. 

Thanks

[1]: https://lore.kernel.org/all/20230521102307.87081-1-jiaxun.y...@flygoat.com/

To: qemu-devel@nongnu.org
Cc: Song Gao 

Signed-off-by: Jiaxun Yang 
---
Jiaxun Yang (5):
  hw/intc/loongarch_ipi: Remove pointless MAX_CPU check
  hw/intc/loongarch_ipi: Rename as loongson_ipi
  hw/intc/loongson_ipi: Implement IOCSR address space for MIPS
  hw/intc/loongson_ipi: Provide per core MMIO address spaces
  hw/mips/loongson3_virt: Wire up loongson_ipi device

 MAINTAINERS|   4 +
 hw/intc/Kconfig|   2 +-
 hw/intc/loongarch_ipi.c|  19 +-
 hw/intc/loongson_ipi.c | 411 +
 hw/intc/meson.build|   2 +-
 hw/intc/trace-events   |   8 +-
 hw/loongarch/Kconfig   |   2 +-
 hw/loongarch/virt.c|   4 +-
 hw/mips/Kconfig|   1 +
 hw/mips/loongson3_bootp.c  |   2 -
 hw/mips/loongson3_bootp.h  |   3 +
 hw/mips/loongson3_virt.c   |  39 +-
 .../hw/intc/{loongarch_ipi.h => loongson_ipi.h}|  14 +-
 include/hw/loongarch/virt.h|   2 +-
 14 files changed, 475 insertions(+), 38 deletions(-)
---
base-commit: 248f6f62df073a3b4158fd0093863ab885feabb5
change-id: 20240508-loongson3-ipi-65e99b47c400

Best regards,
-- 
Jiaxun Yang 




[PATCH 5/5] hw/mips/loongson3_virt: Wire up loongson_ipi device

2024-05-08 Thread Jiaxun Yang
Wire up loongson_ipi device for loongson3_virt machine, so we
can have SMP support for TCG backend as well.

Signed-off-by: Jiaxun Yang 
---
 hw/mips/Kconfig   |  1 +
 hw/mips/loongson3_bootp.c |  2 --
 hw/mips/loongson3_bootp.h |  3 +++
 hw/mips/loongson3_virt.c  | 39 +--
 4 files changed, 41 insertions(+), 4 deletions(-)

diff --git a/hw/mips/Kconfig b/hw/mips/Kconfig
index 5c83ef49cf6f..6f09fedc946e 100644
--- a/hw/mips/Kconfig
+++ b/hw/mips/Kconfig
@@ -57,6 +57,7 @@ config LOONGSON3V
 imply USB_OHCI_PCI
 select SERIAL
 select GOLDFISH_RTC
+select LOONGSON_IPI
 select LOONGSON_LIOINTC
 select PCI_EXPRESS_GENERIC_BRIDGE
 select MSI_NONBROKEN
diff --git a/hw/mips/loongson3_bootp.c b/hw/mips/loongson3_bootp.c
index f99af229327a..474d3556b2e5 100644
--- a/hw/mips/loongson3_bootp.c
+++ b/hw/mips/loongson3_bootp.c
@@ -25,8 +25,6 @@
 #include "hw/boards.h"
 #include "hw/mips/loongson3_bootp.h"
 
-#define LOONGSON3_CORE_PER_NODE 4
-
 static void init_cpu_info(void *g_cpuinfo, uint64_t cpu_freq)
 {
 struct efi_cpuinfo_loongson *c = g_cpuinfo;
diff --git a/hw/mips/loongson3_bootp.h b/hw/mips/loongson3_bootp.h
index 1b0dd3b59171..9091265df7fc 100644
--- a/hw/mips/loongson3_bootp.h
+++ b/hw/mips/loongson3_bootp.h
@@ -200,6 +200,8 @@ struct boot_params {
 struct efi_reset_system_t reset_system;
 };
 
+#define LOONGSON3_CORE_PER_NODE 4
+
 /* Overall MMIO & Memory layout */
 enum {
 VIRT_LOWMEM,
@@ -211,6 +213,7 @@ enum {
 VIRT_BIOS_ROM,
 VIRT_UART,
 VIRT_LIOINTC,
+VIRT_IPI,
 VIRT_PCIE_MMIO,
 VIRT_HIGHMEM
 };
diff --git a/hw/mips/loongson3_virt.c b/hw/mips/loongson3_virt.c
index b10a611a98f4..1052fb7d6747 100644
--- a/hw/mips/loongson3_virt.c
+++ b/hw/mips/loongson3_virt.c
@@ -36,6 +36,7 @@
 #include "hw/mips/loongson3_bootp.h"
 #include "hw/misc/unimp.h"
 #include "hw/intc/i8259.h"
+#include "hw/intc/loongson_ipi.h"
 #include "hw/loader.h"
 #include "hw/isa/superio.h"
 #include "hw/pci/msi.h"
@@ -74,6 +75,7 @@ const MemMapEntry virt_memmap[] = {
 [VIRT_PCIE_ECAM] =   { 0x1a00, 0x200 },
 [VIRT_BIOS_ROM] ={ 0x1fc0,  0x20 },
 [VIRT_UART] ={ 0x1fe001e0,   0x8 },
+[VIRT_IPI] = { 0x3ff01000, 0x400 },
 [VIRT_LIOINTC] = { 0x3ff01400,  0x64 },
 [VIRT_PCIE_MMIO] =   { 0x4000,0x4000 },
 [VIRT_HIGHMEM] = { 0x8000,   0x0 }, /* Variable */
@@ -466,6 +468,7 @@ static void mips_loongson3_virt_init(MachineState *machine)
 Clock *cpuclk;
 CPUMIPSState *env;
 DeviceState *liointc;
+DeviceState *ipi = NULL;
 char *filename;
 const char *kernel_cmdline = machine->kernel_cmdline;
 const char *kernel_filename = machine->kernel_filename;
@@ -475,6 +478,7 @@ static void mips_loongson3_virt_init(MachineState *machine)
 MemoryRegion *ram = g_new(MemoryRegion, 1);
 MemoryRegion *bios = g_new(MemoryRegion, 1);
 MemoryRegion *iomem = g_new(MemoryRegion, 1);
+MemoryRegion *iocsr = g_new(MemoryRegion, 1);
 
 /* TODO: TCG will support all CPU types */
 if (!kvm_enabled()) {
@@ -508,6 +512,19 @@ static void mips_loongson3_virt_init(MachineState *machine)
 create_unimplemented_device("mmio fallback 0", 0x1000, 256 * MiB);
 create_unimplemented_device("mmio fallback 1", 0x3000, 256 * MiB);
 
+memory_region_init(iocsr, OBJECT(machine), "loongson3.iocsr", UINT32_MAX);
+
+/* IPI controller is in kernel for KVM */
+if (!kvm_enabled()) {
+ipi = qdev_new(TYPE_LOONGSON_IPI);
+qdev_prop_set_uint32(ipi, "num-cpu", machine->smp.cpus);
+sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), _fatal);
+memory_region_add_subregion(iocsr, SMP_IPI_MAILBOX,
+sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 0));
+memory_region_add_subregion(iocsr, MAIL_SEND_ADDR,
+sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 1));
+}
+
 liointc = qdev_new("loongson.liointc");
 sysbus_realize_and_unref(SYS_BUS_DEVICE(liointc), _fatal);
 
@@ -524,6 +541,8 @@ static void mips_loongson3_virt_init(MachineState *machine)
 clock_set_hz(cpuclk, DEF_LOONGSON3_FREQ);
 
 for (i = 0; i < machine->smp.cpus; i++) {
+int node = i / LOONGSON3_CORE_PER_NODE;
+int core = i % LOONGSON3_CORE_PER_NODE;
 int ip;
 
 /* init CPUs */
@@ -534,12 +553,28 @@ static void mips_loongson3_virt_init(MachineState 
*machine)
 cpu_mips_clock_init(cpu);
 qemu_register_reset(main_cpu_reset, cpu);
 
-if (i >= 4) {
+if (ipi) {
+hwaddr base = ((hwaddr)node << 44) + virt_memmap[VIRT_IPI].base;
+base += core * 0x100;
+qdev_connect_gpio_out(ipi, i, cpu->env.irq[6]);
+sysbu

[PATCH 4/5] hw/intc/loongson_ipi: Provide per core MMIO address spaces

2024-05-08 Thread Jiaxun Yang
The real IPI hardware have dedicated MMIO registers mapped into
memory address space for every core. This is not used by LoongArch
guest software but it is essential for CPU without IOCSR such as
Loongson-3A1000.

Implement it with existing infrastructure.

Signed-off-by: Jiaxun Yang 
---
 hw/intc/loongson_ipi.c | 81 --
 include/hw/intc/loongson_ipi.h |  2 ++
 2 files changed, 64 insertions(+), 19 deletions(-)

diff --git a/hw/intc/loongson_ipi.c b/hw/intc/loongson_ipi.c
index 93cc50a37a11..c8a25b4eb8e2 100644
--- a/hw/intc/loongson_ipi.c
+++ b/hw/intc/loongson_ipi.c
@@ -23,16 +23,14 @@
 #endif
 #include "trace.h"
 
-static MemTxResult loongson_ipi_readl(void *opaque, hwaddr addr,
+static MemTxResult loongson_ipi_core_readl(void *opaque, hwaddr addr,
uint64_t *data,
unsigned size, MemTxAttrs attrs)
 {
-IPICore *s;
-LoongsonIPI *ipi = opaque;
+IPICore *s = opaque;
 uint64_t ret = 0;
 int index = 0;
 
-s = >cpu[attrs.requester_id];
 addr &= 0xff;
 switch (addr) {
 case CORE_STATUS_OFF:
@@ -61,6 +59,21 @@ static MemTxResult loongson_ipi_readl(void *opaque, hwaddr 
addr,
 return MEMTX_OK;
 }
 
+static MemTxResult loongson_ipi_iocsr_readl(void *opaque, hwaddr addr,
+   uint64_t *data,
+   unsigned size, MemTxAttrs attrs)
+{
+LoongsonIPI *ipi = opaque;
+IPICore *s;
+
+if (attrs.requester_id >= ipi->num_cpu) {
+return MEMTX_DECODE_ERROR;
+}
+
+s = >cpu[attrs.requester_id];
+return loongson_ipi_core_readl(s, addr, data, size, attrs);
+}
+
 static AddressSpace *get_cpu_iocsr_as(CPUState *cpu)
 {
 #ifdef TARGET_LOONGARCH64
@@ -174,17 +187,17 @@ static MemTxResult any_send(uint64_t val, MemTxAttrs 
attrs)
 return send_ipi_data(cs, val, addr, attrs);
 }
 
-static MemTxResult loongson_ipi_writel(void *opaque, hwaddr addr, uint64_t val,
-unsigned size, MemTxAttrs attrs)
+static MemTxResult loongson_ipi_core_writel(void *opaque, hwaddr addr,
+uint64_t val, unsigned size,
+MemTxAttrs attrs)
 {
-LoongsonIPI *ipi = opaque;
-IPICore *s;
+IPICore *s = opaque;
+LoongsonIPI *ipi = s->ipi;
 int index = 0;
 uint32_t cpuid;
 uint8_t vector;
 CPUState *cs;
 
-s = >cpu[attrs.requester_id];
 addr &= 0xff;
 trace_loongson_ipi_write(size, (uint64_t)addr, val);
 switch (addr) {
@@ -215,13 +228,11 @@ static MemTxResult loongson_ipi_writel(void *opaque, 
hwaddr addr, uint64_t val,
 /* IPI status vector */
 vector = extract8(val, 0, 5);
 cs = ipi_getcpu(cpuid);
-if (cs == NULL) {
+if (cs == NULL || cs->cpu_index >= ipi->num_cpu) {
 return MEMTX_DECODE_ERROR;
 }
-
-/* override requester_id */
-attrs.requester_id = cs->cpu_index;
-loongson_ipi_writel(ipi, CORE_SET_OFF, BIT(vector), 4, attrs);
+loongson_ipi_core_writel(>cpu[cs->cpu_index], CORE_SET_OFF,
+ BIT(vector), 4, attrs);
 break;
 default:
 qemu_log_mask(LOG_UNIMP, "invalid write: %x", (uint32_t)addr);
@@ -231,9 +242,34 @@ static MemTxResult loongson_ipi_writel(void *opaque, 
hwaddr addr, uint64_t val,
 return MEMTX_OK;
 }
 
-static const MemoryRegionOps loongson_ipi_ops = {
-.read_with_attrs = loongson_ipi_readl,
-.write_with_attrs = loongson_ipi_writel,
+static MemTxResult loongson_ipi_iocsr_writel(void *opaque, hwaddr addr,
+uint64_t val, unsigned size,
+MemTxAttrs attrs)
+{
+LoongsonIPI *ipi = opaque;
+IPICore *s;
+
+if (attrs.requester_id >= ipi->num_cpu) {
+return MEMTX_DECODE_ERROR;
+}
+
+s = >cpu[attrs.requester_id];
+return loongson_ipi_core_writel(s, addr, val, size, attrs);
+}
+
+static const MemoryRegionOps loongson_ipi_core_ops = {
+.read_with_attrs = loongson_ipi_core_readl,
+.write_with_attrs = loongson_ipi_core_writel,
+.impl.min_access_size = 4,
+.impl.max_access_size = 4,
+.valid.min_access_size = 4,
+.valid.max_access_size = 8,
+.endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static const MemoryRegionOps loongson_ipi_iocsr_ops = {
+.read_with_attrs = loongson_ipi_iocsr_readl,
+.write_with_attrs = loongson_ipi_iocsr_writel,
 .impl.min_access_size = 4,
 .impl.max_access_size = 4,
 .valid.min_access_size = 4,
@@ -282,7 +318,7 @@ static void loongson_ipi_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 
-memory_region_init_io(>ipi_iocsr_mem, OBJECT(dev), _ipi_ops,
+memory_region_init_io(>ipi_iocsr_mem, OBJECT(

[PATCH 1/5] hw/intc/loongarch_ipi: Remove pointless MAX_CPU check

2024-05-08 Thread Jiaxun Yang
Since cpuid will be checked by ipi_getcpu anyway, there is
no point to enforce MAX_CPU here.

This also saved us from including loongarch board header.

Signed-off-by: Jiaxun Yang 
---
 hw/intc/loongarch_ipi.c | 19 ++-
 hw/intc/trace-events|  2 --
 2 files changed, 2 insertions(+), 19 deletions(-)

diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c
index a184112b0923..44b3b9c138d6 100644
--- a/hw/intc/loongarch_ipi.c
+++ b/hw/intc/loongarch_ipi.c
@@ -6,6 +6,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "hw/boards.h"
 #include "hw/sysbus.h"
 #include "hw/intc/loongarch_ipi.h"
 #include "hw/irq.h"
@@ -13,9 +14,8 @@
 #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 "target/loongarch/cpu.h"
 #include "trace.h"
 
 static MemTxResult loongarch_ipi_readl(void *opaque, hwaddr addr,
@@ -122,11 +122,6 @@ static MemTxResult mail_send(uint64_t val, MemTxAttrs 
attrs)
 CPUState *cs;
 
 cpuid = extract32(val, 16, 10);
-if (cpuid >= LOONGARCH_MAX_CPUS) {
-trace_loongarch_ipi_unsupported_cpuid("IOCSR_MAIL_SEND", cpuid);
-return MEMTX_DECODE_ERROR;
-}
-
 cs = ipi_getcpu(cpuid);
 if (cs == NULL) {
 return MEMTX_DECODE_ERROR;
@@ -146,11 +141,6 @@ static MemTxResult any_send(uint64_t val, MemTxAttrs attrs)
 CPUState *cs;
 
 cpuid = extract32(val, 16, 10);
-if (cpuid >= LOONGARCH_MAX_CPUS) {
-trace_loongarch_ipi_unsupported_cpuid("IOCSR_ANY_SEND", cpuid);
-return MEMTX_DECODE_ERROR;
-}
-
 cs = ipi_getcpu(cpuid);
 if (cs == NULL) {
 return MEMTX_DECODE_ERROR;
@@ -201,11 +191,6 @@ static MemTxResult loongarch_ipi_writel(void *opaque, 
hwaddr addr, uint64_t val,
 break;
 case IOCSR_IPI_SEND:
 cpuid = extract32(val, 16, 10);
-if (cpuid >= LOONGARCH_MAX_CPUS) {
-trace_loongarch_ipi_unsupported_cpuid("IOCSR_IPI_SEND", cpuid);
-return MEMTX_DECODE_ERROR;
-}
-
 /* IPI status vector */
 vector = extract8(val, 0, 5);
 cs = ipi_getcpu(cpuid);
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
index 47340b5bc138..a979784f9bee 100644
--- a/hw/intc/trace-events
+++ b/hw/intc/trace-events
@@ -294,8 +294,6 @@ sh_intc_set(int id, int enable) "setting interrupt group %d 
to %d"
 # loongarch_ipi.c
 loongarch_ipi_read(unsigned size, uint64_t addr, uint64_t val) "size: %u addr: 
0x%"PRIx64 "val: 0x%"PRIx64
 loongarch_ipi_write(unsigned size, uint64_t addr, uint64_t val) "size: %u 
addr: 0x%"PRIx64 "val: 0x%"PRIx64
-loongarch_ipi_unsupported_cpuid(const char *s, uint32_t cpuid) "%s unsupported 
cpuid 0x%" PRIx32
-
 # loongarch_pch_pic.c
 loongarch_pch_pic_irq_handler(int irq, int level) "irq %d level %d"
 loongarch_pch_pic_low_readw(unsigned size, uint64_t addr, uint64_t val) "size: 
%u addr: 0x%"PRIx64 "val: 0x%" PRIx64

-- 
2.34.1




[PATCH 2/5] hw/intc/loongarch_ipi: Rename as loongson_ipi

2024-05-08 Thread Jiaxun Yang
This device will be shared among LoongArch and MIPS
based Loongson machine, rename it as loongson_ipi
to reflect this nature.

Signed-off-by: Jiaxun Yang 
---
 MAINTAINERS|   4 +
 hw/intc/Kconfig|   2 +-
 hw/intc/loongson_ipi.c | 347 +
 hw/intc/meson.build|   2 +-
 hw/intc/trace-events   |   6 +-
 hw/loongarch/Kconfig   |   2 +-
 hw/loongarch/virt.c|   4 +-
 .../hw/intc/{loongarch_ipi.h => loongson_ipi.h}|  12 +-
 include/hw/loongarch/virt.h|   2 +-
 9 files changed, 366 insertions(+), 15 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 2f08cc528eb6..290dc3227baf 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1241,7 +1241,9 @@ F: configs/devices/loongarch64-softmmu/default.mak
 F: hw/loongarch/
 F: include/hw/loongarch/virt.h
 F: include/hw/intc/loongarch_*.h
+F: include/hw/intc/loongson_ipi.h
 F: hw/intc/loongarch_*.c
+F: hw/intc/loongson_ipi.c
 F: include/hw/pci-host/ls7a.h
 F: hw/rtc/ls7a_rtc.c
 F: gdb-xml/loongarch*.xml
@@ -1375,10 +1377,12 @@ Loongson-3 virtual platforms
 M: Huacai Chen 
 R: Jiaxun Yang 
 S: Maintained
+F: hw/intc/loongson_ipi.c
 F: hw/intc/loongson_liointc.c
 F: hw/mips/loongson3_bootp.c
 F: hw/mips/loongson3_bootp.h
 F: hw/mips/loongson3_virt.c
+F: include/hw/intc/loongson_ipi.h
 F: include/hw/intc/loongson_liointc.h
 F: tests/avocado/machine_mips_loongson3v.py
 
diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
index ad59abebaa1d..58b6d3a71003 100644
--- a/hw/intc/Kconfig
+++ b/hw/intc/Kconfig
@@ -87,7 +87,7 @@ config GOLDFISH_PIC
 config M68K_IRQC
 bool
 
-config LOONGARCH_IPI
+config LOONGSON_IPI
 bool
 
 config LOONGARCH_PCH_PIC
diff --git a/hw/intc/loongson_ipi.c b/hw/intc/loongson_ipi.c
new file mode 100644
index ..8c888da3b27c
--- /dev/null
+++ b/hw/intc/loongson_ipi.c
@@ -0,0 +1,347 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Loongson ipi interrupt support
+ *
+ * Copyright (C) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "hw/boards.h"
+#include "hw/sysbus.h"
+#include "hw/intc/loongson_ipi.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+#include "qapi/error.h"
+#include "qemu/log.h"
+#include "exec/address-spaces.h"
+#include "migration/vmstate.h"
+#include "target/loongarch/cpu.h"
+#include "trace.h"
+
+static MemTxResult loongson_ipi_readl(void *opaque, hwaddr addr,
+   uint64_t *data,
+   unsigned size, MemTxAttrs attrs)
+{
+IPICore *s;
+LoongsonIPI *ipi = opaque;
+uint64_t ret = 0;
+int index = 0;
+
+s = >cpu[attrs.requester_id];
+addr &= 0xff;
+switch (addr) {
+case CORE_STATUS_OFF:
+ret = s->status;
+break;
+case CORE_EN_OFF:
+ret = s->en;
+break;
+case CORE_SET_OFF:
+ret = 0;
+break;
+case CORE_CLEAR_OFF:
+ret = 0;
+break;
+case CORE_BUF_20 ... CORE_BUF_38 + 4:
+index = (addr - CORE_BUF_20) >> 2;
+ret = s->buf[index];
+break;
+default:
+qemu_log_mask(LOG_UNIMP, "invalid read: %x", (uint32_t)addr);
+break;
+}
+
+trace_loongson_ipi_read(size, (uint64_t)addr, ret);
+*data = ret;
+return MEMTX_OK;
+}
+
+static void send_ipi_data(CPULoongArchState *env, uint64_t val, hwaddr addr,
+  MemTxAttrs attrs)
+{
+int i, mask = 0, data = 0;
+
+/*
+ * bit 27-30 is mask for byte writing,
+ * if the mask is 0, we need not to do anything.
+ */
+if ((val >> 27) & 0xf) {
+data = address_space_ldl(env->address_space_iocsr, addr,
+ attrs, NULL);
+for (i = 0; i < 4; i++) {
+/* get mask for byte writing */
+if (val & (0x1 << (27 + i))) {
+mask |= 0xff << (i * 8);
+}
+}
+}
+
+data &= mask;
+data |= (val >> 32) & ~mask;
+address_space_stl(env->address_space_iocsr, addr,
+  data, attrs, NULL);
+}
+
+static int archid_cmp(const void *a, const void *b)
+{
+   CPUArchId *archid_a = (CPUArchId *)a;
+   CPUArchId *archid_b = (CPUArchId *)b;
+
+   return archid_a->arch_id - archid_b->arch_id;
+}
+
+static CPUArchId *find_cpu_by_archid(MachineState *ms, uint32_t id)
+{
+CPUArchId apic_id, *found_cpu;
+
+apic_id.arch_id = id;
+found_cpu = bsearch(_id, ms->possible_cpus->cpus,
+ms->possible_cpus->len, sizeof(*ms->possible_cpus->cpus),
+archid_cmp)

[PATCH 3/5] hw/intc/loongson_ipi: Implement IOCSR address space for MIPS

2024-05-08 Thread Jiaxun Yang
Implement IOCSR address space get functions for MIPS/Loongson CPUs.

For MIPS/Loongson without IOCSR (i.e. Loongson-3A1000), get_cpu_iocsr_as
will return as null, and send_ipi_data will fail with MEMTX_DECODE_ERROR,
which matches expected behavior on hardware.

Signed-off-by: Jiaxun Yang 
---
I understand that there was a review comment stating that I shouldn't
use TARGET_* macros in device drivers. But I still think this is the
best way to handle architectural difference. There are many TARGET_*
usages in hw/virtio for similiar purpose.
---
 hw/intc/loongson_ipi.c | 39 ++-
 1 file changed, 30 insertions(+), 9 deletions(-)

diff --git a/hw/intc/loongson_ipi.c b/hw/intc/loongson_ipi.c
index 8c888da3b27c..93cc50a37a11 100644
--- a/hw/intc/loongson_ipi.c
+++ b/hw/intc/loongson_ipi.c
@@ -15,7 +15,12 @@
 #include "qemu/log.h"
 #include "exec/address-spaces.h"
 #include "migration/vmstate.h"
+#ifdef TARGET_LOONGARCH64
 #include "target/loongarch/cpu.h"
+#endif
+#ifdef TARGET_MIPS
+#include "target/mips/cpu.h"
+#endif
 #include "trace.h"
 
 static MemTxResult loongson_ipi_readl(void *opaque, hwaddr addr,
@@ -56,18 +61,35 @@ static MemTxResult loongson_ipi_readl(void *opaque, hwaddr 
addr,
 return MEMTX_OK;
 }
 
-static void send_ipi_data(CPULoongArchState *env, uint64_t val, hwaddr addr,
+static AddressSpace *get_cpu_iocsr_as(CPUState *cpu)
+{
+#ifdef TARGET_LOONGARCH64
+return LOONGARCH_CPU(cpu)->env.address_space_iocsr;
+#endif
+#ifdef TARGET_MIPS
+if (ase_lcsr_available(_CPU(cpu)->env)) {
+return _CPU(cpu)->env.iocsr.as;
+}
+#endif
+return NULL;
+}
+
+static MemTxResult send_ipi_data(CPUState *cpu, uint64_t val, hwaddr addr,
   MemTxAttrs attrs)
 {
 int i, mask = 0, data = 0;
+AddressSpace *iocsr_as = get_cpu_iocsr_as(cpu);
+
+if (!iocsr_as) {
+return MEMTX_DECODE_ERROR;
+}
 
 /*
  * bit 27-30 is mask for byte writing,
  * if the mask is 0, we need not to do anything.
  */
 if ((val >> 27) & 0xf) {
-data = address_space_ldl(env->address_space_iocsr, addr,
- attrs, NULL);
+data = address_space_ldl(iocsr_as, addr, attrs, NULL);
 for (i = 0; i < 4; i++) {
 /* get mask for byte writing */
 if (val & (0x1 << (27 + i))) {
@@ -78,8 +100,9 @@ static void send_ipi_data(CPULoongArchState *env, uint64_t 
val, hwaddr addr,
 
 data &= mask;
 data |= (val >> 32) & ~mask;
-address_space_stl(env->address_space_iocsr, addr,
-  data, attrs, NULL);
+address_space_stl(iocsr_as, addr, data, attrs, NULL);
+
+return MEMTX_OK;
 }
 
 static int archid_cmp(const void *a, const void *b)
@@ -130,8 +153,7 @@ static MemTxResult mail_send(uint64_t val, MemTxAttrs attrs)
 /* override requester_id */
 addr = SMP_IPI_MAILBOX + CORE_BUF_20 + (val & 0x1c);
 attrs.requester_id = cs->cpu_index;
-send_ipi_data(_CPU(cs)->env, val, addr, attrs);
-return MEMTX_OK;
+return send_ipi_data(cs, val, addr, attrs);
 }
 
 static MemTxResult any_send(uint64_t val, MemTxAttrs attrs)
@@ -149,8 +171,7 @@ static MemTxResult any_send(uint64_t val, MemTxAttrs attrs)
 /* override requester_id */
 addr = val & 0x;
 attrs.requester_id = cs->cpu_index;
-send_ipi_data(_CPU(cs)->env, val, addr, attrs);
-return MEMTX_OK;
+return send_ipi_data(cs, val, addr, attrs);
 }
 
 static MemTxResult loongson_ipi_writel(void *opaque, hwaddr addr, uint64_t val,

-- 
2.34.1




[PATCH] hw/mips/loongson3_virt: Emulate suspend function

2024-05-08 Thread Jiaxun Yang
Suspend function is emulated as what hardware actually do.
Doorbell register fields are updates to include suspend value,
suspend vector is encoded in firmware blob and fw_cfg is updated
to include S3 bits as what x86 did.

Signed-off-by: Jiaxun Yang 
---
 hw/mips/loongson3_bootp.c |  1 +
 hw/mips/loongson3_virt.c  | 19 +++
 2 files changed, 20 insertions(+)

diff --git a/hw/mips/loongson3_bootp.c b/hw/mips/loongson3_bootp.c
index f99af229327a..03a10b63c1b4 100644
--- a/hw/mips/loongson3_bootp.c
+++ b/hw/mips/loongson3_bootp.c
@@ -148,4 +148,5 @@ void init_reset_system(struct efi_reset_system_t *reset)
 reset->Shutdown = cpu_to_le64(0xbfc000a8);
 reset->ResetCold = cpu_to_le64(0xbfc00080);
 reset->ResetWarm = cpu_to_le64(0xbfc00080);
+reset->DoSuspend = cpu_to_le64(0xbfc000d0);
 }
diff --git a/hw/mips/loongson3_virt.c b/hw/mips/loongson3_virt.c
index 33eae01eca2b..f06518ad8f54 100644
--- a/hw/mips/loongson3_virt.c
+++ b/hw/mips/loongson3_virt.c
@@ -127,6 +127,9 @@ static void loongson3_pm_write(void *opaque, hwaddr addr,
 case 0x00:
 qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
 return;
+case 0x01:
+qemu_system_suspend_request();
+return;
 case 0xff:
 qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
 return;
@@ -250,6 +253,17 @@ static void init_boot_rom(void)
 0x240D00FF,   /* li  t1, 0xff 
*/
 0xA18D,   /* sb  t1, (t0) 
*/
 0x1000,   /* 1:  b   1b   
*/
+0x,   /* nop  
*/
+  /* Suspend  
*/
+0x3C0C9000,   /* dli t0, 0x900010080010   
*/
+0x358C,
+0x000C6438,
+0x358C1008,
+0x000C6438,
+0x358C0010,
+0x240D0001,   /* li  t1, 0x01 
*/
+0xA18D,   /* sb  t1, (t0) 
*/
+0x03e8,   /* jr  ra   
*/
 0x/* nop  
*/
 };
 
@@ -274,6 +288,10 @@ static void fw_conf_init(unsigned long ram_size)
 fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
 fw_cfg_add_i32(fw_cfg, FW_CFG_MACHINE_VERSION, 1);
 fw_cfg_add_i64(fw_cfg, FW_CFG_CPU_FREQ, get_cpu_freq_hz());
+
+uint8_t suspend[6] = {128, 0, 0, 129, 128, 128};
+fw_cfg_add_file(fw_cfg, "etc/system-states", g_memdup(suspend, 6), 6);
+
 qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
 }
 
@@ -551,6 +569,7 @@ static void mips_loongson3_virt_init(MachineState *machine)
machine->ram, 0, virt_memmap[VIRT_LOWMEM].size);
 memory_region_init_io(iomem, NULL, _pm_ops,
NULL, "loongson3_pm", virt_memmap[VIRT_PM].size);
+qemu_register_wakeup_support();
 
 memory_region_add_subregion(address_space_mem,
   virt_memmap[VIRT_LOWMEM].base, ram);

---
base-commit: d762bf97931b58839316b68a570eecc6143c9e3e
change-id: 20240508-loongson3v-suspend-cdd33a169eab

Best regards,
-- 
Jiaxun Yang 




[PATCH 5/5] hw/mips/boston: Implement multi core support

2024-05-06 Thread Jiaxun Yang
Implement multiple physical core support by passing topology
to CPS subsystem and generate cpu-map fdt node to decribe
new topology.

Signed-off-by: Jiaxun Yang 
---
 hw/mips/boston.c | 37 -
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/hw/mips/boston.c b/hw/mips/boston.c
index 1b44fb354c..4ed7d366fe 100644
--- a/hw/mips/boston.c
+++ b/hw/mips/boston.c
@@ -542,7 +542,10 @@ static const void *create_fdt(BostonState *s,
 qemu_fdt_setprop_cell(fdt, "/cpus", "#size-cells", 0x0);
 qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 0x1);
 
+qemu_fdt_add_subnode(fdt, "/cpus/cpu-map");
 for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
+char *map_path;
+
 name = g_strdup_printf("/cpus/cpu@%d", cpu);
 qemu_fdt_add_subnode(fdt, name);
 qemu_fdt_setprop_string(fdt, name, "compatible", "img,mips");
@@ -550,6 +553,27 @@ static const void *create_fdt(BostonState *s,
 qemu_fdt_setprop_cell(fdt, name, "reg", cpu);
 qemu_fdt_setprop_string(fdt, name, "device_type", "cpu");
 qemu_fdt_setprop_cells(fdt, name, "clocks", clk_ph, 
FDT_BOSTON_CLK_CPU);
+qemu_fdt_setprop_cell(fdt, name, "phandle", 
qemu_fdt_alloc_phandle(fdt));
+
+if (ms->smp.threads > 1) {
+map_path = g_strdup_printf(
+"/cpus/cpu-map/socket%d/cluster%d/core%d/thread%d",
+cpu / (ms->smp.clusters * ms->smp.cores * ms->smp.threads),
+(cpu / (ms->smp.cores * ms->smp.threads)) % ms->smp.clusters,
+(cpu / ms->smp.threads) % ms->smp.cores,
+cpu % ms->smp.threads);
+} else {
+map_path = g_strdup_printf(
+"/cpus/cpu-map/socket%d/cluster%d/core%d",
+cpu / (ms->smp.clusters * ms->smp.cores),
+(cpu / ms->smp.cores) % ms->smp.clusters,
+cpu % ms->smp.cores);
+}
+
+qemu_fdt_add_path(fdt, map_path);
+qemu_fdt_setprop_phandle(fdt, map_path, "cpu", name);
+
+g_free(map_path);
 g_free(name);
 }
 
@@ -591,6 +615,15 @@ static const void *create_fdt(BostonState *s,
 g_free(name);
 g_free(gic_name);
 
+/* CM node */
+name = g_strdup_printf("/soc/cm@%" HWADDR_PRIx, memmap[BOSTON_CM].base);
+qemu_fdt_add_subnode(fdt, name);
+qemu_fdt_setprop_string(fdt, name, "compatible", "mti,mips-cm");
+qemu_fdt_setprop_cells(fdt, name, "reg", memmap[BOSTON_CM].base,
+memmap[BOSTON_CM].size);
+g_free(name);
+
+
 /* CDMM node */
 name = g_strdup_printf("/soc/cdmm@%" HWADDR_PRIx, 
memmap[BOSTON_CDMM].base);
 qemu_fdt_add_subnode(fdt, name);
@@ -703,7 +736,9 @@ static void boston_mach_init(MachineState *machine)
 object_initialize_child(OBJECT(machine), "cps", >cps, TYPE_MIPS_CPS);
 object_property_set_str(OBJECT(>cps), "cpu-type", machine->cpu_type,
 _fatal);
-object_property_set_uint(OBJECT(>cps), "num-vp", machine->smp.cpus,
+object_property_set_uint(OBJECT(>cps), "num-pcore", machine->smp.cores,
+_fatal);
+object_property_set_uint(OBJECT(>cps), "num-vp", machine->smp.threads,
 _fatal);
 qdev_connect_clock_in(DEVICE(>cps), "clk-in",
   qdev_get_clock_out(dev, "cpu-refclk"));

-- 
2.34.1




[PATCH 2/5] hw/msic/mips_cmgcr: Implement multicore functions

2024-05-06 Thread Jiaxun Yang
We implemented following functions to allow software
to probe and control VPs on secondary core

- Reading out pcore count and coherence state
- Two scratch GCRs for firmware
- Semaphore GCR for register locking
- Redirect block to other cores

Signed-off-by: Jiaxun Yang 
---
 hw/misc/mips_cmgcr.c | 168 +++
 include/hw/misc/mips_cmgcr.h |  87 +++---
 2 files changed, 215 insertions(+), 40 deletions(-)

diff --git a/hw/misc/mips_cmgcr.c b/hw/misc/mips_cmgcr.c
index 2703040f45..8c2d184f2c 100644
--- a/hw/misc/mips_cmgcr.c
+++ b/hw/misc/mips_cmgcr.c
@@ -73,14 +73,19 @@ static inline void update_gic_base(MIPSGCRState *gcr, 
uint64_t val)
 static uint64_t gcr_read(void *opaque, hwaddr addr, unsigned size)
 {
 MIPSGCRState *gcr = (MIPSGCRState *) opaque;
-MIPSGCRVPState *current_vps = >vps[current_cpu->cpu_index];
-MIPSGCRVPState *other_vps = >vps[current_vps->other];
+int redirect_corenum = mips_gcr_get_redirect_corenum(gcr);
+int redirect_vpid = mips_gcr_get_redirect_vpid(gcr);
+int current_corenum = mips_gcr_get_current_corenum(gcr);
+int current_vpid = mips_gcr_get_current_vpid(gcr);
+MIPSGCRPCoreState *current_pcore = >pcs[current_corenum];
+MIPSGCRVPState *current_vps = _pcore->vps[current_vpid];
+MIPSGCRPCoreState *other_pcore = >pcs[redirect_corenum];
+MIPSGCRVPState *other_vps = _pcore->vps[redirect_vpid];
 
 switch (addr) {
 /* Global Control Block Register */
 case GCR_CONFIG_OFS:
-/* Set PCORES to 0 */
-return 0;
+return gcr->num_pcores - 1;
 case GCR_BASE_OFS:
 return gcr->gcr_base;
 case GCR_REV_OFS:
@@ -96,7 +101,19 @@ static uint64_t gcr_read(void *opaque, hwaddr addr, 
unsigned size)
 case GCR_L2_CONFIG_OFS:
 /* L2 BYPASS */
 return GCR_L2_CONFIG_BYPASS_MSK;
+case GCR_SYS_CONFIG2_OFS:
+return gcr->num_vps << GCR_SYS_CONFIG2_MAXVP_SHF;
+case GCR_SCRATCH0_OFS:
+return gcr->scratch[0];
+case GCR_SCRATCH1_OFS:
+return gcr->scratch[1];
+case GCR_SEM_OFS:
+return gcr->sem;
 /* Core-Local and Core-Other Control Blocks */
+case MIPS_CLCB_OFS + GCR_CL_COH_EN_OFS:
+return current_pcore->coh_en;
+case MIPS_COCB_OFS + GCR_CL_COH_EN_OFS:
+return other_pcore->coh_en;
 case MIPS_CLCB_OFS + GCR_CL_CONFIG_OFS:
 case MIPS_COCB_OFS + GCR_CL_CONFIG_OFS:
 /* Set PVP to # of VPs - 1 */
@@ -105,10 +122,18 @@ static uint64_t gcr_read(void *opaque, hwaddr addr, 
unsigned size)
 return current_vps->reset_base;
 case MIPS_COCB_OFS + GCR_CL_RESETBASE_OFS:
 return other_vps->reset_base;
-case MIPS_CLCB_OFS + GCR_CL_OTHER_OFS:
-return current_vps->other;
-case MIPS_COCB_OFS + GCR_CL_OTHER_OFS:
-return other_vps->other;
+case MIPS_CLCB_OFS + GCR_CL_REDIRECT_OFS:
+return current_vps->redirect;
+case MIPS_COCB_OFS + GCR_CL_REDIRECT_OFS:
+return other_vps->redirect;
+case MIPS_CLCB_OFS + GCR_CL_ID_OFS:
+return current_corenum;
+case MIPS_COCB_OFS + GCR_CL_ID_OFS:
+return redirect_corenum;
+case MIPS_CLCB_OFS + GCR_CL_SCRATCH_OFS:
+return current_vps->scratch;
+case MIPS_COCB_OFS + GCR_CL_SCRATCH_OFS:
+return other_vps->scratch;
 default:
 qemu_log_mask(LOG_UNIMP, "Read %d bytes at GCR offset 0x%" HWADDR_PRIx
   "\n", size, addr);
@@ -123,12 +148,36 @@ static inline target_ulong 
get_exception_base(MIPSGCRVPState *vps)
 return (int32_t)(vps->reset_base & GCR_CL_RESET_BASE_RESETBASE_MSK);
 }
 
+static inline void set_redirect(MIPSGCRState *gcr,
+MIPSGCRVPState *vps, target_ulong data)
+{
+int new_vpid = data & GCR_CL_REDIRECT_VP_MSK;
+int new_coreid = (data & GCR_CL_REDIRECT_CORE_MSK) >> 
GCR_CL_REDIRECT_CORE_SHF;
+
+if (new_vpid >= gcr->num_vps) {
+return;
+}
+
+if (new_coreid >= gcr->num_pcores) {
+return;
+}
+
+vps->redirect = data & (GCR_CL_REDIRECT_VP_MSK | GCR_CL_REDIRECT_CORE_MSK);
+}
+
 /* Write GCR registers */
 static void gcr_write(void *opaque, hwaddr addr, uint64_t data, unsigned size)
 {
-MIPSGCRState *gcr = (MIPSGCRState *)opaque;
-MIPSGCRVPState *current_vps = >vps[current_cpu->cpu_index];
-MIPSGCRVPState *other_vps = >vps[current_vps->other];
+MIPSGCRState *gcr = (MIPSGCRState *) opaque;
+int redirect_corenum = mips_gcr_get_redirect_corenum(gcr);
+int redirect_vpid = mips_gcr_get_redirect_vpid(gcr);
+int redirect_vpnum = mips_gcr_get_redirect_vpnum(gcr);
+int current_corenum = mips_gcr_get_current_corenum(gcr);
+int current_vpid = mips_gcr_get_current_vpid(gcr);
+MIPSGCRPCoreState *current_pcore = >pcs[current_corenum];
+

[PATCH 1/5] target/mips: Make globalnumber a CPU property

2024-05-06 Thread Jiaxun Yang
GlobalNumber marks topology information of a CPU instance.

Make it a CPU property to allow CPS to override topology information.

Signed-off-by: Jiaxun Yang 
---
 target/mips/cpu.c| 16 +++-
 target/mips/cpu.h| 10 +-
 target/mips/sysemu/machine.c |  5 ++---
 3 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index bbe01d07dd..762000d09b 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -296,7 +296,6 @@ static void mips_cpu_reset_hold(Object *obj, ResetType type)
 env->CP0_Random = env->tlb->nb_tlb - 1;
 env->tlb->tlb_in_use = env->tlb->nb_tlb;
 env->CP0_Wired = 0;
-env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
 env->CP0_EBase = KSEG0_BASE | (cs->cpu_index & 0x3FF);
 if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
 env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
@@ -484,6 +483,12 @@ static void mips_cpu_realizefn(DeviceState *dev, Error 
**errp)
 
 env->exception_base = (int32_t)0xBFC0;
 
+#if !defined(CONFIG_USER_ONLY)
+if (env->CP0_GlobalNumber == -1) {
+env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
+}
+#endif
+
 #if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
 mmu_init(env, env->cpu_model);
 #endif
@@ -563,6 +568,13 @@ static const TCGCPUOps mips_tcg_ops = {
 };
 #endif /* CONFIG_TCG */
 
+static Property mips_cpu_properties[] = {
+#if !defined(CONFIG_USER_ONLY)
+DEFINE_PROP_INT32("globalnumber", MIPSCPU, env.CP0_GlobalNumber, -1),
+#endif
+DEFINE_PROP_END_OF_LIST(),
+};
+
 static void mips_cpu_class_init(ObjectClass *c, void *data)
 {
 MIPSCPUClass *mcc = MIPS_CPU_CLASS(c);
@@ -592,6 +604,8 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
 #ifdef CONFIG_TCG
 cc->tcg_ops = _tcg_ops;
 #endif /* CONFIG_TCG */
+
+device_class_set_props(dc, mips_cpu_properties);
 }
 
 static const TypeInfo mips_cpu_type_info = {
diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 3e906a175a..7499608678 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -612,8 +612,13 @@ typedef struct CPUArchState {
 # define CP0EnLo_RI 31
 # define CP0EnLo_XI 30
 #endif
-int32_t CP0_GlobalNumber;
+/* CP0_GlobalNumber is preserved across CPU reset. */
 #define CP0GN_VPId 0
+#define CP0GN_VPId_MASK (0xFFUL << CP0GN_VPId)
+#define CP0GN_CoreNum 8
+#define CP0GN_CoreNum_MASK (0xFUL << CP0GN_CoreNum)
+#define CP0GN_ClusterNum 16
+#define CP0GN_ClusterNum_MASK (0xFUL << CP0GN_ClusterNum)
 /*
  * CP0 Register 4
  */
@@ -1175,6 +1180,9 @@ typedef struct CPUArchState {
 struct {} end_reset_fields;
 
 /* Fields from here on are preserved across CPU reset. */
+#if !defined(CONFIG_USER_ONLY)
+int32_t CP0_GlobalNumber;
+#endif
 CPUMIPSMVPContext *mvp;
 #if !defined(CONFIG_USER_ONLY)
 CPUMIPSTLBContext *tlb;
diff --git a/target/mips/sysemu/machine.c b/target/mips/sysemu/machine.c
index 213fd637fc..235d640862 100644
--- a/target/mips/sysemu/machine.c
+++ b/target/mips/sysemu/machine.c
@@ -218,8 +218,8 @@ static const VMStateDescription vmstate_tlb = {
 
 const VMStateDescription vmstate_mips_cpu = {
 .name = "cpu",
-.version_id = 21,
-.minimum_version_id = 21,
+.version_id = 22,
+.minimum_version_id = 22,
 .post_load = cpu_post_load,
 .fields = (const VMStateField[]) {
 /* Active TC */
@@ -257,7 +257,6 @@ const VMStateDescription vmstate_mips_cpu = {
 VMSTATE_INT32(env.CP0_VPEOpt, MIPSCPU),
 VMSTATE_UINT64(env.CP0_EntryLo0, MIPSCPU),
 VMSTATE_UINT64(env.CP0_EntryLo1, MIPSCPU),
-VMSTATE_INT32(env.CP0_GlobalNumber, MIPSCPU),
 VMSTATE_UINTTL(env.CP0_Context, MIPSCPU),
 VMSTATE_INT32(env.CP0_MemoryMapID, MIPSCPU),
 VMSTATE_INT32(env.CP0_PageMask, MIPSCPU),

-- 
2.34.1




[PATCH 0/5] hw/mips: Proper multi core support

2024-05-06 Thread Jiaxun Yang
Hi all,

This series implemented propper multiple core support for MIPS
CPS systsm.

Previously all CPUs are being implemented as a smt thread in a
single core. Now it respects topology supplied in QEMU args.

To test:
Build a latest kernel with 64r6el_defconfig (tested on 6.6,
next-20240506).

Then run:
```
qemu-system-mips64el -M boston -cpu I6500 -kernel ~/linux-next/vmlinux -smp 
4,cores=2,threads=2 -append "console=ttyS0,115200" -nographic
```
In dmesg of guest kernel:
```
[0.00] VP topology {2,2} total 4
...
[0.085190] smp: Bringing up secondary CPUs ...
[0.090219] Primary instruction cache 64kB, VIPT, 4-way, linesize 64 bytes.
[0.095461] Primary data cache 64kB, 4-way, PIPT, no aliases, linesize 64 
bytes
[0.096658] CPU1 revision is: 0001b000 (MIPS I6500)
[0.096718] FPU revision is: 20f30300
[0.124711] Synchronize counters for CPU 1: done.
[0.940979] Primary instruction cache 64kB, VIPT, 4-way, linesize 64 bytes.
[0.941041] Primary data cache 64kB, 4-way, PIPT, no aliases, linesize 64 
bytes
[0.941256] CPU2 revision is: 0001b000 (MIPS I6500)
[0.941289] FPU revision is: 20f30300
[0.965322] Synchronize counters for CPU 2: done.
[1.260937] Primary instruction cache 64kB, VIPT, 4-way, linesize 64 bytes.
[1.261001] Primary data cache 64kB, 4-way, PIPT, no aliases, linesize 64 
bytes
[1.261172] CPU3 revision is: 0001b000 (MIPS I6500)
[1.261209] FPU revision is: 20f30300
[1.285390] Synchronize counters for CPU 3: done.
[1.346985] smp: Brought up 1 node, 4 CPUs
```

Please review.

Thanks

To: qemu-devel@nongnu.org
Cc: Philippe Mathieu-Daudé 

Signed-off-by: Jiaxun Yang 
---
Jiaxun Yang (5):
  target/mips: Make globalnumber a CPU property
  hw/msic/mips_cmgcr: Implement multicore functions
  hw/msic/mips_cpc: Implement multi core support
  hw/mips/cps: Implement multi core support
  hw/mips/boston: Implement multi core support

 hw/mips/boston.c |  37 +-
 hw/mips/cps.c|  66 ++---
 hw/misc/mips_cmgcr.c | 168 +++
 hw/misc/mips_cpc.c   |  97 ++---
 include/hw/mips/cps.h|   1 +
 include/hw/misc/mips_cmgcr.h |  87 +++---
 include/hw/misc/mips_cpc.h   |  15 +++-
 target/mips/cpu.c|  16 -
 target/mips/cpu.h|  10 ++-
 target/mips/sysemu/machine.c |   5 +-
 10 files changed, 403 insertions(+), 99 deletions(-)
---
base-commit: 248f6f62df073a3b4158fd0093863ab885feabb5
change-id: 20240506-mips-smp-9af9e71ad8c2

Best regards,
-- 
Jiaxun Yang 




[PATCH 4/5] hw/mips/cps: Implement multi core support

2024-05-06 Thread Jiaxun Yang
Implement multiple physical core support by creating
CPU devices accorading to the new topology and passing
pcore/vp information to CPC and CMGCR sub-devices.

Signed-off-by: Jiaxun Yang 
---
 hw/mips/cps.c | 66 +++
 include/hw/mips/cps.h |  1 +
 2 files changed, 41 insertions(+), 26 deletions(-)

diff --git a/hw/mips/cps.c b/hw/mips/cps.c
index 07b73b0a1f..6cf02379a9 100644
--- a/hw/mips/cps.c
+++ b/hw/mips/cps.c
@@ -73,31 +73,43 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
 return;
 }
 
-for (int i = 0; i < s->num_vp; i++) {
-MIPSCPU *cpu = MIPS_CPU(object_new(s->cpu_type));
-CPUMIPSState *env = >env;
+object_initialize_child(OBJECT(dev), "gcr", >gcr, TYPE_MIPS_GCR);
 
-/* All VPs are halted on reset. Leave powering up to CPC. */
-object_property_set_bool(OBJECT(cpu), "start-powered-off", true,
- _abort);
+for (int corenum = 0; corenum < s->num_pcore; corenum++) {
+for (int vpid = 0; vpid < s->num_vp; vpid++) {
+int vpnum = corenum * s->num_vp + vpid;
+int32_t globalnumber = (corenum << CP0GN_CoreNum) | vpid;
 
-/* All cores use the same clock tree */
-qdev_connect_clock_in(DEVICE(cpu), "clk-in", s->clock);
+MIPSCPU *cpu = MIPS_CPU(object_new(s->cpu_type));
+CPUMIPSState *env = >env;
 
-if (!qdev_realize_and_unref(DEVICE(cpu), NULL, errp)) {
-return;
-}
+/* All VPs are halted on reset. Leave powering up to CPC. */
+object_property_set_bool(OBJECT(cpu), "start-powered-off", true,
+_abort);
+
+object_property_set_int(OBJECT(cpu), "globalnumber", globalnumber,
+_abort);
+
+/* All cores use the same clock tree */
+qdev_connect_clock_in(DEVICE(cpu), "clk-in", s->clock);
+
+if (!qdev_realize_and_unref(DEVICE(cpu), NULL, errp)) {
+return;
+}
+
+g_assert(vpnum == CPU(cpu)->cpu_index);
 
-/* Init internal devices */
-cpu_mips_irq_init_cpu(cpu);
-cpu_mips_clock_init(cpu);
+/* Init internal devices */
+cpu_mips_irq_init_cpu(cpu);
+cpu_mips_clock_init(cpu);
 
-if (cpu_mips_itu_supported(env)) {
-itu_present = true;
-/* Attach ITC Tag to the VP */
-env->itc_tag = mips_itu_get_tag_region(>itu);
+if (cpu_mips_itu_supported(env)) {
+itu_present = true;
+/* Attach ITC Tag to the VP */
+env->itc_tag = mips_itu_get_tag_region(>itu);
+}
+qemu_register_reset(main_cpu_reset, cpu);
 }
-qemu_register_reset(main_cpu_reset, cpu);
 }
 
 /* Inter-Thread Communication Unit */
@@ -119,8 +131,12 @@ static void mips_cps_realize(DeviceState *dev, Error 
**errp)
 object_initialize_child(OBJECT(dev), "cpc", >cpc, TYPE_MIPS_CPC);
 object_property_set_uint(OBJECT(>cpc), "num-vp", s->num_vp,
 _abort);
+object_property_set_uint(OBJECT(>cpc), "num-pcore", s->num_pcore,
+_abort);
 object_property_set_int(OBJECT(>cpc), "vp-start-running", 1,
 _abort);
+object_property_set_link(OBJECT(>cpc), "gcr", OBJECT(>gcr),
+_abort);
 if (!sysbus_realize(SYS_BUS_DEVICE(>cpc), errp)) {
 return;
 }
@@ -130,7 +146,7 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
 
 /* Global Interrupt Controller */
 object_initialize_child(OBJECT(dev), "gic", >gic, TYPE_MIPS_GIC);
-object_property_set_uint(OBJECT(>gic), "num-vp", s->num_vp,
+object_property_set_uint(OBJECT(>gic), "num-vp", s->num_vp * 
s->num_pcore,
 _abort);
 object_property_set_uint(OBJECT(>gic), "num-irq", 128,
 _abort);
@@ -141,16 +157,13 @@ static void mips_cps_realize(DeviceState *dev, Error 
**errp)
 memory_region_add_subregion(>container, 0,
 sysbus_mmio_get_region(SYS_BUS_DEVICE(>gic), 
0));
 
-/* Global Configuration Registers */
-gcr_base = MIPS_CPU(first_cpu)->env.CP0_CMGCRBase << 4;
-
-object_initialize_child(OBJECT(dev), "gcr", >gcr, TYPE_MIPS_GCR);
+gcr_base = GCR_BASE_ADDR;
+object_property_set_uint(OBJECT(>gcr), "num-pcores", s->num_pcore,
+_abort);
 object_property_set_uint(OBJECT(>gcr), "num-vp"

[PATCH 3/5] hw/msic/mips_cpc: Implement multi core support

2024-05-06 Thread Jiaxun Yang
Implement multiple physical core support for MIPS CPC
controller. Including some R/O configuration registers
and VP bring up support on multiple cores.

Signed-off-by: Jiaxun Yang 
---
 hw/misc/mips_cpc.c | 97 ++
 include/hw/misc/mips_cpc.h | 15 ++-
 2 files changed, 85 insertions(+), 27 deletions(-)

diff --git a/hw/misc/mips_cpc.c b/hw/misc/mips_cpc.c
index 1e8fd2e699..f6a2f29088 100644
--- a/hw/misc/mips_cpc.c
+++ b/hw/misc/mips_cpc.c
@@ -25,9 +25,25 @@
 #include "hw/sysbus.h"
 #include "migration/vmstate.h"
 
+#include "hw/misc/mips_cmgcr.h"
 #include "hw/misc/mips_cpc.h"
 #include "hw/qdev-properties.h"
 
+static inline int cpc_vpnum_to_corenum(MIPSCPCState *cpc, int vpnum)
+{
+return vpnum / cpc->num_vp;
+}
+
+static inline int cpc_vpnum_to_vpid(MIPSCPCState *cpc, int vpnum)
+{
+return vpnum % cpc->num_vp;
+}
+
+static inline MIPSCPCPCoreState *cpc_vpnum_to_pcs(MIPSCPCState *cpc, int vpnum)
+{
+return >pcs[cpc_vpnum_to_corenum(cpc, vpnum)];
+}
+
 static inline uint64_t cpc_vp_run_mask(MIPSCPCState *cpc)
 {
 return (1ULL << cpc->num_vp) - 1;
@@ -39,36 +55,41 @@ static void mips_cpu_reset_async_work(CPUState *cs, 
run_on_cpu_data data)
 
 cpu_reset(cs);
 cs->halted = 0;
-cpc->vp_running |= 1ULL << cs->cpu_index;
+cpc_vpnum_to_pcs(cpc, cs->cpu_index)->vp_running |=
+1 << cpc_vpnum_to_vpid(cpc, cs->cpu_index);
 }
 
-static void cpc_run_vp(MIPSCPCState *cpc, uint64_t vp_run)
+static void cpc_run_vp(MIPSCPCState *cpc, int pcore, uint64_t vp_run)
 {
-CPUState *cs = first_cpu;
+MIPSCPCPCoreState *pcs = >pcs[pcore];
 
-CPU_FOREACH(cs) {
-uint64_t i = 1ULL << cs->cpu_index;
-if (i & vp_run & ~cpc->vp_running) {
+for (int vpid = 0; vpid < cpc->num_vp; vpid++) {
+if ((1 << vpid) & vp_run & ~pcs->vp_running) {
+int vpnum = pcore * cpc->num_vp + vpid;
 /*
  * To avoid racing with a CPU we are just kicking off.
  * We do the final bit of preparation for the work in
  * the target CPUs context.
  */
-async_safe_run_on_cpu(cs, mips_cpu_reset_async_work,
-  RUN_ON_CPU_HOST_PTR(cpc));
+async_safe_run_on_cpu(qemu_get_cpu(vpnum),
+mips_cpu_reset_async_work,
+RUN_ON_CPU_HOST_PTR(cpc));
+pcs->vp_running |= 1 << vpid;
 }
 }
 }
 
-static void cpc_stop_vp(MIPSCPCState *cpc, uint64_t vp_stop)
+static void cpc_stop_vp(MIPSCPCState *cpc, int pcore, uint64_t vp_stop)
 {
-CPUState *cs = first_cpu;
+MIPSCPCPCoreState *pcs = >pcs[pcore];
+
+for (int vpid = 0; vpid < cpc->num_vp; vpid++) {
+if ((1 << vpid) & vp_stop & pcs->vp_running) {
+int vpnum = pcore * cpc->num_vp + vpid;
+CPUState *cs = qemu_get_cpu(vpnum);
 
-CPU_FOREACH(cs) {
-uint64_t i = 1ULL << cs->cpu_index;
-if (i & vp_stop & cpc->vp_running) {
 cpu_interrupt(cs, CPU_INTERRUPT_HALT);
-cpc->vp_running &= ~i;
+pcs->vp_running &= ~(1 << vpid);
 }
 }
 }
@@ -77,15 +98,20 @@ static void cpc_write(void *opaque, hwaddr offset, uint64_t 
data,
   unsigned size)
 {
 MIPSCPCState *s = opaque;
+int current_corenum = cpc_vpnum_to_corenum(s, current_cpu->cpu_index);
 
 switch (offset) {
 case CPC_CL_BASE_OFS + CPC_VP_RUN_OFS:
+cpc_run_vp(s, current_corenum, data);
+break;
 case CPC_CO_BASE_OFS + CPC_VP_RUN_OFS:
-cpc_run_vp(s, data & cpc_vp_run_mask(s));
+cpc_run_vp(s, mips_gcr_get_redirect_corenum(s->gcr), data);
 break;
 case CPC_CL_BASE_OFS + CPC_VP_STOP_OFS:
+cpc_stop_vp(s, current_corenum, data);
+break;
 case CPC_CO_BASE_OFS + CPC_VP_STOP_OFS:
-cpc_stop_vp(s, data & cpc_vp_run_mask(s));
+cpc_stop_vp(s, mips_gcr_get_redirect_corenum(s->gcr), data);
 break;
 default:
 qemu_log_mask(LOG_UNIMP,
@@ -101,9 +127,13 @@ static uint64_t cpc_read(void *opaque, hwaddr offset, 
unsigned size)
 MIPSCPCState *s = opaque;
 
 switch (offset) {
+case CPC_CL_BASE_OFS + CPC_CL_STAT_CONF_OFS:
+case CPC_CO_BASE_OFS + CPC_CL_STAT_CONF_OFS:
+return CPC_CL_STAT_CONF_SEQ_STATE_U6 << CPC_CL_STAT_CONF_SEQ_STATE_SHF;
 case CPC_CL_BASE_OFS + CPC_VP_RUNNING_OFS:
+return cpc_vpnum_to_pcs(s, current_cpu->cpu_index)->vp_running;
 case CPC_CO_BASE_OFS + CPC_VP_RUNNING_OFS:
-return s->vp_running;
+return s->pcs[mips_gcr_get_redirect_corenum(s->gcr)].vp_running;
 default:

Re: [RFC PATCH 00/11] target/mips: Remove I6500 CPU definition

2024-02-09 Thread Jiaxun Yang




在 2024/2/9 09:05, Philippe Mathieu-Daudé 写道:

Alternative to:
https://lore.kernel.org/qemu-devel/20240209085347.8446-1-phi...@linaro.org/
If the I6500 can not be tested or its support is incomplete,
there is no point in wasting energy maintaining it.


Actually all SAAR and ITU stuff are optional for I6500 in real world so 
it's fine

to just leave I6500 defined without SAAR support.

The main difference between I6400 and I6500 is multi-cluster support, I do
have some patch for bringing proper multi-cluster support to QEMU, but
it can't work with boston due to address space limitations.

Should I give mips-virt stuff another go?

Thanks
- Jiaxun



Philippe Mathieu-Daudé (11):
   target/mips: Remove helpers accessing SAAR registers
   hw/misc/mips: Reduce itc_reconfigure() scope
   target/mips: Remove MIPSITUState::itu field
   target/mips: Remove CPUMIPSState::saarp field
   hw/misc/mips_itu: Remove MIPSITUState::cpu0 field
   hw/misc/mips_itu: Remove MIPSITUState::saar field
   target/mips: Remove CPUMIPSState::CP0_SAAR[2] field
   target/mips: Remove helpers accessing SAARI register
   target/mips: Remove CPUMIPSState::CP0_SAARI field
   target/mips: Remove the unused DisasContext::saar field
   target/mips: Remove I6500 CPU definition

  docs/about/removed-features.rst |  5 +++
  include/hw/misc/mips_itu.h  |  6 ---
  target/mips/cpu.h   |  4 --
  target/mips/tcg/translate.h |  1 -
  target/mips/tcg/sysemu_helper.h.inc |  6 ---
  hw/mips/cps.c   |  3 --
  hw/misc/mips_itu.c  | 35 ++--
  target/mips/sysemu/machine.c|  4 +-
  target/mips/tcg/sysemu/cp0_helper.c | 63 -
  target/mips/tcg/translate.c | 62 
  tests/qtest/machine-none-test.c |  2 +-
  target/mips/cpu-defs.c.inc  | 40 --
  12 files changed, 12 insertions(+), 219 deletions(-)



--
---
Jiaxun Yang




Re: why various devices are loading x86 roms on non-x86 architectures?

2024-01-31 Thread Jiaxun Yang




在 2024/1/31 10:28, Michael Tokarev 写道:

Hi!

qemu-system-aarch64 -device virtio-vga

this one loads vgabios-virtio.bin.  Why?
Does this bios work on aarch64 (or any other non-x86 arch)?
Should there may be some conditional in this and similar places?
The same is true for x86 pxe roms and other x86-only roms.


FYI on some systems they use x86emu (or biosemu) to run x86 only
OpROMs, this is at least true for u-boot (u-boot/drivers/bios_emulator),
PMON (MIPS/Loongson) and coreboot.

Thanks
- Jiaxun



Thanks,

/mjt



--
---
Jiaxun Yang




Re: [PATCH] target/mips: enable GINVx support for I6400 and I6500

2023-07-10 Thread Jiaxun Yang




在 2023/6/30 15:28, Marcin Nowakowski 写道:

GINVI and GINVT operations are supported on MIPS I6400 and I6500 cores,
so indicate that properly in CP0.Config5 register bits [16:15].

Signed-off-by: Marcin Nowakowski 


VZ is unimplemented in TCG so perhaps we should leave them as not supported?

Thanks
- Jiaxun


---
  target/mips/cpu-defs.c.inc | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/mips/cpu-defs.c.inc b/target/mips/cpu-defs.c.inc
index d45f245a67..da122e72d7 100644
--- a/target/mips/cpu-defs.c.inc
+++ b/target/mips/cpu-defs.c.inc
@@ -709,7 +709,7 @@ const mips_def_t mips_defs[] =
  .CP0_Config4 = MIPS_CONFIG4 | (1U << CP0C4_M) | (3 << CP0C4_IE) |
 (1 << CP0C4_AE) | (0xfc << CP0C4_KScrExist),
  .CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_XNP) | (1 << CP0C5_VP) |
-   (1 << CP0C5_LLB) | (1 << CP0C5_MRP),
+   (1 << CP0C5_LLB) | (1 << CP0C5_MRP) | (3 << CP0C5_GI),
  .CP0_Config5_rw_bitmask = (1 << CP0C5_MSAEn) | (1 << CP0C5_SBRI) |
(1 << CP0C5_FRE) | (1 << CP0C5_UFE),
  .CP0_LLAddr_rw_bitmask = 0,
@@ -749,7 +749,7 @@ const mips_def_t mips_defs[] =
  .CP0_Config4 = MIPS_CONFIG4 | (1U << CP0C4_M) | (3 << CP0C4_IE) |
 (1 << CP0C4_AE) | (0xfc << CP0C4_KScrExist),
  .CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_XNP) | (1 << CP0C5_VP) |
-   (1 << CP0C5_LLB) | (1 << CP0C5_MRP),
+   (1 << CP0C5_LLB) | (1 << CP0C5_MRP) | (3 << CP0C5_GI),
  .CP0_Config5_rw_bitmask = (1 << CP0C5_MSAEn) | (1 << CP0C5_SBRI) |
(1 << CP0C5_FRE) | (1 << CP0C5_UFE),
  .CP0_LLAddr_rw_bitmask = 0,





Re: [PATCH 1/4] hw/intc/loongarch_ipi: Bring back all 4 IPI mailboxes

2023-06-03 Thread Jiaxun Yang



> 2023年6月3日 01:28,Peter Maydell  写道:
> 
> On Sun, 21 May 2023 at 11:24, Jiaxun Yang  wrote:
>> 
>> As per "Loongson 3A5000/3B5000 Processor Reference Manual",
>> Loongson 3A5000's IPI implementation have 4 mailboxes per
>> core.
>> 
>> However, in 78464f023b54 ("hw/loongarch/virt: Modify ipi as
>> percpu device"), the number of IPI mailboxes was reduced to
>> one, which mismatches actual hardware.
>> 
>> It won't affect LoongArch based system as LoongArch boot code
>> only uses the first mailbox, however MIPS based Loongson boot
>> code uses all 4 mailboxes.
>> 
>> Fixes: 78464f023b54 ("hw/loongarch/virt: Modify ipi as percpu device")
>> Signed-off-by: Jiaxun Yang 
>> ---
>> hw/intc/loongarch_ipi.c | 6 +++---
>> include/hw/intc/loongarch_ipi.h | 4 +++-
>> 2 files changed, 6 insertions(+), 4 deletions(-)
>> 
>> diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c
>> index d6ab91721ea1..3e453816524e 100644
>> --- a/hw/intc/loongarch_ipi.c
>> +++ b/hw/intc/loongarch_ipi.c
>> @@ -238,14 +238,14 @@ static void loongarch_ipi_init(Object *obj)
>> 
>> static const VMStateDescription vmstate_ipi_core = {
>> .name = "ipi-single",
>> -.version_id = 1,
>> -.minimum_version_id = 1,
>> +.version_id = 2,
>> +.minimum_version_id = 2,
>> .fields = (VMStateField[]) {
>> VMSTATE_UINT32(status, IPICore),
>> VMSTATE_UINT32(en, IPICore),
>> VMSTATE_UINT32(set, IPICore),
>> VMSTATE_UINT32(clear, IPICore),
>> -VMSTATE_UINT32_ARRAY(buf, IPICore, 2),
>> +VMSTATE_UINT32_ARRAY(buf, IPICore, IPI_MBX_NUM * 2),
>> VMSTATE_END_OF_LIST()
>> }
>> };
>> diff --git a/include/hw/intc/loongarch_ipi.h 
>> b/include/hw/intc/loongarch_ipi.h
>> index 664e050b926e..6c6194786e80 100644
>> --- a/include/hw/intc/loongarch_ipi.h
>> +++ b/include/hw/intc/loongarch_ipi.h
>> @@ -28,6 +28,8 @@
>> #define MAIL_SEND_OFFSET  0
>> #define ANY_SEND_OFFSET   (IOCSR_ANY_SEND - IOCSR_MAIL_SEND)
>> 
>> +#define IPI_MBX_NUM   4
>> +
>> #define TYPE_LOONGARCH_IPI "loongarch_ipi"
>> OBJECT_DECLARE_SIMPLE_TYPE(LoongArchIPI, LOONGARCH_IPI)
>> 
>> @@ -37,7 +39,7 @@ typedef struct IPICore {
>> uint32_t set;
>> uint32_t clear;
>> /* 64bit buf divide into 2 32bit buf */
>> -uint32_t buf[2];
>> +uint32_t buf[IPI_MBX_NUM * 2];
>> qemu_irq irq;
>> } IPICore;
> 
> In particular, this fixes Coverity issues CID 1512452 and 1512453,
> where Coverity notices that the code in loongarch_ipi_writel() and
> loongarch_ipi_readl() reads off the end of the too-short buf[].

LoongArch maintainers, do you mind to take this patch while I’m refactoring
rest of the series?

Thanks
Jiaxun

> 
> thanks
> -- PMM





Re: [PATCH 1/4] hw/intc/loongarch_ipi: Bring back all 4 IPI mailboxes

2023-05-23 Thread Jiaxun Yang



> 2023年5月23日 11:01,Song Gao  写道:
> 
> 
> 
> 在 2023/5/23 上午11:22, Jiaxun Yang 写道:
[...]
>> 
>>> 
>> Is totally the same on MIPS and LoongArch. I’m guarding them out because
>> We have different way to get IOCSR address space on MIPS, which is due
>> to be implemented.
>> 
>> I can further abstract out a function to get IOCSR address space. But still,
>> I think the best way to differ those two architecture is using TARGET_* 
>> macros,
>> as it doesn’t make much sense to have unused code for another architecture
>> compiled.
> Most of the code in hw/intc or hw/ uses property to distinguish between 
> different devices,  not TARGE_* macro.

They are the *same* device, with different way to handle IOCSR address space.

Another problem is casting CPUState with LOONGARCH_CPU() is something invalid on
MIPS, vice-versa. We are potentially introducing a security issue here.

I know nobody have done something like this before, but not necessarily to be a 
bad idea.

I’ll introduce something like:

+#ifdef TARGET_LOONGARCH64
+static inline void *AddressSpace get_iocsr_as(int cpuid)
+{
+CPUState *cs = qemu_get_cpu(cpuid);
+LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+
+return >env.address_space_iocsr;
+}
+#endif
+
+#ifdef TARGET_MIPS64
+static inline void *AddressSpace get_iocsr_as(int cpuid)
+{
+CPUState *cs = qemu_get_cpu(cpuid);
+MIPSCPU *cpu = MIPS_CPU(cs);
+
+return >env.iocsr.as;
+}
+#endif

Thanks
- Jiaxun

> 
> I still think it is better to use property.
> 
> Thanks.
> Song Gao
>>> All references to loongarch_ipi should also be changed.
>> Sure.
>> 
>> Thanks
>> - Jiaxun
> 




Re: [PATCH 1/4] hw/intc/loongarch_ipi: Bring back all 4 IPI mailboxes

2023-05-22 Thread Jiaxun Yang



> 2023年5月23日 02:25,Song Gao  写道:
> 
> 
> 
> 在 2023/5/22 下午9:44, Philippe Mathieu-Daudé 写道:
>> On 22/5/23 13:47, Jiaxun Yang wrote:
>>> 
>>> 
>>>> 2023年5月22日 04:52,Huacai Chen  写道:
>>>> 
>>>> Hi, Jiaxun,
>>>> 
>>>> Rename loongarch_ipi to loongson_ipi? It will be shared by both MIPS
>>>> and LoongArch in your series.
>>> 
>>> Hi Huacai,
>>> 
>>> Thanks for the point, what’s the opinion from LoongArch mainatiners?
>>> 
>>> Or perhaps rename it as loong_ipi to reflect the nature that it’s shared
>>> by MIPS based Loongson and LoongArch based Loongson?
>> 
>> I'm not a LoongArch maintainer, but a model named "loong_ipi" makes
>> sense to me.
>> 
>> Please add it to the two Virt machine sections in MAINTAINERS.

Hi Song,

>> 
> 'loonggson_ipi' is better, qemu doesn't have naming with 'loong' as prefix.

Thanks, I’ll take looongson_ipi then.

> 
> And  patch2 should not use macros. Some attributes should be added to 
> distinguish between MIPS and LongArch.

By attribute do you mean property? If so I don’t see any necessity, the IP block
Is totally the same on MIPS and LoongArch. I’m guarding them out because
We have different way to get IOCSR address space on MIPS, which is due
to be implemented.

I can further abstract out a function to get IOCSR address space. But still,
I think the best way to differ those two architecture is using TARGET_* macros,
as it doesn’t make much sense to have unused code for another architecture
compiled.

> 
> All references to loongarch_ipi should also be changed.
Sure.

Thanks
- Jiaxun

> 
> Thanks.
> Song Gao





Re: [PATCH 2/2] hw/mips/loongson3_virt: Remove CPU restrictions for TCG

2023-05-22 Thread Jiaxun Yang



> 2023年5月22日 13:08,Philippe Mathieu-Daudé  写道:
> 
> On 21/5/23 23:48, Jiaxun Yang wrote:
>> After implemented CPUCFG and CSR, we are now able to boot Linux
>> kernel with Loongson-3A4000 CPU, so there is no point to restrict
>> CPU type for TCG.
> 
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1639
> ?

Potentially yes, although I think the issue itself is just a question on usage
of the board.

Thanks
- Jiaxun

> 
>> Signed-off-by: Jiaxun Yang 
>> ---
>>  hw/mips/loongson3_virt.c | 4 
>>  1 file changed, 4 deletions(-)
> 
> 




Re: [PATCH 1/4] hw/intc/loongarch_ipi: Bring back all 4 IPI mailboxes

2023-05-22 Thread Jiaxun Yang



> 2023年5月22日 04:52,Huacai Chen  写道:
> 
> Hi, Jiaxun,
> 
> Rename loongarch_ipi to loongson_ipi? It will be shared by both MIPS
> and LoongArch in your series.

Hi Huacai,

Thanks for the point, what’s the opinion from LoongArch mainatiners?

Or perhaps rename it as loong_ipi to reflect the nature that it’s shared
by MIPS based Loongson and LoongArch based Loongson?

Thanks
- Jiaxun

> 
> 
> Huacai
> 
> On Sun, May 21, 2023 at 6:24 PM Jiaxun Yang  wrote:
>> 
>> As per "Loongson 3A5000/3B5000 Processor Reference Manual",
>> Loongson 3A5000's IPI implementation have 4 mailboxes per
>> core.
>> 
>> However, in 78464f023b54 ("hw/loongarch/virt: Modify ipi as
>> percpu device"), the number of IPI mailboxes was reduced to
>> one, which mismatches actual hardware.
>> 
>> It won't affect LoongArch based system as LoongArch boot code
>> only uses the first mailbox, however MIPS based Loongson boot
>> code uses all 4 mailboxes.
>> 
>> Fixes: 78464f023b54 ("hw/loongarch/virt: Modify ipi as percpu device")
>> Signed-off-by: Jiaxun Yang 
>> ---
>> hw/intc/loongarch_ipi.c | 6 +++---
>> include/hw/intc/loongarch_ipi.h | 4 +++-
>> 2 files changed, 6 insertions(+), 4 deletions(-)
>> 
>> diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c
>> index d6ab91721ea1..3e453816524e 100644
>> --- a/hw/intc/loongarch_ipi.c
>> +++ b/hw/intc/loongarch_ipi.c
>> @@ -238,14 +238,14 @@ static void loongarch_ipi_init(Object *obj)
>> 
>> static const VMStateDescription vmstate_ipi_core = {
>> .name = "ipi-single",
>> -.version_id = 1,
>> -.minimum_version_id = 1,
>> +.version_id = 2,
>> +.minimum_version_id = 2,
>> .fields = (VMStateField[]) {
>> VMSTATE_UINT32(status, IPICore),
>> VMSTATE_UINT32(en, IPICore),
>> VMSTATE_UINT32(set, IPICore),
>> VMSTATE_UINT32(clear, IPICore),
>> -VMSTATE_UINT32_ARRAY(buf, IPICore, 2),
>> +VMSTATE_UINT32_ARRAY(buf, IPICore, IPI_MBX_NUM * 2),
>> VMSTATE_END_OF_LIST()
>> }
>> };
>> diff --git a/include/hw/intc/loongarch_ipi.h 
>> b/include/hw/intc/loongarch_ipi.h
>> index 664e050b926e..6c6194786e80 100644
>> --- a/include/hw/intc/loongarch_ipi.h
>> +++ b/include/hw/intc/loongarch_ipi.h
>> @@ -28,6 +28,8 @@
>> #define MAIL_SEND_OFFSET  0
>> #define ANY_SEND_OFFSET   (IOCSR_ANY_SEND - IOCSR_MAIL_SEND)
>> 
>> +#define IPI_MBX_NUM   4
>> +
>> #define TYPE_LOONGARCH_IPI "loongarch_ipi"
>> OBJECT_DECLARE_SIMPLE_TYPE(LoongArchIPI, LOONGARCH_IPI)
>> 
>> @@ -37,7 +39,7 @@ typedef struct IPICore {
>> uint32_t set;
>> uint32_t clear;
>> /* 64bit buf divide into 2 32bit buf */
>> -uint32_t buf[2];
>> +uint32_t buf[IPI_MBX_NUM * 2];
>> qemu_irq irq;
>> } IPICore;
>> 
>> --
>> 2.39.2 (Apple Git-143)
>> 




[PATCH 0/2] MIPS: Enable Loongson-3A4000 TCG for system emulation

2023-05-21 Thread Jiaxun Yang
Hi there,

This series enables Loongson-3A4000 TCG for system emulation.
It Implemented Loongson CSR insertions which is required for
Linux Kernel to probe CPU features and removed CPU type restrictions
for loongson3_virt board.

This series is based on two of my previous series[1] [2]. However it's
just a soft dependency for me to do boot test, feel free to apply this
series without them.

Note that loongarch_ipi is still not hooked up in IOCSR. I've sucessfully
done it locally but I just want to confirm some details on hardware.

Thanks
- Jiaxun

[1]: 
https://lore.kernel.org/qemu-devel/20230521102307.87081-1-jiaxun.y...@flygoat.com/T/#t
[2]: 
https://lore.kernel.org/qemu-devel/0bb0cded-8450-536e-b90f-1a9d33311...@linaro.org/T/#t

Jiaxun Yang (2):
  target/mips: Implement Loongson CSR instructions
  hw/mips/loongson3_virt: Remove CPU restrictions for TCG

 hw/mips/loongson3_virt.c |  4 --
 target/mips/cpu-defs.c.inc   |  9 
 target/mips/cpu.c|  8 
 target/mips/cpu.h| 40 
 target/mips/helper.h |  4 ++
 target/mips/internal.h   |  2 +
 target/mips/tcg/lcsr.decode  | 17 +++
 target/mips/tcg/lcsr_translate.c | 69 
 target/mips/tcg/meson.build  |  2 +
 target/mips/tcg/op_helper.c  | 16 +++
 target/mips/tcg/sysemu/lcsr_helper.c | 45 ++
 target/mips/tcg/sysemu/meson.build   |  4 ++
 target/mips/tcg/sysemu_helper.h.inc  |  8 
 target/mips/tcg/translate.c  |  3 ++
 target/mips/tcg/translate.h  |  7 +++
 15 files changed, 234 insertions(+), 4 deletions(-)
 create mode 100644 target/mips/tcg/lcsr.decode
 create mode 100644 target/mips/tcg/lcsr_translate.c
 create mode 100644 target/mips/tcg/sysemu/lcsr_helper.c

-- 
2.39.2 (Apple Git-143)




[PATCH 2/2] hw/mips/loongson3_virt: Remove CPU restrictions for TCG

2023-05-21 Thread Jiaxun Yang
After implemented CPUCFG and CSR, we are now able to boot Linux
kernel with Loongson-3A4000 CPU, so there is no point to restrict
CPU type for TCG.

Signed-off-by: Jiaxun Yang 
---
 hw/mips/loongson3_virt.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/hw/mips/loongson3_virt.c b/hw/mips/loongson3_virt.c
index a57245012598..47289fb6bf85 100644
--- a/hw/mips/loongson3_virt.c
+++ b/hw/mips/loongson3_virt.c
@@ -488,10 +488,6 @@ static void mips_loongson3_virt_init(MachineState *machine)
 if (!machine->cpu_type) {
 machine->cpu_type = MIPS_CPU_TYPE_NAME("Loongson-3A1000");
 }
-if (!strstr(machine->cpu_type, "Loongson-3A1000")) {
-error_report("Loongson-3/TCG needs cpu type Loongson-3A1000");
-exit(1);
-}
 } else {
 if (!machine->cpu_type) {
 machine->cpu_type = MIPS_CPU_TYPE_NAME("Loongson-3A4000");
-- 
2.39.2 (Apple Git-143)




[PATCH 1/2] target/mips: Implement Loongson CSR instructions

2023-05-21 Thread Jiaxun Yang
Loongson introduced CSR instructions since 3A4000, which looks
similar to IOCSR and CPUCFG instructions we seen in LoongArch.

Unfortunately we don't have much document about those instructions,
bit fields of CPUCFG instructions and IOCSR registers can be found
at 3A4000's user manual, while instruction encodings can be found
at arch/mips/include/asm/mach-loongson64/loongson_regs.h from
Linux Kernel.

Our predefined CPUCFG bits are differ from actual 3A4000, since
we can't emulate all CPUCFG features present in 3A4000 for now,
we just enable bits for what we have in TCG.

Signed-off-by: Jiaxun Yang 
---
 target/mips/cpu-defs.c.inc   |  9 
 target/mips/cpu.c|  8 
 target/mips/cpu.h| 40 
 target/mips/helper.h |  4 ++
 target/mips/internal.h   |  2 +
 target/mips/tcg/lcsr.decode  | 17 +++
 target/mips/tcg/lcsr_translate.c | 69 
 target/mips/tcg/meson.build  |  2 +
 target/mips/tcg/op_helper.c  | 16 +++
 target/mips/tcg/sysemu/lcsr_helper.c | 45 ++
 target/mips/tcg/sysemu/meson.build   |  4 ++
 target/mips/tcg/sysemu_helper.h.inc  |  8 
 target/mips/tcg/translate.c  |  3 ++
 target/mips/tcg/translate.h  |  7 +++
 14 files changed, 234 insertions(+)
 create mode 100644 target/mips/tcg/lcsr.decode
 create mode 100644 target/mips/tcg/lcsr_translate.c
 create mode 100644 target/mips/tcg/sysemu/lcsr_helper.c

diff --git a/target/mips/cpu-defs.c.inc b/target/mips/cpu-defs.c.inc
index d45f245a6718..167c96cb2748 100644
--- a/target/mips/cpu-defs.c.inc
+++ b/target/mips/cpu-defs.c.inc
@@ -895,6 +895,15 @@ const mips_def_t mips_defs[] =
 .CP1_fcr31 = 0,
 .CP1_fcr31_rw_bitmask = 0xFF83,
 .MSAIR = (0x01 << MSAIR_ProcID) | (0x40 << MSAIR_Rev),
+.lcsr_cpucfg1 = (1 << CPUCFG1_FP) | (2 << CPUCFG1_FPREV) |
+(1 << CPUCFG1_MSA1) | (1 << CPUCFG1_LSLDR0) |
+(1 << CPUCFG1_LSPERF) | (1 << CPUCFG1_LSPERFX) |
+(1 << CPUCFG1_LSSYNCI) | (1 << CPUCFG1_LLEXC) |
+(1 << CPUCFG1_SCRAND) | (1 << CPUCFG1_MUALP) |
+(1 << CPUCFG1_KMUALEN) | (1 << CPUCFG1_ITLBT) |
+(1 << CPUCFG1_SFBP) | (1 << CPUCFG1_CDMAP),
+.lcsr_cpucfg2 = (1 << CPUCFG2_LEXT1) | (1 << CPUCFG2_LCSRP) |
+(1 << CPUCFG2_LDISBLIKELY),
 .SEGBITS = 48,
 .PABITS = 48,
 .insn_flags = CPU_MIPS64R2 | INSN_LOONGSON3A |
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index b7119cbbb459..e675b9178192 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -244,6 +244,8 @@ static void mips_cpu_reset_hold(Object *obj)
 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
 env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
+env->lcsr_cpucfg1 = env->cpu_model->lcsr_cpucfg1;
+env->lcsr_cpucfg2 = env->cpu_model->lcsr_cpucfg2;
 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
 env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
 env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
@@ -507,6 +509,12 @@ static void mips_cpu_initfn(Object *obj)
 cpu->count_div = clock_new(OBJECT(obj), "clk-div-count");
 env->count_clock = clock_new(OBJECT(obj), "clk-count");
 env->cpu_model = mcc->cpu_def;
+if (mcc->cpu_def->lcsr_cpucfg2 & (1 << CPUCFG2_LCSRP)) {
+memory_region_init_io(>system_iocsr, OBJECT(cpu), NULL,
+env, "iocsr", UINT64_MAX);
+address_space_init(>address_space_iocsr,
+>system_iocsr, "IOCSR");
+}
 }
 
 static char *mips_cpu_type_name(const char *cpu_model)
diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 1b8107b0af86..f63b128ff3d3 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -3,6 +3,9 @@
 
 #include "cpu-qom.h"
 #include "exec/cpu-defs.h"
+#ifndef CONFIG_USER_ONLY
+#include "exec/memory.h"
+#endif
 #include "fpu/softfloat-types.h"
 #include "hw/clock.h"
 #include "mips-defs.h"
@@ -1068,6 +1071,33 @@ typedef struct CPUArchState {
  */
 int32_t CP0_DESAVE;
 target_ulong CP0_KScratch[MIPS_KSCRATCH_NUM];
+/*
+ * Loongson CSR CPUCFG registers
+ */
+uint32_t lcsr_cpucfg1;
+#define CPUCFG1_FP 0
+#define CPUCFG1_FPREV  1
+#define CPUCFG1_MMI4
+#define CPUCFG1_MSA1   5
+#define CPUCFG1_MSA2   6
+#define CPUCFG1_LSLDR0 16
+#define CPUCFG1_LSPERF 17
+#define CPUCFG1_LSPERFX 18
+#define CPUCFG1_LSSYNCI 19
+#d

[PATCH] target/mips: Rework cp0_timer with clock API

2023-05-21 Thread Jiaxun Yang
Previous implementation of MIPS cp0_timer computes a
cp0_count_ns based on input clock. However rounding
error of cp0_count_ns can affect precision of cp0_timer.

Using clock API and a divider for cp0_timer, so we can
use clock_ns_to_ticks/clock_ns_to_ticks to avoid rounding
issue.

Also workaround the situation that in such handler flow:

count = read_c0_count()
write_c0_compare(count)

If timer had not progressed when compare was written, the
interrupt would trigger again.

Signed-off-by: Jiaxun Yang 
---
This seems fixed MTTCG booting issue on malta 5kEc with SMP.
I'm going to do more test and see if we can enable MTTCG for
mips64el.
---
 target/mips/cpu.c  |  8 +---
 target/mips/cpu.h  |  3 ++-
 target/mips/sysemu/cp0_timer.c | 35 ++
 3 files changed, 26 insertions(+), 20 deletions(-)

diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index 01e0fbe10db2..b7119cbbb459 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -449,9 +449,9 @@ static void mips_cp0_period_set(MIPSCPU *cpu)
 {
 CPUMIPSState *env = >env;
 
-env->cp0_count_ns = clock_ticks_to_ns(MIPS_CPU(cpu)->clock,
-  env->cpu_model->CCRes);
-assert(env->cp0_count_ns);
+clock_set_mul_div(cpu->count_div, env->cpu_model->CCRes, 1);
+clock_set_source(cpu->count_div, cpu->clock);
+clock_set_source(env->count_clock, cpu->count_div);
 }
 
 static void mips_cpu_realizefn(DeviceState *dev, Error **errp)
@@ -504,6 +504,8 @@ static void mips_cpu_initfn(Object *obj)
 
 cpu_set_cpustate_pointers(cpu);
 cpu->clock = qdev_init_clock_in(DEVICE(obj), "clk-in", NULL, cpu, 0);
+cpu->count_div = clock_new(OBJECT(obj), "clk-div-count");
+env->count_clock = clock_new(OBJECT(obj), "clk-count");
 env->cpu_model = mcc->cpu_def;
 }
 
diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 142c55af478b..1b8107b0af86 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -1160,8 +1160,8 @@ typedef struct CPUArchState {
 
 const mips_def_t *cpu_model;
 QEMUTimer *timer; /* Internal timer */
+Clock *count_clock; /* CP0_Count clock */
 target_ulong exception_base; /* ExceptionBase input to the core */
-uint64_t cp0_count_ns; /* CP0_Count clock period (in nanoseconds) */
 } CPUMIPSState;
 
 /**
@@ -1178,6 +1178,7 @@ struct ArchCPU {
 /*< public >*/
 
 Clock *clock;
+Clock *count_div; /* Divider for CP0_Count clock */
 CPUNegativeOffsetState neg;
 CPUMIPSState env;
 };
diff --git a/target/mips/sysemu/cp0_timer.c b/target/mips/sysemu/cp0_timer.c
index 70de95d338f8..9d2bcb0dea21 100644
--- a/target/mips/sysemu/cp0_timer.c
+++ b/target/mips/sysemu/cp0_timer.c
@@ -28,15 +28,26 @@
 #include "internal.h"
 
 /* MIPS R4K timer */
+static uint32_t cpu_mips_get_count_val(CPUMIPSState *env)
+{
+int64_t now_ns;
+now_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+return env->CP0_Count +
+(uint32_t)clock_ns_to_ticks(env->count_clock, now_ns);
+}
+
 static void cpu_mips_timer_update(CPUMIPSState *env)
 {
 uint64_t now_ns, next_ns;
 uint32_t wait;
 
 now_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
-wait = env->CP0_Compare - env->CP0_Count -
-   (uint32_t)(now_ns / env->cp0_count_ns);
-next_ns = now_ns + (uint64_t)wait * env->cp0_count_ns;
+wait = env->CP0_Compare - cpu_mips_get_count_val(env);
+/* Clamp interval to overflow if virtual time had not progressed */
+if (!wait) {
+wait = UINT32_MAX;
+}
+next_ns = now_ns + clock_ticks_to_ns(env->count_clock, wait);
 timer_mod(env->timer, next_ns);
 }
 
@@ -64,7 +75,7 @@ uint32_t cpu_mips_get_count(CPUMIPSState *env)
 cpu_mips_timer_expire(env);
 }
 
-return env->CP0_Count + (uint32_t)(now_ns / env->cp0_count_ns);
+return cpu_mips_get_count_val(env);
 }
 }
 
@@ -79,9 +90,8 @@ void cpu_mips_store_count(CPUMIPSState *env, uint32_t count)
 env->CP0_Count = count;
 } else {
 /* Store new count register */
-env->CP0_Count = count -
-   (uint32_t)(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) /
-  env->cp0_count_ns);
+env->CP0_Count = count - (uint32_t)clock_ns_to_ticks(env->count_clock,
+qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
 /* Update timer timer */
 cpu_mips_timer_update(env);
 }
@@ -107,8 +117,8 @@ void cpu_mips_start_count(CPUMIPSState *env)
 void cpu_mips_stop_count(CPUMIPSState *env)
 {
 /* Store the current value */
-env->CP0_Count += (uint32_t)(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) /
- env->cp0_count_ns);
+env->CP0_Count += (uint32_t)clock_ns_to_ticks(env->count_clock,
+qe

[PATCH 4/4] tests/avocado: Add boot_linux_console test for loongson3-virt

2023-05-21 Thread Jiaxun Yang
Test loongson3-virt machine againt debian kernel and cpio rootfs.

Signed-off-by: Jiaxun Yang 
---
 tests/avocado/boot_linux_console.py | 46 +
 1 file changed, 46 insertions(+)

diff --git a/tests/avocado/boot_linux_console.py 
b/tests/avocado/boot_linux_console.py
index c0675809e641..fdb479448e47 100644
--- a/tests/avocado/boot_linux_console.py
+++ b/tests/avocado/boot_linux_console.py
@@ -191,6 +191,52 @@ def test_mips64el_fuloong2e(self):
 console_pattern = 'Kernel command line: %s' % kernel_command_line
 self.wait_for_console_pattern(console_pattern)
 
+def test_mips64el_loongson3_virt_cpio(self):
+"""
+:avocado: tags=arch:mips64el
+:avocado: tags=endian:little
+:avocado: tags=machine:loongson3-virt
+:avocado: tags=cpu:Loongson-3A1000
+:avocado: tags=device:liointc
+:avocado: tags=device:loongarch_ipi
+:avocado: tags=device:goldfish_rtc
+"""
+deb_url = ('http://snapshot.debian.org/archive/debian/'
+   '20230501T024743Z/pool/main/l/linux/'
+   'linux-image-5.10.0-22-loongson-3_5.10.178-3_mips64el.deb')
+deb_hash = 'af4fcc721b727df0bef31057325e4cc02725ae0c'
+deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
+kernel_path = self.extract_from_deb(deb_path,
+'/boot/vmlinuz-5.10.0-22-loongson-3')
+initrd_url = ('https://github.com/groeck/linux-build-test/'
+  'raw/8584a59e/rootfs/'
+  'mipsel64/rootfs.mipsel64r1.cpio.gz')
+initrd_hash = '1dbb8a396e916847325284dbe2151167'
+initrd_path_gz = self.fetch_asset(initrd_url, algorithm='md5',
+  asset_hash=initrd_hash)
+initrd_path = self.workdir + "rootfs.cpio"
+archive.gzip_uncompress(initrd_path_gz, initrd_path)
+
+self.vm.set_console()
+kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE
+   + 'console=ttyS0,115200 '
+   + 'rdinit=/sbin/init noreboot')
+self.vm.add_args('-kernel', kernel_path,
+ '-initrd', initrd_path,
+ '-append', kernel_command_line,
+ '-no-reboot')
+self.vm.launch()
+wait_for_console_pattern(self, 'Boot successful.')
+
+exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo',
+'ICT Loongson-3')
+exec_command_and_wait_for_pattern(self, 'uname -a',
+'5.10.0-22-loongson-3')
+exec_command_and_wait_for_pattern(self, 'reboot',
+'reboot: Restarting system')
+# Wait for VM to shut down gracefully
+self.vm.wait()
+
 def test_mips_malta_cpio(self):
 """
 :avocado: tags=arch:mips
-- 
2.39.2 (Apple Git-143)




[PATCH 2/4] hw/intc/loongarch_ipi: Guard LoongArch only features with ifdef

2023-05-21 Thread Jiaxun Yang
IOCSR based send features are tied to LoongArch's CPU implmentation,
ifdef them for LoongArch only so we can build loongarch_ipi on MIPS.

Note that Loongson-3A4000 have IOCSR as well, so we may implement
those features for MIPS in future.

Signed-off-by: Jiaxun Yang 
---
 hw/intc/loongarch_ipi.c | 20 
 1 file changed, 20 insertions(+)

diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c
index 3e453816524e..895a2ee96e1e 100644
--- a/hw/intc/loongarch_ipi.c
+++ b/hw/intc/loongarch_ipi.c
@@ -50,6 +50,7 @@ static uint64_t loongarch_ipi_readl(void *opaque, hwaddr 
addr, unsigned size)
 return ret;
 }
 
+#ifdef TARGET_LOONGARCH64
 static void send_ipi_data(CPULoongArchState *env, uint64_t val, hwaddr addr)
 {
 int i, mask = 0, data = 0;
@@ -140,6 +141,25 @@ static void any_send(uint64_t val)
 env = >env;
 send_ipi_data(env, val, addr);
 }
+#else
+static void ipi_send(uint64_t val)
+{
+qemu_log_mask(LOG_UNIMP, "%s: Unimplemented send 0x%" PRIx64 "\n",
+__func__, val);
+}
+
+static void mail_send(uint64_t val)
+{
+qemu_log_mask(LOG_UNIMP, "%s: Unimplemented send 0x%" PRIx64 "\n",
+__func__, val);
+}
+
+static void any_send(uint64_t val)
+{
+qemu_log_mask(LOG_UNIMP, "%s: Unimplemented send 0x%" PRIx64 "\n",
+__func__, val);
+}
+#endif
 
 static void loongarch_ipi_writel(void *opaque, hwaddr addr, uint64_t val,
  unsigned size)
-- 
2.39.2 (Apple Git-143)




[PATCH 0/4] hw/mips/loongson3_virt: Wire up loongarch_ipi device

2023-05-21 Thread Jiaxun Yang
Hi all,

This series wires up loongarch_ipi device for loongson3-virt,
which is required for SMP support.

We also add a new test for loongson3-virt for acceptance harness.

Thanks
- Jiaxun

Jiaxun Yang (4):
  hw/intc/loongarch_ipi: Bring back all 4 IPI mailboxes
  hw/intc/loongarch_ipi: Guard LoongArch only features with ifdef
  hw/mips/loongson3_virt: Wire up loongarch_ipi device
  tests/avocado: Add boot_linux_console test for loongson3-virt

 hw/intc/loongarch_ipi.c | 26 ++--
 hw/mips/Kconfig |  1 +
 hw/mips/loongson3_bootp.c   |  2 --
 hw/mips/loongson3_bootp.h   |  3 ++
 hw/mips/loongson3_virt.c| 20 +++--
 include/hw/intc/loongarch_ipi.h |  4 ++-
 tests/avocado/boot_linux_console.py | 46 +
 7 files changed, 94 insertions(+), 8 deletions(-)

-- 
2.39.2 (Apple Git-143)




[PATCH 3/4] hw/mips/loongson3_virt: Wire up loongarch_ipi device

2023-05-21 Thread Jiaxun Yang
Wire up loongarch_ipi device for loongson3_virt machine, so we
can have SMP support for TCG backend as well.

Signed-off-by: Jiaxun Yang 
---
 hw/mips/Kconfig   |  1 +
 hw/mips/loongson3_bootp.c |  2 --
 hw/mips/loongson3_bootp.h |  3 +++
 hw/mips/loongson3_virt.c  | 20 ++--
 4 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/hw/mips/Kconfig b/hw/mips/Kconfig
index da3a37e215ec..7cb6c1def16c 100644
--- a/hw/mips/Kconfig
+++ b/hw/mips/Kconfig
@@ -40,6 +40,7 @@ config LOONGSON3V
 imply QXL if SPICE
 select SERIAL
 select GOLDFISH_RTC
+select LOONGARCH_IPI
 select LOONGSON_LIOINTC
 select PCI_DEVICES
 select PCI_EXPRESS_GENERIC_BRIDGE
diff --git a/hw/mips/loongson3_bootp.c b/hw/mips/loongson3_bootp.c
index f99af229327a..474d3556b2e5 100644
--- a/hw/mips/loongson3_bootp.c
+++ b/hw/mips/loongson3_bootp.c
@@ -25,8 +25,6 @@
 #include "hw/boards.h"
 #include "hw/mips/loongson3_bootp.h"
 
-#define LOONGSON3_CORE_PER_NODE 4
-
 static void init_cpu_info(void *g_cpuinfo, uint64_t cpu_freq)
 {
 struct efi_cpuinfo_loongson *c = g_cpuinfo;
diff --git a/hw/mips/loongson3_bootp.h b/hw/mips/loongson3_bootp.h
index d525ab745a69..55f98858a5f4 100644
--- a/hw/mips/loongson3_bootp.h
+++ b/hw/mips/loongson3_bootp.h
@@ -200,6 +200,8 @@ struct boot_params {
 struct efi_reset_system_t reset_system;
 };
 
+#define LOONGSON3_CORE_PER_NODE 4
+
 /* Overall MMIO & Memory layout */
 enum {
 VIRT_LOWMEM,
@@ -211,6 +213,7 @@ enum {
 VIRT_BIOS_ROM,
 VIRT_UART,
 VIRT_LIOINTC,
+VIRT_IPI,
 VIRT_PCIE_MMIO,
 VIRT_HIGHMEM
 };
diff --git a/hw/mips/loongson3_virt.c b/hw/mips/loongson3_virt.c
index 25534288dd81..a57245012598 100644
--- a/hw/mips/loongson3_virt.c
+++ b/hw/mips/loongson3_virt.c
@@ -38,6 +38,7 @@
 #include "hw/mips/loongson3_bootp.h"
 #include "hw/misc/unimp.h"
 #include "hw/intc/i8259.h"
+#include "hw/intc/loongarch_ipi.h"
 #include "hw/loader.h"
 #include "hw/isa/superio.h"
 #include "hw/pci/msi.h"
@@ -76,6 +77,7 @@ const MemMapEntry virt_memmap[] = {
 [VIRT_PCIE_ECAM] =   { 0x1a00, 0x200 },
 [VIRT_BIOS_ROM] ={ 0x1fc0,  0x20 },
 [VIRT_UART] ={ 0x1fe001e0,   0x8 },
+[VIRT_IPI] = { 0x3ff01000, 0x400 },
 [VIRT_LIOINTC] = { 0x3ff01400,  0x64 },
 [VIRT_PCIE_MMIO] =   { 0x4000,0x4000 },
 [VIRT_HIGHMEM] = { 0x8000,   0x0 }, /* Variable */
@@ -529,6 +531,8 @@ static void mips_loongson3_virt_init(MachineState *machine)
 clock_set_hz(cpuclk, DEF_LOONGSON3_FREQ);
 
 for (i = 0; i < machine->smp.cpus; i++) {
+int node = i / LOONGSON3_CORE_PER_NODE;
+int core = i % LOONGSON3_CORE_PER_NODE;
 int ip;
 
 /* init CPUs */
@@ -539,12 +543,24 @@ static void mips_loongson3_virt_init(MachineState 
*machine)
 cpu_mips_clock_init(cpu);
 qemu_register_reset(main_cpu_reset, cpu);
 
-if (i >= 4) {
+/* IPI controller is in kernel for KVM */
+if (!kvm_enabled()) {
+DeviceState *ipi;
+
+hwaddr base = ((hwaddr)node << 44) + virt_memmap[VIRT_IPI].base;
+base += core * 0x100;
+ipi = qdev_new(TYPE_LOONGARCH_IPI);
+sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), _fatal);
+qdev_connect_gpio_out(ipi, 0, cpu->env.irq[6]);
+sysbus_mmio_map(SYS_BUS_DEVICE(ipi), 0, base);
+}
+
+if (node > 0) {
 continue; /* Only node-0 can be connected to LIOINTC */
 }
 
 for (ip = 0; ip < 4 ; ip++) {
-int pin = i * 4 + ip;
+int pin = core * LOONGSON3_CORE_PER_NODE + ip;
 sysbus_connect_irq(SYS_BUS_DEVICE(liointc),
pin, cpu->env.irq[ip + 2]);
 }
-- 
2.39.2 (Apple Git-143)




[PATCH 1/4] hw/intc/loongarch_ipi: Bring back all 4 IPI mailboxes

2023-05-21 Thread Jiaxun Yang
As per "Loongson 3A5000/3B5000 Processor Reference Manual",
Loongson 3A5000's IPI implementation have 4 mailboxes per
core.

However, in 78464f023b54 ("hw/loongarch/virt: Modify ipi as
percpu device"), the number of IPI mailboxes was reduced to
one, which mismatches actual hardware.

It won't affect LoongArch based system as LoongArch boot code
only uses the first mailbox, however MIPS based Loongson boot
code uses all 4 mailboxes.

Fixes: 78464f023b54 ("hw/loongarch/virt: Modify ipi as percpu device")
Signed-off-by: Jiaxun Yang 
---
 hw/intc/loongarch_ipi.c | 6 +++---
 include/hw/intc/loongarch_ipi.h | 4 +++-
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c
index d6ab91721ea1..3e453816524e 100644
--- a/hw/intc/loongarch_ipi.c
+++ b/hw/intc/loongarch_ipi.c
@@ -238,14 +238,14 @@ static void loongarch_ipi_init(Object *obj)
 
 static const VMStateDescription vmstate_ipi_core = {
 .name = "ipi-single",
-.version_id = 1,
-.minimum_version_id = 1,
+.version_id = 2,
+.minimum_version_id = 2,
 .fields = (VMStateField[]) {
 VMSTATE_UINT32(status, IPICore),
 VMSTATE_UINT32(en, IPICore),
 VMSTATE_UINT32(set, IPICore),
 VMSTATE_UINT32(clear, IPICore),
-VMSTATE_UINT32_ARRAY(buf, IPICore, 2),
+VMSTATE_UINT32_ARRAY(buf, IPICore, IPI_MBX_NUM * 2),
 VMSTATE_END_OF_LIST()
 }
 };
diff --git a/include/hw/intc/loongarch_ipi.h b/include/hw/intc/loongarch_ipi.h
index 664e050b926e..6c6194786e80 100644
--- a/include/hw/intc/loongarch_ipi.h
+++ b/include/hw/intc/loongarch_ipi.h
@@ -28,6 +28,8 @@
 #define MAIL_SEND_OFFSET  0
 #define ANY_SEND_OFFSET   (IOCSR_ANY_SEND - IOCSR_MAIL_SEND)
 
+#define IPI_MBX_NUM   4
+
 #define TYPE_LOONGARCH_IPI "loongarch_ipi"
 OBJECT_DECLARE_SIMPLE_TYPE(LoongArchIPI, LOONGARCH_IPI)
 
@@ -37,7 +39,7 @@ typedef struct IPICore {
 uint32_t set;
 uint32_t clear;
 /* 64bit buf divide into 2 32bit buf */
-uint32_t buf[2];
+uint32_t buf[IPI_MBX_NUM * 2];
 qemu_irq irq;
 } IPICore;
 
-- 
2.39.2 (Apple Git-143)




Re: [PATCH 21/22] tests/avocado: use http for mipsdistros.mips.com

2023-05-10 Thread Jiaxun Yang



> 2023年5月3日 10:12,Alex Bennée  写道:
> 
> As the cached assets have fallen out of our cache new attempts to
> fetch these binaries fail hard due to certificate expirty. It's hard
> to find a contact email for the domain as the root page of mipsdistros
> throws up some random XML. I suspect Amazon are merely the hosts.
> 
> Signed-off-by: Alex Bennée 
> Cc: Philippe Mathieu-Daudé 

Hi  all,

Just reached MIPS to get certification fixed.

Thanks
- Jiaxun


Re: [PATCH] linux-user: Fix mips fp64 executables loading

2023-04-05 Thread Jiaxun Yang



> 2023年4月4日 06:21,Daniil Kovalev  写道:
> 
> If a program requires fr1, we should set the FR bit of CP0 control status
> register and add F64 hardware flag. The corresponding `else if` branch
> statement is copied from the linux kernel sources (see `arch_check_elf` 
> function
> in linux/arch/mips/kernel/elf.c).
> 
> Signed-off-by: Daniil Kovalev 

Reviewed-by: Jiaxun Yang 

Thanks!

> ---
> linux-user/mips/cpu_loop.c | 5 -
> 1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c
> index d5c1c7941d..8735e58bad 100644
> --- a/linux-user/mips/cpu_loop.c
> +++ b/linux-user/mips/cpu_loop.c
> @@ -290,7 +290,10 @@ void target_cpu_copy_regs(CPUArchState *env, struct 
> target_pt_regs *regs)
> env->CP0_Status |= (1 << CP0St_FR);
> env->hflags |= MIPS_HFLAG_F64;
> }
> -} else  if (!prog_req.fre && !prog_req.frdefault &&
> +} else if (prog_req.fr1) {
> +env->CP0_Status |= (1 << CP0St_FR);
> +env->hflags |= MIPS_HFLAG_F64;
> +} else if (!prog_req.fre && !prog_req.frdefault &&
>   !prog_req.fr1 && !prog_req.single && !prog_req.soft) {
> fprintf(stderr, "qemu: Can't find a matching FPU mode\n");
> exit(1);
> -- 
> 2.40.0
> 




Re: [PATCH] linux-user/mips: Low down switchable NaN2008 requirement

2023-03-21 Thread Jiaxun Yang



> 2023年3月15日 08:18,Philippe Mathieu-Daudé  写道:
> 
> On 11/3/23 13:39, Jiaxun Yang wrote:
>>> 2023年3月9日 12:32,Philippe Mathieu-Daudé  写道:
>>> 
>>> Hi Jiaxun,
>>> 
>>> On 11/2/23 18:34, Jiaxun Yang wrote:
>>>> Previously switchable NaN2008 requires fcsr31.nan2008 to be writable
>>>> for guest. However as per MIPS arch spec this bit can never be writable.
>>>> This cause NaN2008 ELF to be rejected by QEMU.
>>>> NaN2008 can be enabled on R2~R5 processors, just make it available
>>>> unconditionally.
>>>> Signed-off-by: Jiaxun Yang 
>>>> ---
>>>>  linux-user/mips/cpu_loop.c | 3 +--
>>>>  1 file changed, 1 insertion(+), 2 deletions(-)
>>>> diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c
>>>> index d5c1c7941d..b5c2ca4a3e 100644
>>>> --- a/linux-user/mips/cpu_loop.c
>>>> +++ b/linux-user/mips/cpu_loop.c
>>>> @@ -301,8 +301,7 @@ void target_cpu_copy_regs(CPUArchState *env, struct 
>>>> target_pt_regs *regs)
>>>>  }
>>>>  if (((info->elf_flags & EF_MIPS_NAN2008) != 0) !=
>>>>  ((env->active_fpu.fcr31 & (1 << FCR31_NAN2008)) != 0)) {
>>>> -if ((env->active_fpu.fcr31_rw_bitmask &
>>>> -  (1 << FCR31_NAN2008)) == 0) {
>>>> +if (!(env->insn_flags & ISA_MIPS_R2)) {
>>>>  fprintf(stderr, "ELF binary's NaN mode not supported by 
>>>> CPU\n");
>>>>  exit(1);
>>>>  }
>>> 
>>> Looking at R6.06 revision history:
>>> 
>>>  5.03 August 21, 2013
>>> 
>>>  • ABS2008 and NAN2008 fields of Table 5.7 “FCSR RegisterField
>>>Descriptions” were optional in release 3 and could be R/W,
>>>but as of release 5 are required, read-only, and preset by
>>>hardware.
>>> So I tried with this change:
>>> 
>>> -- >8 --
>>> diff --git a/target/mips/cpu.c b/target/mips/cpu.c
>>> index 05caf54999..5f1364ffaf 100644
>>> --- a/target/mips/cpu.c
>>> +++ b/target/mips/cpu.c
>>> @@ -243,6 +243,13 @@ static void mips_cpu_reset_hold(Object *obj)
>>> env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
>>> env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
>>> env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
>>> +if (env->insn_flags & ISA_MIPS_R5) {
>>> +assert(!(env->cpu_model->CP1_fcr31_rw_bitmask & (1 << 
>>> FCR31_ABS2008)));
>>> +assert(!(env->cpu_model->CP1_fcr31_rw_bitmask & (1 << 
>>> FCR31_NAN2008)));
>>> +} else if (env->insn_flags & ISA_MIPS_R3) {
>>> +assert(env->cpu_model->CP1_fcr31_rw_bitmask & (1 << 
>>> FCR31_ABS2008));
>>> +assert(env->cpu_model->CP1_fcr31_rw_bitmask & (1 << 
>>> FCR31_NAN2008));
>>> +}
>>> env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
>>> env->msair = env->cpu_model->MSAIR;
>>> env->insn_flags = env->cpu_model->insn_flags;
>>> ---
>>> 
>>> and got:
>>> 
>>> $ for cpu in $(./qemu-system-mips64el -cpu help | cut -d\' -f2); do \
>>>  echo -n ${cpu}...;echo q \
>>>  | ./qemu-system-mips64el -accel tcg -cpu ${cpu} \
>>>   -S -monitor stdio 1> /dev/null || break; \
>>>  echo OK; done
>>> 4Kc...OK
>>> 4Km...OK
>>> 4KEcR1...OK
>>> 4KEmR1...OK
>>> 4KEc...OK
>>> 4KEm...OK
>>> 24Kc...OK
>>> 24KEc...OK
>>> 24Kf...OK
>>> 34Kf...OK
>>> 74Kf...OK
>>> M14K...OK
>>> M14Kc...OK
>>> P5600...OK
>>> mips32r6-generic...OK
>>> I7200...OK
>>> R4000...OK
>>> VR5432...OK
>>> 5Kc...OK
>>> 5Kf...OK
>>> 20Kc...OK
>>> MIPS64R2-generic...OK
>>> 5KEc...OK
>>> 5KEf...OK
>>> I6400...OK
>>> I6500...OK
>>> Loongson-2E...OK
>>> Loongson-2F...OK
>>> Loongson-3A1000...OK
>>> Loongson-3A4000...OK
>>> mips64dspr2...OK
>>> Octeon68XX...OK
>>> $
>> Well that’s because there is no CPU being marked as MIPS Release 3 in QEMU, 
>> and only
>> P5600 is marked as MIPS Release 5.
>> In reality R3 implementations are all advertising themself as R2, and later 
>> RCs of microAptiv
>> and interaptiv can all be configured as NaN2008 only. So for those CPUs we 
>> have binary compiled
>> with -march=mips32r2 -mnan=2008.
>> Given that default CPU of mips32r2 in QEMU is 24Kf, I think the best 
>> approach to deal with such
>> situation is to allow NaN2008 to be enabled for early processors for 
>> linux-user.
>> There is a NAN2008 Debian port for test:
>> http://repo.oss.cipunited.com/mipsel-nan2008/tarball/sid-mipsel-nan2008-20230309-1.tar.xz
> 
> $ qemu-mipsel -L sid-mipsel-nan2008-20230313-1/usr -cpu P5600 usr/bin/uname  
> -ms
> Linux mips
> 
> What about something like:

That would lost capability of testing NaN2008 binaries again other CPU models.

Thanks
- Jiaxun

> 
> -- >8 --
> --- a/linux-user/mips/target_elf.h
> +++ b/linux-user/mips/target_elf.h
> @@ -15,6 +15,9 @@ static inline const char *cpu_get_model(uint32_t eflags)
> if ((eflags & EF_MIPS_MACH) == EF_MIPS_MACH_5900) {
> return "R5900";
> }
> +if (eflags & EF_MIPS_NAN2008) {
> +return "P5600";
> +}
> return "24Kf";
> }
> #endif
> ---





Re: [PATCH] linux-user/mips: Low down switchable NaN2008 requirement

2023-03-11 Thread Jiaxun Yang



> 2023年3月9日 12:32,Philippe Mathieu-Daudé  写道:
> 
> Hi Jiaxun,
> 
> On 11/2/23 18:34, Jiaxun Yang wrote:
>> Previously switchable NaN2008 requires fcsr31.nan2008 to be writable
>> for guest. However as per MIPS arch spec this bit can never be writable.
>> This cause NaN2008 ELF to be rejected by QEMU.
>> NaN2008 can be enabled on R2~R5 processors, just make it available
>> unconditionally.
>> Signed-off-by: Jiaxun Yang 
>> ---
>>  linux-user/mips/cpu_loop.c | 3 +--
>>  1 file changed, 1 insertion(+), 2 deletions(-)
>> diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c
>> index d5c1c7941d..b5c2ca4a3e 100644
>> --- a/linux-user/mips/cpu_loop.c
>> +++ b/linux-user/mips/cpu_loop.c
>> @@ -301,8 +301,7 @@ void target_cpu_copy_regs(CPUArchState *env, struct 
>> target_pt_regs *regs)
>>  }
>>  if (((info->elf_flags & EF_MIPS_NAN2008) != 0) !=
>>  ((env->active_fpu.fcr31 & (1 << FCR31_NAN2008)) != 0)) {
>> -if ((env->active_fpu.fcr31_rw_bitmask &
>> -  (1 << FCR31_NAN2008)) == 0) {
>> +if (!(env->insn_flags & ISA_MIPS_R2)) {
>>  fprintf(stderr, "ELF binary's NaN mode not supported by CPU\n");
>>  exit(1);
>>  }
> 
> Looking at R6.06 revision history:
> 
>  5.03 August 21, 2013
> 
>  • ABS2008 and NAN2008 fields of Table 5.7 “FCSR RegisterField
>Descriptions” were optional in release 3 and could be R/W,
>but as of release 5 are required, read-only, and preset by
>hardware.
> So I tried with this change:
> 
> -- >8 --
> diff --git a/target/mips/cpu.c b/target/mips/cpu.c
> index 05caf54999..5f1364ffaf 100644
> --- a/target/mips/cpu.c
> +++ b/target/mips/cpu.c
> @@ -243,6 +243,13 @@ static void mips_cpu_reset_hold(Object *obj)
> env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
> env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
> env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
> +if (env->insn_flags & ISA_MIPS_R5) {
> +assert(!(env->cpu_model->CP1_fcr31_rw_bitmask & (1 << 
> FCR31_ABS2008)));
> +assert(!(env->cpu_model->CP1_fcr31_rw_bitmask & (1 << 
> FCR31_NAN2008)));
> +} else if (env->insn_flags & ISA_MIPS_R3) {
> +assert(env->cpu_model->CP1_fcr31_rw_bitmask & (1 << FCR31_ABS2008));
> +assert(env->cpu_model->CP1_fcr31_rw_bitmask & (1 << FCR31_NAN2008));
> +}
> env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
> env->msair = env->cpu_model->MSAIR;
> env->insn_flags = env->cpu_model->insn_flags;
> ---
> 
> and got:
> 
> $ for cpu in $(./qemu-system-mips64el -cpu help | cut -d\' -f2); do \
>  echo -n ${cpu}...;echo q \
>  | ./qemu-system-mips64el -accel tcg -cpu ${cpu} \
>   -S -monitor stdio 1> /dev/null || break; \
>  echo OK; done
> 4Kc...OK
> 4Km...OK
> 4KEcR1...OK
> 4KEmR1...OK
> 4KEc...OK
> 4KEm...OK
> 24Kc...OK
> 24KEc...OK
> 24Kf...OK
> 34Kf...OK
> 74Kf...OK
> M14K...OK
> M14Kc...OK
> P5600...OK
> mips32r6-generic...OK
> I7200...OK
> R4000...OK
> VR5432...OK
> 5Kc...OK
> 5Kf...OK
> 20Kc...OK
> MIPS64R2-generic...OK
> 5KEc...OK
> 5KEf...OK
> I6400...OK
> I6500...OK
> Loongson-2E...OK
> Loongson-2F...OK
> Loongson-3A1000...OK
> Loongson-3A4000...OK
> mips64dspr2...OK
> Octeon68XX...OK
> $

Well that’s because there is no CPU being marked as MIPS Release 3 in QEMU, and 
only
P5600 is marked as MIPS Release 5.

In reality R3 implementations are all advertising themself as R2, and later RCs 
of microAptiv
and interaptiv can all be configured as NaN2008 only. So for those CPUs we have 
binary compiled
with -march=mips32r2 -mnan=2008.

Given that default CPU of mips32r2 in QEMU is 24Kf, I think the best approach 
to deal with such
situation is to allow NaN2008 to be enabled for early processors for linux-user.

There is a NAN2008 Debian port for test: 

http://repo.oss.cipunited.com/mipsel-nan2008/tarball/sid-mipsel-nan2008-20230309-1.tar.xz

Thanks

> 
> Which CPU are you testing? Where can I get such ELF binary for testing?
> 
> Thanks,
> 
> Phil.





Re: [PATCH v2 0/2] MIPS Virt machine

2023-03-07 Thread Jiaxun Yang



> 2023年3月7日 21:07,Philippe Mathieu-Daudé  写道:
> 
> On 7/3/23 21:14, Philippe Mathieu-Daudé wrote:
>> On 7/3/23 21:07, Jiaxun Yang wrote:
>>> 
>>> 
>>>> 2023年3月7日 15:01,Philippe Mathieu-Daudé  写道:
>>>> 
>>>> On 4/3/23 23:38, Jiaxun Yang wrote:
>>>>> Hi there,
>>>>> This patchset is to add a new machine type for MIPS architecture, which
>>>>> is purely a VirtIO machine.
>>>> 
>>>>> Jiaxun Yang (2):
>>>>>   hw/misc: Add MIPS Trickbox device
>>>>>   hw/mips: Add MIPS virt board
>>>> Thanks, applied with following changes:
>>> 
>>> Thanks for those clean-ups!
> 
> Unfortunately I have to drop this due to the libfdt
> dependency, which fails the --disable-fdt job:
> https://gitlab.com/philmd/qemu/-/jobs/3890587748

Perhaps we should just select TARGET_NEED_FDT for all MIPS variants?

Thanks
- Jiaxun


Re: [PATCH v2 2/2] hw/mips: Add MIPS virt board

2023-03-07 Thread Jiaxun Yang



> 2023年3月7日 20:10,Philippe Mathieu-Daudé  写道:
> 
> On 4/3/23 23:38, Jiaxun Yang wrote:
>> MIPS virt board is design to utilize existing VirtIO infrastures
>> but also comptitable with MIPS's existing internal simulation tools.
>> It includes virtio-pci, virtio-mmio, pcie gpex, flash rom, fw_cfg,
>> goldfish-rtc and MIPS CPS system.
>> It should be able to cooperate with any MIPS CPU cores.
>> Signed-off-by: Jiaxun Yang 
>> ---
>> v1:
>>  - Rename to virt board
>>  - Convert BIOS flash to ROM
>>  - Cleanups
>> v2:
>>  - Fix fdt flash
>>  - Remove UP variant
>> ---
>>  MAINTAINERS |   7 +
>>  configs/devices/mips-softmmu/common.mak |   1 +
>>  docs/system/target-mips.rst |  22 +
>>  hw/mips/Kconfig |  17 +
>>  hw/mips/meson.build |   1 +
>>  hw/mips/virt.c  | 916 
>>  6 files changed, 964 insertions(+)
>>  create mode 100644 hw/mips/virt.c
> 
> 
>> +static void virt_machine_init(MachineState *machine)
>> +{
>> +MIPSVirtState *s = MIPS_VIRT_MACHINE(machine);
>> +MemoryRegion *system_memory = get_system_memory();
>> +const MemMapEntry *memmap = virt_memmap;
>> +int i;
>> +
>> +s->cpuclk = clock_new(OBJECT(machine), "cpu-refclk");
>> +clock_set_hz(s->cpuclk, VIRT_CPU_REF_CLK_FREQ);
>> +
>> +s->cps = MIPS_CPS(qdev_new(TYPE_MIPS_CPS));
>> +object_property_set_str(OBJECT(s->cps), "cpu-type", machine->cpu_type,
>> +_fatal);
>> +object_property_set_int(OBJECT(s->cps), "num-core", machine->smp.cpus,
>> +_fatal);
>> +qdev_connect_clock_in(DEVICE(s->cps), "clk-in", s->cpuclk);
>> +sysbus_realize(SYS_BUS_DEVICE(s->cps), _fatal);
> 
> qemu-system-mips64el: Property 'mips-cps.num-core' not found
> 
> I'm worried. I suppose you want this property:
> 
>  DEFINE_PROP_UINT32("num-vp", MIPSCPSState, num_vp, 1),

Yes

> 
> Is your series based on mainstream QEMU?


Whoops, rebasing issue not caught by CI…

Accidentally leaked part of following patch into this one, was trying to fix SMP
support for earlier CPUs.

Apologise for this.

Thanks
- Jiaxun








  1   2   3   4   5   >