Re: [PATCH v1 4/4] tests/functional: Remove sleep workarounds from Aspeed tests

2024-11-12 Thread Cédric Le Goater

On 11/12/24 08:14, Thomas Huth wrote:

On 12/11/2024 07.28, Cédric Le Goater wrote:

These were introduced in the avocado tests to workaround read issues
when interacting with console. They are no longer necessary.

Signed-off-by: Cédric Le Goater 
---
  tests/functional/test_arm_aspeed.py | 7 ++-
  1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/tests/functional/test_arm_aspeed.py 
b/tests/functional/test_arm_aspeed.py
index bdd5771a794e..07a8905e2365 100755
--- a/tests/functional/test_arm_aspeed.py
+++ b/tests/functional/test_arm_aspeed.py
@@ -136,10 +136,8 @@ def do_test_arm_aspeed_buildroot_start(self, image, 
cpu_id, pattern='Aspeed EVB'
  self.wait_for_console_pattern('lease of 10.0.2.15')
  # the line before login:
  self.wait_for_console_pattern(pattern)


Could we please wait for the "login:" string now instead, to make sure that 
there is no race between detecting the previous line and the real login prompt?


Yes. I have done that in other tests. I should do it in this test also.

Thanks,

C.




Re: [PATCH v1 1/4] tests/functional: Introduce _console_read()

2024-11-12 Thread Cédric Le Goater

On 11/12/24 08:11, Thomas Huth wrote:

On 12/11/2024 07.28, Cédric Le Goater wrote:

Interaction with the console has been a problem in our avocado
tests. In some cases, the expected string does not match in the
output, causing the test to fail with a timeout. These were worked
around by sleeping before reading the console and even with SSH
connections in some places.

To fix, process the console output char by char and not with
readline. This routine was largely inspired by console_wait() in
tests/vm/basevm.py.

Signed-off-by: Cédric Le Goater 
---
  tests/functional/qemu_test/cmd.py | 17 -
  1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/tests/functional/qemu_test/cmd.py 
b/tests/functional/qemu_test/cmd.py
index cbabb1ceed3c..bb39857e6cae 100644
--- a/tests/functional/qemu_test/cmd.py
+++ b/tests/functional/qemu_test/cmd.py
@@ -12,6 +12,7 @@
  # later.  See the COPYING file in the top-level directory.
  import logging
+import re
  import os
  import os.path
  import subprocess
@@ -78,6 +79,20 @@ def run_cmd(args):
  def is_readable_executable_file(path):
  return os.path.isfile(path) and os.access(path, os.R_OK | os.X_OK)
+def _console_read(vm, expect, expectalt = None):
+    output = ""
+    while True:
+    data = vm.console_socket.recv(1)
+    if not data:
+    break
+    output += data.decode("latin1")
+    if expect in output:
+    break
+    if "\r" in output or "\n" in output:
+    lines = re.split("[\r\n]", output)
+    output = lines.pop()
+    return output
+


The idea looks promising, but I just realized that this is breaking the 
console.log:

$ cat 
tests/functional/arm/test_arm_aspeed.AST2x00Machine.test_arm_ast2500_evb_buildroot/console.log
  | wc -l
12

Without your patch, the log is way more verbose:

$ cat 
tests/functional/arm/test_arm_aspeed.AST2x00Machine.test_arm_ast2500_evb_buildroot/console.log
  | wc -l
232

Could you please have another look?


sure. I can add a log.debug.


Thanks,

C.










Re: [PATCH v1 2/4] tests/functional: Convert Aspeed aarch64 SDK tests

2024-11-12 Thread Cédric Le Goater

On 11/12/24 07:53, Thomas Huth wrote:

On 12/11/2024 07.28, Cédric Le Goater wrote:

Drop the SSH connection which was introduced in the avocado tests to
workaround read issues when interacting with console.

Signed-off-by: Cédric Le Goater 
---
  tests/avocado/machine_aspeed.py | 78 
  tests/functional/meson.build    |  2 +
  tests/functional/test_aarch64_aspeed.py | 97 +
  3 files changed, 99 insertions(+), 78 deletions(-)
  create mode 100644 tests/functional/test_aarch64_aspeed.py

diff --git a/tests/avocado/machine_aspeed.py b/tests/avocado/machine_aspeed.py
index 241ef180affc..2240c82abff9 100644
--- a/tests/avocado/machine_aspeed.py
+++ b/tests/avocado/machine_aspeed.py
@@ -59,17 +59,6 @@ def do_test_arm_aspeed_sdk_start(self, image):
  self, 'boot', '## Loading kernel from FIT Image')
  self.wait_for_console_pattern('Starting kernel ...')
-    def do_test_aarch64_aspeed_sdk_start(self, image):
-    self.vm.set_console()
-    self.vm.add_args('-drive', 'file=' + image + ',if=mtd,format=raw',
- '-net', 'nic', '-net', 
'user,hostfwd=:127.0.0.1:0-:22')
-
-    self.vm.launch()
-
-    self.wait_for_console_pattern('U-Boot 2023.10')
-    self.wait_for_console_pattern('## Loading kernel from FIT Image')
-    self.wait_for_console_pattern('Starting kernel ...')
-
  @skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable on 
GitLab')
  def test_arm_ast2500_evb_sdk(self):
  """
@@ -133,70 +122,3 @@ def test_arm_ast2600_evb_sdk(self):
  year = time.strftime("%Y")
  self.ssh_command_output_contains('/sbin/hwclock -f /dev/rtc1', year);
-    def test_aarch64_ast2700_evb_sdk_v09_02(self):
-    """
-    :avocado: tags=arch:aarch64
-    :avocado: tags=machine:ast2700-evb
-    """
-
-    image_url = ('https://github.com/AspeedTech-BMC/openbmc/releases/'
- 'download/v09.02/ast2700-default-obmc.tar.gz')
-    image_hash = 
'ac969c2602f4e6bdb69562ff466b89ae3fe1d86e1f6797bb7969d787f82116a7'
-    image_path = self.fetch_asset(image_url, asset_hash=image_hash,
-  algorithm='sha256')
-    archive.extract(image_path, self.workdir)
-
-    num_cpu = 4
-    image_dir = self.workdir + '/ast2700-default/'
-    uboot_size = os.path.getsize(image_dir + 'u-boot-nodtb.bin')
-    uboot_dtb_load_addr = hex(0x4 + uboot_size)
-
-    load_images_list = [
-    {
-    'addr': '0x4',
-    'file': image_dir + 'u-boot-nodtb.bin'
-    },
-    {
-    'addr': str(uboot_dtb_load_addr),
-    'file': image_dir + 'u-boot.dtb'
-    },
-    {
-    'addr': '0x43000',
-    'file': image_dir + 'bl31.bin'
-    },
-    {
-    'addr': '0x43008',
-    'file': image_dir + 'optee/tee-raw.bin'
-    }
-    ]
-
-    for load_image in load_images_list:
-    addr = load_image['addr']
-    file = load_image['file']
-    self.vm.add_args('-device',
- f'loader,force-raw=on,addr={addr},file={file}')
-
-    for i in range(num_cpu):
-    self.vm.add_args('-device',
- f'loader,addr=0x43000,cpu-num={i}')
-
-    self.vm.add_args('-smp', str(num_cpu))
-    self.vm.add_args('-device',
- 
'tmp105,bus=aspeed.i2c.bus.1,address=0x4d,id=tmp-test')
-    self.do_test_aarch64_aspeed_sdk_start(image_dir + 'image-bmc')
-    self.wait_for_console_pattern('nodistro.0 ast2700-default ttyS12')
-
-    self.ssh_connect('root', '0penBmc', False)
-    self.ssh_command('dmesg -c > /dev/null')
-
-    self.ssh_command_output_contains(
-    'echo lm75 0x4d > /sys/class/i2c-dev/i2c-1/device/new_device '
-    '&& dmesg -c',
-    'i2c i2c-1: new_device: Instantiated device lm75 at 0x4d');
-
-    self.ssh_command_output_contains(
-    'cat /sys/class/hwmon/hwmon20/temp1_input', '0')
-    self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test',
-    property='temperature', value=18000)
-    self.ssh_command_output_contains(
-    'cat /sys/class/hwmon/hwmon20/temp1_input', '18000')
diff --git a/tests/functional/meson.build b/tests/functional/meson.build
index 758145d1e5fa..c035eba4f9b8 100644
--- a/tests/functional/meson.build
+++ b/tests/functional/meson.build
@@ -11,6 +11,7 @@ endif
  # Timeouts for individual tests that can be slow e.g. with debugging enabled
  test_timeouts = {
+  'aarch64_aspeed' : 600,
    'aarch64_raspi4' : 480,
    'aarch64_sbsaref_alpine' : 720,
    'aarch64_sbsaref_freebsd' : 720,
@@ -47,6 +48,7 @@ tests_generic_bsduser = [
  ]
  tests_aarch64_system_thorough = [
+  'aarch64_aspeed',
    'aarch64_raspi

[PATCH] MAINTAINERS: Update my email address for COLO

2024-11-12 Thread Zhang Chen
Signed-off-by: Zhang Chen 
---
 MAINTAINERS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 095420f8b0..3f10529d9c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3559,7 +3559,7 @@ F: include/migration/failover.h
 F: docs/COLO-FT.txt
 
 COLO Proxy
-M: Zhang Chen 
+M: Zhang Chen 
 M: Li Zhijian 
 S: Supported
 F: docs/colo-proxy.txt
-- 
2.43.0




Re: [PATCH v2 4/5] target/riscv: Check memory access to meet svuket rule

2024-11-12 Thread Fea Wang
Thank you for refining it.
I fixed some parts and will put them in the V3 patches.

Sincerely,
Fea

On Tue, Nov 12, 2024 at 2:32 AM Daniel Henrique Barboza <
dbarb...@ventanamicro.com> wrote:

>
>
> On 11/8/24 5:52 AM, Fea.Wang wrote:
> > Follow the Svukte spec, do the memory access address checking
> >
> > 1. Include instruction fetches or explicit memory accesses
> > 2. System run in effective privilege U or VU
> > 3. Check senvcfg[UKTE] being set, or hstatus[HUKTE] being set if
> > instruction is HLV, HLVX, HSV and excute from U mode to VU mode
>
> typo: s/excute/execute
>
> > 4. Depend on Sv39 and check virtual addresses bit[SXLEN-1]
> > 5. Raises a page-fault exception corresponding to the original access
> > type.
> >
> > Ref: https://github.com/riscv/riscv-isa-manual/pull/1564/files
> >
> > Signed-off-by: Frank Chang 
> > Signed-off-by: Fea.Wang 
> > Reviewed-by: Jim Shu 
> > ---
> >   target/riscv/cpu_helper.c | 57 +++
> >   1 file changed, 57 insertions(+)
> >
> > diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> > index 0a3ead69ea..725c049f7a 100644
> > --- a/target/riscv/cpu_helper.c
> > +++ b/target/riscv/cpu_helper.c
> > @@ -857,6 +857,57 @@ static int get_physical_address_pmp(CPURISCVState
> *env, int *prot, hwaddr addr,
> >   return TRANSLATE_SUCCESS;
> >   }
> >
> > +/*
> > + * Return 'true' means no need to do svukte check, or need to do svukte
> and the
> > + * address is valid. Return 'false' means need to do svukte check but
> address
> > + * is invalid.
> > + */
>
> I think this function is doing a bit too much while not doing everything
> we need.
> For instance, we're still doing some checks in get_physical_address()
> prior to
> calling it.
>
> I would put all the svukte logic in two functions:
>
> - 'do_svukte_check' would check all dependencies for the svukte check per
> se
> - 'check_svukte_addr' would do the addr check if we need to do a svukte
> check
>
>
> An example:
>
>
>
> /* Returns 'true' if a svukte address check is needed */
> static bool do_svukte_check(CPURISCVState *env, bool first_stage,
>  int mode, bool virt)
> {
>  bool ukte;
>
>  /* Svukte extension depends on Sv39. */
>  if (!(env_archcpu(env)->cfg.ext_svukte &&
>first_stage &&
>VM_1_10_SV39 == get_field(env->satp, SATP64_MODE))) {
>  return false;
>  }
>
>  /*
>   * Check hstatus.HUKTE if the effective mode is switched to VU-mode by
>   * executing HLV/HLVX/HSV in U-mode.
>   * For other cases, check senvcfg.UKTE.
>   */
>  if (env->priv == PRV_U && !env->virt_enabled && virt) {
>  ukte = !!(env->hstatus & HSTATUS_HUKTE);
>  } else {
>  ukte = !!(env->senvcfg & SENVCFG_UKTE);
>  }
>
>  if (!ukte) {
>  return false;
>  }
>
>  /*
>   * Svukte extension is qualified only in U or VU-mode.
>   *
>   * Effective mode can be switched to U or VU-mode by:
>   *   - M-mode + mstatus.MPRV=1 + mstatus.MPP=U-mode.
>   *   - Execute HLV/HLVX/HSV from HS-mode + hstatus.SPVP=0.
>   *   - U-mode.
>   *   - VU-mode.
>   *   - Execute HLV/HLVX/HSV from U-mode + hstatus.HU=1.
>   */
>  if (mode != PRV_U) {
>  return false;
>  }
>
>  return true;
> }
>
>
> static bool check_svukte_addr(CPURISCVState *env, vaddr addr)
> {
>  uint32_t sxl = riscv_cpu_sxl(env);
>  sxl = (sxl == 0) ? MXL_RV32 : sxl;
>  uint32_t sxlen = 32 * sxl;
>  uint64_t high_bit = addr & (1UL << (sxlen - 1));
>
>  return !high_bit;
> }
>
>
> And then on get_physical_addr():
>
>
>  if (do_svukte_check(env, first_stage, mode, virt) &&
>  !check_svukte_addr(env, addr)) {
>  return TRANSLATE_FAIL;
>  }
>
>
> Feel free to use these functions (compiled tested only) if you want.
> Thanks,
>
> Daniel
>
>
> > +static bool check_svukte_valid(CPURISCVState *env, vaddr addr,
> > +   int mode, bool virt)
> > +{
> > +/*
> > + * Check hstatus.HUKTE if the effective mode is switched to VU-mode
> by
> > + * executing HLV/HLVX/HSV in U-mode.
> > + * For other cases, check senvcfg.UKTE.
> > + */
> > +bool ukte;
> > +if (env->priv == PRV_U && !env->virt_enabled && virt) {
> > +ukte = !!(env->hstatus & HSTATUS_HUKTE);
> > +} else {
> > +ukte = !!(env->senvcfg & SENVCFG_UKTE);
> > +}
> > +
> > +if (VM_1_10_SV39 != get_field(env->satp, SATP64_MODE))  {
> > +/* Svukte extension depends on Sv39. */
> > +return true;
> > +}> +
> > +/*
> > + * Svukte extension is qualified only in U or VU-mode.
> > + *
> > + * Effective mode can be switched to U or VU-mode by:
> > + *   - M-mode + mstatus.MPRV=1 + mstatus.MPP=U-mode.
> > + *   - Execute HLV/HLVX/HSV from HS-mode + hstatus.SPVP=0.
> > + *   - U-mode.
> > + *   - VU-mode.
> > + *   - Execute HLV/HLVX

[PATCH v3 2/5] target/riscv: Support senvcfg[UKTE] bit when svukte extension is enabled

2024-11-12 Thread Fea.Wang
Svukte extension add UKTE bit, bit[8] in senvcfg CSR. The bit will be
supported when the svukte extension is enabled.

When senvcfg[UKTE] bit is set, the memory access from U-mode should do
the svukte check only except HLV/HLVX/HSV H-mode instructions which
depend on hstatus[HUKTE].

Signed-off-by: Fea.Wang 
Reviewed-by: Frank Chang 
Reviewed-by: Jim Shu 
Reviewed-by: Daniel Henrique Barboza 
---
 target/riscv/cpu_bits.h | 1 +
 target/riscv/csr.c  | 4 
 2 files changed, 5 insertions(+)

diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 385a2c67c2..4b9f899217 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -785,6 +785,7 @@ typedef enum RISCVException {
 #define SENVCFG_CBIE   MENVCFG_CBIE
 #define SENVCFG_CBCFE  MENVCFG_CBCFE
 #define SENVCFG_CBZE   MENVCFG_CBZE
+#define SENVCFG_UKTE   BIT(8)
 
 #define HENVCFG_FIOM   MENVCFG_FIOM
 #define HENVCFG_LPEMENVCFG_LPE
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 9846770820..1936a6f32a 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -2453,6 +2453,10 @@ static RISCVException write_senvcfg(CPURISCVState *env, 
int csrno,
 mask |= SENVCFG_SSE;
 }
 
+if (env_archcpu(env)->cfg.ext_svukte) {
+mask |= SENVCFG_UKTE;
+}
+
 env->senvcfg = (env->senvcfg & ~mask) | (val & mask);
 return RISCV_EXCP_NONE;
 }
-- 
2.34.1




[PATCH v3 0/5] Introduce svukte ISA extension

2024-11-12 Thread Fea.Wang
The Svukte ISA extension has been approved for fast-track development.
https://lf-riscv.atlassian.net/browse/RVS-2977 
And there are Linux patches for the Svukte that are under review.
https://lore.kernel.org/kvm/20240920-dev-maxh-svukte-rebase-v1-0-7864a88a6...@sifive.com/T/#mf70fcb22cd2987ad268c0efee9b8583197d3cb4f

Svukte provides a means to make user-mode accesses to supervisor memory
raise page faults in constant time, mitigating attacks that attempt to
discover the supervisor software's address-space layout.

Refer to the draft of svukte extension from:
https://github.com/riscv/riscv-isa-manual/pull/1564

base-commit: 27652f9ca9d831c67dd447346c6ee953669255f0

[v3]
* Fix some typos
* Refine code by separating a function into two dedicated functions.
* Follow the riscv,isa order

[v2]
* Refactor the code

[v1]
* Add svukte extension

Fea.Wang (5):
  target/riscv: Add svukte extension capability variable
  target/riscv: Support senvcfg[UKTE] bit when svukte extension is
enabled
  target/riscv: Support hstatus[HUKTE] bit when svukte extension is
enabled
  target/riscv: Check memory access to meet svukte rule
  target/riscv: Expose svukte ISA extension

 target/riscv/cpu.c|  2 ++
 target/riscv/cpu_bits.h   |  2 ++
 target/riscv/cpu_cfg.h|  1 +
 target/riscv/cpu_helper.c | 61 +++
 target/riscv/csr.c|  7 +
 5 files changed, 73 insertions(+)

-- 
2.34.1




[PATCH v3 5/5] target/riscv: Expose svukte ISA extension

2024-11-12 Thread Fea.Wang
Add "svukte" in the ISA string when svukte extension is enabled.

Signed-off-by: Fea.Wang 
Reviewed-by: Frank Chang 
Reviewed-by: Jim Shu 
---
 target/riscv/cpu.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index f219f0c3b5..6d3e9d563d 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -199,6 +199,7 @@ const RISCVIsaExtData isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(svinval, PRIV_VERSION_1_12_0, ext_svinval),
 ISA_EXT_DATA_ENTRY(svnapot, PRIV_VERSION_1_12_0, ext_svnapot),
 ISA_EXT_DATA_ENTRY(svpbmt, PRIV_VERSION_1_12_0, ext_svpbmt),
+ISA_EXT_DATA_ENTRY(svukte, PRIV_VERSION_1_13_0, ext_svukte),
 ISA_EXT_DATA_ENTRY(svvptc, PRIV_VERSION_1_13_0, ext_svvptc),
 ISA_EXT_DATA_ENTRY(xtheadba, PRIV_VERSION_1_11_0, ext_xtheadba),
 ISA_EXT_DATA_ENTRY(xtheadbb, PRIV_VERSION_1_11_0, ext_xtheadbb),
@@ -1595,6 +1596,7 @@ const RISCVCPUMultiExtConfig riscv_cpu_vendor_exts[] = {
 
 /* These are experimental so mark with 'x-' */
 const RISCVCPUMultiExtConfig riscv_cpu_experimental_exts[] = {
+MULTI_EXT_CFG_BOOL("x-svukte", ext_svukte, false),
 DEFINE_PROP_END_OF_LIST(),
 };
 
-- 
2.34.1




[PATCH v3 3/5] target/riscv: Support hstatus[HUKTE] bit when svukte extension is enabled

2024-11-12 Thread Fea.Wang
Svukte extension add HUKTE bit, bit[24] in hstatus CSR. The written
value will be masked when the svukte extension is not enabled.

When hstatus[HUKTE] bit is set, HLV/HLVX/HSV work in the U-mode should
do svukte check.

Signed-off-by: Fea.Wang 
Reviewed-by: Frank Chang 
Reviewed-by: Jim Shu 
Reviewed-by: Daniel Henrique Barboza 
---
 target/riscv/cpu_bits.h | 1 +
 target/riscv/csr.c  | 3 +++
 2 files changed, 4 insertions(+)

diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 4b9f899217..fe4e34c64a 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -604,6 +604,7 @@ typedef enum {
 #define HSTATUS_VTVM 0x0010
 #define HSTATUS_VTW  0x0020
 #define HSTATUS_VTSR 0x0040
+#define HSTATUS_HUKTE0x0100
 #define HSTATUS_VSXL 0x3
 
 #define HSTATUS32_WPRI   0xFF8FF87E
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 1936a6f32a..b6fa8ae53f 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -3540,6 +3540,9 @@ static RISCVException read_hstatus(CPURISCVState *env, 
int csrno,
 static RISCVException write_hstatus(CPURISCVState *env, int csrno,
 target_ulong val)
 {
+if (!env_archcpu(env)->cfg.ext_svukte) {
+val = val & (~HSTATUS_HUKTE);
+}
 env->hstatus = val;
 if (riscv_cpu_mxl(env) != MXL_RV32 && get_field(val, HSTATUS_VSXL) != 2) {
 qemu_log_mask(LOG_UNIMP,
-- 
2.34.1




[PATCH v3 1/5] target/riscv: Add svukte extension capability variable

2024-11-12 Thread Fea.Wang
Refer to the draft of svukte extension from:
https://github.com/riscv/riscv-isa-manual/pull/1564

Svukte provides a means to make user-mode accesses to supervisor memory
raise page faults in constant time, mitigating attacks that attempt to
discover the supervisor software's address-space layout.

Signed-off-by: Fea.Wang 
Reviewed-by: Frank Chang 
Reviewed-by: Jim Shu 
Reviewed-by: Daniel Henrique Barboza 
---
 target/riscv/cpu_cfg.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
index 59d6fc445d..d8771ca641 100644
--- a/target/riscv/cpu_cfg.h
+++ b/target/riscv/cpu_cfg.h
@@ -84,6 +84,7 @@ struct RISCVCPUConfig {
 bool ext_svnapot;
 bool ext_svpbmt;
 bool ext_svvptc;
+bool ext_svukte;
 bool ext_zdinx;
 bool ext_zaamo;
 bool ext_zacas;
-- 
2.34.1




[PATCH v3 4/5] target/riscv: Check memory access to meet svukte rule

2024-11-12 Thread Fea.Wang
Follow the Svukte spec, do the memory access address checking

1. Include instruction fetches or explicit memory accesses
2. System run in effective privilege U or VU
3. Check senvcfg[UKTE] being set, or hstatus[HUKTE] being set if
instruction is HLV, HLVX, HSV and execute from U mode to VU mode
4. Depend on Sv39 and check virtual addresses bit[SXLEN-1]
5. Raises a page-fault exception corresponding to the original access
type.

Ref: https://github.com/riscv/riscv-isa-manual/pull/1564/files

Signed-off-by: Frank Chang 
Signed-off-by: Fea.Wang 
Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Jim Shu 
---
 target/riscv/cpu_helper.c | 61 +++
 1 file changed, 61 insertions(+)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 0a3ead69ea..5b29344c4f 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -857,6 +857,61 @@ static int get_physical_address_pmp(CPURISCVState *env, 
int *prot, hwaddr addr,
 return TRANSLATE_SUCCESS;
 }
 
+/* Returns 'true' if a svukte address check is needed */
+static bool do_svukte_check(CPURISCVState *env, bool first_stage,
+ int mode, bool virt)
+{
+bool ukte;
+
+/* Svukte extension depends on Sv39. */
+if (!(env_archcpu(env)->cfg.ext_svukte ||
+!first_stage ||
+VM_1_10_SV39 != get_field(env->satp, SATP64_MODE))) {
+return false;
+}
+
+/*
+ * Check hstatus.HUKTE if the effective mode is switched to VU-mode by
+ * executing HLV/HLVX/HSV in U-mode.
+ * For other cases, check senvcfg.UKTE.
+ */
+if (env->priv == PRV_U && !env->virt_enabled && virt) {
+ukte = !!(env->hstatus & HSTATUS_HUKTE);
+} else {
+ukte = !!(env->senvcfg & SENVCFG_UKTE);
+}
+
+if (!ukte) {
+return false;
+}
+
+/*
+ * Svukte extension is qualified only in U or VU-mode.
+ *
+ * Effective mode can be switched to U or VU-mode by:
+ *   - M-mode + mstatus.MPRV=1 + mstatus.MPP=U-mode.
+ *   - Execute HLV/HLVX/HSV from HS-mode + hstatus.SPVP=0.
+ *   - U-mode.
+ *   - VU-mode.
+ *   - Execute HLV/HLVX/HSV from U-mode + hstatus.HU=1.
+ */
+if (mode != PRV_U) {
+return false;
+}
+
+return true;
+}
+
+static bool check_svukte_addr(CPURISCVState *env, vaddr addr)
+{
+uint32_t sxl = riscv_cpu_sxl(env);
+sxl = (sxl == 0) ? MXL_RV32 : sxl;
+uint32_t sxlen = 32 * sxl;
+uint64_t high_bit = addr & (1UL << (sxlen - 1));
+
+return !high_bit;
+}
+
 /*
  * get_physical_address - get the physical address for this virtual address
  *
@@ -894,6 +949,7 @@ static int get_physical_address(CPURISCVState *env, hwaddr 
*physical,
 MemTxResult res;
 MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
 int mode = mmuidx_priv(mmu_idx);
+bool virt = mmuidx_2stage(mmu_idx);
 bool use_background = false;
 hwaddr ppn;
 int napot_bits = 0;
@@ -901,6 +957,11 @@ static int get_physical_address(CPURISCVState *env, hwaddr 
*physical,
 bool is_sstack_idx = ((mmu_idx & MMU_IDX_SS_WRITE) == MMU_IDX_SS_WRITE);
 bool sstack_page = false;
 
+if (do_svukte_check(env, first_stage, mode, virt) &&
+!check_svukte_addr(env, addr)) {
+return TRANSLATE_FAIL;
+}
+
 /*
  * Check if we should use the background registers for the two
  * stage translation. We don't need to check if we actually need
-- 
2.34.1




Re: [PATCH] tests/qtest: fix non portable env varibles access

2024-11-12 Thread Дмитрий Фролов

Hi, Prasad!

It looks like this is a clang optimization issue.
I`ve made a simple experiment:

When environ is mentioned somewhere in the source code -
everything is fine - test passed.
The value of envp is equal to environ and is always
0x51400040 (reproducible).

When environ is absent (not mentioned in the source code)
The value of envp is also 0x51400040 (reproducible),
but the behavior may be each time different.
Mostly test fails with error, with or without ASAN report.

Thus, it seems, that when environ variable is not used -
it`s being optimized, the corresponding memory is being
freed, but envp pointer still points to the freed memory.

Thanks a lot!

With best regards,
Dmitry.

On 12.11.2024 10:11, Prasad Pandit wrote:

On Tue, 12 Nov 2024 at 12:08, Dmitry Frolov  wrote:

"int main(int argc, char **argv, char** envp)" is non-standart

standart -> standard


Microsoft`s extention of the C language and it`s not portable.

* But it looks widely supported.


In my particular case (Debian 13, clang-16) this raises wild-pointer
dereference with ASAN message "heap-use-after-free".

v2: changed confusing commit header

* We need to include a pointer to the earlier version/discussion:
   v1: -> 
https://lore.kernel.org/qemu-devel/23ef463e-744d-472c-bd25-30f68a97a...@swemel.ru/T/#t

Thank you.
---
   - Prasad






Re: [PATCH v2] tests/tcg: Stop using exit() in the gdbstub testcases

2024-11-12 Thread Alex Bennée
Ilya Leoshkevich  writes:

> GDB 15 does not like exit() anymore:
>
> (gdb) python exit(0)
> Python Exception : 0
> Error occurred in Python: 0
>
> Use the GDB's own exit command, like it's already done in a couple
> places, everywhere. This is the same fix as commit 93a3048dcf45
> ("tests: Gently exit from GDB when tests complete"), but applied to
> more places.

Queued to maintainer/for-9.2, thanks.

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



Re: [PATCH v3 0/3] plugins: generate list of symbols automatically

2024-11-12 Thread Alex Bennée
Pierrick Bouvier  writes:

> Now that meson build for plugins was merged, we can cleanup another part with
> the symbols file.
> It has to be kept in sync between the header (qemu-plugin.h) and the symbols
> file. This has proved to be error prone and tedious.
>
> We solve this by generating this list from header directly using a python
> script. Dependencies are triggered correctly, and the file is regenerated if 
> the
> header is modified, as expected.
>
> Pierrick Bouvier (3):
>   plugins: add missing export for qemu_plugin_num_vcpus
>   plugins: detect qemu plugin API symbols from header
>   plugins: eradicate qemu-plugins.symbols static file
>
>  MAINTAINERS|  1 +
>  include/qemu/qemu-plugin.h |  1 +
>  plugins/meson.build| 12 +--

this failed to apply cleanly. 

>  plugins/qemu-plugins.symbols   | 59 --
>  scripts/qemu-plugin-symbols.py | 45 ++
>  5 files changed, 56 insertions(+), 62 deletions(-)
>  delete mode 100644 plugins/qemu-plugins.symbols
>  create mode 100755 scripts/qemu-plugin-symbols.py

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



[PATCH v4 0/3] plugins: generate list of symbols automatically

2024-11-12 Thread Pierrick Bouvier
Now that meson build for plugins was merged, we can cleanup another part with
the symbols file.
It has to be kept in sync between the header (qemu-plugin.h) and the symbols
file. This has proved to be error prone and tedious.

We solve this by generating this list from header directly using a python
script. Dependencies are triggered correctly, and the file is regenerated if the
header is modified, as expected.

v4:
fix second patch to apply cleanly on master (was applied from a previous series
to enable windows clang build before).

Pierrick Bouvier (3):
  plugins: add missing export for qemu_plugin_num_vcpus
  plugins: detect qemu plugin API symbols from header
  plugins: eradicate qemu-plugins.symbols static file

 MAINTAINERS|  1 +
 include/qemu/qemu-plugin.h |  1 +
 plugins/meson.build| 12 +--
 plugins/qemu-plugins.symbols   | 59 --
 scripts/qemu-plugin-symbols.py | 45 ++
 5 files changed, 56 insertions(+), 62 deletions(-)
 delete mode 100644 plugins/qemu-plugins.symbols
 create mode 100755 scripts/qemu-plugin-symbols.py

-- 
2.39.5




Re: [PATCH v3 0/3] plugins: generate list of symbols automatically

2024-11-12 Thread Pierrick Bouvier

On 11/12/24 13:08, Alex Bennée wrote:

Pierrick Bouvier  writes:


Now that meson build for plugins was merged, we can cleanup another part with
the symbols file.
It has to be kept in sync between the header (qemu-plugin.h) and the symbols
file. This has proved to be error prone and tedious.

We solve this by generating this list from header directly using a python
script. Dependencies are triggered correctly, and the file is regenerated if the
header is modified, as expected.

Pierrick Bouvier (3):
   plugins: add missing export for qemu_plugin_num_vcpus
   plugins: detect qemu plugin API symbols from header
   plugins: eradicate qemu-plugins.symbols static file

  MAINTAINERS|  1 +
  include/qemu/qemu-plugin.h |  1 +
  plugins/meson.build| 12 +--


this failed to apply cleanly.


Sorry about that. The commit is correct but the patch context is 
incorrect. Fixed in v4.





  plugins/qemu-plugins.symbols   | 59 --
  scripts/qemu-plugin-symbols.py | 45 ++
  5 files changed, 56 insertions(+), 62 deletions(-)
  delete mode 100644 plugins/qemu-plugins.symbols
  create mode 100755 scripts/qemu-plugin-symbols.py






[PATCH v4 3/3] plugins: eradicate qemu-plugins.symbols static file

2024-11-12 Thread Pierrick Bouvier
Signed-off-by: Pierrick Bouvier 
---
 plugins/qemu-plugins.symbols | 59 
 1 file changed, 59 deletions(-)
 delete mode 100644 plugins/qemu-plugins.symbols

diff --git a/plugins/qemu-plugins.symbols b/plugins/qemu-plugins.symbols
deleted file mode 100644
index 032661f9ea7..000
--- a/plugins/qemu-plugins.symbols
+++ /dev/null
@@ -1,59 +0,0 @@
-{
-  qemu_plugin_bool_parse;
-  qemu_plugin_end_code;
-  qemu_plugin_entry_code;
-  qemu_plugin_get_hwaddr;
-  qemu_plugin_get_registers;
-  qemu_plugin_hwaddr_device_name;
-  qemu_plugin_hwaddr_is_io;
-  qemu_plugin_hwaddr_phys_addr;
-  qemu_plugin_insn_data;
-  qemu_plugin_insn_disas;
-  qemu_plugin_insn_haddr;
-  qemu_plugin_insn_size;
-  qemu_plugin_insn_symbol;
-  qemu_plugin_insn_vaddr;
-  qemu_plugin_mem_get_value;
-  qemu_plugin_mem_is_big_endian;
-  qemu_plugin_mem_is_sign_extended;
-  qemu_plugin_mem_is_store;
-  qemu_plugin_mem_size_shift;
-  qemu_plugin_num_vcpus;
-  qemu_plugin_outs;
-  qemu_plugin_path_to_binary;
-  qemu_plugin_read_memory_vaddr;
-  qemu_plugin_read_register;
-  qemu_plugin_register_atexit_cb;
-  qemu_plugin_register_flush_cb;
-  qemu_plugin_register_vcpu_exit_cb;
-  qemu_plugin_register_vcpu_idle_cb;
-  qemu_plugin_register_vcpu_init_cb;
-  qemu_plugin_register_vcpu_insn_exec_cb;
-  qemu_plugin_register_vcpu_insn_exec_cond_cb;
-  qemu_plugin_register_vcpu_insn_exec_inline_per_vcpu;
-  qemu_plugin_register_vcpu_mem_cb;
-  qemu_plugin_register_vcpu_mem_inline_per_vcpu;
-  qemu_plugin_register_vcpu_resume_cb;
-  qemu_plugin_register_vcpu_syscall_cb;
-  qemu_plugin_register_vcpu_syscall_ret_cb;
-  qemu_plugin_register_vcpu_tb_exec_cb;
-  qemu_plugin_register_vcpu_tb_exec_cond_cb;
-  qemu_plugin_register_vcpu_tb_exec_inline_per_vcpu;
-  qemu_plugin_register_vcpu_tb_trans_cb;
-  qemu_plugin_request_time_control;
-  qemu_plugin_reset;
-  qemu_plugin_scoreboard_free;
-  qemu_plugin_scoreboard_find;
-  qemu_plugin_scoreboard_new;
-  qemu_plugin_start_code;
-  qemu_plugin_tb_get_insn;
-  qemu_plugin_tb_n_insns;
-  qemu_plugin_tb_vaddr;
-  qemu_plugin_u64_add;
-  qemu_plugin_u64_get;
-  qemu_plugin_u64_set;
-  qemu_plugin_u64_sum;
-  qemu_plugin_uninstall;
-  qemu_plugin_update_ns;
-  qemu_plugin_vcpu_for_each;
-};
-- 
2.39.5




[PATCH v4 2/3] plugins: detect qemu plugin API symbols from header

2024-11-12 Thread Pierrick Bouvier
Instead of using a static file (error prone and hard to keep in sync),
we generate it using a script.

Note: if a symbol is not exported, we'll now notice it when linking for
Windows/MacOS platforms.

Signed-off-by: Pierrick Bouvier 
---
 MAINTAINERS|  1 +
 plugins/meson.build| 12 ++---
 scripts/qemu-plugin-symbols.py | 45 ++
 3 files changed, 55 insertions(+), 3 deletions(-)
 create mode 100755 scripts/qemu-plugin-symbols.py

diff --git a/MAINTAINERS b/MAINTAINERS
index 095420f8b0e..7d6d2bd59e8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3747,6 +3747,7 @@ F: plugins/
 F: tests/tcg/plugins/
 F: tests/functional/test_aarch64_tcg_plugins.py
 F: contrib/plugins/
+F: scripts/qemu-plugin-symbols.py
 
 AArch64 TCG target
 M: Richard Henderson 
diff --git a/plugins/meson.build b/plugins/meson.build
index 1cc039d29b2..98542e926f8 100644
--- a/plugins/meson.build
+++ b/plugins/meson.build
@@ -2,17 +2,23 @@ if not get_option('plugins')
   subdir_done()
 endif
 
+qemu_plugin_symbols = configure_file(
+  input: files('../include/qemu/qemu-plugin.h'),
+  output: 'qemu-plugin.symbols',
+  capture: true,
+  command: [files('../scripts/qemu-plugin-symbols.py'), '@INPUT@'])
+
 # Modules need more symbols than just those in plugins/qemu-plugins.symbols
 if not enable_modules
   if host_os == 'darwin'
 configure_file(
-  input: files('qemu-plugins.symbols'),
+  input: qemu_plugin_symbols,
   output: 'qemu-plugins-ld64.symbols',
   capture: true,
   command: ['sed', '-ne', 's/^[[:space:]]*\\(qemu_.*\\);/_\\1/p', 
'@INPUT@'])
 emulator_link_args += 
['-Wl,-exported_symbols_list,plugins/qemu-plugins-ld64.symbols']
   else
-emulator_link_args += ['-Xlinker', '--dynamic-list=' + 
(meson.project_source_root() / 'plugins/qemu-plugins.symbols')]
+emulator_link_args += ['-Xlinker', '--dynamic-list=' + 
qemu_plugin_symbols.full_path()]
   endif
 endif
 
@@ -23,7 +29,7 @@ if host_os == 'windows'
   # First, create a .def file listing all the symbols a plugin should expect 
to have
   # available in qemu
   win32_plugin_def = configure_file(
-input: files('qemu-plugins.symbols'),
+input: qemu_plugin_symbols,
 output: 'qemu_plugin_api.def',
 capture: true,
 command: ['sed', '-e', '0,/^/s//EXPORTS/; s/[{};]//g', '@INPUT@'])
diff --git a/scripts/qemu-plugin-symbols.py b/scripts/qemu-plugin-symbols.py
new file mode 100755
index 000..e285ebb8f9e
--- /dev/null
+++ b/scripts/qemu-plugin-symbols.py
@@ -0,0 +1,45 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#
+# Extract QEMU Plugin API symbols from a header file
+#
+# Copyright 2024 Linaro Ltd
+#
+# Author: Pierrick Bouvier 
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or later.
+# See the COPYING file in the top-level directory.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+import argparse
+import re
+
+def extract_symbols(plugin_header):
+with open(plugin_header) as file:
+content = file.read()
+# Remove QEMU_PLUGIN_API macro definition.
+content = content.replace('#define QEMU_PLUGIN_API', '')
+expected = content.count('QEMU_PLUGIN_API')
+# Find last word between QEMU_PLUGIN_API and (, matching on several lines.
+# We use *? non-greedy quantifier.
+syms = re.findall(r'QEMU_PLUGIN_API.*?(\w+)\s*\(', content, re.DOTALL)
+syms.sort()
+# Ensure we found as many symbols as API markers.
+assert len(syms) == expected
+return syms
+
+def main() -> None:
+parser = argparse.ArgumentParser(description='Extract QEMU plugin symbols')
+parser.add_argument('plugin_header', help='Path to QEMU plugin header.')
+args = parser.parse_args()
+
+syms = extract_symbols(args.plugin_header)
+
+print('{')
+for s in syms:
+print("  {};".format(s))
+print('};')
+
+if __name__ == '__main__':
+main()
-- 
2.39.5




[PATCH v4 1/3] plugins: add missing export for qemu_plugin_num_vcpus

2024-11-12 Thread Pierrick Bouvier
Fixes: 4a448b148ca ("plugins: add qemu_plugin_num_vcpus function")
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Pierrick Bouvier 
---
 include/qemu/qemu-plugin.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/qemu/qemu-plugin.h b/include/qemu/qemu-plugin.h
index 622c9a02327..0fba36ae028 100644
--- a/include/qemu/qemu-plugin.h
+++ b/include/qemu/qemu-plugin.h
@@ -803,6 +803,7 @@ void qemu_plugin_register_atexit_cb(qemu_plugin_id_t id,
 qemu_plugin_udata_cb_t cb, void *userdata);
 
 /* returns how many vcpus were started at this point */
+QEMU_PLUGIN_API
 int qemu_plugin_num_vcpus(void);
 
 /**
-- 
2.39.5




Re: [PATCH] GTM19-448: Fix script to work without realpath

2024-11-12 Thread Alex Bennée
Aleksandar Rakic  writes:

> The archive-source.sh script depends on realpath command, which was
> introduced in coreutils-8.15. CentOS-6 build systems use coreutils-4.7,
> which does not have realpath, so fix the script to use 'readlink -e' to
> perform the same action.

Isn't CentOS-6 outside of our supported build platform range? We aim for
latest stable release + 5 years. CentOS got to 8 before being replaced
with CentOS Stream.

>
> Cherry-picked 5d1d5766f0219ce2bec4e41c2467317df920ec0a
> and 8003ab4032772a0e5b46e5983fe06268d3469289
> from https://github.com/MIPS/gnutools-qemu
>
> An instance of a pipeline of QEMU CI jobs run with input
> variable QEMU_CI=1 for this patch is available here:
> https://gitlab.com/rakicaleksandar1999/qemu/-/pipelines/1538854588
> and for the master branch is available here:
> https://gitlab.com/rakicaleksandar1999/qemu/-/pipelines/1533465414
>
> Signed-off-by: Faraz Shahbazker 
> Signed-off-by: Chao-ying Fu 
> Signed-off-by: Aleksandar Rakic 
> ---
>  scripts/archive-source.sh | 8 +++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/scripts/archive-source.sh b/scripts/archive-source.sh
> index 30677c3ec9..bfaa0c1483 100755
> --- a/scripts/archive-source.sh
> +++ b/scripts/archive-source.sh
> @@ -18,7 +18,13 @@ if test $# -lt 1; then
>  error "Usage: $0 "
>  fi
>  
> -tar_file=$(realpath "$1")
> +which realpath
> +if [ $? -eq 0 ]; then
> +tar_file=$(realpath -s "$1")
> +else
> +d=$(dirname "$1")
> +tar_file=$(readlink -e "$d")"/"$(basename "$1")
> +fi
>  sub_tdir=$(mktemp -d "${tar_file%.tar}.sub.")
>  sub_file="${sub_tdir}/submodule.tar"

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



[PATCH 06/10] usb/uhci: Add aspeed specific read and write functions

2024-11-12 Thread Guenter Roeck
Aspeed uses non-standard UHCI register addresses. On top of that,
registers are 32 bit wide instead of 16 bit.

Map Aspeed UHCI addresses to standard UHCI addresses and where needed
combine/split 32 bit accesses to solve the problem.

In addition to that, Aspeed SoCs starting with AST2600 support and use EHCI
companion mode on the second EHCI interface. Support this by moving the
property initialization to the Aspeed class initialization code. Since the
USB ports are part of the SoC and always present, set user_creatable to
false for the Aspeed UHCI controller.

Signed-off-by: Guenter Roeck 
---
Changes since RFC:
- Rebased to v9.1.0-1673-g134b443512
- Added support for EHCI companion mode

 hw/usb/hcd-uhci-sysbus.c | 104 ++-
 hw/usb/hcd-uhci-sysbus.h |  11 +
 2 files changed, 114 insertions(+), 1 deletion(-)

diff --git a/hw/usb/hcd-uhci-sysbus.c b/hw/usb/hcd-uhci-sysbus.c
index 3a6c56c3df..628b6601a1 100644
--- a/hw/usb/hcd-uhci-sysbus.c
+++ b/hw/usb/hcd-uhci-sysbus.c
@@ -20,7 +20,9 @@
 
 #include "qemu/osdep.h"
 #include "hw/irq.h"
+#include "hw/usb/uhci-regs.h"
 #include "qapi/error.h"
+#include "qemu/log.h"
 #include "qemu/module.h"
 #include "qemu/timer.h"
 #include "hw/usb.h"
@@ -84,10 +86,104 @@ static void uhci_sysbus_class_init(ObjectClass *klass, 
void *data)
 dc->realize = uhci_sysbus_realize;
 set_bit(DEVICE_CATEGORY_USB, dc->categories);
 dc->desc = "UHCI USB Controller";
-device_class_set_props(dc, uhci_sysbus_properties);
 device_class_set_legacy_reset(dc, uhci_sysbus_reset_sysbus);
 }
 
+static hwaddr aspeed_uhci_chip_to_uhci(hwaddr addr)
+{
+switch (addr) {
+case 0x00:
+return UHCI_USBCMD;
+case 0x04:
+return UHCI_USBSTS;
+case 0x08:
+return UHCI_USBINTR;
+case 0x0c:
+return UHCI_USBFLBASEADD;
+case 0x80:
+return UHCI_USBFRNUM;
+case 0x84:
+return UHCI_USBSOF;
+case 0x88:
+return UHCI_USBPORTSC1;
+case 0x8c:
+return UHCI_USBPORTSC2;
+case 0x90:
+return UHCI_USBPORTSC3;
+case 0x94:
+return UHCI_USBPORTSC4;
+default:/* unimplemented */
+qemu_log_mask(LOG_UNIMP, "Unimplemented Aspeed UHCI register 0x%lx\n",
+  addr);
+return 0x20;
+}
+}
+
+/*
+ * Aspeed UHCI registers are 32 bit wide.
+ * Convert to 16 bit to access standard UHCI code.
+ */
+static uint64_t aspeed_uhci_port_read(void *opaque, hwaddr addr, unsigned size)
+{
+UHCIState *uhci = opaque;
+MemoryRegion *mr = &uhci->mem;
+hwaddr uaddr = aspeed_uhci_chip_to_uhci(addr);
+
+if (uaddr == UHCI_USBFLBASEADD) {
+return mr->ops->read(opaque, uaddr, 2) |
+   mr->ops->read(opaque, uaddr + 2, 2) << 16;
+}
+return mr->ops->read(opaque, uaddr, 2);
+}
+
+static void aspeed_uhci_port_write(void *opaque, hwaddr addr, uint64_t val,
+   unsigned size)
+{
+UHCIState *uhci = opaque;
+MemoryRegion *mr = &uhci->mem;
+hwaddr uaddr = aspeed_uhci_chip_to_uhci(addr);
+
+if (uaddr == UHCI_USBFLBASEADD) {
+mr->ops->write(opaque, uaddr, val & 0x, 2);
+mr->ops->write(opaque, uaddr + 2, val >> 16, 2);
+} else {
+mr->ops->write(opaque, uaddr, val, 2);
+}
+}
+
+static const MemoryRegionOps aspeed_uhci_mmio_ops = {
+.read = aspeed_uhci_port_read,
+.write = aspeed_uhci_port_write,
+.valid.min_access_size = 4,
+.valid.max_access_size = 4,
+.endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static void uhci_sysbus_aspeed_realize(DeviceState *dev, Error **errp)
+{
+UHCISysBusState *s = SYSBUS_UHCI(dev);
+ASPEEDUHCIState *f = ASPEED_UHCI(dev);
+UHCIState *uhci = &s->uhci;
+
+uhci_sysbus_realize(dev, errp);
+
+memory_region_init_io(&f->mem_aspeed, OBJECT(f), &aspeed_uhci_mmio_ops,
+  uhci, "aspeed", 0x100);
+memory_region_add_subregion(&uhci->mem, 0, &f->mem_aspeed);
+}
+
+static void uhci_sysbus_aspeed_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+dc->realize = uhci_sysbus_aspeed_realize;
+set_bit(DEVICE_CATEGORY_USB, dc->categories);
+dc->desc = "ASPEED UHCI USB Controller";
+device_class_set_legacy_reset(dc, uhci_sysbus_reset_sysbus);
+device_class_set_props(dc, uhci_sysbus_properties);
+dc->user_creatable = false;
+}
+
 static const TypeInfo uhci_sysbus_types[] = {
 {
 .name  = TYPE_SYSBUS_UHCI,
@@ -95,6 +191,12 @@ static const TypeInfo uhci_sysbus_types[] = {
 .instance_size = sizeof(UHCISysBusState),
 .class_init= uhci_sysbus_class_init,
 },
+{
+.name  = TYPE_ASPEED_UHCI,
+.parent= TYPE_SYSBUS_UHCI,
+.instance_size = sizeof(ASPEEDUHCIState),
+.class_init= uhci_sysbus_aspeed_class_init,
+},
 };
 
 DEFINE_TYPES(uhci_sysbus_types);
diff --git a/hw/usb/hcd-uhci-sysbus.h b/hw/usb/hc

[PATCH 08/10] aspeed: Add uhci support for ast2400 and ast2500

2024-11-12 Thread Guenter Roeck
Add UHCI support for ast2400 and ast2500 SoCs. With this patch,
the UHCI port is successfully enabled on the ast2500-evb machine.

Note that the EHCI controller on AST2400 and AST2500 does not support
companion mode, so the UHCI controller is instantiated as stand-alone
device and creates an additional USB bus.

Reviewed-by: Cédric Le Goater 
Signed-off-by: Guenter Roeck 
---
Changes since RFC:
- Rebased to v9.1.0-1673-g134b443512
- Added Reviewed-by: tag
- Added explanation for not using EHCI companion mode

 hw/arm/aspeed_ast2400.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/hw/arm/aspeed_ast2400.c b/hw/arm/aspeed_ast2400.c
index ecc81ecc79..8a5d21459d 100644
--- a/hw/arm/aspeed_ast2400.c
+++ b/hw/arm/aspeed_ast2400.c
@@ -31,6 +31,7 @@ static const hwaddr aspeed_soc_ast2400_memmap[] = {
 [ASPEED_DEV_FMC]= 0x1E62,
 [ASPEED_DEV_SPI1]   = 0x1E63,
 [ASPEED_DEV_EHCI1]  = 0x1E6A1000,
+[ASPEED_DEV_UHCI]   = 0x1E6B,
 [ASPEED_DEV_VIC]= 0x1E6C,
 [ASPEED_DEV_SDMC]   = 0x1E6E,
 [ASPEED_DEV_SCU]= 0x1E6E2000,
@@ -68,6 +69,7 @@ static const hwaddr aspeed_soc_ast2500_memmap[] = {
 [ASPEED_DEV_SPI2]   = 0x1E631000,
 [ASPEED_DEV_EHCI1]  = 0x1E6A1000,
 [ASPEED_DEV_EHCI2]  = 0x1E6A3000,
+[ASPEED_DEV_UHCI]   = 0x1E6B,
 [ASPEED_DEV_VIC]= 0x1E6C,
 [ASPEED_DEV_SDMC]   = 0x1E6E,
 [ASPEED_DEV_SCU]= 0x1E6E2000,
@@ -107,6 +109,7 @@ static const int aspeed_soc_ast2400_irqmap[] = {
 [ASPEED_DEV_FMC]= 19,
 [ASPEED_DEV_EHCI1]  = 5,
 [ASPEED_DEV_EHCI2]  = 13,
+[ASPEED_DEV_UHCI]   = 14,
 [ASPEED_DEV_SDMC]   = 0,
 [ASPEED_DEV_SCU]= 21,
 [ASPEED_DEV_ADC]= 31,
@@ -199,6 +202,8 @@ static void aspeed_ast2400_soc_init(Object *obj)
 TYPE_PLATFORM_EHCI);
 }
 
+object_initialize_child(obj, "uhci", &s->uhci, TYPE_ASPEED_UHCI);
+
 snprintf(typename, sizeof(typename), "aspeed.sdmc-%s", socname);
 object_initialize_child(obj, "sdmc", &s->sdmc, typename);
 object_property_add_alias(obj, "ram-size", OBJECT(&s->sdmc),
@@ -393,6 +398,15 @@ static void aspeed_ast2400_soc_realize(DeviceState *dev, 
Error **errp)
aspeed_soc_get_irq(s, ASPEED_DEV_EHCI1 + i));
 }
 
+/* UHCI */
+if (!sysbus_realize(SYS_BUS_DEVICE(&s->uhci), errp)) {
+return;
+}
+aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->uhci), 0,
+sc->memmap[ASPEED_DEV_UHCI]);
+sysbus_connect_irq(SYS_BUS_DEVICE(&s->uhci), 0,
+   aspeed_soc_get_irq(s, ASPEED_DEV_UHCI));
+
 /* SDMC - SDRAM Memory Controller */
 if (!sysbus_realize(SYS_BUS_DEVICE(&s->sdmc), errp)) {
 return;
-- 
2.45.2




[RFC 7/7] DO NOT MERGE: acpi: cpuhp: preserve always present vCPUs on unplug

2024-11-12 Thread Igor Mammedov
do not drop reference to always present vCPU and also
avoid destroying it (unparent) on unplug.

Based-on: 2d6cfbaf174 (hw/acpi: Make CPUs ACPI `presence` conditional during 
vCPU hot-unplug)
Signed-off-by: Igor Mammedov 
---
 include/hw/acpi/cpu.h   |  4 +++-
 hw/acpi/acpi-cpu-hotplug-stub.c |  3 ++-
 hw/acpi/cpu.c   | 10 --
 hw/acpi/cpu_hotplug.c   |  2 +-
 hw/acpi/generic_event_device.c  |  2 +-
 5 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/include/hw/acpi/cpu.h b/include/hw/acpi/cpu.h
index e9e9c28359..f6708cafba 100644
--- a/include/hw/acpi/cpu.h
+++ b/include/hw/acpi/cpu.h
@@ -36,6 +36,7 @@ typedef struct CPUHotplugState {
 uint32_t selector;
 uint8_t command;
 uint32_t dev_count;
+bool always_present_cpus;
 AcpiCpuStatus *devs;
 } CPUHotplugState;
 
@@ -50,7 +51,8 @@ void acpi_cpu_unplug_cb(CPUHotplugState *cpu_st,
 DeviceState *dev, Error **errp);
 
 void cpu_hotplug_hw_init(MemoryRegion *as, Object *owner,
- CPUHotplugState *state, hwaddr base_addr);
+ CPUHotplugState *state, hwaddr base_addr,
+ bool always_present_cpus);
 
 typedef struct CPUHotplugFeatures {
 bool acpi_1_compatible;
diff --git a/hw/acpi/acpi-cpu-hotplug-stub.c b/hw/acpi/acpi-cpu-hotplug-stub.c
index c6c61bb9cd..748fd04006 100644
--- a/hw/acpi/acpi-cpu-hotplug-stub.c
+++ b/hw/acpi/acpi-cpu-hotplug-stub.c
@@ -20,7 +20,8 @@ void legacy_acpi_cpu_hotplug_init(MemoryRegion *parent, 
Object *owner,
 }
 
 void cpu_hotplug_hw_init(MemoryRegion *as, Object *owner,
- CPUHotplugState *state, hwaddr base_addr)
+ CPUHotplugState *state, hwaddr base_addr,
+ bool always_present_cpus)
 {
 return;
 }
diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
index 992ae5d233..d85d4add60 100644
--- a/hw/acpi/cpu.c
+++ b/hw/acpi/cpu.c
@@ -145,7 +145,6 @@ static void cpu_hotplug_wr(void *opaque, hwaddr addr, 
uint64_t data,
 dev = DEVICE(cdev->cpu);
 hotplug_ctrl = qdev_get_hotplug_handler(dev);
 hotplug_handler_unplug(hotplug_ctrl, dev, NULL);
-object_unparent(OBJECT(dev));
 cdev->fw_remove = false;
 } else if (data & 16) {
 if (!cdev->cpu || cdev->cpu == first_cpu) {
@@ -215,7 +214,8 @@ static const MemoryRegionOps cpu_hotplug_ops = {
 };
 
 void cpu_hotplug_hw_init(MemoryRegion *as, Object *owner,
- CPUHotplugState *state, hwaddr base_addr)
+ CPUHotplugState *state, hwaddr base_addr,
+ bool always_present_cpus)
 {
 MachineState *machine = MACHINE(qdev_get_machine());
 MachineClass *mc = MACHINE_GET_CLASS(machine);
@@ -226,6 +226,7 @@ void cpu_hotplug_hw_init(MemoryRegion *as, Object *owner,
 id_list = mc->possible_cpu_arch_ids(machine);
 state->dev_count = id_list->len;
 state->devs = g_new0(typeof(*state->devs), state->dev_count);
+state->always_present_cpus = always_present_cpus;
 for (i = 0; i < id_list->len; i++) {
 state->devs[i].cpu =  CPU(id_list->cpus[i].cpu);
 state->devs[i].arch_id = id_list->cpus[i].arch_id;
@@ -286,12 +287,17 @@ void acpi_cpu_unplug_cb(CPUHotplugState *cpu_st,
 {
 AcpiCpuStatus *cdev;
 
+if (cpu_st->always_present_cpus) {
+return;
+}
+
 cdev = get_cpu_status(cpu_st, dev);
 if (!cdev) {
 return;
 }
 
 cdev->cpu = NULL;
+object_unparent(OBJECT(dev));
 }
 
 static const VMStateDescription vmstate_cpuhp_sts = {
diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c
index 83b8bc5deb..8c3618680f 100644
--- a/hw/acpi/cpu_hotplug.c
+++ b/hw/acpi/cpu_hotplug.c
@@ -115,7 +115,7 @@ void acpi_switch_to_modern_cphp(AcpiCpuHotplug *gpe_cpu,
 MemoryRegion *parent = pci_address_space_io(PCI_DEVICE(gpe_cpu->device));
 
 memory_region_del_subregion(parent, &gpe_cpu->io);
-cpu_hotplug_hw_init(parent, gpe_cpu->device, cpuhp_state, io_port);
+cpu_hotplug_hw_init(parent, gpe_cpu->device, cpuhp_state, io_port, false);
 }
 
 void build_legacy_cpu_hotplug_aml(Aml *ctx, MachineState *machine,
diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
index 663d9cb093..9099b76f80 100644
--- a/hw/acpi/generic_event_device.c
+++ b/hw/acpi/generic_event_device.c
@@ -427,7 +427,7 @@ static void acpi_ged_realize(DeviceState *dev, Error **errp)
 ACPI_CPU_HOTPLUG_REG_LEN);
 sysbus_init_mmio(sbd, &s->container_cpuhp);
 cpu_hotplug_hw_init(&s->container_cpuhp, OBJECT(dev),
-&s->cpuhp_state, 0);
+&s->cpuhp_state, 0, false);
 break;
 }
 ged_events--;
-- 
2.43.0




[PATCH 3/7 for-9.2] Revert "hw/acpi: Make CPUs ACPI `presence` conditional during vCPU hot-unplug"

2024-11-12 Thread Igor Mammedov
This reverts commit 2d6cfbaf174b91dfa9a50065f7494634afb39c23.

The patch is supposed to be part of ARM CPU hotplug series and has not value
on its own without it. The series however is still in RFC stage and outside
of scope 9.2 release.

On top of that it introduces not needed callback that pokes directly into
CPU state without any need for that. Instead properties and AML generator
option should be used to configure static platform depended vCPU presence
state.

Drop the patch so that corrected version could be posted along with
ARM CPU hotplug series and properly reviewed in relevant context.
That also helps us to keep history cleaner with new patch being
against original code vs a string of fixups on top of current mess.

Signed-off-by: Igor Mammedov 
---
 include/hw/core/cpu.h |  1 -
 hw/acpi/cpu.c | 15 +--
 2 files changed, 1 insertion(+), 15 deletions(-)

diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index e7de77dc6d..c3ca0babcb 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -158,7 +158,6 @@ struct CPUClass {
 void (*dump_state)(CPUState *cpu, FILE *, int flags);
 void (*query_cpu_fast)(CPUState *cpu, CpuInfoFast *value);
 int64_t (*get_arch_id)(CPUState *cpu);
-bool (*cpu_persistent_status)(CPUState *cpu);
 void (*set_pc)(CPUState *cpu, vaddr value);
 vaddr (*get_pc)(CPUState *cpu);
 int (*gdb_read_register)(CPUState *cpu, GByteArray *buf, int reg);
diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
index 9b03b4292e..5cb60ca8bc 100644
--- a/hw/acpi/cpu.c
+++ b/hw/acpi/cpu.c
@@ -233,17 +233,6 @@ void cpu_hotplug_hw_init(MemoryRegion *as, Object *owner,
 memory_region_add_subregion(as, base_addr, &state->ctrl_reg);
 }
 
-static bool should_remain_acpi_present(DeviceState *dev)
-{
-CPUClass *k = CPU_GET_CLASS(dev);
-/*
- * A system may contain CPUs that are always present on one die, NUMA node,
- * or socket, yet may be non-present on another simultaneously. Check from
- * architecture specific code.
- */
-return k->cpu_persistent_status && k->cpu_persistent_status(CPU(dev));
-}
-
 static AcpiCpuStatus *get_cpu_status(CPUHotplugState *cpu_st, DeviceState *dev)
 {
 CPUClass *k = CPU_GET_CLASS(dev);
@@ -300,9 +289,7 @@ void acpi_cpu_unplug_cb(CPUHotplugState *cpu_st,
 return;
 }
 
-if (!should_remain_acpi_present(dev)) {
-cdev->cpu = NULL;
-}
+cdev->cpu = NULL;
 }
 
 static const VMStateDescription vmstate_cpuhp_sts = {
-- 
2.43.0




[PATCH 1/7 for-9.2] qtest: allow ACPI DSDT Table changes

2024-11-12 Thread Igor Mammedov
From: Salil Mehta 

list changed files in tests/qtest/bios-tables-test-allowed-diff.h

Message-ID: <20241106100047.18901...@imammedo.users.ipa.redhat.com>
Signed-off-by: Salil Mehta 
Signed-off-by: Igor Mammedov 
---
 tests/qtest/bios-tables-test-allowed-diff.h | 41 +
 1 file changed, 41 insertions(+)

diff --git a/tests/qtest/bios-tables-test-allowed-diff.h 
b/tests/qtest/bios-tables-test-allowed-diff.h
index dfb8523c8b..512d40665d 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1 +1,42 @@
 /* List of comma-separated changed AML files to ignore */
+"tests/data/acpi/x86/pc/DSDT",
+"tests/data/acpi/x86/pc/DSDT.acpierst",
+"tests/data/acpi/x86/pc/DSDT.acpihmat",
+"tests/data/acpi/x86/pc/DSDT.bridge",
+"tests/data/acpi/x86/pc/DSDT.cphp",
+"tests/data/acpi/x86/pc/DSDT.dimmpxm",
+"tests/data/acpi/x86/pc/DSDT.hpbridge",
+"tests/data/acpi/x86/pc/DSDT.hpbrroot",
+"tests/data/acpi/x86/pc/DSDT.ipmikcs",
+"tests/data/acpi/x86/pc/DSDT.memhp",
+"tests/data/acpi/x86/pc/DSDT.nohpet",
+"tests/data/acpi/x86/pc/DSDT.numamem",
+"tests/data/acpi/x86/pc/DSDT.roothp",
+"tests/data/acpi/x86/q35/DSDT",
+"tests/data/acpi/x86/q35/DSDT.acpierst",
+"tests/data/acpi/x86/q35/DSDT.acpihmat",
+"tests/data/acpi/x86/q35/DSDT.acpihmat-noinitiator",
+"tests/data/acpi/x86/q35/DSDT.applesmc",
+"tests/data/acpi/x86/q35/DSDT.bridge",
+"tests/data/acpi/x86/q35/DSDT.core-count",
+"tests/data/acpi/x86/q35/DSDT.core-count2",
+"tests/data/acpi/x86/q35/DSDT.cphp",
+"tests/data/acpi/x86/q35/DSDT.cxl",
+"tests/data/acpi/x86/q35/DSDT.dimmpxm",
+"tests/data/acpi/x86/q35/DSDT.ipmibt",
+"tests/data/acpi/x86/q35/DSDT.ipmismbus",
+"tests/data/acpi/x86/q35/DSDT.ivrs",
+"tests/data/acpi/x86/q35/DSDT.memhp",
+"tests/data/acpi/x86/q35/DSDT.mmio64",
+"tests/data/acpi/x86/q35/DSDT.multi-bridge",
+"tests/data/acpi/x86/q35/DSDT.noacpihp",
+"tests/data/acpi/x86/q35/DSDT.nohpet",
+"tests/data/acpi/x86/q35/DSDT.numamem",
+"tests/data/acpi/x86/q35/DSDT.pvpanic-isa",
+"tests/data/acpi/x86/q35/DSDT.thread-count",
+"tests/data/acpi/x86/q35/DSDT.thread-count2",
+"tests/data/acpi/x86/q35/DSDT.tis.tpm12",
+"tests/data/acpi/x86/q35/DSDT.tis.tpm2",
+"tests/data/acpi/x86/q35/DSDT.type4-count",
+"tests/data/acpi/x86/q35/DSDT.viot",
+"tests/data/acpi/x86/q35/DSDT.xapic",
-- 
2.43.0




Re: [RFC PATCH 0/5] hw/arm/virt: Add support for user-creatable nested SMMUv3

2024-11-12 Thread Nicolin Chen
On Fri, Nov 08, 2024 at 12:52:37PM +, Shameer Kolothum wrote:
> Few ToDos to note,
> 1. At present default-bus-bypass-iommu=on should be set when
>arm-smmuv3-nested dev is specified. Otherwise you may get an IORT
>related boot error.  Requires fixing.
> 2. Hot adding a device is not working at the moment. Looks like pcihp irq 
> issue.
>Could be a bug in IORT id mappings.

Do we have enough bus number space for each pbx bus in IORT?

The bus range is defined by min_/max_bus in hort_host_bridges(),
where the pci_bus_range() function call might not leave enough
space in the range for hotplugs IIRC.

> ./qemu-system-aarch64 -machine virt,gic-version=3,default-bus-bypass-iommu=on 
> \
> -enable-kvm -cpu host -m 4G -smp cpus=8,maxcpus=8 \
> -object iommufd,id=iommufd0 \
> -bios QEMU_EFI.fd \
> -kernel Image \
> -device virtio-blk-device,drive=fs \
> -drive if=none,file=rootfs.qcow2,id=fs \
> -device pxb-pcie,id=pcie.1,bus_nr=8,bus=pcie.0 \
> -device pcie-root-port,id=pcie.port1,bus=pcie.1,chassis=1 \
> -device arm-smmuv3-nested,id=smmuv1,pci-bus=pcie.1 \
> -device vfio-pci,host=:7d:02.1,bus=pcie.port1,iommufd=iommufd0 \
> -device pxb-pcie,id=pcie.2,bus_nr=16,bus=pcie.0 \
> -device pcie-root-port,id=pcie.port2,bus=pcie.2,chassis=2 \
> -device arm-smmuv3-nested,id=smmuv2,pci-bus=pcie.2 \
> -device vfio-pci,host=:75:00.1,bus=pcie.port2,iommufd=iommufd0 \
> -append "rdinit=init console=ttyAMA0 root=/dev/vda2 rw 
> earlycon=pl011,0x900" \
> -device virtio-9p-pci,fsdev=p9fs2,mount_tag=p9,bus=pcie.0 \
> -fsdev local,id=p9fs2,path=p9root,security_model=mapped \
> -net none \
> -nographic
..
> With a pci topology like below,
> [root@localhost ~]# lspci -tv
> -+-[:00]-+-00.0  Red Hat, Inc. QEMU PCIe Host bridge
>  |   +-01.0  Red Hat, Inc. QEMU PCIe Expander bridge
>  |   +-02.0  Red Hat, Inc. QEMU PCIe Expander bridge
>  |   \-03.0  Virtio: Virtio filesystem
>  +-[:08]---00.0-[09]00.0  Huawei Technologies Co., Ltd. HNS Network 
> Controller (Virtual Function)
>  \-[:10]---00.0-[11]00.0  Huawei Technologies Co., Ltd. HiSilicon ZIP 
> Engine(Virtual Function)
> [root@localhost ~]#
> 
> And if you want to add another HNS VF, it should be added to the same SMMUv3
> as of the first HNS dev,
> 
> -device pcie-root-port,id=pcie.port3,bus=pcie.1,chassis=3 \
> -device vfio-pci,host=:7d:02.2,bus=pcie.port3,iommufd=iommufd0 \
..
> At present Qemu is not doing any extra validation other than the above
> failure to make sure the user configuration is correct or not. The
> assumption is libvirt will take care of this.

Nathan from NVIDIA side is working on the libvirt. And he already
did some prototype coding in libvirt that could generate required
PCI topology. I think he can take this patches for a combined test.

Thanks
Nicolin



Re: [PATCH 1/1] vfio/platform: Add mmio-base property to define start address for MMIO mapping

2024-11-12 Thread Alex Williamson
On Tue, 12 Nov 2024 22:02:12 +
Juan Pablo Ruiz  wrote:

> Some platform devices have large MMIO regions (e.g., GPU reserved memory). For
> certain devices, it's preferable to have a 1:1 address translation in the VM 
> to
> avoid modifying driver source code.

Why do we need 1:1 mappings?  Shouldn't the device tree describe where
the device lives in the VM address space and the driver should adapt
rather than use hard coded addresses?

How does a user know which devices need fixed base addresses and what
those addresses should be?

> This patch:

... should be split into at least 3 patches.

> 
> 1. Increases the VFIO platform bus size from 32MB to 130GB.

That's a very strange and specific size.

> 2. Changes the mmio_size property from 32 to 64 bits.
> 3. Adds an mmio-base property to define the starting MMIO address for mapping
>the VFIO device.
> 
> Signed-off-by: Juan Pablo Ruiz juanpablo.r...@unikie.com
> ---
>  hw/arm/virt.c   |  6 +++---
>  hw/core/platform-bus.c  | 28 ++--
>  hw/vfio/platform.c  |  1 +
>  include/hw/platform-bus.h   |  2 +-
>  include/hw/vfio/vfio-platform.h |  1 +
>  5 files changed, 32 insertions(+), 6 deletions(-)
> 
> diff --git a/hw/arm/virt.c b/hw/arm/virt.c
> index 1a381e9a2b..9fc8f4425a 100644
> --- a/hw/arm/virt.c
> +++ b/hw/arm/virt.c
> @@ -183,13 +183,13 @@ static const MemMapEntry base_memmap[] = {
>  [VIRT_SECURE_GPIO] ={ 0x090b, 0x1000 },
>  [VIRT_MMIO] =   { 0x0a00, 0x0200 },
>  /* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size 
> */
> -[VIRT_PLATFORM_BUS] =   { 0x0c00, 0x0200 },
> +[VIRT_PLATFORM_BUS] =   { 0x6000, 0x1FC000 },  // 
> 130048MB
>  [VIRT_SECURE_MEM] = { 0x0e00, 0x0100 },
>  [VIRT_PCIE_MMIO] =  { 0x1000, 0x2eff },
>  [VIRT_PCIE_PIO] =   { 0x3eff, 0x0001 },
>  [VIRT_PCIE_ECAM] =  { 0x3f00, 0x0100 },
>  /* Actual RAM size depends on initial RAM and device memory settings */
> -[VIRT_MEM] ={ GiB, LEGACY_RAMLIMIT_BYTES },
> +[VIRT_MEM] ={ 0x20, LEGACY_RAMLIMIT_BYTES },
>  };
>  
>  /*
> @@ -1625,7 +1625,7 @@ static void create_platform_bus(VirtMachineState *vms)
>  dev = qdev_new(TYPE_PLATFORM_BUS_DEVICE);
>  dev->id = g_strdup(TYPE_PLATFORM_BUS_DEVICE);
>  qdev_prop_set_uint32(dev, "num_irqs", PLATFORM_BUS_NUM_IRQS);
> -qdev_prop_set_uint32(dev, "mmio_size", 
> vms->memmap[VIRT_PLATFORM_BUS].size);
> +qdev_prop_set_uint64(dev, "mmio_size", 
> vms->memmap[VIRT_PLATFORM_BUS].size);
>  sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
>  vms->platform_bus_dev = dev;
>  
> diff --git a/hw/core/platform-bus.c b/hw/core/platform-bus.c
> index dc58bf505a..f545fab6e5 100644
> --- a/hw/core/platform-bus.c
> +++ b/hw/core/platform-bus.c
> @@ -22,6 +22,7 @@
>  #include "qemu/osdep.h"
>  #include "hw/platform-bus.h"
>  #include "hw/qdev-properties.h"
> +#include "hw/vfio/vfio-platform.h"
>  #include "qapi/error.h"
>  #include "qemu/error-report.h"
>  #include "qemu/module.h"
> @@ -130,11 +131,29 @@ static void platform_bus_map_mmio(PlatformBusDevice 
> *pbus, SysBusDevice *sbdev,
>int n)
>  {
>  MemoryRegion *sbdev_mr = sysbus_mmio_get_region(sbdev, n);
> +VFIOPlatformDevice *vdev = VFIO_PLATFORM_DEVICE(sbdev);

How do you know it's a vfio-platform device?  This completely breaks
device abstraction.  Thanks,

Alex

>  uint64_t size = memory_region_size(sbdev_mr);
>  uint64_t alignment = (1ULL << (63 - clz64(size + size - 1)));
>  uint64_t off;
> +uint64_t mmio_base_off;
>  bool found_region = false;
>  
> +if (vdev->mmio_base) {
> +if(vdev->mmio_base < pbus->mmio.addr || 
> +   vdev->mmio_base >= pbus->mmio.addr + pbus->mmio_size){
> +error_report("Platform Bus: MMIO base 0x%"PRIx64
> +" outside platform bus region [0x%"PRIx64",0x%"PRIx64"]",
> +vdev->mmio_base,
> +pbus->mmio.addr,
> +pbus->mmio.addr + pbus->mmio_size);
> +exit(1);
> +}
> +
> +mmio_base_off = vdev->mmio_base - pbus->mmio.addr;
> +} else {
> +mmio_base_off = 0;
> +}
> +
>  if (memory_region_is_mapped(sbdev_mr)) {
>  /* Region is already mapped, nothing to do */
>  return;
> @@ -144,7 +163,7 @@ static void platform_bus_map_mmio(PlatformBusDevice 
> *pbus, SysBusDevice *sbdev,
>   * Look for empty space in the MMIO space that is naturally aligned with
>   * the target device's memory region
>   */
> -for (off = 0; off < pbus->mmio_size; off += alignment) {
> +for (off = mmio_base_off; off < pbus->mmio_size; off += alignment) {
>  MemoryRegion *mr = memory_region_find(&pbus->mmio, off, size).mr;
>  

[PATCH 03/20] hw/net/xilinx_ethlite: Remove unuseful debug logs

2024-11-12 Thread Philippe Mathieu-Daudé
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/net/xilinx_ethlite.c | 8 
 1 file changed, 8 deletions(-)

diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c
index bb330a233f..2b52597f03 100644
--- a/hw/net/xilinx_ethlite.c
+++ b/hw/net/xilinx_ethlite.c
@@ -32,7 +32,6 @@
 #include "net/net.h"
 #include "trace.h"
 
-#define D(x)
 #define R_TX_BUF0 0
 #define R_TX_LEN0 (0x07f4 / 4)
 #define R_TX_GIE0 (0x07f8 / 4)
@@ -100,7 +99,6 @@ eth_read(void *opaque, hwaddr addr, unsigned int size)
 case R_RX_CTRL1:
 case R_RX_CTRL0:
 r = s->regs[addr];
-D(qemu_log("%s " HWADDR_FMT_plx "=%x\n", __func__, addr * 4, r));
 break;
 
 default:
@@ -126,13 +124,10 @@ eth_write(void *opaque, hwaddr addr,
 if (addr == R_TX_CTRL1)
 base = 0x800 / 4;
 
-D(qemu_log("%s addr=" HWADDR_FMT_plx " val=%x\n",
-   __func__, addr * 4, value));
 if ((value & (CTRL_P | CTRL_S)) == CTRL_S) {
 qemu_send_packet(qemu_get_queue(s->nic),
  (void *) &s->regs[base],
  s->regs[base + R_TX_LEN0]);
-D(qemu_log("eth_tx %d\n", s->regs[base + R_TX_LEN0]));
 if (s->regs[base + R_TX_CTRL0] & CTRL_I)
 eth_pulse_irq(s);
 } else if ((value & (CTRL_P | CTRL_S)) == (CTRL_P | CTRL_S)) {
@@ -156,8 +151,6 @@ eth_write(void *opaque, hwaddr addr,
 case R_TX_LEN0:
 case R_TX_LEN1:
 case R_TX_GIE0:
-D(qemu_log("%s addr=" HWADDR_FMT_plx " val=%x\n",
-   __func__, addr * 4, value));
 s->regs[addr] = value;
 break;
 
@@ -203,7 +196,6 @@ static ssize_t eth_rx(NetClientState *nc, const uint8_t 
*buf, size_t size)
 return -1;
 }
 
-D(qemu_log("%s %zd rxbase=%x\n", __func__, size, rxbase));
 if (size > (R_MAX - R_RX_BUF0 - rxbase) * 4) {
 trace_ethlite_pkt_size_too_big(size);
 return -1;
-- 
2.45.2




[PATCH 02/20] hw/net/xilinx_ethlite: Convert some debug logs to trace events

2024-11-12 Thread Philippe Mathieu-Daudé
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/net/xilinx_ethlite.c | 5 +++--
 hw/net/trace-events | 4 
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c
index e84b4cdd35..bb330a233f 100644
--- a/hw/net/xilinx_ethlite.c
+++ b/hw/net/xilinx_ethlite.c
@@ -30,6 +30,7 @@
 #include "hw/irq.h"
 #include "hw/qdev-properties.h"
 #include "net/net.h"
+#include "trace.h"
 
 #define D(x)
 #define R_TX_BUF0 0
@@ -198,13 +199,13 @@ static ssize_t eth_rx(NetClientState *nc, const uint8_t 
*buf, size_t size)
 return size;
 
 if (s->regs[rxbase + R_RX_CTRL0] & CTRL_S) {
-D(qemu_log("ethlite lost packet %x\n", s->regs[R_RX_CTRL0]));
+trace_ethlite_pkt_lost(s->regs[R_RX_CTRL0]);
 return -1;
 }
 
 D(qemu_log("%s %zd rxbase=%x\n", __func__, size, rxbase));
 if (size > (R_MAX - R_RX_BUF0 - rxbase) * 4) {
-D(qemu_log("ethlite packet is too big, size=%x\n", size));
+trace_ethlite_pkt_size_too_big(size);
 return -1;
 }
 memcpy(&s->regs[rxbase + R_RX_BUF0], buf, size);
diff --git a/hw/net/trace-events b/hw/net/trace-events
index d0f1d8c0fb..2b36cd967e 100644
--- a/hw/net/trace-events
+++ b/hw/net/trace-events
@@ -511,3 +511,7 @@ xen_netdev_connect(int dev, unsigned int tx, unsigned int 
rx, int port) "vif%u t
 xen_netdev_frontend_changed(const char *dev, int state) "vif%s state %d"
 xen_netdev_tx(int dev, int ref, int off, int len, unsigned int flags, const 
char *c, const char *d, const char *m, const char *e) "vif%u ref %u off %u len 
%u flags 0x%x%s%s%s%s"
 xen_netdev_rx(int dev, int idx, int status, int flags) "vif%u idx %d status %d 
flags 0x%x"
+
+# xilinx_ethlite.c
+ethlite_pkt_lost(uint32_t rx_ctrl) "rx_ctrl:0x%" PRIx32
+ethlite_pkt_size_too_big(uint64_t size) "size:0x%" PRIx64
-- 
2.45.2




[PATCH 00/20] hw/net/xilinx_ethlite: Map RAM buffers as RAM and remove tswap() calls

2024-11-12 Thread Philippe Mathieu-Daudé
This is the result of a long discussion with Edgar (started few
years ago!) and Paolo:
https://lore.kernel.org/qemu-devel/34f6fe2f-06e0-4e2a-a361-2d662f681...@redhat.com/
After clarification from Richard on MMIO/RAM accesses, I figured
strengthening the model regions would make things obvious,
eventually allowing to remove the tswap() calls for good.

This costly series mostly plays around with MemoryRegions.

The model has a mix of RAM/MMIO in its address range. Currently
they are implemented as a MMIO array of u32. Since the core
memory layer swaps accesses for MMIO, the device implementation
has to swap them back.
In order to avoid that, we'll map the RAM regions as RAM MRs.
First we move each MMIO register to new MMIO regions (RX and TX).
Then what is left are the RAM buffers; we convert them to RAM MRs,
removing the need for tswap() at all.

Once reviewed, I'll respin my "hw/microblaze: Allow running
cross-endian vCPUs" series based on this.

Please review,

Phil.

Philippe Mathieu-Daudé (20):
  hw/microblaze: Restrict MemoryRegionOps are implemented as 32-bit
  hw/net/xilinx_ethlite: Convert some debug logs to trace events
  hw/net/xilinx_ethlite: Remove unuseful debug logs
  hw/net/xilinx_ethlite: Update QOM style
  hw/net/xilinx_ethlite: Correct maximum RX buffer size
  hw/net/xilinx_ethlite: Map MDIO registers (as unimplemented)
  hw/net/xilinx_ethlite: Rename rxbuf -> port_index
  hw/net/xilinx_ethlite: Add addr_to_port_index() helper
  hw/net/xilinx_ethlite: Introduce txbuf_ptr() helper
  hw/net/xilinx_ethlite: Introduce rxbuf_ptr() helper
  hw/net/xilinx_ethlite: Access RX_CTRL register for each port
  hw/net/xilinx_ethlite: Access TX_GIE register for each port
  hw/net/xilinx_ethlite: Access TX_LEN register for each port
  hw/net/xilinx_ethlite: Access TX_CTRL register for each port
  hw/net/xilinx_ethlite: Map RX_CTRL as MMIO
  hw/net/xilinx_ethlite: Map TX_LEN as MMIO
  hw/net/xilinx_ethlite: Map TX_GIE as MMIO
  hw/net/xilinx_ethlite: Map TX_CTRL as MMIO
  hw/net/xilinx_ethlite: Map the RAM buffer as RAM memory region
  hw/net/xilinx_ethlite: Rename 'mmio' MR as 'container'

 hw/char/xilinx_uartlite.c |   4 +
 hw/intc/xilinx_intc.c |   4 +
 hw/net/xilinx_ethlite.c   | 357 --
 hw/timer/xilinx_timer.c   |   4 +
 hw/net/trace-events   |   4 +
 5 files changed, 246 insertions(+), 127 deletions(-)

-- 
2.45.2




[PATCH 07/20] hw/net/xilinx_ethlite: Rename rxbuf -> port_index

2024-11-12 Thread Philippe Mathieu-Daudé
'rxbuf' is the index of the port used. Rename it as 'port_index'.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/net/xilinx_ethlite.c | 11 +--
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c
index 76b1e7d826..20919b4f54 100644
--- a/hw/net/xilinx_ethlite.c
+++ b/hw/net/xilinx_ethlite.c
@@ -72,8 +72,7 @@ struct XlnxXpsEthLite
 
 uint32_t c_tx_pingpong;
 uint32_t c_rx_pingpong;
-unsigned int txbuf;
-unsigned int rxbuf;
+unsigned int port_index;
 
 UnimplementedDeviceState mdio;
 uint32_t regs[R_MAX];
@@ -183,7 +182,7 @@ static const MemoryRegionOps eth_ops = {
 static bool eth_can_rx(NetClientState *nc)
 {
 XlnxXpsEthLite *s = qemu_get_nic_opaque(nc);
-unsigned int rxbase = s->rxbuf * (0x800 / 4);
+unsigned int rxbase = s->port_index * (0x800 / 4);
 
 return !(s->regs[rxbase + R_RX_CTRL0] & CTRL_S);
 }
@@ -191,7 +190,7 @@ static bool eth_can_rx(NetClientState *nc)
 static ssize_t eth_rx(NetClientState *nc, const uint8_t *buf, size_t size)
 {
 XlnxXpsEthLite *s = qemu_get_nic_opaque(nc);
-unsigned int rxbase = s->rxbuf * (0x800 / 4);
+unsigned int rxbase = s->port_index * (0x800 / 4);
 
 /* DA filter.  */
 if (!(buf[0] & 0x80) && memcmp(&s->conf.macaddr.a[0], buf, 6))
@@ -214,7 +213,7 @@ static ssize_t eth_rx(NetClientState *nc, const uint8_t 
*buf, size_t size)
 }
 
 /* If c_rx_pingpong was set flip buffers.  */
-s->rxbuf ^= s->c_rx_pingpong;
+s->port_index ^= s->c_rx_pingpong;
 return size;
 }
 
@@ -222,7 +221,7 @@ static void xilinx_ethlite_reset(DeviceState *dev)
 {
 XlnxXpsEthLite *s = XILINX_ETHLITE(dev);
 
-s->rxbuf = 0;
+s->port_index = 0;
 }
 
 static NetClientInfo net_xilinx_ethlite_info = {
-- 
2.45.2




[PATCH 10/20] hw/net/xilinx_ethlite: Introduce rxbuf_ptr() helper

2024-11-12 Thread Philippe Mathieu-Daudé
rxbuf_ptr() points to the beginning of a (RAM) RX buffer
within the device state.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/net/xilinx_ethlite.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c
index d4882f43f7..fdbf25fd91 100644
--- a/hw/net/xilinx_ethlite.c
+++ b/hw/net/xilinx_ethlite.c
@@ -99,6 +99,13 @@ static void *txbuf_ptr(XlnxXpsEthLite *s, unsigned 
port_index)
 return &s->regs[rxbase + R_TX_BUF0];
 }
 
+static void *rxbuf_ptr(XlnxXpsEthLite *s, unsigned port_index)
+{
+unsigned int rxbase = port_index * (0x800 / 4);
+
+return &s->regs[rxbase + R_RX_BUF0];
+}
+
 static uint64_t
 eth_read(void *opaque, hwaddr addr, unsigned int size)
 {
@@ -220,7 +227,7 @@ static ssize_t eth_rx(NetClientState *nc, const uint8_t 
*buf, size_t size)
 trace_ethlite_pkt_size_too_big(size);
 return -1;
 }
-memcpy(&s->regs[rxbase + R_RX_BUF0], buf, size);
+memcpy(rxbuf_ptr(s, port_index), buf, size);
 
 s->regs[rxbase + R_RX_CTRL0] |= CTRL_S;
 if (s->regs[R_RX_CTRL0] & CTRL_I) {
-- 
2.45.2




[PATCH 06/20] hw/net/xilinx_ethlite: Map MDIO registers (as unimplemented)

2024-11-12 Thread Philippe Mathieu-Daudé
Rather than handling the MDIO registers as RAM, map them
as unimplemented I/O within the device MR.

The memory flat view becomes:

  (qemu) info mtree -f
  FlatView #0
   Root memory region: system
8100-810007e3 (prio 0, i/o): xlnx.xps-ethernetlite
810007e4-810007f3 (prio 0, i/o): ethlite.mdio
810007f4-81001fff (prio 0, i/o): xlnx.xps-ethernetlite 
@07f4

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/net/xilinx_ethlite.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c
index e6f6179fce..76b1e7d826 100644
--- a/hw/net/xilinx_ethlite.c
+++ b/hw/net/xilinx_ethlite.c
@@ -25,13 +25,17 @@
 #include "qemu/osdep.h"
 #include "qemu/module.h"
 #include "qom/object.h"
+#include "qapi/error.h"
 #include "exec/tswap.h"
 #include "hw/sysbus.h"
 #include "hw/irq.h"
 #include "hw/qdev-properties.h"
+#include "hw/misc/unimp.h"
 #include "net/net.h"
 #include "trace.h"
 
+#define A_MDIO_BASE   0x07e4
+
 #define R_TX_BUF0 0
 #define R_TX_LEN0 (0x07f4 / 4)
 #define R_TX_GIE0 (0x07f8 / 4)
@@ -71,6 +75,7 @@ struct XlnxXpsEthLite
 unsigned int txbuf;
 unsigned int rxbuf;
 
+UnimplementedDeviceState mdio;
 uint32_t regs[R_MAX];
 };
 
@@ -231,6 +236,14 @@ static void xilinx_ethlite_realize(DeviceState *dev, Error 
**errp)
 {
 XlnxXpsEthLite *s = XILINX_ETHLITE(dev);
 
+object_initialize_child(OBJECT(dev), "ethlite.mdio", &s->mdio,
+   TYPE_UNIMPLEMENTED_DEVICE);
+qdev_prop_set_string(DEVICE(&s->mdio), "name", "ethlite.mdio");
+qdev_prop_set_uint64(DEVICE(&s->mdio), "size", 4 * 4);
+sysbus_realize(SYS_BUS_DEVICE(&s->mdio), &error_fatal);
+memory_region_add_subregion(&s->mmio, A_MDIO_BASE,
+sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mdio), 
0));
+
 qemu_macaddr_default_if_unset(&s->conf.macaddr);
 s->nic = qemu_new_nic(&net_xilinx_ethlite_info, &s->conf,
   object_get_typename(OBJECT(dev)), dev->id,
-- 
2.45.2




[PATCH 05/20] hw/net/xilinx_ethlite: Correct maximum RX buffer size

2024-11-12 Thread Philippe Mathieu-Daudé
The current max RX bufsize is set to 0x800. This is
invalid, since it contains the MMIO registers region.
Add the correct definition and use it.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/net/xilinx_ethlite.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c
index 0f59811c78..e6f6179fce 100644
--- a/hw/net/xilinx_ethlite.c
+++ b/hw/net/xilinx_ethlite.c
@@ -46,6 +46,8 @@
 #define R_RX_CTRL1(0x1ffc / 4)
 #define R_MAX (0x2000 / 4)
 
+#define RX_BUFSZ_MAX  0x07e0
+
 #define GIE_GIE0x8000
 
 #define CTRL_I 0x8
@@ -195,7 +197,7 @@ static ssize_t eth_rx(NetClientState *nc, const uint8_t 
*buf, size_t size)
 return -1;
 }
 
-if (size > (R_MAX - R_RX_BUF0 - rxbase) * 4) {
+if (size > RX_BUFSZ_MAX) {
 trace_ethlite_pkt_size_too_big(size);
 return -1;
 }
-- 
2.45.2




[PATCH 20/20] hw/net/xilinx_ethlite: Rename 'mmio' MR as 'container'

2024-11-12 Thread Philippe Mathieu-Daudé
Having all its address range mapped by subregions,
s->mmio MemoryRegion effectively became a container.
Rename it as 'container' for clarity.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/net/xilinx_ethlite.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c
index da453465ca..c65001cf46 100644
--- a/hw/net/xilinx_ethlite.c
+++ b/hw/net/xilinx_ethlite.c
@@ -93,7 +93,7 @@ struct XlnxXpsEthLite
 {
 SysBusDevice parent_obj;
 
-MemoryRegion mmio;
+MemoryRegion container;
 qemu_irq irq;
 NICState *nic;
 NICConf conf;
@@ -306,7 +306,7 @@ static void xilinx_ethlite_realize(DeviceState *dev, Error 
**errp)
 {
 XlnxXpsEthLite *s = XILINX_ETHLITE(dev);
 
-memory_region_init(&s->mmio, OBJECT(dev),
+memory_region_init(&s->container, OBJECT(dev),
"xlnx.xps-ethernetlite", 0x2000);
 
 object_initialize_child(OBJECT(dev), "ethlite.mdio", &s->mdio,
@@ -314,31 +314,31 @@ static void xilinx_ethlite_realize(DeviceState *dev, 
Error **errp)
 qdev_prop_set_string(DEVICE(&s->mdio), "name", "ethlite.mdio");
 qdev_prop_set_uint64(DEVICE(&s->mdio), "size", 4 * 4);
 sysbus_realize(SYS_BUS_DEVICE(&s->mdio), &error_fatal);
-memory_region_add_subregion(&s->mmio, A_MDIO_BASE,
+memory_region_add_subregion(&s->container, A_MDIO_BASE,
 sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mdio), 
0));
 
 for (unsigned i = 0; i < 2; i++) {
 memory_region_init_ram(&s->port[i].txbuf, OBJECT(dev),
i ? "ethlite.tx[1]buf" : "ethlite.tx[0]buf",
0x07f4, &error_abort);
-memory_region_add_subregion(&s->mmio, 0x0800 * i, &s->port[i].txbuf);
+memory_region_add_subregion(&s->container, 0x0800 * i, 
&s->port[i].txbuf);
 memory_region_init_io(&s->port[i].txio, OBJECT(dev),
   ð_porttx_ops, s,
   i ? "ethlite.tx[1]io" : "ethlite.tx[0]io",
   4 * TX_MAX);
-memory_region_add_subregion(&s->mmio, i ? A_TX_BASE1 : A_TX_BASE0,
+memory_region_add_subregion(&s->container, i ? A_TX_BASE1 : A_TX_BASE0,
 &s->port[i].txio);
 
 memory_region_init_ram(&s->port[i].rxbuf, OBJECT(dev),
i ? "ethlite.rx[1]buf" : "ethlite.rx[0]buf",
0x07f4, &error_abort);
-memory_region_add_subregion(&s->mmio, 0x1000 + 0x0800 * i,
+memory_region_add_subregion(&s->container, 0x1000 + 0x0800 * i,
 &s->port[i].rxbuf);
 memory_region_init_io(&s->port[i].rxio, OBJECT(dev),
   ð_portrx_ops, s,
   i ? "ethlite.rx[1]io" : "ethlite.rx[0]io",
   4 * RX_MAX);
-memory_region_add_subregion(&s->mmio, i ? A_RX_BASE1 : A_RX_BASE0,
+memory_region_add_subregion(&s->container, i ? A_RX_BASE1 : A_RX_BASE0,
 &s->port[i].rxio);
 }
 
@@ -354,7 +354,7 @@ static void xilinx_ethlite_init(Object *obj)
 XlnxXpsEthLite *s = XILINX_ETHLITE(obj);
 
 sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
-sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
+sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->container);
 }
 
 static Property xilinx_ethlite_properties[] = {
-- 
2.45.2




[PATCH 14/20] hw/net/xilinx_ethlite: Access TX_CTRL register for each port

2024-11-12 Thread Philippe Mathieu-Daudé
Rather than accessing the registers within the mixed RAM/MMIO
region as indexed register, declare a per-port TX_CTRL. This
will help to map the RAM as RAM (keeping MMIO as MMIO) in few
commits.

Previous s->regs[R_TX_CTRL0] and s->regs[R_TX_CTRL1] are now
unused. Not a concern, this array will soon disappear.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/net/xilinx_ethlite.c | 15 +++
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c
index 1a3b295b4b..4d86851f38 100644
--- a/hw/net/xilinx_ethlite.c
+++ b/hw/net/xilinx_ethlite.c
@@ -64,6 +64,7 @@ typedef struct XlnxXpsEthLitePort
 struct {
 uint32_t tx_len;
 uint32_t tx_gie;
+uint32_t tx_ctrl;
 
 uint32_t rx_ctrl;
 } reg;
@@ -139,7 +140,7 @@ eth_read(void *opaque, hwaddr addr, unsigned int size)
 
 case R_TX_CTRL1:
 case R_TX_CTRL0:
-r = s->regs[addr];
+r = s->port[port_index].reg.tx_ctrl;
 break;
 
 case R_RX_CTRL1:
@@ -159,7 +160,6 @@ eth_write(void *opaque, hwaddr addr,
 {
 XlnxXpsEthLite *s = opaque;
 unsigned int port_index = addr_to_port_index(addr);
-unsigned int base = 0;
 uint32_t value = val64;
 
 addr >>= 2;
@@ -167,24 +167,23 @@ eth_write(void *opaque, hwaddr addr,
 {
 case R_TX_CTRL0:
 case R_TX_CTRL1:
-if (addr == R_TX_CTRL1)
-base = 0x800 / 4;
-
 if ((value & (CTRL_P | CTRL_S)) == CTRL_S) {
 qemu_send_packet(qemu_get_queue(s->nic),
  txbuf_ptr(s, port_index),
  s->port[port_index].reg.tx_len);
-if (s->regs[base + R_TX_CTRL0] & CTRL_I)
+if (s->port[port_index].reg.tx_ctrl & CTRL_I) {
 eth_pulse_irq(s);
+}
 } else if ((value & (CTRL_P | CTRL_S)) == (CTRL_P | CTRL_S)) {
 memcpy(&s->conf.macaddr.a[0], txbuf_ptr(s, port_index), 6);
-if (s->regs[base + R_TX_CTRL0] & CTRL_I)
+if (s->port[port_index].reg.tx_ctrl & CTRL_I) {
 eth_pulse_irq(s);
+}
 }
 
 /* We are fast and get ready pretty much immediately so
we actually never flip the S nor P bits to one.  */
-s->regs[addr] = value & ~(CTRL_P | CTRL_S);
+s->port[port_index].reg.tx_ctrl = value & ~(CTRL_P | CTRL_S);
 break;
 
 /* Keep these native.  */
-- 
2.45.2




[PATCH 18/20] hw/net/xilinx_ethlite: Map TX_CTRL as MMIO

2024-11-12 Thread Philippe Mathieu-Daudé
Add TX_CTRL to the TX registers MMIO region.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/net/xilinx_ethlite.c | 56 +++--
 1 file changed, 26 insertions(+), 30 deletions(-)

diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c
index f7a5b1620a..f681b91769 100644
--- a/hw/net/xilinx_ethlite.c
+++ b/hw/net/xilinx_ethlite.c
@@ -39,10 +39,8 @@
 
 #define R_TX_BUF0 0
 #define A_TX_BASE00x07f4
-#define R_TX_CTRL0(0x07fc / 4)
 #define R_TX_BUF1 (0x0800 / 4)
 #define A_TX_BASE10x0ff4
-#define R_TX_CTRL1(0x0ffc / 4)
 
 #define R_RX_BUF0 (0x1000 / 4)
 #define A_RX_BASE00x17fc
@@ -55,6 +53,7 @@
 enum {
 TX_LEN =  0,
 TX_GIE =  1,
+TX_CTRL = 2,
 TX_MAX
 };
 
@@ -71,6 +70,7 @@ enum {
 
 typedef struct XlnxXpsEthLitePort
 {
+MemoryRegion txio;
 MemoryRegion rxio;
 
 struct {
@@ -143,6 +143,9 @@ static uint64_t port_tx_read(void *opaque, hwaddr addr, 
unsigned int size)
 case TX_GIE:
 r = s->port[port_index].reg.tx_gie;
 break;
+case TX_CTRL:
+r = s->port[port_index].reg.tx_ctrl;
+break;
 default:
 g_assert_not_reached();
 }
@@ -154,6 +157,7 @@ static void port_tx_write(void *opaque, hwaddr addr, 
uint64_t value,
   unsigned int size)
 {
 XlnxXpsEthLite *s = opaque;
+unsigned port_index = addr_to_port_index(addr);
 
 switch (addr >> 2) {
 case TX_LEN:
@@ -162,6 +166,26 @@ static void port_tx_write(void *opaque, hwaddr addr, 
uint64_t value,
 case TX_GIE:
 s->port[port_index].reg.tx_gie = value;
 break;
+case TX_CTRL:
+if ((value & (CTRL_P | CTRL_S)) == CTRL_S) {
+qemu_send_packet(qemu_get_queue(s->nic),
+ txbuf_ptr(s, port_index),
+ s->port[port_index].reg.tx_len);
+if (s->port[port_index].reg.tx_ctrl & CTRL_I) {
+eth_pulse_irq(s);
+}
+} else if ((value & (CTRL_P | CTRL_S)) == (CTRL_P | CTRL_S)) {
+memcpy(&s->conf.macaddr.a[0], txbuf_ptr(s, port_index), 6);
+if (s->port[port_index].reg.tx_ctrl & CTRL_I) {
+eth_pulse_irq(s);
+}
+}
+/*
+ * We are fast and get ready pretty much immediately
+ * so we actually never flip the S nor P bits to one.
+ */
+s->port[port_index].reg.tx_ctrl = value & ~(CTRL_P | CTRL_S);
+break;
 default:
 g_assert_not_reached();
 }
@@ -232,18 +256,12 @@ static uint64_t
 eth_read(void *opaque, hwaddr addr, unsigned int size)
 {
 XlnxXpsEthLite *s = opaque;
-unsigned port_index = addr_to_port_index(addr);
 uint32_t r = 0;
 
 addr >>= 2;
 
 switch (addr)
 {
-case R_TX_CTRL1:
-case R_TX_CTRL0:
-r = s->port[port_index].reg.tx_ctrl;
-break;
-
 default:
 r = tswap32(s->regs[addr]);
 break;
@@ -256,33 +274,11 @@ eth_write(void *opaque, hwaddr addr,
   uint64_t val64, unsigned int size)
 {
 XlnxXpsEthLite *s = opaque;
-unsigned int port_index = addr_to_port_index(addr);
 uint32_t value = val64;
 
 addr >>= 2;
 switch (addr) 
 {
-case R_TX_CTRL0:
-case R_TX_CTRL1:
-if ((value & (CTRL_P | CTRL_S)) == CTRL_S) {
-qemu_send_packet(qemu_get_queue(s->nic),
- txbuf_ptr(s, port_index),
- s->port[port_index].reg.tx_len);
-if (s->port[port_index].reg.tx_ctrl & CTRL_I) {
-eth_pulse_irq(s);
-}
-} else if ((value & (CTRL_P | CTRL_S)) == (CTRL_P | CTRL_S)) {
-memcpy(&s->conf.macaddr.a[0], txbuf_ptr(s, port_index), 6);
-if (s->port[port_index].reg.tx_ctrl & CTRL_I) {
-eth_pulse_irq(s);
-}
-}
-
-/* We are fast and get ready pretty much immediately so
-   we actually never flip the S nor P bits to one.  */
-s->port[port_index].reg.tx_ctrl = value & ~(CTRL_P | CTRL_S);
-break;
-
 default:
 s->regs[addr] = tswap32(value);
 break;
-- 
2.45.2




[PATCH 17/20] hw/net/xilinx_ethlite: Map TX_GIE as MMIO

2024-11-12 Thread Philippe Mathieu-Daudé
Add TX_GIE to the TX registers MMIO region.

Before TX_GIE1 was accessed as RAM, with no effect.
Now it is accessed as MMIO, also without any effect.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/net/xilinx_ethlite.c | 17 +++--
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c
index 159b2b0c64..f7a5b1620a 100644
--- a/hw/net/xilinx_ethlite.c
+++ b/hw/net/xilinx_ethlite.c
@@ -39,7 +39,6 @@
 
 #define R_TX_BUF0 0
 #define A_TX_BASE00x07f4
-#define R_TX_GIE0 (0x07f8 / 4)
 #define R_TX_CTRL0(0x07fc / 4)
 #define R_TX_BUF1 (0x0800 / 4)
 #define A_TX_BASE10x0ff4
@@ -55,6 +54,7 @@
 
 enum {
 TX_LEN =  0,
+TX_GIE =  1,
 TX_MAX
 };
 
@@ -140,6 +140,9 @@ static uint64_t port_tx_read(void *opaque, hwaddr addr, 
unsigned int size)
 case TX_LEN:
 r = s->port[port_index].reg.tx_len;
 break;
+case TX_GIE:
+r = s->port[port_index].reg.tx_gie;
+break;
 default:
 g_assert_not_reached();
 }
@@ -156,6 +159,9 @@ static void port_tx_write(void *opaque, hwaddr addr, 
uint64_t value,
 case TX_LEN:
 s->port[port_index].reg.tx_len = value;
 break;
+case TX_GIE:
+s->port[port_index].reg.tx_gie = value;
+break;
 default:
 g_assert_not_reached();
 }
@@ -233,10 +239,6 @@ eth_read(void *opaque, hwaddr addr, unsigned int size)
 
 switch (addr)
 {
-case R_TX_GIE0:
-r = s->port[port_index].reg.tx_gie;
-break;
-
 case R_TX_CTRL1:
 case R_TX_CTRL0:
 r = s->port[port_index].reg.tx_ctrl;
@@ -281,11 +283,6 @@ eth_write(void *opaque, hwaddr addr,
 s->port[port_index].reg.tx_ctrl = value & ~(CTRL_P | CTRL_S);
 break;
 
-/* Keep these native.  */
-case R_TX_GIE0:
-s->port[port_index].reg.tx_gie = value;
-break;
-
 default:
 s->regs[addr] = tswap32(value);
 break;
-- 
2.45.2




[PATCH 16/20] hw/net/xilinx_ethlite: Map TX_LEN as MMIO

2024-11-12 Thread Philippe Mathieu-Daudé
Declare TX registers as MMIO region, split it out
of the current mixed RAM/MMIO region.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/net/xilinx_ethlite.c | 71 ++---
 1 file changed, 59 insertions(+), 12 deletions(-)

diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c
index 161fd97f06..159b2b0c64 100644
--- a/hw/net/xilinx_ethlite.c
+++ b/hw/net/xilinx_ethlite.c
@@ -38,11 +38,11 @@
 #define A_MDIO_BASE   0x07e4
 
 #define R_TX_BUF0 0
-#define R_TX_LEN0 (0x07f4 / 4)
+#define A_TX_BASE00x07f4
 #define R_TX_GIE0 (0x07f8 / 4)
 #define R_TX_CTRL0(0x07fc / 4)
 #define R_TX_BUF1 (0x0800 / 4)
-#define R_TX_LEN1 (0x0ff4 / 4)
+#define A_TX_BASE10x0ff4
 #define R_TX_CTRL1(0x0ffc / 4)
 
 #define R_RX_BUF0 (0x1000 / 4)
@@ -53,6 +53,11 @@
 
 #define RX_BUFSZ_MAX  0x07e0
 
+enum {
+TX_LEN =  0,
+TX_MAX
+};
+
 enum {
 RX_CTRL = 0,
 RX_MAX
@@ -125,6 +130,51 @@ static void *rxbuf_ptr(XlnxXpsEthLite *s, unsigned 
port_index)
 return &s->regs[rxbase + R_RX_BUF0];
 }
 
+static uint64_t port_tx_read(void *opaque, hwaddr addr, unsigned int size)
+{
+XlnxXpsEthLite *s = opaque;
+unsigned port_index = addr_to_port_index(addr);
+uint32_t r = 0;
+
+switch (addr >> 2) {
+case TX_LEN:
+r = s->port[port_index].reg.tx_len;
+break;
+default:
+g_assert_not_reached();
+}
+
+return r;
+}
+
+static void port_tx_write(void *opaque, hwaddr addr, uint64_t value,
+  unsigned int size)
+{
+XlnxXpsEthLite *s = opaque;
+
+switch (addr >> 2) {
+case TX_LEN:
+s->port[port_index].reg.tx_len = value;
+break;
+default:
+g_assert_not_reached();
+}
+}
+
+static const MemoryRegionOps eth_porttx_ops = {
+.read = port_tx_read,
+.write = port_tx_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+.impl = {
+.min_access_size = 4,
+.max_access_size = 4,
+},
+.valid = {
+.min_access_size = 4,
+.max_access_size = 4,
+},
+};
+
 static uint64_t port_rx_read(void *opaque, hwaddr addr, unsigned int size)
 {
 XlnxXpsEthLite *s = opaque;
@@ -187,11 +237,6 @@ eth_read(void *opaque, hwaddr addr, unsigned int size)
 r = s->port[port_index].reg.tx_gie;
 break;
 
-case R_TX_LEN0:
-case R_TX_LEN1:
-r = s->port[port_index].reg.tx_len;
-break;
-
 case R_TX_CTRL1:
 case R_TX_CTRL0:
 r = s->port[port_index].reg.tx_ctrl;
@@ -237,11 +282,6 @@ eth_write(void *opaque, hwaddr addr,
 break;
 
 /* Keep these native.  */
-case R_TX_LEN0:
-case R_TX_LEN1:
-s->port[port_index].reg.tx_len = value;
-break;
-
 case R_TX_GIE0:
 s->port[port_index].reg.tx_gie = value;
 break;
@@ -330,6 +370,13 @@ static void xilinx_ethlite_realize(DeviceState *dev, Error 
**errp)
 sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mdio), 
0));
 
 for (unsigned i = 0; i < 2; i++) {
+memory_region_init_io(&s->port[i].txio, OBJECT(dev),
+  ð_porttx_ops, s,
+  i ? "ethlite.tx[1]io" : "ethlite.tx[0]io",
+  4 * TX_MAX);
+memory_region_add_subregion(&s->mmio, i ? A_TX_BASE1 : A_TX_BASE0,
+&s->port[i].txio);
+
 memory_region_init_io(&s->port[i].rxio, OBJECT(dev),
   ð_portrx_ops, s,
   i ? "ethlite.rx[1]io" : "ethlite.rx[0]io",
-- 
2.45.2




[PATCH 11/20] hw/net/xilinx_ethlite: Access RX_CTRL register for each port

2024-11-12 Thread Philippe Mathieu-Daudé
Rather than accessing the registers within the mixed RAM/MMIO
region as indexed register, declare a per-port RX_CTRL. This
will help to map the RAM as RAM (keeping MMIO as MMIO) in few
commits.

Previous s->regs[R_RX_CTRL0] and s->regs[R_RX_CTRL1] are now
unused. Not a concern, this array will soon disappear.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/net/xilinx_ethlite.c | 31 +--
 1 file changed, 21 insertions(+), 10 deletions(-)

diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c
index fdbf25fd91..605451a522 100644
--- a/hw/net/xilinx_ethlite.c
+++ b/hw/net/xilinx_ethlite.c
@@ -59,6 +59,13 @@
 #define CTRL_P 0x2
 #define CTRL_S 0x1
 
+typedef struct XlnxXpsEthLitePort
+{
+struct {
+uint32_t rx_ctrl;
+} reg;
+} XlnxXpsEthLitePort;
+
 #define TYPE_XILINX_ETHLITE "xlnx.xps-ethernetlite"
 OBJECT_DECLARE_SIMPLE_TYPE(XlnxXpsEthLite, XILINX_ETHLITE)
 
@@ -76,6 +83,7 @@ struct XlnxXpsEthLite
 unsigned int port_index;
 
 UnimplementedDeviceState mdio;
+XlnxXpsEthLitePort port[2];
 uint32_t regs[R_MAX];
 };
 
@@ -110,6 +118,7 @@ static uint64_t
 eth_read(void *opaque, hwaddr addr, unsigned int size)
 {
 XlnxXpsEthLite *s = opaque;
+unsigned port_index = addr_to_port_index(addr);
 uint32_t r = 0;
 
 addr >>= 2;
@@ -121,11 +130,13 @@ eth_read(void *opaque, hwaddr addr, unsigned int size)
 case R_TX_LEN1:
 case R_TX_CTRL1:
 case R_TX_CTRL0:
-case R_RX_CTRL1:
-case R_RX_CTRL0:
 r = s->regs[addr];
 break;
 
+case R_RX_CTRL1:
+case R_RX_CTRL0:
+r = s->port[port_index].reg.rx_ctrl;
+
 default:
 r = tswap32(s->regs[addr]);
 break;
@@ -173,7 +184,9 @@ eth_write(void *opaque, hwaddr addr,
 if (!(value & CTRL_S)) {
 qemu_flush_queued_packets(qemu_get_queue(s->nic));
 }
-/* fall through */
+s->port[port_index].reg.rx_ctrl = value;
+break;
+
 case R_TX_LEN0:
 case R_TX_LEN1:
 case R_TX_GIE0:
@@ -203,23 +216,21 @@ static const MemoryRegionOps eth_ops = {
 static bool eth_can_rx(NetClientState *nc)
 {
 XlnxXpsEthLite *s = qemu_get_nic_opaque(nc);
-unsigned int rxbase = s->port_index * (0x800 / 4);
 
-return !(s->regs[rxbase + R_RX_CTRL0] & CTRL_S);
+return !(s->port[s->port_index].reg.rx_ctrl & CTRL_S);
 }
 
 static ssize_t eth_rx(NetClientState *nc, const uint8_t *buf, size_t size)
 {
 XlnxXpsEthLite *s = qemu_get_nic_opaque(nc);
 unsigned int port_index = s->port_index;
-unsigned int rxbase = port_index * (0x800 / 4);
 
 /* DA filter.  */
 if (!(buf[0] & 0x80) && memcmp(&s->conf.macaddr.a[0], buf, 6))
 return size;
 
-if (s->regs[rxbase + R_RX_CTRL0] & CTRL_S) {
-trace_ethlite_pkt_lost(s->regs[R_RX_CTRL0]);
+if (s->port[port_index].reg.rx_ctrl & CTRL_S) {
+trace_ethlite_pkt_lost(s->port[port_index].reg.rx_ctrl);
 return -1;
 }
 
@@ -229,8 +240,8 @@ static ssize_t eth_rx(NetClientState *nc, const uint8_t 
*buf, size_t size)
 }
 memcpy(rxbuf_ptr(s, port_index), buf, size);
 
-s->regs[rxbase + R_RX_CTRL0] |= CTRL_S;
-if (s->regs[R_RX_CTRL0] & CTRL_I) {
+s->port[port_index].reg.rx_ctrl |= CTRL_S;
+if (s->port[port_index].reg.rx_ctrl & CTRL_I) {
 eth_pulse_irq(s);
 }
 
-- 
2.45.2




[PATCH 19/20] hw/net/xilinx_ethlite: Map the RAM buffer as RAM memory region

2024-11-12 Thread Philippe Mathieu-Daudé
Rather than using I/O registers for RAM buffer, having to
swap endianness back and forth (because the core memory layer
automatically swaps endiannes for us), declare the buffers
as RAM regions. Remove the now unused s->regs[] array.

The memory flat view becomes:

  FlatView #0
   Root memory region: system
8100-810007f3 (prio 0, ram): ethlite.tx[0]buf
810007f4-810007ff (prio 0, i/o): ethlite.tx[0]io
81000800-81000ff3 (prio 0, ram): ethlite.tx[1]buf
81000ff4-81000fff (prio 0, i/o): ethlite.tx[1]io
81001000-810017f3 (prio 0, ram): ethlite.rx[0]buf
810017fc-810017ff (prio 0, i/o): ethlite.rx[0]io
81001800-81001ff3 (prio 0, ram): ethlite.rx[1]buf
81001ffc-81001fff (prio 0, i/o): ethlite.rx[1]io

Mention the device datasheet in the file header.

Reported-by: Paolo Bonzini 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/net/xilinx_ethlite.c | 79 +++--
 1 file changed, 20 insertions(+), 59 deletions(-)

diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c
index f681b91769..da453465ca 100644
--- a/hw/net/xilinx_ethlite.c
+++ b/hw/net/xilinx_ethlite.c
@@ -2,6 +2,10 @@
  * QEMU model of the Xilinx Ethernet Lite MAC.
  *
  * Copyright (c) 2009 Edgar E. Iglesias.
+ * Copyright (c) 2024 Linaro, Ltd
+ *
+ * DS580: https://docs.amd.com/v/u/en-US/xps_ethernetlite
+ * LogiCORE IP XPS Ethernet Lite Media Access Controller
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to 
deal
@@ -27,7 +31,6 @@
 #include "qemu/bitops.h"
 #include "qom/object.h"
 #include "qapi/error.h"
-#include "exec/tswap.h"
 #include "hw/sysbus.h"
 #include "hw/irq.h"
 #include "hw/qdev-properties.h"
@@ -46,7 +49,6 @@
 #define A_RX_BASE00x17fc
 #define R_RX_BUF1 (0x1800 / 4)
 #define A_RX_BASE10x1ffc
-#define R_MAX (0x2000 / 4)
 
 #define RX_BUFSZ_MAX  0x07e0
 
@@ -72,6 +74,8 @@ typedef struct XlnxXpsEthLitePort
 {
 MemoryRegion txio;
 MemoryRegion rxio;
+MemoryRegion txbuf;
+MemoryRegion rxbuf;
 
 struct {
 uint32_t tx_len;
@@ -100,7 +104,6 @@ struct XlnxXpsEthLite
 
 UnimplementedDeviceState mdio;
 XlnxXpsEthLitePort port[2];
-uint32_t regs[R_MAX];
 };
 
 static inline void eth_pulse_irq(XlnxXpsEthLite *s)
@@ -118,16 +121,12 @@ static unsigned addr_to_port_index(hwaddr addr)
 
 static void *txbuf_ptr(XlnxXpsEthLite *s, unsigned port_index)
 {
-unsigned int rxbase = port_index * (0x800 / 4);
-
-return &s->regs[rxbase + R_TX_BUF0];
+return memory_region_get_ram_ptr(&s->port[port_index].txbuf);
 }
 
 static void *rxbuf_ptr(XlnxXpsEthLite *s, unsigned port_index)
 {
-unsigned int rxbase = port_index * (0x800 / 4);
-
-return &s->regs[rxbase + R_RX_BUF0];
+return memory_region_get_ram_ptr(&s->port[port_index].rxbuf);
 }
 
 static uint64_t port_tx_read(void *opaque, hwaddr addr, unsigned int size)
@@ -252,53 +251,6 @@ static const MemoryRegionOps eth_portrx_ops = {
 },
 };
 
-static uint64_t
-eth_read(void *opaque, hwaddr addr, unsigned int size)
-{
-XlnxXpsEthLite *s = opaque;
-uint32_t r = 0;
-
-addr >>= 2;
-
-switch (addr)
-{
-default:
-r = tswap32(s->regs[addr]);
-break;
-}
-return r;
-}
-
-static void
-eth_write(void *opaque, hwaddr addr,
-  uint64_t val64, unsigned int size)
-{
-XlnxXpsEthLite *s = opaque;
-uint32_t value = val64;
-
-addr >>= 2;
-switch (addr) 
-{
-default:
-s->regs[addr] = tswap32(value);
-break;
-}
-}
-
-static const MemoryRegionOps eth_ops = {
-.read = eth_read,
-.write = eth_write,
-.endianness = DEVICE_NATIVE_ENDIAN,
-.impl = {
-.min_access_size = 4,
-.max_access_size = 4,
-},
-.valid = {
-.min_access_size = 4,
-.max_access_size = 4
-}
-};
-
 static bool eth_can_rx(NetClientState *nc)
 {
 XlnxXpsEthLite *s = qemu_get_nic_opaque(nc);
@@ -354,6 +306,9 @@ static void xilinx_ethlite_realize(DeviceState *dev, Error 
**errp)
 {
 XlnxXpsEthLite *s = XILINX_ETHLITE(dev);
 
+memory_region_init(&s->mmio, OBJECT(dev),
+   "xlnx.xps-ethernetlite", 0x2000);
+
 object_initialize_child(OBJECT(dev), "ethlite.mdio", &s->mdio,
TYPE_UNIMPLEMENTED_DEVICE);
 qdev_prop_set_string(DEVICE(&s->mdio), "name", "ethlite.mdio");
@@ -363,6 +318,10 @@ static void xilinx_ethlite_realize(DeviceState *dev, Error 
**errp)
 sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mdio), 
0));
 
 for (unsigned i = 0; i < 2; i++) {
+memory_region_init_ram(&s->port[i].txbuf, OBJECT(dev),
+   i ? "ethlite.tx[1]buf" : "ethlite.tx[0]buf",
+  

[PATCH 15/20] hw/net/xilinx_ethlite: Map RX_CTRL as MMIO

2024-11-12 Thread Philippe Mathieu-Daudé
Declare RX registers as MMIO region, split it out
of the current mixed RAM/MMIO region.
The memory flat view becomes:

  FlatView #0
   Root memory region: system
8100-810007e3 (prio 0, i/o): xlnx.xps-ethernetlite
810007e4-810007f3 (prio 0, i/o): ethlite.mdio
810007f4-810017fb (prio 0, i/o): xlnx.xps-ethernetlite 
@07f4
810017fc-810017ff (prio 0, i/o): ethlite.rx[0]io
81001800-81001ffb (prio 0, i/o): xlnx.xps-ethernetlite 
@1800
81001ffc-81001fff (prio 0, i/o): ethlite.rx[1]io

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/net/xilinx_ethlite.c | 79 +
 1 file changed, 65 insertions(+), 14 deletions(-)

diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c
index 4d86851f38..161fd97f06 100644
--- a/hw/net/xilinx_ethlite.c
+++ b/hw/net/xilinx_ethlite.c
@@ -46,13 +46,18 @@
 #define R_TX_CTRL1(0x0ffc / 4)
 
 #define R_RX_BUF0 (0x1000 / 4)
-#define R_RX_CTRL0(0x17fc / 4)
+#define A_RX_BASE00x17fc
 #define R_RX_BUF1 (0x1800 / 4)
-#define R_RX_CTRL1(0x1ffc / 4)
+#define A_RX_BASE10x1ffc
 #define R_MAX (0x2000 / 4)
 
 #define RX_BUFSZ_MAX  0x07e0
 
+enum {
+RX_CTRL = 0,
+RX_MAX
+};
+
 #define GIE_GIE0x8000
 
 #define CTRL_I 0x8
@@ -61,6 +66,8 @@
 
 typedef struct XlnxXpsEthLitePort
 {
+MemoryRegion rxio;
+
 struct {
 uint32_t tx_len;
 uint32_t tx_gie;
@@ -118,6 +125,53 @@ static void *rxbuf_ptr(XlnxXpsEthLite *s, unsigned 
port_index)
 return &s->regs[rxbase + R_RX_BUF0];
 }
 
+static uint64_t port_rx_read(void *opaque, hwaddr addr, unsigned int size)
+{
+XlnxXpsEthLite *s = opaque;
+unsigned port_index = addr_to_port_index(addr);
+uint32_t r = 0;
+
+switch (addr >> 2) {
+case RX_CTRL:
+r = s->port[port_index].reg.rx_ctrl;
+break;
+default:
+g_assert_not_reached();
+}
+
+return r;
+}
+
+static void port_rx_write(void *opaque, hwaddr addr, uint64_t value,
+  unsigned int size)
+{
+XlnxXpsEthLite *s = opaque;
+
+switch (addr >> 2) {
+case RX_CTRL:
+if (!(value & CTRL_S)) {
+qemu_flush_queued_packets(qemu_get_queue(s->nic));
+}
+break;
+default:
+g_assert_not_reached();
+}
+}
+
+static const MemoryRegionOps eth_portrx_ops = {
+.read = port_rx_read,
+.write = port_rx_write,
+.endianness = DEVICE_NATIVE_ENDIAN,
+.impl = {
+.min_access_size = 4,
+.max_access_size = 4,
+},
+.valid = {
+.min_access_size = 4,
+.max_access_size = 4,
+},
+};
+
 static uint64_t
 eth_read(void *opaque, hwaddr addr, unsigned int size)
 {
@@ -143,10 +197,6 @@ eth_read(void *opaque, hwaddr addr, unsigned int size)
 r = s->port[port_index].reg.tx_ctrl;
 break;
 
-case R_RX_CTRL1:
-case R_RX_CTRL0:
-r = s->port[port_index].reg.rx_ctrl;
-
 default:
 r = tswap32(s->regs[addr]);
 break;
@@ -187,14 +237,6 @@ eth_write(void *opaque, hwaddr addr,
 break;
 
 /* Keep these native.  */
-case R_RX_CTRL0:
-case R_RX_CTRL1:
-if (!(value & CTRL_S)) {
-qemu_flush_queued_packets(qemu_get_queue(s->nic));
-}
-s->port[port_index].reg.rx_ctrl = value;
-break;
-
 case R_TX_LEN0:
 case R_TX_LEN1:
 s->port[port_index].reg.tx_len = value;
@@ -287,6 +329,15 @@ static void xilinx_ethlite_realize(DeviceState *dev, Error 
**errp)
 memory_region_add_subregion(&s->mmio, A_MDIO_BASE,
 sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mdio), 
0));
 
+for (unsigned i = 0; i < 2; i++) {
+memory_region_init_io(&s->port[i].rxio, OBJECT(dev),
+  ð_portrx_ops, s,
+  i ? "ethlite.rx[1]io" : "ethlite.rx[0]io",
+  4 * RX_MAX);
+memory_region_add_subregion(&s->mmio, i ? A_RX_BASE1 : A_RX_BASE0,
+&s->port[i].rxio);
+}
+
 qemu_macaddr_default_if_unset(&s->conf.macaddr);
 s->nic = qemu_new_nic(&net_xilinx_ethlite_info, &s->conf,
   object_get_typename(OBJECT(dev)), dev->id,
-- 
2.45.2




Re: [PATCH v2 5/6] target/mips: Convert microMIPS LSA opcode to decodetree

2024-11-12 Thread Richard Henderson

On 11/12/24 09:20, Philippe Mathieu-Daudé wrote:

Simply call the generic gen_lsa(), using the plus_1()
helper to add 1 to the shift amount.

Signed-off-by: Philippe Mathieu-Daudé 
---
  target/mips/tcg/micromips32.decode|  8 
  target/mips/tcg/micromips_translate.c | 10 ++
  target/mips/tcg/micromips_translate.c.inc |  5 -
  3 files changed, 18 insertions(+), 5 deletions(-)


Reviewed-by: Richard Henderson 

r~



diff --git a/target/mips/tcg/micromips32.decode 
b/target/mips/tcg/micromips32.decode
index c115ed2eab..958883ce84 100644
--- a/target/mips/tcg/micromips32.decode
+++ b/target/mips/tcg/micromips32.decode
@@ -7,3 +7,11 @@
  # Reference: MIPS Architecture for Programmers, Volume II-B
  #microMIPS32 Instruction Set
  #(Document Number: MD00582)
+
+&r  rs rt rd sa
+
+%lsa_sa 9:2  !function=plus_1
+
+@lsa.. rt:5  rs:5  rd:5  .. ... ..  &r sa=%lsa_sa
+
+LSA 00 . . . .. 000 00  @lsa
diff --git a/target/mips/tcg/micromips_translate.c 
b/target/mips/tcg/micromips_translate.c
index 49e90e7eca..f0b5dbf655 100644
--- a/target/mips/tcg/micromips_translate.c
+++ b/target/mips/tcg/micromips_translate.c
@@ -9,6 +9,16 @@
  #include "qemu/osdep.h"
  #include "translate.h"
  
+static inline int plus_1(DisasContext *ctx, int x)

+{
+return x + 1;
+}
+
  /* Include the auto-generated decoders.  */
  #include "decode-micromips16.c.inc"
  #include "decode-micromips32.c.inc"
+
+static bool trans_LSA(DisasContext *ctx, arg_r *a)
+{
+return gen_lsa(ctx, a->rd, a->rt, a->rs, a->sa);
+}
diff --git a/target/mips/tcg/micromips_translate.c.inc 
b/target/mips/tcg/micromips_translate.c.inc
index e8ec5a0ff2..4b4550872f 100644
--- a/target/mips/tcg/micromips_translate.c.inc
+++ b/target/mips/tcg/micromips_translate.c.inc
@@ -191,7 +191,6 @@ enum {
  /* The following can be distinguished by their lower 6 bits. */
  BREAK32 = 0x07,
  INS = 0x0c,
-LSA = 0x0f,
  ALIGN = 0x1f,
  EXT = 0x2c,
  POOL32AXF = 0x3c,
@@ -1793,10 +1792,6 @@ static void decode_micromips32_opc(CPUMIPSState *env, 
DisasContext *ctx)
  case INS:
  gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
  return;
-case LSA:
-check_insn(ctx, ISA_MIPS_R6);
-gen_lsa(ctx, rd, rt, rs, extract32(ctx->opcode, 9, 2) + 1);
-break;
  case ALIGN:
  check_insn(ctx, ISA_MIPS_R6);
  gen_align(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 9, 2));





Re: [PATCH v2 6/7] hostmem: Handle remapping of RAM

2024-11-12 Thread William Roche

On 11/12/24 14:45, David Hildenbrand wrote:

On 07.11.24 11:21, “William Roche wrote:

From: David Hildenbrand 

Let's register a RAM block notifier and react on remap notifications.
Simply re-apply the settings. Warn only when something goes wrong.

Note: qemu_ram_remap() will not remap when RAM_PREALLOC is set. Could be
that hostmem is still missing to update that flag ...

Signed-off-by: David Hildenbrand 
Signed-off-by: William Roche 
---
  backends/hostmem.c   | 29 +
  include/sysemu/hostmem.h |  1 +
  2 files changed, 30 insertions(+)

diff --git a/backends/hostmem.c b/backends/hostmem.c
index bf85d716e5..fbd8708664 100644
--- a/backends/hostmem.c
+++ b/backends/hostmem.c
@@ -361,11 +361,32 @@ static void 
host_memory_backend_set_prealloc_threads(Object *obj, Visitor *v,

  backend->prealloc_threads = value;
  }
+static void host_memory_backend_ram_remapped(RAMBlockNotifier *n, 
void *host,

+ size_t offset, size_t size)
+{
+    HostMemoryBackend *backend = container_of(n, HostMemoryBackend,
+  ram_notifier);
+    Error *err = NULL;
+
+    if (!host_memory_backend_mr_inited(backend) ||
+    memory_region_get_ram_ptr(&backend->mr) != host) {
+    return;
+    }
+
+    host_memory_backend_apply_settings(backend, host + offset, size, 
&err);

+    if (err) {
+    warn_report_err(err);


I wonder if we want to fail hard instead, or have a way to tell the 
notifier that something wen wrong.




It depends on what the caller would do with this information. Is there a 
way to workaround the problem ? (I don't think so)

Can the VM continue to run without doing anything about it ? (Maybe?)

Currently all numa notifiers don't return errors.

This function is only called from ram_block_notify_remap() in 
qemu_ram_remap(), I would vote for a "fail hard" in case where the 
settings are mandatory to continue.


HTH.



[PATCH 09/20] hw/net/xilinx_ethlite: Introduce txbuf_ptr() helper

2024-11-12 Thread Philippe Mathieu-Daudé
txbuf_ptr() points to the beginning of a (RAM) TX buffer
within the device state.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/net/xilinx_ethlite.c | 13 ++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c
index fe91891310..d4882f43f7 100644
--- a/hw/net/xilinx_ethlite.c
+++ b/hw/net/xilinx_ethlite.c
@@ -87,12 +87,18 @@ static inline void eth_pulse_irq(XlnxXpsEthLite *s)
 }
 }
 
-__attribute__((unused))
 static unsigned addr_to_port_index(hwaddr addr)
 {
 return extract64(addr, 11, 1);
 }
 
+static void *txbuf_ptr(XlnxXpsEthLite *s, unsigned port_index)
+{
+unsigned int rxbase = port_index * (0x800 / 4);
+
+return &s->regs[rxbase + R_TX_BUF0];
+}
+
 static uint64_t
 eth_read(void *opaque, hwaddr addr, unsigned int size)
 {
@@ -125,6 +131,7 @@ eth_write(void *opaque, hwaddr addr,
   uint64_t val64, unsigned int size)
 {
 XlnxXpsEthLite *s = opaque;
+unsigned int port_index = addr_to_port_index(addr);
 unsigned int base = 0;
 uint32_t value = val64;
 
@@ -138,12 +145,12 @@ eth_write(void *opaque, hwaddr addr,
 
 if ((value & (CTRL_P | CTRL_S)) == CTRL_S) {
 qemu_send_packet(qemu_get_queue(s->nic),
- (void *) &s->regs[base],
+ txbuf_ptr(s, port_index),
  s->regs[base + R_TX_LEN0]);
 if (s->regs[base + R_TX_CTRL0] & CTRL_I)
 eth_pulse_irq(s);
 } else if ((value & (CTRL_P | CTRL_S)) == (CTRL_P | CTRL_S)) {
-memcpy(&s->conf.macaddr.a[0], &s->regs[base], 6);
+memcpy(&s->conf.macaddr.a[0], txbuf_ptr(s, port_index), 6);
 if (s->regs[base + R_TX_CTRL0] & CTRL_I)
 eth_pulse_irq(s);
 }
-- 
2.45.2




[PATCH 04/20] hw/net/xilinx_ethlite: Update QOM style

2024-11-12 Thread Philippe Mathieu-Daudé
Use XlnxXpsEthLite typedef, OBJECT_DECLARE_SIMPLE_TYPE macro;
convert type_init() to DEFINE_TYPES().

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/net/xilinx_ethlite.c | 48 +++--
 1 file changed, 22 insertions(+), 26 deletions(-)

diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c
index 2b52597f03..0f59811c78 100644
--- a/hw/net/xilinx_ethlite.c
+++ b/hw/net/xilinx_ethlite.c
@@ -53,10 +53,9 @@
 #define CTRL_S 0x1
 
 #define TYPE_XILINX_ETHLITE "xlnx.xps-ethernetlite"
-DECLARE_INSTANCE_CHECKER(struct xlx_ethlite, XILINX_ETHLITE,
- TYPE_XILINX_ETHLITE)
+OBJECT_DECLARE_SIMPLE_TYPE(XlnxXpsEthLite, XILINX_ETHLITE)
 
-struct xlx_ethlite
+struct XlnxXpsEthLite
 {
 SysBusDevice parent_obj;
 
@@ -73,7 +72,7 @@ struct xlx_ethlite
 uint32_t regs[R_MAX];
 };
 
-static inline void eth_pulse_irq(struct xlx_ethlite *s)
+static inline void eth_pulse_irq(XlnxXpsEthLite *s)
 {
 /* Only the first gie reg is active.  */
 if (s->regs[R_TX_GIE0] & GIE_GIE) {
@@ -84,7 +83,7 @@ static inline void eth_pulse_irq(struct xlx_ethlite *s)
 static uint64_t
 eth_read(void *opaque, hwaddr addr, unsigned int size)
 {
-struct xlx_ethlite *s = opaque;
+XlnxXpsEthLite *s = opaque;
 uint32_t r = 0;
 
 addr >>= 2;
@@ -112,7 +111,7 @@ static void
 eth_write(void *opaque, hwaddr addr,
   uint64_t val64, unsigned int size)
 {
-struct xlx_ethlite *s = opaque;
+XlnxXpsEthLite *s = opaque;
 unsigned int base = 0;
 uint32_t value = val64;
 
@@ -176,7 +175,7 @@ static const MemoryRegionOps eth_ops = {
 
 static bool eth_can_rx(NetClientState *nc)
 {
-struct xlx_ethlite *s = qemu_get_nic_opaque(nc);
+XlnxXpsEthLite *s = qemu_get_nic_opaque(nc);
 unsigned int rxbase = s->rxbuf * (0x800 / 4);
 
 return !(s->regs[rxbase + R_RX_CTRL0] & CTRL_S);
@@ -184,7 +183,7 @@ static bool eth_can_rx(NetClientState *nc)
 
 static ssize_t eth_rx(NetClientState *nc, const uint8_t *buf, size_t size)
 {
-struct xlx_ethlite *s = qemu_get_nic_opaque(nc);
+XlnxXpsEthLite *s = qemu_get_nic_opaque(nc);
 unsigned int rxbase = s->rxbuf * (0x800 / 4);
 
 /* DA filter.  */
@@ -214,7 +213,7 @@ static ssize_t eth_rx(NetClientState *nc, const uint8_t 
*buf, size_t size)
 
 static void xilinx_ethlite_reset(DeviceState *dev)
 {
-struct xlx_ethlite *s = XILINX_ETHLITE(dev);
+XlnxXpsEthLite *s = XILINX_ETHLITE(dev);
 
 s->rxbuf = 0;
 }
@@ -228,7 +227,7 @@ static NetClientInfo net_xilinx_ethlite_info = {
 
 static void xilinx_ethlite_realize(DeviceState *dev, Error **errp)
 {
-struct xlx_ethlite *s = XILINX_ETHLITE(dev);
+XlnxXpsEthLite *s = XILINX_ETHLITE(dev);
 
 qemu_macaddr_default_if_unset(&s->conf.macaddr);
 s->nic = qemu_new_nic(&net_xilinx_ethlite_info, &s->conf,
@@ -239,7 +238,7 @@ static void xilinx_ethlite_realize(DeviceState *dev, Error 
**errp)
 
 static void xilinx_ethlite_init(Object *obj)
 {
-struct xlx_ethlite *s = XILINX_ETHLITE(obj);
+XlnxXpsEthLite *s = XILINX_ETHLITE(obj);
 
 sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
 
@@ -249,9 +248,9 @@ static void xilinx_ethlite_init(Object *obj)
 }
 
 static Property xilinx_ethlite_properties[] = {
-DEFINE_PROP_UINT32("tx-ping-pong", struct xlx_ethlite, c_tx_pingpong, 1),
-DEFINE_PROP_UINT32("rx-ping-pong", struct xlx_ethlite, c_rx_pingpong, 1),
-DEFINE_NIC_PROPERTIES(struct xlx_ethlite, conf),
+DEFINE_PROP_UINT32("tx-ping-pong", XlnxXpsEthLite, c_tx_pingpong, 1),
+DEFINE_PROP_UINT32("rx-ping-pong", XlnxXpsEthLite, c_rx_pingpong, 1),
+DEFINE_NIC_PROPERTIES(XlnxXpsEthLite, conf),
 DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -264,17 +263,14 @@ static void xilinx_ethlite_class_init(ObjectClass *klass, 
void *data)
 device_class_set_props(dc, xilinx_ethlite_properties);
 }
 
-static const TypeInfo xilinx_ethlite_info = {
-.name  = TYPE_XILINX_ETHLITE,
-.parent= TYPE_SYS_BUS_DEVICE,
-.instance_size = sizeof(struct xlx_ethlite),
-.instance_init = xilinx_ethlite_init,
-.class_init= xilinx_ethlite_class_init,
+static const TypeInfo xilinx_ethlite_types[] = {
+{
+.name  = TYPE_XILINX_ETHLITE,
+.parent= TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(XlnxXpsEthLite),
+.instance_init = xilinx_ethlite_init,
+.class_init= xilinx_ethlite_class_init,
+},
 };
 
-static void xilinx_ethlite_register_types(void)
-{
-type_register_static(&xilinx_ethlite_info);
-}
-
-type_init(xilinx_ethlite_register_types)
+DEFINE_TYPES(xilinx_ethlite_types)
-- 
2.45.2




[PATCH v3 4/4] target/mips: Enable MSA ASE for mips64R2-generic

2024-11-12 Thread Aleksandar Rakic
Enable MSA ASE for mips64R2-generic CPU.

Cherry-picked 60f6ae8d3d685ba1ea5d301222fb72b67f39264f
from  https://github.com/MIPS/gnutools-qemu

Signed-off-by: Faraz Shahbazker 
Signed-off-by: Aleksandar Rakic 
---
 target/mips/cpu-defs.c.inc | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/target/mips/cpu-defs.c.inc b/target/mips/cpu-defs.c.inc
index 922fc39138..e77a327422 100644
--- a/target/mips/cpu-defs.c.inc
+++ b/target/mips/cpu-defs.c.inc
@@ -678,7 +678,9 @@ const mips_def_t mips_defs[] =
(2 << CP0C1_DS) | (4 << CP0C1_DL) | (3 << CP0C1_DA) |
(1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP),
 .CP0_Config2 = MIPS_CONFIG2,
-.CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_LPA),
+.CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_LPA) |
+   (1 << CP0C3_VInt) | (1 << CP0C3_MSAP),
+.CP0_Config5_rw_bitmask = (1 << CP0C5_MSAEn),
 .CP0_LLAddr_rw_bitmask = 0,
 .CP0_LLAddr_shift = 0,
 .SYNCI_Step = 32,
-- 
2.34.1




Re: [PATCH v2 1/7] accel/kvm: Keep track of the HWPoisonPage page_size

2024-11-12 Thread David Hildenbrand

On 12.11.24 19:17, William Roche wrote:

On 11/12/24 11:30, David Hildenbrand wrote:

On 07.11.24 11:21, “William Roche wrote:

From: William Roche 

When a memory page is added to the hwpoison_page_list, include
the page size information.  This size is the backend real page
size. To better deal with hugepages, we create a single entry
for the entire page.

Signed-off-by: William Roche 
---
   accel/kvm/kvm-all.c   |  8 +++-
   include/exec/cpu-common.h |  1 +
   system/physmem.c  | 13 +
   3 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 801cff16a5..6dd06f5edf 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -1266,6 +1266,7 @@ int kvm_vm_check_extension(KVMState *s, unsigned
int extension)
    */
   typedef struct HWPoisonPage {
   ram_addr_t ram_addr;
+    size_t page_size;
   QLIST_ENTRY(HWPoisonPage) list;
   } HWPoisonPage;
@@ -1278,7 +1279,7 @@ static void kvm_unpoison_all(void *param)
   QLIST_FOREACH_SAFE(page, &hwpoison_page_list, list, next_page) {
   QLIST_REMOVE(page, list);
-    qemu_ram_remap(page->ram_addr, TARGET_PAGE_SIZE);
+    qemu_ram_remap(page->ram_addr, page->page_size);
   g_free(page);


I'm curious, can't we simply drop the size parameter from qemu_ram_remap()
completely and determine the page size internally from the RAMBlock that
we are looking up already?

This way, we avoid yet another lookup in qemu_ram_pagesize_from_addr(),
and can just handle it completely in qemu_ram_remap().

In particular, to be future proof, we should also align the offset down to
the pagesize.

I'm thinking about something like this:

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 801cff16a5..8a47aa7258 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -1278,7 +1278,7 @@ static void kvm_unpoison_all(void *param)

   QLIST_FOREACH_SAFE(page, &hwpoison_page_list, list, next_page) {
   QLIST_REMOVE(page, list);
-    qemu_ram_remap(page->ram_addr, TARGET_PAGE_SIZE);
+    qemu_ram_remap(page->ram_addr);
   g_free(page);
   }
   }
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 638dc806a5..50a829d31f 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -67,7 +67,7 @@ typedef uintptr_t ram_addr_t;

   /* memory API */

-void qemu_ram_remap(ram_addr_t addr, ram_addr_t length);
+void qemu_ram_remap(ram_addr_t addr);
   /* This should not be used by devices.  */
   ram_addr_t qemu_ram_addr_from_host(void *ptr);
   ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr);
diff --git a/system/physmem.c b/system/physmem.c
index dc1db3a384..5f19bec089 100644
--- a/system/physmem.c
+++ b/system/physmem.c
@@ -2167,10 +2167,10 @@ void qemu_ram_free(RAMBlock *block)
   }

   #ifndef _WIN32
-void qemu_ram_remap(ram_addr_t addr, ram_addr_t length)
+void qemu_ram_remap(ram_addr_t addr)
   {
   RAMBlock *block;
-    ram_addr_t offset;
+    ram_addr_t offset, length;
   int flags;
   void *area, *vaddr;
   int prot;
@@ -2178,6 +2178,10 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t
length)
   RAMBLOCK_FOREACH(block) {
   offset = addr - block->offset;
   if (offset < block->max_length) {
+    /* Respect the pagesize of our RAMBlock. */
+    offset = QEMU_ALIGN_DOWN(offset, qemu_ram_pagesize(block));
+    length = qemu_ram_pagesize(block);
+
   vaddr = ramblock_ptr(block, offset);
   if (block->flags & RAM_PREALLOC) {
   ;
@@ -2206,6 +2210,8 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t
length)
   memory_try_enable_merging(vaddr, length);
   qemu_ram_setup_dump(vaddr, length);
   }
+
+    break;
   }
   }
   }





Yes this is a working possibility, and as you say it would provide the
advantage to avoid a size lookup (needed because the kernel siginfo can
be incorrect) and avoid tracking the poisoned pages size, with the
addresses.

> > But if we want to keep the information about the loss of a large page

(which I think is useful) we would have to introduce the page size
lookup when adding the page to the poison list. So according to me,


Right, that would be independent of the remap logic.

What I dislike about qemu_ram_remap() is that it looks like we could be 
remapping a range that's possibly larger than a single page.


But it really only works on a single address, expanding that to the 
page. Passing in a length that crosses RAMBlocks would not work as 
expected ...


So I'd prefer if we let qemu_ram_remap() do exactly that ... remap a 
single page ...



keeping track of the page size and reusing it on remap isn't so bad. But
if you prefer that we don't track the page size and do a lookup on page
insert into the poison list and another in qemu_ram_remap(), of course
we can do that.


... and lookup the page 

[PATCH 0/2] Add RW support for 4k sector size vhdx

2024-11-12 Thread Takeshi Suzuki
The first patch adds support to read and write VHDX images with 4k logical
sector sizes. This is done by internally converting bdrv sectors of size 512 to
logical sectors. VHDX image creation with 4k logical sector size is NOT
implemented.

The second patch adds an iotest which reads and writes to a VHDX image with 4k
logical sector size.

Takeshi Suzuki (2):
  Add RW support for 4k sector size vhdx
  Add iotest for 4k sector size vhdx

 block/vhdx.c |  76 +--
 tests/qemu-iotests/315   |  65 
 tests/qemu-iotests/315.out   |  20 +
 tests/qemu-iotests/sample_images/4k.vhdx.bz2 | Bin 0 -> 37834 bytes
 4 files changed, 155 insertions(+), 6 deletions(-)
 create mode 100644 tests/qemu-iotests/315
 create mode 100644 tests/qemu-iotests/315.out
 create mode 100644 tests/qemu-iotests/sample_images/4k.vhdx.bz2

-- 
2.34.1




[PATCH 2/2] Add iotest for 4k sector size vhdx

2024-11-12 Thread Takeshi Suzuki
See
https://github.com/takeshibaconsuzuki/qemu/blob/vhdx_4k_rw/tests/qemu-iotests/sample_images/4k.vhdx.bz2
for binary file.

Signed-off-by: Takeshi Suzuki 
---
 tests/qemu-iotests/315   |  65 +++
 tests/qemu-iotests/315.out   |  20 ++
 tests/qemu-iotests/sample_images/4k.vhdx.bz2 | Bin 0 -> 37834 bytes
 3 files changed, 85 insertions(+)
 create mode 100644 tests/qemu-iotests/315
 create mode 100644 tests/qemu-iotests/315.out
 create mode 100644 tests/qemu-iotests/sample_images/4k.vhdx.bz2

diff --git a/tests/qemu-iotests/315 b/tests/qemu-iotests/315
new file mode 100644
index 00..e5c4978c8c
--- /dev/null
+++ b/tests/qemu-iotests/315
@@ -0,0 +1,65 @@
+#!/usr/bin/env bash
+# group: rw quick
+#
+# Test VHDX read/write from a 4k sector size sample image created with Hyper-V
+#
+# Copyright (C) 2013 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see .
+#
+
+# creator
+owner=takeshibaconsuz...@gmail.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+status=1   # failure is the default!
+
+_cleanup()
+{
+_cleanup_test_img
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_supported_fmt vhdx
+_supported_proto generic
+_supported_os Linux
+
+_use_sample_img 4k.vhdx.bz2
+
+echo
+echo "=== Verify pattern 0xaa, 1024MB - 1088MB ==="
+$QEMU_IO -r -c "read -pP 0xaa 1024M 64M" "$TEST_IMG" | _filter_qemu_io
+echo
+echo "=== Verify pattern 0x00, 1088MB - 1152MB ==="
+$QEMU_IO -r -c "read -pP 0x00 1088M 64M" "$TEST_IMG" | _filter_qemu_io
+
+echo
+echo "=== Verify pattern write, 0xbb 1072MB - 1104MB ==="
+$QEMU_IO -c "write -pP 0xbb 1072M 32M" "$TEST_IMG" | _filter_qemu_io
+# first verify we didn't write where we should not have
+$QEMU_IO -r -c "read -pP 0xaa 1024M 48M" "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -r -c "read -pP 0x00 1104M 48M" "$TEST_IMG" | _filter_qemu_io
+# now verify what we should have actually written
+$QEMU_IO -r -c "read -pP 0xbb 1072M 32M" "$TEST_IMG" | _filter_qemu_io
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/315.out b/tests/qemu-iotests/315.out
new file mode 100644
index 00..31dd48b223
--- /dev/null
+++ b/tests/qemu-iotests/315.out
@@ -0,0 +1,20 @@
+QA output created by 315
+
+=== Verify pattern 0xaa, 1024MB - 1088MB ===
+read 67108864/67108864 bytes at offset 1073741824
+64 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+=== Verify pattern 0x00, 1088MB - 1152MB ===
+read 67108864/67108864 bytes at offset 1140850688
+64 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+=== Verify pattern write, 0xbb 1072MB - 1104MB ===
+wrote 33554432/33554432 bytes at offset 1124073472
+32 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 50331648/50331648 bytes at offset 1073741824
+48 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 50331648/50331648 bytes at offset 1157627904
+48 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 33554432/33554432 bytes at offset 1124073472
+32 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+*** done
diff --git a/tests/qemu-iotests/sample_images/4k.vhdx.bz2 
b/tests/qemu-iotests/sample_images/4k.vhdx.bz2
new file mode 100644
index 00..6cc10919ab
Binary files /dev/null and b/tests/qemu-iotests/sample_images/4k.vhdx.bz2 differ
-- 
2.34.1




[PATCH 1/2] Add RW support for 4k sector size vhdx

2024-11-12 Thread Takeshi Suzuki
Signed-off-by: Takeshi Suzuki 
---
 block/vhdx.c | 76 +++-
 1 file changed, 70 insertions(+), 6 deletions(-)

diff --git a/block/vhdx.c b/block/vhdx.c
index 5aa1a13506..495ddc2815 100644
--- a/block/vhdx.c
+++ b/block/vhdx.c
@@ -824,8 +824,8 @@ vhdx_parse_metadata(BlockDriverState *bs, BDRVVHDXState *s)
 goto exit;
 }
 
-/* Currently we only support 512 */
-if (s->logical_sector_size != 512) {
+/* Currently we only support 512 and 4096 */
+if (s->logical_sector_size != 512 && s->logical_sector_size != 4096) {
 ret = -ENOTSUP;
 goto exit;
 }
@@ -1060,7 +1060,7 @@ static int vhdx_open(BlockDriverState *bs, QDict 
*options, int flags,
 
 /* the VHDX spec dictates that virtual_disk_size is always a multiple of
  * logical_sector_size */
-bs->total_sectors = s->virtual_disk_size >> s->logical_sector_size_bits;
+bs->total_sectors = s->virtual_disk_size >> BDRV_SECTOR_BITS;
 
 vhdx_calc_bat_entries(s);
 
@@ -1178,11 +1178,52 @@ vhdx_co_get_info(BlockDriverState *bs, BlockDriverInfo 
*bdi)
 }
 
 
+/*
+ * Converts bdrv sectors to sectors of s->logical_sector_size.
+ */
+static void bdrv_sectors_to_sectors(const int64_t bdrv_sector_num,
+const int bdrv_nb_sectors,
+const BDRVVHDXState *const s,
+int64_t * const out_sector_num,
+int * const out_nb_sectors,
+/* in bytes */
+int * const out_begin_skip,
+/* in bytes */
+int * const out_end_skip) {
+if (bdrv_nb_sectors == 0) {
+*out_nb_sectors = 0;
+return;
+}
+const int64_t begin_off = bdrv_sector_num * BDRV_SECTOR_SIZE;
+const int64_t sector_num = begin_off >> s->logical_sector_size_bits;
+const int begin_skip = begin_off - sector_num * s->logical_sector_size;
+const int64_t end_off = (bdrv_sector_num + bdrv_nb_sectors) *
+BDRV_SECTOR_SIZE;
+const int64_t end_sector_num = (end_off + s->logical_sector_size - 1) >>
+   s->logical_sector_size_bits;
+const int end_skip = end_sector_num * s->logical_sector_size - end_off;
+const int nb_sectors = end_sector_num - sector_num;
+*out_sector_num = sector_num;
+*out_nb_sectors = nb_sectors;
+*out_begin_skip = begin_skip;
+*out_end_skip = end_skip;
+}
+
+
 static int coroutine_fn GRAPH_RDLOCK
 vhdx_co_readv(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
   QEMUIOVector *qiov)
 {
 BDRVVHDXState *s = bs->opaque;
+int begin_skip, end_skip;
+bdrv_sectors_to_sectors(sector_num,
+nb_sectors,
+s,
+§or_num,
+&nb_sectors,
+&begin_skip,
+&end_skip);
+
 int ret = 0;
 VHDXSectorInfo sinfo;
 uint64_t bytes_done = 0;
@@ -1216,9 +1257,16 @@ vhdx_co_readv(BlockDriverState *bs, int64_t sector_num, 
int nb_sectors,
 qemu_iovec_memset(&hd_qiov, 0, 0, sinfo.bytes_avail);
 break;
 case PAYLOAD_BLOCK_FULLY_PRESENT:
+if (bytes_done == 0) {
+sinfo.file_offset += begin_skip;
+sinfo.bytes_avail -= begin_skip;
+}
+if (nb_sectors - sinfo.sectors_avail <= 0) {
+sinfo.bytes_avail -= end_skip;
+}
 qemu_co_mutex_unlock(&s->lock);
 ret = bdrv_co_preadv(bs->file, sinfo.file_offset,
- sinfo.sectors_avail * BDRV_SECTOR_SIZE,
+ sinfo.bytes_avail,
  &hd_qiov, 0);
 qemu_co_mutex_lock(&s->lock);
 if (ret < 0) {
@@ -1336,8 +1384,17 @@ static int coroutine_fn GRAPH_RDLOCK
 vhdx_co_writev(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
QEMUIOVector *qiov, int flags)
 {
-int ret = -ENOTSUP;
 BDRVVHDXState *s = bs->opaque;
+int begin_skip, end_skip;
+bdrv_sectors_to_sectors(sector_num,
+nb_sectors,
+s,
+§or_num,
+&nb_sectors,
+&begin_skip,
+&end_skip);
+
+int ret = -ENOTSUP;
 VHDXSectorInfo sinfo;
 uint64_t bytes_done = 0;
 uint64_t bat_entry = 0;
@@ -1451,9 +1508,16 @@ vhdx_co_writev(BlockDriverState *bs, int64_t sector_num, 
int nb_sectors,
   sinfo.bytes_avail);
 }
 /* block exists, so we can just overwrite it */
+   

Re: [PATCH v3 4/4] target/mips: Enable MSA ASE for mips64R2-generic

2024-11-12 Thread Philippe Mathieu-Daudé

On 12/11/24 16:41, Aleksandar Rakic wrote:

Enable MSA ASE for mips64R2-generic CPU.

Cherry-picked 60f6ae8d3d685ba1ea5d301222fb72b67f39264f
from  https://github.com/MIPS/gnutools-qemu

Signed-off-by: Faraz Shahbazker 
Signed-off-by: Aleksandar Rakic 
---
  target/mips/cpu-defs.c.inc | 4 +++-
  1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/target/mips/cpu-defs.c.inc b/target/mips/cpu-defs.c.inc
index 922fc39138..e77a327422 100644
--- a/target/mips/cpu-defs.c.inc
+++ b/target/mips/cpu-defs.c.inc
@@ -678,7 +678,9 @@ const mips_def_t mips_defs[] =
 (2 << CP0C1_DS) | (4 << CP0C1_DL) | (3 << CP0C1_DA) |
 (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP),
  .CP0_Config2 = MIPS_CONFIG2,
-.CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_LPA),
+.CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_LPA) |
+   (1 << CP0C3_VInt) | (1 << CP0C3_MSAP),
+.CP0_Config5_rw_bitmask = (1 << CP0C5_MSAEn),


See v2:
https://lore.kernel.org/qemu-devel/50dd60b2-f789-4828-9a7e-3becc6721...@linaro.org/


  .CP0_LLAddr_rw_bitmask = 0,
  .CP0_LLAddr_shift = 0,
  .SYNCI_Step = 32,





[PATCH 1/6] linux-user: Honor elf alignment when placing images

2024-11-12 Thread Richard Henderson
Most binaries don't actually depend on more than page alignment,
but any binary can request it.  Not honoring this was a bug.

This became obvious when gdb reported

Failed to read a valid object file image from memory

when examining some vdso which are marked as needing more
than page alignment.

Signed-off-by: Richard Henderson 
---
 linux-user/elfload.c | 35 ---
 1 file changed, 28 insertions(+), 7 deletions(-)

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index d6ad77d27d..90e79a01b4 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -3179,7 +3179,8 @@ static void load_elf_image(const char *image_name, const 
ImageSource *src,
char **pinterp_name)
 {
 g_autofree struct elf_phdr *phdr = NULL;
-abi_ulong load_addr, load_bias, loaddr, hiaddr, error;
+abi_ulong load_addr, load_bias, loaddr, hiaddr, error, align;
+size_t reserve_size, align_size;
 int i, prot_exec;
 Error *err = NULL;
 
@@ -3263,6 +3264,9 @@ static void load_elf_image(const char *image_name, const 
ImageSource *src,
 
 load_addr = loaddr;
 
+align = pow2ceil(info->alignment);
+info->alignment = align;
+
 if (pinterp_name != NULL) {
 if (ehdr->e_type == ET_EXEC) {
 /*
@@ -3271,8 +3275,6 @@ static void load_elf_image(const char *image_name, const 
ImageSource *src,
  */
 probe_guest_base(image_name, loaddr, hiaddr);
 } else {
-abi_ulong align;
-
 /*
  * The binary is dynamic, but we still need to
  * select guest_base.  In this case we pass a size.
@@ -3290,10 +3292,7 @@ static void load_elf_image(const char *image_name, const 
ImageSource *src,
  * Since we do not have complete control over the guest
  * address space, we prefer the kernel to choose some address
  * rather than force the use of LOAD_ADDR via MAP_FIXED.
- * But without MAP_FIXED we cannot guarantee alignment,
- * only suggest it.
  */
-align = pow2ceil(info->alignment);
 if (align) {
 load_addr &= -align;
 }
@@ -3317,13 +3316,35 @@ static void load_elf_image(const char *image_name, 
const ImageSource *src,
  * In both cases, we will overwrite pages in this range with mappings
  * from the executable.
  */
-load_addr = target_mmap(load_addr, (size_t)hiaddr - loaddr + 1, PROT_NONE,
+reserve_size = (size_t)hiaddr - loaddr + 1;
+align_size = reserve_size;
+
+if (ehdr->e_type != ET_EXEC && align > qemu_real_host_page_size()) {
+align_size += align - 1;
+}
+
+load_addr = target_mmap(load_addr, align_size, PROT_NONE,
 MAP_PRIVATE | MAP_ANON | MAP_NORESERVE |
 (ehdr->e_type == ET_EXEC ? MAP_FIXED_NOREPLACE : 
0),
 -1, 0);
 if (load_addr == -1) {
 goto exit_mmap;
 }
+
+if (align_size != reserve_size) {
+abi_ulong align_addr = ROUND_UP(load_addr, align);
+abi_ulong align_end = align_addr + reserve_size;
+abi_ulong load_end = load_addr + align_size;
+
+if (align_addr != load_addr) {
+target_munmap(load_addr, align_addr - load_addr);
+}
+if (align_end != load_end) {
+target_munmap(align_end, load_end - align_end);
+}
+load_addr = align_addr;
+}
+
 load_bias = load_addr - loaddr;
 
 if (elf_is_fdpic(ehdr)) {
-- 
2.43.0




[PATCH 3/6] linux-user/aarch64: Reduce vdso alignment to 4k

2024-11-12 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/aarch64/Makefile.vdso |   5 +++--
 linux-user/aarch64/vdso-be.so| Bin 3224 -> 3224 bytes
 linux-user/aarch64/vdso-le.so| Bin 3224 -> 3224 bytes
 3 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/linux-user/aarch64/Makefile.vdso b/linux-user/aarch64/Makefile.vdso
index 599958116b..c33a679c0f 100644
--- a/linux-user/aarch64/Makefile.vdso
+++ b/linux-user/aarch64/Makefile.vdso
@@ -5,8 +5,9 @@ VPATH += $(SUBDIR)
 
 all: $(SUBDIR)/vdso-be.so $(SUBDIR)/vdso-le.so
 
-LDFLAGS = -nostdlib -shared -Wl,-h,linux-vdso.so.1 -Wl,--build-id=sha1 \
- -Wl,--hash-style=both -Wl,-T,$(SUBDIR)/vdso.ld
+LDFLAGS = -nostdlib -shared -Wl,-h,linux-vdso.so.1 \
+ -Wl,--build-id=sha1 -Wl,--hash-style=both \
+ -Wl,-z,max-page-size=4096 -Wl,-T,$(SUBDIR)/vdso.ld
 
 $(SUBDIR)/vdso-be.so: vdso.S vdso.ld
$(CC) -o $@ $(LDFLAGS) -mbig-endian $<
diff --git a/linux-user/aarch64/vdso-be.so b/linux-user/aarch64/vdso-be.so
index 
808206ade824b09d786f6cc34f7cddf80b63130e..d43c3b19cdf6588757f2039f2308a8bce21aed9c
 100755
GIT binary patch
delta 50
zcmV-20L}lH8JHQ6tpWfLk+0bl4vUoZ1rE*XtsXbvz!6Y1qE4ha#lpM
HaR(;_22&J+

delta 49
zcmV-10M7rI8JHQ6sR952k*nPl^~i=KtbcHFtl42<9TUsw2PpfHvz!6Y1qD@cX=ik^
HaR(;_8o3m&

-- 
2.43.0




[PATCH 6/6] linux-user/ppc: Reduce vdso alignment to 4k

2024-11-12 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/ppc/Makefile.vdso |   6 --
 linux-user/ppc/vdso-32.so| Bin 3020 -> 3020 bytes
 linux-user/ppc/vdso-64.so| Bin 3896 -> 3896 bytes
 linux-user/ppc/vdso-64le.so  | Bin 3896 -> 3896 bytes
 4 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/linux-user/ppc/Makefile.vdso b/linux-user/ppc/Makefile.vdso
index 3ca3c6b83e..e2b8facbb5 100644
--- a/linux-user/ppc/Makefile.vdso
+++ b/linux-user/ppc/Makefile.vdso
@@ -6,9 +6,11 @@ VPATH += $(SUBDIR)
 all: $(SUBDIR)/vdso-32.so $(SUBDIR)/vdso-64.so $(SUBDIR)/vdso-64le.so
 
 LDFLAGS32 = -nostdlib -shared -Wl,-T,$(SUBDIR)/vdso-32.ld \
--Wl,-h,linux-vdso32.so.1 -Wl,--hash-style=both -Wl,--build-id=sha1
+-Wl,-h,linux-vdso32.so.1 -Wl,--hash-style=both \
+   -Wl,--build-id=sha1 -Wl,-z,max-page-size=4096
 LDFLAGS64 = -nostdlib -shared -Wl,-T,$(SUBDIR)/vdso-64.ld \
--Wl,-h,linux-vdso64.so.1 -Wl,--hash-style=both -Wl,--build-id=sha1
+-Wl,-h,linux-vdso64.so.1 -Wl,--hash-style=both \
+   -Wl,--build-id=sha1 -Wl,-z,max-page-size=4096
 
 $(SUBDIR)/vdso-32.so: vdso.S vdso-32.ld vdso-asmoffset.h
$(CC) -o $@ $(LDFLAGS32) -m32 $<
diff --git a/linux-user/ppc/vdso-32.so b/linux-user/ppc/vdso-32.so
index 
b19baafb0d38e15b4a24def5c44a6d684714be45..0dc55e0dddff618b954dbb939335e99956daf64a
 100755
GIT binary patch
delta 42
zcmV+_0M-A@7t9xsCINtvCrSbU5Rr3n6lq1YQP%3b&XBjV4sl%JXqmbIL$UbO3Tx34
A(f|Me

delta 42
xcmX>jenxzP8Y9C*buT6$SzIX6c=(tjbAN``v6&a|RP{JtzgDQRW#f-4TmVmR5>WsE

diff --git a/linux-user/ppc/vdso-64.so b/linux-user/ppc/vdso-64.so
index 
913c831b3819fc09912b9b31f7fbe9ee311ae12f..ac1ab2582e4675979ffca3ce90dce17df579ab2a
 100755
GIT binary patch
delta 38
wcmV+>0NMYz9=INmtpWfLk*~QFqejR%tq=sGFts+qF9Cf{%e>^#vwQ)(4KYR#WB>pF

delta 38
wcmV+>0NMYz9=INmtpWi6k*~QF<@TF=qRS8+wHM`Qf0n_&>m=ZivwQ)(4PLhrs{jB1

diff --git a/linux-user/ppc/vdso-64le.so b/linux-user/ppc/vdso-64le.so
index 
258a03b807c4eca23547d978c16d1ad5ebd08bc5..424abb4290b7d3100e9dede2f3059483608ba703
 100755
GIT binary patch
delta 38
wcmV+>0NMYz9=INmsR9rHk*mEFj|Vri9^_Z(nV0Nw;)4VN>*aZovwQ)(4Mvj@kpKVy

delta 38
wcmV+>0NMYz9=INmsR952k*mEF`$9%&`;)~jB!C2C?=itIoQ(CfvwQ)(4MbHDMgRZ+

-- 
2.43.0




[PATCH 4/6] linux-user/arm: Reduce vdso alignment to 4k

2024-11-12 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/arm/Makefile.vdso |   2 +-
 linux-user/arm/vdso-be.so| Bin 2648 -> 2648 bytes
 linux-user/arm/vdso-le.so| Bin 2648 -> 2648 bytes
 3 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/linux-user/arm/Makefile.vdso b/linux-user/arm/Makefile.vdso
index 2d098a5748..8a24b0e534 100644
--- a/linux-user/arm/Makefile.vdso
+++ b/linux-user/arm/Makefile.vdso
@@ -6,7 +6,7 @@ VPATH += $(SUBDIR)
 all: $(SUBDIR)/vdso-be.so $(SUBDIR)/vdso-le.so
 
 # Adding -use-blx disables unneeded interworking without actually using blx.
-LDFLAGS = -nostdlib -shared -Wl,-use-blx \
+LDFLAGS = -nostdlib -shared -Wl,-use-blx -Wl,-z,max-page-size=4096 \
  -Wl,-h,linux-vdso.so.1 -Wl,--build-id=sha1 \
  -Wl,--hash-style=both -Wl,-T,$(SUBDIR)/vdso.ld
 
diff --git a/linux-user/arm/vdso-be.so b/linux-user/arm/vdso-be.so
index 
69cafbb956e283e2975bac59a10491c0cbafca57..bed02804a4bd367eb9fd8ca54d0c980103c02245
 100755
GIT binary patch
delta 49
zcmV-10M7r|6xbAyaRLAkk#lhrGQ`BrU>NUTo0WUr&~YvSTwestvG{WZ25D?qS41(h
HaR%oD3DgvN

delta 49
zcmV-10M7r|6xbAyaRLDVk#lhrweyTc_Z*p@&&2@VLR1?$m|vtIvG{WZ23l}Oc}8xt
HaR%oD4;B=<

diff --git a/linux-user/arm/vdso-le.so b/linux-user/arm/vdso-le.so
index 
ad05a1251875ac0c76685e1f9190a7307a8444d1..38d3d51047372391b3125c3f9f6ea5401f04bba1
 100755
GIT binary patch
delta 49
zcmV-10M7r|6xbAyaRLwkk#lhr8{q*880U1i=t7z4dQ|b*DDU}VvG{WZ25CxDZDwh+
HaR%oD5d#(3

delta 49
zcmV-10M7r|6xbAyaRLAVk#lhrkUMV7Jk`NO!6O#urC$6IB@6+uvG{WZ26R_8MpaO=
HaR%oD?$r}}

-- 
2.43.0




[PATCH 5/6] linux-user/loongarch64: Reduce vdso alignment to 4k

2024-11-12 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/loongarch64/Makefile.vdso |   3 ++-
 linux-user/loongarch64/vdso.so   | Bin 3560 -> 3560 bytes
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/linux-user/loongarch64/Makefile.vdso 
b/linux-user/loongarch64/Makefile.vdso
index 369de13344..1d760b1e47 100644
--- a/linux-user/loongarch64/Makefile.vdso
+++ b/linux-user/loongarch64/Makefile.vdso
@@ -8,4 +8,5 @@ all: $(SUBDIR)/vdso.so
 $(SUBDIR)/vdso.so: vdso.S vdso.ld vdso-asmoffset.h
$(CC) -o $@ -nostdlib -shared -fpic -Wl,-h,linux-vdso.so.1 \
  -Wl,--build-id=sha1 -Wl,--hash-style=both \
- -Wl,--no-warn-rwx-segments -Wl,-T,$(SUBDIR)/vdso.ld $<
+ -Wl,--no-warn-rwx-segments -Wl,-z,max-page-size=4096 \
+ -Wl,-T,$(SUBDIR)/vdso.ld $<
diff --git a/linux-user/loongarch64/vdso.so b/linux-user/loongarch64/vdso.so
index 
bfaa26f2bfe1aaa01d9a349b8b030ef6323e1f8e..7c2de6c50e706164225e82f652d4becc04c71ff0
 100755
GIT binary patch
delta 37
tcmaDM{X%-eN=AW+tM-YA3hb&jk8@2

[PATCH for-9.2 0/6] linux-user: Fix elf load and vdso alignment

2024-11-12 Thread Richard Henderson
GDB picked up that we weren't properly honoring alignment.
After fixing that, reduce vdso alignment to minimum page size.


r~


Richard Henderson (6):
  linux-user: Honor elf alignment when placing images
  linux-user: Drop image_info.alignment
  linux-user/aarch64: Reduce vdso alignment to 4k
  linux-user/arm: Reduce vdso alignment to 4k
  linux-user/loongarch64: Reduce vdso alignment to 4k
  linux-user/ppc: Reduce vdso alignment to 4k

 linux-user/qemu.h|   1 -
 linux-user/elfload.c |  38 ---
 linux-user/aarch64/Makefile.vdso |   5 ++--
 linux-user/aarch64/vdso-be.so| Bin 3224 -> 3224 bytes
 linux-user/aarch64/vdso-le.so| Bin 3224 -> 3224 bytes
 linux-user/arm/Makefile.vdso |   2 +-
 linux-user/arm/vdso-be.so| Bin 2648 -> 2648 bytes
 linux-user/arm/vdso-le.so| Bin 2648 -> 2648 bytes
 linux-user/loongarch64/Makefile.vdso |   3 ++-
 linux-user/loongarch64/vdso.so   | Bin 3560 -> 3560 bytes
 linux-user/ppc/Makefile.vdso |   6 +++--
 linux-user/ppc/vdso-32.so| Bin 3020 -> 3020 bytes
 linux-user/ppc/vdso-64.so| Bin 3896 -> 3896 bytes
 linux-user/ppc/vdso-64le.so  | Bin 3896 -> 3896 bytes
 14 files changed, 39 insertions(+), 16 deletions(-)

-- 
2.43.0




[PATCH 2/6] linux-user: Drop image_info.alignment

2024-11-12 Thread Richard Henderson
This field is write-only.  Use only the function-local
variable within load_elf_image.

Signed-off-by: Richard Henderson 
---
 linux-user/qemu.h| 1 -
 linux-user/elfload.c | 7 +++
 2 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index 895bdd722a..67bc81b149 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -44,7 +44,6 @@ struct image_info {
 abi_ulong   file_string;
 uint32_telf_flags;
 int personality;
-abi_ulong   alignment;
 boolexec_stack;
 
 /* Generic semihosting knows about these pointers. */
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 90e79a01b4..ef9cffbe4a 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -3220,7 +3220,7 @@ static void load_elf_image(const char *image_name, const 
ImageSource *src,
  * amount of memory to handle that.  Locate the interpreter, if any.
  */
 loaddr = -1, hiaddr = 0;
-info->alignment = 0;
+align = 0;
 info->exec_stack = EXSTACK_DEFAULT;
 for (i = 0; i < ehdr->e_phnum; ++i) {
 struct elf_phdr *eppnt = phdr + i;
@@ -3234,7 +3234,7 @@ static void load_elf_image(const char *image_name, const 
ImageSource *src,
 hiaddr = a;
 }
 ++info->nsegs;
-info->alignment |= eppnt->p_align;
+align |= eppnt->p_align;
 } else if (eppnt->p_type == PT_INTERP && pinterp_name) {
 g_autofree char *interp_name = NULL;
 
@@ -3264,8 +3264,7 @@ static void load_elf_image(const char *image_name, const 
ImageSource *src,
 
 load_addr = loaddr;
 
-align = pow2ceil(info->alignment);
-info->alignment = align;
+align = pow2ceil(align);
 
 if (pinterp_name != NULL) {
 if (ehdr->e_type == ET_EXEC) {
-- 
2.43.0




Re: [RFC v3 3/3] vhost: Allocate memory for packed vring

2024-11-12 Thread Sahil Siddiq

Hi,

On 10/28/24 11:07 AM, Sahil Siddiq wrote:

[...]
The payload that VHOST_SET_VRING_BASE accepts depends on whether
split virtqueues or packed virtqueues are used [6].  In hw/virtio/vhost-
vdpa.c:vhost_vdpa_svq_setup() [7], the following payload is used which is
not suitable for packed virtqueues:

struct vhost_vring_state s = {
 .index = vq_index,
};

Based on the implementation in the linux kernel, the payload needs to
be as shown below for the ioctl to succeed for packed virtqueues:

struct vhost_vring_state s = {
 .index = vq_index,
 .num = 0x80008000,
};

After making these changes, it looks like QEMU is able to set up the
virtqueues and shadow virtqueues are enabled as well.

Unfortunately, before the L2 VM can finish booting the kernel crashes.
The reason is that even though packed virtqueues are to be used, the
kernel tries to run
drivers/virtio/virtio_ring.c:virtqueue_get_buf_ctx_split() [8]
(instead of virtqueue_get_buf_ctx_packed) and throws an "invalid vring
head" error. I am still investigating this issue.


I made a mistake here. "virtqueue_get_buf_ctx_packed" [1] in the linux
kernel also throws the same error. I think the issue might be because
hw/virtio/vhost-vdpa.c:vhost_vdpa_svq_map_rings [2] does not handle
mapping packed virtqueues at the moment.

Probably because of this, vq->packed.desc_state[id].data [1] is NULL in the
kernel.

Regarding one of the earlier reviews in the same thread [3]:

On 8/7/24 9:52 PM, Eugenio Perez Martin wrote:

On Fri, Aug 2, 2024 at 1:22 PM Sahil Siddiq  wrote:


Allocate memory for the packed vq format and support
packed vq in the SVQ "start" and "stop" operations.

Signed-off-by: Sahil Siddiq 
---
[...]

diff --git a/hw/virtio/vhost-shadow-virtqueue.c 
b/hw/virtio/vhost-shadow-virtqueue.c
index 4c308ee53d..f4285db2b4 100644
--- a/hw/virtio/vhost-shadow-virtqueue.c
+++ b/hw/virtio/vhost-shadow-virtqueue.c
[...]
@@ -672,6 +674,16 @@ size_t vhost_svq_device_area_size(const 
VhostShadowVirtqueue *svq)
  return ROUND_UP(used_size, qemu_real_host_page_size());
  }

+size_t vhost_svq_memory_packed(const VhostShadowVirtqueue *svq)
+{
+size_t desc_size = sizeof(struct vring_packed_desc) * svq->num_free;
+size_t driver_event_suppression = sizeof(struct vring_packed_desc_event);
+size_t device_event_suppression = sizeof(struct vring_packed_desc_event);
+
+return ROUND_UP(desc_size + driver_event_suppression + 
device_event_suppression,
+qemu_real_host_page_size());
+}
+
  /**
   * Set a new file descriptor for the guest to kick the SVQ and notify for 
avail
   *
@@ -726,17 +738,30 @@ void vhost_svq_start(VhostShadowVirtqueue *svq, 
VirtIODevice *vdev,

 svq->vring.num = virtio_queue_get_num(vdev, virtio_get_queue_index(vq));
 svq->num_free = svq->vring.num;
-svq->vring.desc = mmap(NULL, vhost_svq_driver_area_size(svq),
-   PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS,
-   -1, 0);
-desc_size = sizeof(vring_desc_t) * svq->vring.num;
-svq->vring.avail = (void *)((char *)svq->vring.desc + desc_size);
-svq->vring.used = mmap(NULL, vhost_svq_device_area_size(svq),
-   PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS,
-   -1, 0);
-svq->desc_state = g_new0(SVQDescState, svq->vring.num);
-svq->desc_next = g_new0(uint16_t, svq->vring.num);
-for (unsigned i = 0; i < svq->vring.num - 1; i++) {
+svq->is_packed = virtio_vdev_has_feature(svq->vdev, VIRTIO_F_RING_PACKED);
+
+if (virtio_vdev_has_feature(svq->vdev, VIRTIO_F_RING_PACKED)) {
+svq->vring_packed.vring.desc = mmap(NULL, vhost_svq_memory_packed(svq),
+PROT_READ | PROT_WRITE, MAP_SHARED 
| MAP_ANONYMOUS,
+-1, 0);
+desc_size = sizeof(struct vring_packed_desc) * svq->vring.num;
+svq->vring_packed.vring.driver = (void *)((char 
*)svq->vring_packed.vring.desc + desc_size);
+svq->vring_packed.vring.device = (void *)((char 
*)svq->vring_packed.vring.driver +
+  sizeof(struct 
vring_packed_desc_event));


This is a great start but it will be problematic when you start
mapping the areas to the vdpa device. The driver area should be read
only for the device, but it is placed in the same page as a RW one.

More on this later.


+} else {
+svq->vring.desc = mmap(NULL, vhost_svq_driver_area_size(svq),
+   PROT_READ | PROT_WRITE, MAP_SHARED | 
MAP_ANONYMOUS,
+   -1, 0);
+desc_size = sizeof(vring_desc_t) * svq->vring.num;
+svq->vring.avail = (void *)((char *)svq->vring.desc + desc_size);
+svq->vring.used = mmap(NULL, vhost_svq_device_area_size(svq),
+   PROT_READ | PROT_WRITE, MAP_SHARED | 
MAP_ANONYMOUS,
+   -1, 0);

Re: [PATCH v5 17/20] tests/acpi: q35: Update host address width in DMAR

2024-11-12 Thread CLEMENT MATHIEU--DRIF
Hi Zhenzhong,

Ack

 >cmd


On 11/11/2024 09:34, Zhenzhong Duan wrote:
> Caution: External email. Do not open attachments or click links, unless this 
> email comes from a known sender and you know the content is safe.
>
>
> Differences:
>
> @@ -1,39 +1,39 @@
>   /*
>* Intel ACPI Component Architecture
>* AML/ASL+ Disassembler version 20200925 (64-bit version)
>* Copyright (c) 2000 - 2020 Intel Corporation
>*
> - * Disassembly of tests/data/acpi/x86/q35/DMAR.dmar, Mon Nov 11 15:31:18 2024
> + * Disassembly of /tmp/aml-SPJ4W2, Mon Nov 11 15:31:18 2024
>*
>* ACPI Data Table [DMAR]
>*
>* Format: [HexOffset DecimalOffset ByteLength]  FieldName : FieldValue
>*/
>
>   [000h    4]Signature : "DMAR"[DMA Remapping 
> table]
>   [004h 0004   4] Table Length : 0078
>   [008h 0008   1] Revision : 01
> -[009h 0009   1] Checksum : 15
> +[009h 0009   1] Checksum : 0C
>   [00Ah 0010   6]   Oem ID : "BOCHS "
>   [010h 0016   8] Oem Table ID : "BXPC"
>   [018h 0024   4] Oem Revision : 0001
>   [01Ch 0028   4]  Asl Compiler ID : "BXPC"
>   [020h 0032   4]Asl Compiler Revision : 0001
>
> -[024h 0036   1]   Host Address Width : 26
> +[024h 0036   1]   Host Address Width : 2F
>   [025h 0037   1]Flags : 01
>   [026h 0038  10] Reserved : 00 00 00 00 00 00 00 00 00 00
>
>   [030h 0048   2]Subtable Type :  [Hardware Unit 
> Definition]
>   [032h 0050   2]   Length : 0040
>
>   [034h 0052   1]Flags : 00
>   [035h 0053   1] Reserved : 00
>   [036h 0054   2]   PCI Segment Number : 
>   [038h 0056   8]Register Base Address : FED9
>
>   [040h 0064   1]Device Scope Type : 03 [IOAPIC Device]
>   [041h 0065   1] Entry Length : 08
>   [042h 0066   2] Reserved : 
>   [044h 0068   1]   Enumeration ID : 00
>   [045h 0069   1]   PCI Bus Number : FF
>
> Signed-off-by: Zhenzhong Duan 
> ---
>   tests/qtest/bios-tables-test-allowed-diff.h |   1 -
>   tests/data/acpi/x86/q35/DMAR.dmar   | Bin 120 -> 120 bytes
>   2 files changed, 1 deletion(-)
>
> diff --git a/tests/qtest/bios-tables-test-allowed-diff.h 
> b/tests/qtest/bios-tables-test-allowed-diff.h
> index 46f80be9ca..dfb8523c8b 100644
> --- a/tests/qtest/bios-tables-test-allowed-diff.h
> +++ b/tests/qtest/bios-tables-test-allowed-diff.h
> @@ -1,2 +1 @@
>   /* List of comma-separated changed AML files to ignore */
> -"tests/data/acpi/x86/q35/DMAR.dmar",
> diff --git a/tests/data/acpi/x86/q35/DMAR.dmar 
> b/tests/data/acpi/x86/q35/DMAR.dmar
> index 
> 0dca6e68ad8a8ca5b981bcfbc745385a63e9f216..0c05976715c6f2f6ec46ef6d37790f86a392b5ea
>  100644
> GIT binary patch
> delta 21
> ccmb=Z;BxVG460yYU|{5#$R)+7KT$Op05(qqk^lez
>
> delta 21
> ccmb=Z;BxVG460yYU|Sg05*ICk^lez
>
> --
> 2.34.1
>


Re: [RFC PATCH 08/11] rust: build: establish a baseline of lints across all crates

2024-11-12 Thread Junjie Mao


Paolo Bonzini  writes:

> Many lints that default to allow can be helpful in detecting bugs or
> keeping the code style homogeneous.  Add them liberally, though perhaps
> not as liberally as in hw/char/pl011/src/lib.rs.  In particular, enabling
> entire groups can be problematic because of bitrot when new links are
> added in the future.
>
> For Clippy, this is actually a feature that is only present in Cargo
> 1.74.0 but, since we are not using Cargo to *build* QEMU, only developers
> will need a new-enough cargo and only to run tools such as clippy.
> The requirement does not apply to distros that are building QEMU.
>
> Signed-off-by: Paolo Bonzini 
> ---
>  rust/Cargo.toml   | 66 +++
>  rust/hw/char/pl011/src/lib.rs | 18 ++
>  rust/qemu-api/src/bindings.rs |  6 ++--
>  3 files changed, 71 insertions(+), 19 deletions(-)
>
> diff --git a/rust/Cargo.toml b/rust/Cargo.toml
> index 1ff8f5c2781..43cca33a8d8 100644
> --- a/rust/Cargo.toml
> +++ b/rust/Cargo.toml
> @@ -19,3 +19,69 @@ unknown_lints = "allow"
>
>  # Prohibit code that is forbidden in Rust 2024
>  unsafe_op_in_unsafe_fn = "deny"
> +
[snip]
> +
> +# nice to have, but cannot be enabled yet
> +#wildcard_imports = "deny"
> +
> +# these may have false positives
> +#option_if_let_else = "deny"
> +cognitive_complexity = "deny"

Just to confirm, CC <= 25 is to be enforced for all methods, right?

--
Best Regards
Junjie Mao



Re: [PATCH v6 07/60] kvm: Introduce kvm_arch_pre_create_vcpu()

2024-11-12 Thread Philippe Mathieu-Daudé

Hi,

On 5/11/24 06:23, Xiaoyao Li wrote:

Introduce kvm_arch_pre_create_vcpu(), to perform arch-dependent
work prior to create any vcpu. This is for i386 TDX because it needs
call TDX_INIT_VM before creating any vcpu.

Signed-off-by: Xiaoyao Li 
Acked-by: Gerd Hoffmann 
---
Changes in v3:
- pass @errp to kvm_arch_pre_create_vcpu(); (Per Daniel)
---
  accel/kvm/kvm-all.c  | 10 ++
  include/sysemu/kvm.h |  1 +
  2 files changed, 11 insertions(+)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 930a5bfed58f..1732fa1adecd 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -523,6 +523,11 @@ void kvm_destroy_vcpu(CPUState *cpu)
  }
  }
  
+int __attribute__ ((weak)) kvm_arch_pre_create_vcpu(CPUState *cpu, Error **errp)


We don't use the weak attribute. Maybe declare stubs for each arch?


+{
+return 0;
+}
+
  int kvm_init_vcpu(CPUState *cpu, Error **errp)
  {
  KVMState *s = kvm_state;
@@ -531,6 +536,11 @@ int kvm_init_vcpu(CPUState *cpu, Error **errp)
  
  trace_kvm_init_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
  
+ret = kvm_arch_pre_create_vcpu(cpu, errp);

+if (ret < 0) {
+goto err;
+}
+
  ret = kvm_create_vcpu(cpu);
  if (ret < 0) {
  error_setg_errno(errp, -ret,
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index c3a60b28909a..643ca4950543 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -374,6 +374,7 @@ int kvm_arch_get_default_type(MachineState *ms);
  
  int kvm_arch_init(MachineState *ms, KVMState *s);
  
+int kvm_arch_pre_create_vcpu(CPUState *cpu, Error **errp);

  int kvm_arch_init_vcpu(CPUState *cpu);
  int kvm_arch_destroy_vcpu(CPUState *cpu);
  





[PATCH 1/1] vfio/platform: Add mmio-base property to define start address for MMIO mapping

2024-11-12 Thread Juan Pablo Ruiz
Some platform devices have large MMIO regions (e.g., GPU reserved memory). For
certain devices, it's preferable to have a 1:1 address translation in the VM to
avoid modifying driver source code.

This patch:

1. Increases the VFIO platform bus size from 32MB to 130GB.
2. Changes the mmio_size property from 32 to 64 bits.
3. Adds an mmio-base property to define the starting MMIO address for mapping
   the VFIO device.

Signed-off-by: Juan Pablo Ruiz juanpablo.r...@unikie.com
---
 hw/arm/virt.c   |  6 +++---
 hw/core/platform-bus.c  | 28 ++--
 hw/vfio/platform.c  |  1 +
 include/hw/platform-bus.h   |  2 +-
 include/hw/vfio/vfio-platform.h |  1 +
 5 files changed, 32 insertions(+), 6 deletions(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 1a381e9a2b..9fc8f4425a 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -183,13 +183,13 @@ static const MemMapEntry base_memmap[] = {
 [VIRT_SECURE_GPIO] ={ 0x090b, 0x1000 },
 [VIRT_MMIO] =   { 0x0a00, 0x0200 },
 /* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
-[VIRT_PLATFORM_BUS] =   { 0x0c00, 0x0200 },
+[VIRT_PLATFORM_BUS] =   { 0x6000, 0x1FC000 },  // 
130048MB
 [VIRT_SECURE_MEM] = { 0x0e00, 0x0100 },
 [VIRT_PCIE_MMIO] =  { 0x1000, 0x2eff },
 [VIRT_PCIE_PIO] =   { 0x3eff, 0x0001 },
 [VIRT_PCIE_ECAM] =  { 0x3f00, 0x0100 },
 /* Actual RAM size depends on initial RAM and device memory settings */
-[VIRT_MEM] ={ GiB, LEGACY_RAMLIMIT_BYTES },
+[VIRT_MEM] ={ 0x20, LEGACY_RAMLIMIT_BYTES },
 };
 
 /*
@@ -1625,7 +1625,7 @@ static void create_platform_bus(VirtMachineState *vms)
 dev = qdev_new(TYPE_PLATFORM_BUS_DEVICE);
 dev->id = g_strdup(TYPE_PLATFORM_BUS_DEVICE);
 qdev_prop_set_uint32(dev, "num_irqs", PLATFORM_BUS_NUM_IRQS);
-qdev_prop_set_uint32(dev, "mmio_size", 
vms->memmap[VIRT_PLATFORM_BUS].size);
+qdev_prop_set_uint64(dev, "mmio_size", 
vms->memmap[VIRT_PLATFORM_BUS].size);
 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
 vms->platform_bus_dev = dev;
 
diff --git a/hw/core/platform-bus.c b/hw/core/platform-bus.c
index dc58bf505a..f545fab6e5 100644
--- a/hw/core/platform-bus.c
+++ b/hw/core/platform-bus.c
@@ -22,6 +22,7 @@
 #include "qemu/osdep.h"
 #include "hw/platform-bus.h"
 #include "hw/qdev-properties.h"
+#include "hw/vfio/vfio-platform.h"
 #include "qapi/error.h"
 #include "qemu/error-report.h"
 #include "qemu/module.h"
@@ -130,11 +131,29 @@ static void platform_bus_map_mmio(PlatformBusDevice 
*pbus, SysBusDevice *sbdev,
   int n)
 {
 MemoryRegion *sbdev_mr = sysbus_mmio_get_region(sbdev, n);
+VFIOPlatformDevice *vdev = VFIO_PLATFORM_DEVICE(sbdev);
 uint64_t size = memory_region_size(sbdev_mr);
 uint64_t alignment = (1ULL << (63 - clz64(size + size - 1)));
 uint64_t off;
+uint64_t mmio_base_off;
 bool found_region = false;
 
+if (vdev->mmio_base) {
+if(vdev->mmio_base < pbus->mmio.addr || 
+   vdev->mmio_base >= pbus->mmio.addr + pbus->mmio_size){
+error_report("Platform Bus: MMIO base 0x%"PRIx64
+" outside platform bus region [0x%"PRIx64",0x%"PRIx64"]",
+vdev->mmio_base,
+pbus->mmio.addr,
+pbus->mmio.addr + pbus->mmio_size);
+exit(1);
+}
+
+mmio_base_off = vdev->mmio_base - pbus->mmio.addr;
+} else {
+mmio_base_off = 0;
+}
+
 if (memory_region_is_mapped(sbdev_mr)) {
 /* Region is already mapped, nothing to do */
 return;
@@ -144,7 +163,7 @@ static void platform_bus_map_mmio(PlatformBusDevice *pbus, 
SysBusDevice *sbdev,
  * Look for empty space in the MMIO space that is naturally aligned with
  * the target device's memory region
  */
-for (off = 0; off < pbus->mmio_size; off += alignment) {
+for (off = mmio_base_off; off < pbus->mmio_size; off += alignment) {
 MemoryRegion *mr = memory_region_find(&pbus->mmio, off, size).mr;
 if (!mr) {
 found_region = true;
@@ -154,6 +173,11 @@ static void platform_bus_map_mmio(PlatformBusDevice *pbus, 
SysBusDevice *sbdev,
 }
 }
 
+if (vdev->mmio_base && vdev->mmio_base != off + pbus->mmio.addr) {
+warn_report("Platform Bus: Not able to map in mmio base: 0x%"PRIx64, 
+vdev->mmio_base);
+}
+
 if (!found_region) {
 error_report("Platform Bus: Can not fit MMIO region of size %"PRIx64,
  size);
@@ -206,7 +230,7 @@ static void platform_bus_realize(DeviceState *dev, Error 
**errp)
 
 static Property platform_bus_properties[] = {
 DEFINE_PROP_UINT32("num_irqs", PlatformBusDevice, num_irqs, 0),
-DEFINE_PROP_UINT32("mmio_size", Plat

Re: [PATCH 3/7] target/i386/kvm: init PMU information only once

2024-11-12 Thread dongli . zhang
Hi Zhao,

On 11/10/24 7:29 AM, Zhao Liu wrote:
> Hi Dongli,
> 
>>  int kvm_arch_init_vcpu(CPUState *cs)
>>  {
>>  struct {
>> @@ -2237,6 +2247,13 @@ int kvm_arch_init_vcpu(CPUState *cs)
>>  cpuid_i = kvm_x86_build_cpuid(env, cpuid_data.entries, cpuid_i);
>>  cpuid_data.cpuid.nent = cpuid_i;
>>  
>> +/*
>> + * Initialize PMU information only once for the first vCPU.
>> + */
>> +if (cs == first_cpu) {
>> +kvm_init_pmu_info(env);
>> +}
>> +
> 
> Thank you for the optimization. However, I think it’s not necessary
> because:
> 
> * This is not a hot path and not a performance bottleneck.
> * Many CPUID leaves are consistent across CPUs, and 0xA is just one of them.
> * And encoding them all in kvm_x86_build_cpuid() is a common pattern.
>   Separating out 0xa disrupts code readability and fragments the CPUID 
> encoding.
> 
> Therefore, code maintainability and correctness might be more important here,
> than performance concern.

I am going to remove this patch in v2.

Just a reminder, we may have more code in this function by other patches,
including the initialization of both Intel and AMD PMU infortmation (PerfMonV2).

Thank you very much!

Dongli Zhang

> 
>>  if (((env->cpuid_version >> 8)&0xF) >= 6
>>  && (env->features[FEAT_1_EDX] & (CPUID_MCE | CPUID_MCA)) ==
>> (CPUID_MCE | CPUID_MCA)) {
>> -- 
>> 2.39.3
>>




Re: [PATCH RFC 0/5] Change ghes driver to use HEST-based offsets

2024-11-12 Thread Mauro Carvalho Chehab
Em Wed, 13 Nov 2024 07:54:18 +0100
Mauro Carvalho Chehab  escreveu:

> Em Wed, 2 Oct 2024 15:45:34 +0200
> Igor Mammedov  escreveu:
> 
> > On Tue,  1 Oct 2024 13:42:45 +0200
> > Mauro Carvalho Chehab  wrote:
> >   
> > > This RFC series was part of the previous PR to add generic error injection
> > > support on GHES.
> > > 
> > > It contains only the changes of the math used to calculate offsets at
> > > HEST table and hardware_error firmware file.
> > > 
> > > The first patch adds a new firmware file to store HEST address.
> > > The second patch makes use of it.
> > > The remaining ones add migration support.
> > > 
> > > PS.: I'm sending this as a RFC as using the proceudure defined at the
> > > pseudo-migration of:
> > > 
> > >   https://www.linux-kvm.org/page/Migration
> > > 
> > > Didn't work. I tried to use two different QEMU versions to check a
> > > real life case and also to use just one QEMU and trying to load a
> > > virt-9.1 state on a virt-9.2 machine. 
> > > 
> > > For instance, trying to restore a virt-9.1 state on virt-9.2 gave me
> > > this error:
> > > 
> > >   (qemu) qemu: Machine type received is 'virt-9.1' and local is 'virt-9.2'
> > >   qemu: load of migration failed: Invalid argument
> > 
> > that's expected (idea is to keep machine type (virt-X) ABI stable so
> > it would work the same way on old and new QEMU)
> > migration is meant to move VM of the same machine type to a new/another 
> > QEMU instance.  
> 
> I found a couple of issues and, after the fixes, it can successfully
> migrate both virt-9.1 and virt-9.2 machines. 
> 
> > 
> > i.e try migrate 
> > 
> > qemu-9.1 -M virt-9.1  => qemu-9.2 -M virt-9.1
> > and vice-versa
> > migration should succeed and memory error injection should still work
> > the old way in both instances (I don't recall anymore how to simulate SEA,
> > perhaps original author left a description how to do that somewhere on 
> > mail-list).  
> 
> Those work as well, but I had to pass -cpu cortex-a57 to both 9.1
> and 9.2, as using -cpu max caused qemu to refuse loading the guest.
> 
> I tested with both:
> 
>   qemu-9.1 -M virt-9.1 -cpu cortex-a57 => qemu-9.2 -M virt-9.1 -cpu 
> cortex-a57
>   qemu-9.2 -M virt-9.1 -cpu cortex-a57 => qemu-9.1 -M virt-9.1 -cpu 
> cortex-a57

Forgot to mention, but I modified qemu-9.1 to use GPIO instead of SEA, as
it is a lot easier to do the tests using the error injection logic.
Also, I don't know how to test SEA errors.

> I'll address your other comments to the series and post a new version
> today.
> 
> Thanks,
> Mauro



Thanks,
Mauro



Re: [PATCH RFC 0/5] Change ghes driver to use HEST-based offsets

2024-11-12 Thread Mauro Carvalho Chehab
Em Wed, 2 Oct 2024 15:45:34 +0200
Igor Mammedov  escreveu:

> On Tue,  1 Oct 2024 13:42:45 +0200
> Mauro Carvalho Chehab  wrote:
> 
> > This RFC series was part of the previous PR to add generic error injection
> > support on GHES.
> > 
> > It contains only the changes of the math used to calculate offsets at
> > HEST table and hardware_error firmware file.
> > 
> > The first patch adds a new firmware file to store HEST address.
> > The second patch makes use of it.
> > The remaining ones add migration support.
> > 
> > PS.: I'm sending this as a RFC as using the proceudure defined at the
> > pseudo-migration of:
> > 
> > https://www.linux-kvm.org/page/Migration
> > 
> > Didn't work. I tried to use two different QEMU versions to check a
> > real life case and also to use just one QEMU and trying to load a
> > virt-9.1 state on a virt-9.2 machine. 
> > 
> > For instance, trying to restore a virt-9.1 state on virt-9.2 gave me
> > this error:
> > 
> > (qemu) qemu: Machine type received is 'virt-9.1' and local is 'virt-9.2'
> > qemu: load of migration failed: Invalid argument  
> 
> that's expected (idea is to keep machine type (virt-X) ABI stable so
> it would work the same way on old and new QEMU)
> migration is meant to move VM of the same machine type to a new/another QEMU 
> instance.

I found a couple of issues and, after the fixes, it can successfully
migrate both virt-9.1 and virt-9.2 machines. 

> 
> i.e try migrate 
> 
> qemu-9.1 -M virt-9.1  => qemu-9.2 -M virt-9.1
> and vice-versa
> migration should succeed and memory error injection should still work
> the old way in both instances (I don't recall anymore how to simulate SEA,
> perhaps original author left a description how to do that somewhere on 
> mail-list).

Those work as well, but I had to pass -cpu cortex-a57 to both 9.1
and 9.2, as using -cpu max caused qemu to refuse loading the guest.

I tested with both:

qemu-9.1 -M virt-9.1 -cpu cortex-a57 => qemu-9.2 -M virt-9.1 -cpu 
cortex-a57
qemu-9.2 -M virt-9.1 -cpu cortex-a57 => qemu-9.1 -M virt-9.1 -cpu 
cortex-a57

I'll address your other comments to the series and post a new version
today.

Thanks,
Mauro



Re: [PATCH] hw/openrisc: Fixed undercounting of TTCR in continuous mode

2024-11-12 Thread Stafford Horne
On Fri, Jun 07, 2024 at 03:29:33PM -0700, Joel Holdsworth via wrote:
> In the existing design, TTCR is prone to undercounting when running in
> continuous mode. This manifests as a timer interrupt appearing to
> trigger a few cycles prior to the deadline set in SPR_TTMR_TP.
> 
> When the timer triggers, the virtual time delta in nanoseconds between
> the time when the timer was set, and when it triggers is calculated.
> This nanoseconds value is then divided by TIMER_PERIOD (50) to compute
> an increment of cycles to apply to TTCR.
> 
> However, this calculation rounds down the number of cycles causing the
> undercounting.
> 
> A simplistic solution would be to instead round up the number of cycles,
> however this will result in the accumulation of timing error over time.
> 
> This patch corrects the issue by calculating the time delta in
> nanoseconds between when the timer was last reset and the timer event.
> This approach allows the TTCR value to be rounded up, but without
> accumulating error over time.
> 
> Signed-off-by: Joel Holdsworth 
> ---
>  hw/openrisc/cputimer.c | 22 +-
>  1 file changed, 13 insertions(+), 9 deletions(-)
> 
> diff --git a/hw/openrisc/cputimer.c b/hw/openrisc/cputimer.c
> index 835986c4db..ddc129aa48 100644
> --- a/hw/openrisc/cputimer.c
> +++ b/hw/openrisc/cputimer.c
> @@ -29,7 +29,8 @@
>  /* Tick Timer global state to allow all cores to be in sync */
>  typedef struct OR1KTimerState {
>  uint32_t ttcr;
> -uint64_t last_clk;
> +uint32_t ttcr_offset;
> +uint64_t clk_offset;
>  } OR1KTimerState;
>  
>  static OR1KTimerState *or1k_timer;
> @@ -37,6 +38,8 @@ static OR1KTimerState *or1k_timer;
>  void cpu_openrisc_count_set(OpenRISCCPU *cpu, uint32_t val)
>  {
>  or1k_timer->ttcr = val;
> +or1k_timer->ttcr_offset = val;
> +or1k_timer->clk_offset = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
>  }
>  
>  uint32_t cpu_openrisc_count_get(OpenRISCCPU *cpu)
> @@ -53,9 +56,8 @@ void cpu_openrisc_count_update(OpenRISCCPU *cpu)
>  return;
>  }
>  now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
> -or1k_timer->ttcr += (uint32_t)((now - or1k_timer->last_clk)
> -/ TIMER_PERIOD);
> -or1k_timer->last_clk = now;
> +or1k_timer->ttcr = (now - or1k_timer->clk_offset + TIMER_PERIOD - 1) / 
> TIMER_PERIOD +
> +or1k_timer->ttcr_offset;
>  }
>  
>  /* Update the next timeout time as difference between ttmr and ttcr */
> @@ -69,7 +71,7 @@ void cpu_openrisc_timer_update(OpenRISCCPU *cpu)
>  }
>  
>  cpu_openrisc_count_update(cpu);
> -now = or1k_timer->last_clk;
> +now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
>  
>  if ((cpu->env.ttmr & TTMR_TP) <= (or1k_timer->ttcr & TTMR_TP)) {
>  wait = TTMR_TP - (or1k_timer->ttcr & TTMR_TP) + 1;
> @@ -110,7 +112,8 @@ static void openrisc_timer_cb(void *opaque)
>  case TIMER_NONE:
>  break;
>  case TIMER_INTR:
> -or1k_timer->ttcr = 0;
> +/* Zero the count by applying a negative offset to the counter */
> +or1k_timer->ttcr_offset += UINT32_MAX - (cpu->env.ttmr & TTMR_TP);

Hi Joel,

I am trying to get this merged as I am finally getting some time for this again
after a long project at work.

Why here do you do += UINT32_MAX - (cpu->env.ttmr & TTMR_TP)?
Is there an edge case I am not thinking of that is making you use UINT32_MAX?

Wouldn't this be the same as
r1k_timer->ttcr_offset -= 1 - (cpu->env.ttmr & TTMR_TP);

-Stafford



Re: [RFC 18/21] arm/cpu: Introduce a customizable kvm host cpu model

2024-11-12 Thread Cornelia Huck
On Mon, Nov 11 2024, Cornelia Huck  wrote:

> On Mon, Nov 04 2024, Eric Auger  wrote:
>
>> Hi Daniel,
>>
>> On 10/28/24 18:04, Daniel P. Berrangé wrote:
>>> On Mon, Oct 28, 2024 at 04:48:18PM +, Peter Maydell wrote:
 On Mon, 28 Oct 2024 at 16:35, Daniel P. Berrangé  
 wrote:
> On Mon, Oct 28, 2024 at 04:16:31PM +, Peter Maydell wrote:
>> On Fri, 25 Oct 2024 at 14:24, Daniel P. Berrangé  
>> wrote:
>>> On Fri, Oct 25, 2024 at 03:18:25PM +0200, Eric Auger wrote:
 On 10/25/24 15:06, Daniel P. Berrangé wrote:
> Also, is this naming convention really the same one that users
> will see when they look at /proc/cpuinfo to view features ? It
 No it is not. I do agree that the custom cpu model is very low level. 
 It
 is very well suited to test all series turning ID regs as writable but
 this would require an extra layer that adapts /proc/cpuinfo feature
 level to this regid/field abstraction.

 In /cpu/proc you will see somethink like:
  Features: fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp
 asimdhp cpuid asimdrdm lrcpc dcpop asimddp
>>> Right, IMHO, this is the terminology that QEMU must use in user
>>> facing APIs.
>> /proc/cpuinfo's naming is rather weird for historical
>> reasons (for instance there is only one FEAT_FP16 feature
>> but cpuinfo lists "fphp" and "asimdhp" separately).
> There's plenty of wierd history in x86 too. In this
> case I might suggest just picking one of the two
> common names, and ignoring the other.
>
> If we really wanted to, we could alias the 2nd name
> to the first, but its likely not worth the bother.
 Or we could use the standard set of architectural
 feature names, and not have the problem at all, and not
 have to document what we mean by our nonstandard names.
 (cpuinfo names do actually mostly line up with the
 standard names, just not 100%. Similarly gcc/clang command
 line options are mostly the architectural feature name.)
>>> Ah, right, yes. Sorry I mis-understood you originally to be suggesting
>>> the same low level names as this patch.
>> If my understanding is correct, Peter suggested to rely on the
>> terminology used in
>>
>> https://developer.arm.com/documentation/109697/2024_09
>>
>> the doc pointed to by Oliver.
>>
>> So I think the next step is to understand how those "high level" features do 
>> map onto low level ID register field values. I think a high level feature 
>> can map onto separate fields in separate ID regs. This may not be the most 
>> common case though. 
>
> I went through all the FEAT_xxx features defined so far and tried to
> categorize them (probably with some errors here and there, but the
> general trend should be correct.)
>
> There's 335 features defined at the moment.
>
> Of these, the majority (295 by my count) map to one or more values in
> one or more id registers. These are what I'd consider the "easy" ones
> (added complexity if we deal with serveral values, but in general, it is
> clear how to handle them, and most of them actually map to a single
> value.) Of course, dependencies may be on top of that.
>
> Then, we have some features (~25 or so) that are actually defined by
> dependencies (i.e. FEAT_FOO and FEAT_BAR mean that we have FEAT_BAZ,
> sometimes with an architecture extension dependency thrown in as well.)
> These features are not really relevant when we compare two cpus since
> they do not map to registers directly, but they are relevant if we allow
> them to be specified (and use them as a kind of shorthand.) IOW, we'd
> need to think about how we'd handle them for comparisons and baselining.
>
> Next, let's talk about architecture extensions. All features have a
> level where they have been introduced as optional, some have an upper
> limit (e.g. FEAT_AA32EL1 is not allowed from v9.0 onwards), and quite a
> number of them (~65 or so) become mandatory with a certain architecture
> extension. Sometimes, FEAT_FOO + arch ext also implies FEAT_BAR. If we
> introduce Armvx.y named models, we'd need to enforce that some features
> are (not) set for a certain model. Complex, but not a showstopper. (We'd
> also need to deal with that if we worked on the register level.)
>
> We also have some registers like MIDR/REVIDR that do not correlate with
> any FEAT_xxx, but that we still need to handle; I would suggest to deal
> with them via separate cpu properties (e.g. specify a list of possible
> MIDR/REVIDR pairs.) I hope that there are not too many of them, although
> we do have some impdef registers.
>
> That leaves some headscratchers (at least for me.) E.g. FEAT_UINJ, which
> is optional from v9.5, and mandatory from v9.6, but where I'm unsure how
> we'd discover it, especially as we do not have a way to discover the
> architecture extensions. Maybe this will work for named actual cpus
> only? I'm also not sure if I und

[PATCH v3 2/4] Skip NaN mode check for soft-float

2024-11-12 Thread Aleksandar Rakic
Skip NaN mode check for soft-float since NaN mode is irrelevant if an ELF
binary's FPU mode is soft-float, i.e. it doesn't utilize a FPU.

Cherry-picked 63492a56485f6b755fccf7ad623f7a189bfc79b6
from https://github.com/MIPS/gnutools-qemu

Signed-off-by: Faraz Shahbazker 
Signed-off-by: Aleksandar Rakic 
---
 linux-user/mips/cpu_loop.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c
index 462387a073..07c1ebe287 100644
--- a/linux-user/mips/cpu_loop.c
+++ b/linux-user/mips/cpu_loop.c
@@ -304,8 +304,10 @@ void target_cpu_copy_regs(CPUArchState *env, struct 
target_pt_regs *regs)
 if (env->insn_flags & ISA_NANOMIPS32) {
 return;
 }
-if (((info->elf_flags & EF_MIPS_NAN2008) != 0) !=
-((env->active_fpu.fcr31 & (1 << FCR31_NAN2008)) != 0)) {
+if (info->fp_abi != MIPS_ABI_FP_SOFT
+&& ((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) {
 fprintf(stderr, "ELF binary's NaN mode not supported by CPU\n");
-- 
2.34.1




[PATCH v3 1/4] Add support for emulation of CRC32 instructions

2024-11-12 Thread Aleksandar Rakic
Add emulation of MIPS' CRC32 (Cyclic Redundancy Check) instructions.
Reuse zlib crc32() and Linux crc32c().

Cherry-picked 4cc974938aee1588f852590509004e340c072940
from https://github.com/MIPS/gnutools-qemu

Signed-off-by: Yongbok Kim 
Signed-off-by: Aleksandar Markovic 
Signed-off-by: Aleksandar Rakic 
Reviewed-by: Aleksandar Rikalo 
---
 target/mips/helper.h |  2 ++
 target/mips/meson.build  |  1 +
 target/mips/tcg/op_helper.c  | 26 ++
 target/mips/tcg/rel6.decode  |  5 +
 target/mips/tcg/rel6_translate.c | 14 ++
 target/mips/tcg/translate.c  | 25 +
 target/mips/tcg/translate.h  |  3 +++
 7 files changed, 76 insertions(+)

diff --git a/target/mips/helper.h b/target/mips/helper.h
index 0f8462febb..752748d5e6 100644
--- a/target/mips/helper.h
+++ b/target/mips/helper.h
@@ -21,6 +21,8 @@ DEF_HELPER_FLAGS_1(bitswap, TCG_CALL_NO_RWG_SE, tl, tl)
 DEF_HELPER_FLAGS_1(dbitswap, TCG_CALL_NO_RWG_SE, tl, tl)
 #endif
 
+DEF_HELPER_3(crc32, tl, tl, tl, i32)
+DEF_HELPER_3(crc32c, tl, tl, tl, i32)
 DEF_HELPER_FLAGS_4(rotx, TCG_CALL_NO_RWG_SE, tl, tl, i32, i32, i32)
 
 /* microMIPS functions */
diff --git a/target/mips/meson.build b/target/mips/meson.build
index a26d1e1f79..d2d686fc0c 100644
--- a/target/mips/meson.build
+++ b/target/mips/meson.build
@@ -7,6 +7,7 @@ mips_ss.add(files(
   'gdbstub.c',
   'msa.c',
 ))
+mips_ss.add(zlib)
 
 if have_system
   subdir('sysemu')
diff --git a/target/mips/tcg/op_helper.c b/target/mips/tcg/op_helper.c
index 65403f1a87..22600697f0 100644
--- a/target/mips/tcg/op_helper.c
+++ b/target/mips/tcg/op_helper.c
@@ -25,6 +25,8 @@
 #include "exec/exec-all.h"
 #include "exec/memop.h"
 #include "fpu_helper.h"
+#include "qemu/crc32c.h"
+#include 
 
 static inline target_ulong bitswap(target_ulong v)
 {
@@ -143,6 +145,30 @@ target_ulong helper_rotx(target_ulong rs, uint32_t shift, 
uint32_t shiftx,
 return (int64_t)(int32_t)(uint32_t)tmp5;
 }
 
+/* these crc32 functions are based on target/arm/helper-a64.c */
+target_ulong helper_crc32(target_ulong val, target_ulong m, uint32_t sz)
+{
+uint8_t buf[8];
+target_ulong mask = ((sz * 8) == 64) ?
+(target_ulong) -1ULL :
+((1ULL << (sz * 8)) - 1);
+
+m &= mask;
+stq_le_p(buf, m);
+return (int32_t) (crc32(val ^ 0x, buf, sz) ^ 0x);
+}
+
+target_ulong helper_crc32c(target_ulong val, target_ulong m, uint32_t sz)
+{
+uint8_t buf[8];
+target_ulong mask = ((sz * 8) == 64) ?
+(target_ulong) -1ULL :
+((1ULL << (sz * 8)) - 1);
+m &= mask;
+stq_le_p(buf, m);
+return (int32_t) (crc32c(val, buf, sz) ^ 0x);
+}
+
 void helper_fork(target_ulong arg1, target_ulong arg2)
 {
 /*
diff --git a/target/mips/tcg/rel6.decode b/target/mips/tcg/rel6.decode
index d6989cf56e..5074338aa5 100644
--- a/target/mips/tcg/rel6.decode
+++ b/target/mips/tcg/rel6.decode
@@ -16,11 +16,16 @@
 
 &r  rs rt rd sa
 
+&special3_crc   rs rt c sz
+
 @lsa.. rs:5 rt:5 rd:5 ... sa:2 ..   &r
+@crc32  .. rs:5 rt:5 . c:3 sz:2 ..   &special3_crc
 
 LSA 00 . . . 000 .. 000101  @lsa
 DLSA00 . . . 000 .. 010101  @lsa
 
+CRC32   01 . . 0 ... .. 00  @crc32
+
 REMOVED 010011 - - - - --   # COP1X (COP3)
 
 REMOVED 011100 - - - - --   # SPECIAL2
diff --git a/target/mips/tcg/rel6_translate.c b/target/mips/tcg/rel6_translate.c
index 59f237ba3b..423b323ba7 100644
--- a/target/mips/tcg/rel6_translate.c
+++ b/target/mips/tcg/rel6_translate.c
@@ -33,3 +33,17 @@ static bool trans_DLSA(DisasContext *ctx, arg_r *a)
 }
 return gen_dlsa(ctx, a->rd, a->rt, a->rs, a->sa);
 }
+
+static bool trans_CRC32(DisasContext *ctx, arg_special3_crc *a)
+{
+if (unlikely(!ctx->crcp) ||
+unlikely((a->sz == 3) &&
+ (!(ctx->hflags & MIPS_HFLAG_64))) ||
+unlikely((a->c >= 2))) {
+gen_reserved_instruction(ctx);
+return true;
+}
+gen_crc32(ctx, a->rt, a->rs, a->rt,
+  a->sz, a->c);
+return true;
+}
diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
index de7045874d..c97d1d37bd 100644
--- a/target/mips/tcg/translate.c
+++ b/target/mips/tcg/translate.c
@@ -13448,6 +13448,30 @@ static void decode_opc_special2_legacy(CPUMIPSState 
*env, DisasContext *ctx)
 }
 }
 
+void gen_crc32(DisasContext *ctx, int rd, int rs, int rt, int sz,
+  int crc32c)
+{
+TCGv t0;
+TCGv t1;
+TCGv_i32 tsz = tcg_constant_i32(1 << sz);
+if (rd == 0) {
+/* Treat as NOP. */
+return;
+}
+t0 = tcg_temp_new();
+t1 = tcg_temp_new();
+
+gen_load_gpr(t0, rt);
+gen_load_gpr(t1, rs);
+
+if (crc32c) {
+gen_helper

[PATCH v3 3/4] target/mips: Enable MSA ASE using a CLI flag

2024-11-12 Thread Aleksandar Rakic
Enable MSA ASE using a CLI flag -cpu ,msa=on.

Signed-off-by: Aleksandar Rakic 
---
 target/mips/cpu.c  | 16 
 target/mips/cpu.h  |  1 +
 target/mips/internal.h |  2 +-
 3 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index d0a43b6d5c..8e12d303de 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -494,8 +494,24 @@ static void mips_cpu_realizefn(DeviceState *dev, Error 
**errp)
 mcc->parent_realize(dev, errp);
 }
 
+static bool mips_get_msa_on(Object *obj, Error **errp)
+{
+MIPSCPU *cpu = MIPS_CPU(obj);
+CPUMIPSState *env = &cpu->env;
+return env->msa_on;
+}
+
+static void mips_set_msa_on(Object *obj, bool value, Error **errp)
+{
+MIPSCPU *cpu = MIPS_CPU(obj);
+CPUMIPSState *env = &cpu->env;
+env->msa_on = value;
+}
+
 static void mips_cpu_initfn(Object *obj)
 {
+object_property_add_bool(obj, "msa", mips_get_msa_on, mips_set_msa_on);
+object_property_set_bool(obj, "msa", false, NULL);
 MIPSCPU *cpu = MIPS_CPU(obj);
 CPUMIPSState *env = &cpu->env;
 MIPSCPUClass *mcc = MIPS_CPU_GET_CLASS(obj);
diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index f6877ece8b..3e636535c6 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -1191,6 +1191,7 @@ typedef struct CPUArchState {
 QEMUTimer *timer; /* Internal timer */
 Clock *count_clock; /* CP0_Count clock */
 target_ulong exception_base; /* ExceptionBase input to the core */
+bool msa_on; /* Enable MSA using a CLI flag -cpu ...,msa=on/off */
 } CPUMIPSState;
 
 /**
diff --git a/target/mips/internal.h b/target/mips/internal.h
index 91c786cff8..bbe2acffe2 100644
--- a/target/mips/internal.h
+++ b/target/mips/internal.h
@@ -399,7 +399,7 @@ static inline void compute_hflags(CPUMIPSState *env)
 }
 }
 if (ase_msa_available(env)) {
-if (env->CP0_Config5 & (1 << CP0C5_MSAEn)) {
+if ((env->CP0_Config5 & (1 << CP0C5_MSAEn)) || (env->msa_on)) {
 env->hflags |= MIPS_HFLAG_MSA;
 }
 }
-- 
2.34.1




[PATCH v3 0/4] Improve Mips target

2024-11-12 Thread Aleksandar Rakic
Aleksandar Rakic (4):
  Add support for emulation of CRC32 instructions
  Skip NaN mode check for soft-float
  target/mips: Enable MSA ASE using a CLI flag
  target/mips: Enable MSA ASE for mips64R2-generic

 linux-user/mips/cpu_loop.c   |  6 --
 target/mips/cpu-defs.c.inc   |  4 +++-
 target/mips/cpu.c| 16 
 target/mips/cpu.h|  1 +
 target/mips/helper.h |  2 ++
 target/mips/internal.h   |  2 +-
 target/mips/meson.build  |  1 +
 target/mips/tcg/op_helper.c  | 26 ++
 target/mips/tcg/rel6.decode  |  5 +
 target/mips/tcg/rel6_translate.c | 14 ++
 target/mips/tcg/translate.c  | 25 +
 target/mips/tcg/translate.h  |  3 +++
 12 files changed, 101 insertions(+), 4 deletions(-)

-- 
2.34.1




[PATCH v2 6/6] target/mips: Convert nanoMIPS LSA opcode to decodetree

2024-11-12 Thread Philippe Mathieu-Daudé
From: Philippe Mathieu-Daudé 

Simply call the generic gen_lsa() helper.

Signed-off-by: Philippe Mathieu-Daudé 
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/tcg/nanomips32.decode| 6 ++
 target/mips/tcg/nanomips_translate.c | 7 +++
 target/mips/tcg/nanomips_translate.c.inc | 4 
 3 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/target/mips/tcg/nanomips32.decode 
b/target/mips/tcg/nanomips32.decode
index 9cecf1e13d..96d2299bfb 100644
--- a/target/mips/tcg/nanomips32.decode
+++ b/target/mips/tcg/nanomips32.decode
@@ -6,3 +6,9 @@
 #
 # Reference: nanoMIPS32 Instruction Set Technical Reference Manual
 #(Document Number: MD01247)
+
+&r  rs rt rd sa
+
+@lsa.. rt:5 rs:5 rd:5 sa:2 --- ... ...  &r
+
+LSA 001000 . . . .. ... 001 111 @lsa
diff --git a/target/mips/tcg/nanomips_translate.c 
b/target/mips/tcg/nanomips_translate.c
index c148c13ed9..43a934d857 100644
--- a/target/mips/tcg/nanomips_translate.c
+++ b/target/mips/tcg/nanomips_translate.c
@@ -12,3 +12,10 @@
 /* Include the auto-generated decoders.  */
 #include "decode-nanomips16.c.inc"
 #include "decode-nanomips32.c.inc"
+
+static bool trans_LSA(DisasContext *ctx, arg_r *a)
+{
+gen_lsa(ctx, a->rd, a->rt, a->rs, a->sa);
+
+return true;
+}
diff --git a/target/mips/tcg/nanomips_translate.c.inc 
b/target/mips/tcg/nanomips_translate.c.inc
index e118013edc..0e012ab3d0 100644
--- a/target/mips/tcg/nanomips_translate.c.inc
+++ b/target/mips/tcg/nanomips_translate.c.inc
@@ -399,7 +399,6 @@ enum {
 /* POOL32A7 instruction pool */
 enum {
 NM_P_LSX= 0x00,
-NM_LSA  = 0x01,
 NM_EXTW = 0x03,
 NM_POOL32AXF= 0x07,
 };
@@ -3625,9 +3624,6 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, 
DisasContext *ctx)
 case NM_P_LSX:
 gen_p_lsx(ctx, rd, rs, rt);
 break;
-case NM_LSA:
-gen_lsa(ctx, rd, rt, rs, extract32(ctx->opcode, 9, 2));
-break;
 case NM_EXTW:
 gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5));
 break;
-- 
2.45.2




[PATCH 04/10] usb/uhci: enlarge uhci memory space

2024-11-12 Thread Guenter Roeck
hcd-uhci-sysbus will require more memory than hcd-uhci-pci
since registers for some hardware (specifically Aspeed) don't
map 1:1.

Signed-off-by: Guenter Roeck 
---
Changes since RFC:
- Rebased to v9.1.0-1673-g134b443512

 hw/usb/hcd-uhci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
index 68b72f8d3b..d2993a98b8 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -1212,7 +1212,7 @@ void usb_uhci_init(UHCIState *s, DeviceState *dev, Error 
**errp)
 QTAILQ_INIT(&s->queues);
 
 memory_region_init_io(&s->mem, OBJECT(s), &uhci_ioport_ops, s,
-  "uhci", 0x20);
+  "uhci", 0x100);
 }
 
 void usb_uhci_exit(UHCIState *s)
-- 
2.45.2




[PATCH 03/10] usb/uhci: Move PCI-related code into a separate file

2024-11-12 Thread Guenter Roeck
Some machines (like Aspeed ARM) only have a sysbus UHCI controller.
The current UHCI implementation only supports PCI based UHCI controllers.
Move the UHCI-PCI device code into a separate file so that it is possible
to create a sysbus UHCI device without PCI dependency.

Signed-off-by: Guenter Roeck 
---
Changes since RFC:
- Rebased to v9.1.0-1673-g134b443512
- Fixed bug in interrupt initialization

 hw/isa/Kconfig|   4 +-
 hw/isa/vt82c686.c |   4 +-
 hw/usb/Kconfig|   6 +-
 hw/usb/hcd-uhci-pci.c | 255 ++
 hw/usb/hcd-uhci-pci.h |  63 +
 hw/usb/hcd-uhci.c | 221 +
 hw/usb/hcd-uhci.h |  30 ++--
 hw/usb/meson.build|   1 +
 hw/usb/vt82c686-uhci-pci.c|  18 +--
 include/hw/southbridge/piix.h |   4 +-
 10 files changed, 386 insertions(+), 220 deletions(-)
 create mode 100644 hw/usb/hcd-uhci-pci.c
 create mode 100644 hw/usb/hcd-uhci-pci.h

diff --git a/hw/isa/Kconfig b/hw/isa/Kconfig
index 73c6470805..b0e536fad9 100644
--- a/hw/isa/Kconfig
+++ b/hw/isa/Kconfig
@@ -47,7 +47,7 @@ config PIIX
 select IDE_PIIX
 select ISA_BUS
 select MC146818RTC
-select USB_UHCI
+select USB_UHCI_PCI
 
 config VT82C686
 bool
@@ -55,7 +55,7 @@ config VT82C686
 select ISA_SUPERIO
 select ACPI
 select ACPI_SMBUS
-select USB_UHCI
+select USB_UHCI_PCI
 select APM
 select I8254
 select I8257
diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index 6f44b381a5..a47cbd6191 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -26,7 +26,7 @@
 #include "hw/intc/i8259.h"
 #include "hw/irq.h"
 #include "hw/dma/i8257.h"
-#include "hw/usb/hcd-uhci.h"
+#include "hw/usb/hcd-uhci-pci.h"
 #include "hw/timer/i8254.h"
 #include "hw/rtc/mc146818rtc.h"
 #include "migration/vmstate.h"
@@ -600,7 +600,7 @@ struct ViaISAState {
 ViaSuperIOState via_sio;
 MC146818RtcState rtc;
 PCIIDEState ide;
-UHCIState uhci[2];
+UHCIPCIState uhci[2];
 ViaPMState pm;
 ViaAC97State ac97;
 PCIDevice mc97;
diff --git a/hw/usb/Kconfig b/hw/usb/Kconfig
index 5fbecd2f43..bab4d2d67d 100644
--- a/hw/usb/Kconfig
+++ b/hw/usb/Kconfig
@@ -2,10 +2,14 @@ config USB
 bool
 
 config USB_UHCI
+bool
+select USB
+
+config USB_UHCI_PCI
 bool
 default y if PCI_DEVICES
 depends on PCI
-select USB
+select USB_UHCI
 
 config USB_OHCI
 bool
diff --git a/hw/usb/hcd-uhci-pci.c b/hw/usb/hcd-uhci-pci.c
new file mode 100644
index 00..ed9b5f6121
--- /dev/null
+++ b/hw/usb/hcd-uhci-pci.c
@@ -0,0 +1,255 @@
+/*
+ * USB UHCI controller emulation
+ * PCI code
+ *
+ * Copyright (c) 2005 Fabrice Bellard
+ *
+ * Copyright (c) 2008 Max Krasnyansky
+ * Magor rewrite of the UHCI data structures parser and frame processor
+ * Support for fully async operation and multiple outstanding transactions
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/irq.h"
+#include "hw/usb.h"
+#include "migration/vmstate.h"
+#include "hw/pci/pci.h"
+#include "hw/qdev-properties.h"
+#include "qapi/error.h"
+#include "qemu/main-loop.h"
+#include "qemu/module.h"
+#include "qom/object.h"
+#include "hcd-uhci-pci.h"
+
+struct UHCIPCIDeviceClass {
+PCIDeviceClass parent_class;
+UHCIPCIInfo info;
+};
+
+static const VMStateDescription vmstate_uhci = {
+.name = "pci_uhci",
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (const VMStateField[]) {
+VMSTATE_PCI_DEVICE(dev, UHCIPCIState),
+VMSTATE_STRUCT(state, UHCIPCIState, 1, vmstate_uhci_state, UHCIState),
+VMSTATE_END_OF_LIST()
+}
+};
+
+static void uhci_pci_reset(UHCIState *uhci)
+{
+UHCIPCIState *pstate = container_of(uhci, UHCIPCIState, state);
+PCIDevice *d = &pstate->dev;
+
+d->config[0x6a] = 0x01; /* usb clock */
+d->config[0x6b] = 0x00;
+
+   

[PATCH 07/10] aspeed: Add uhci support for ast2600

2024-11-12 Thread Guenter Roeck
Add UHCI support for the ast2600 SoC. With this patch, UHCI support
is successfully enabled on the rainier-bmc and ast2600-evb machines.

Signed-off-by: Guenter Roeck 
---
Changes since RFC:
- Rebased to v9.1.0-1673-g134b443512
- Use EHCI companion mode

 hw/arm/aspeed_ast2600.c | 20 
 include/hw/arm/aspeed_soc.h |  3 +++
 2 files changed, 23 insertions(+)

diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
index be3eb70cdd..0592bfb2bf 100644
--- a/hw/arm/aspeed_ast2600.c
+++ b/hw/arm/aspeed_ast2600.c
@@ -33,6 +33,7 @@ static const hwaddr aspeed_soc_ast2600_memmap[] = {
 [ASPEED_DEV_SPI2]  = 0x1E631000,
 [ASPEED_DEV_EHCI1] = 0x1E6A1000,
 [ASPEED_DEV_EHCI2] = 0x1E6A3000,
+[ASPEED_DEV_UHCI]  = 0x1E6B,
 [ASPEED_DEV_MII1]  = 0x1E65,
 [ASPEED_DEV_MII2]  = 0x1E650008,
 [ASPEED_DEV_MII3]  = 0x1E650010,
@@ -110,6 +111,7 @@ static const int aspeed_soc_ast2600_irqmap[] = {
 [ASPEED_DEV_SDHCI] = 43,
 [ASPEED_DEV_EHCI1] = 5,
 [ASPEED_DEV_EHCI2] = 9,
+[ASPEED_DEV_UHCI]  = 10,
 [ASPEED_DEV_EMMC]  = 15,
 [ASPEED_DEV_GPIO]  = 40,
 [ASPEED_DEV_GPIO_1_8V] = 11,
@@ -206,6 +208,8 @@ static void aspeed_soc_ast2600_init(Object *obj)
 TYPE_PLATFORM_EHCI);
 }
 
+object_initialize_child(obj, "uhci", &s->uhci, TYPE_ASPEED_UHCI);
+
 snprintf(typename, sizeof(typename), "aspeed.sdmc-%s", socname);
 object_initialize_child(obj, "sdmc", &s->sdmc, typename);
 object_property_add_alias(obj, "ram-size", OBJECT(&s->sdmc),
@@ -294,6 +298,7 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, 
Error **errp)
 AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
 qemu_irq irq;
 g_autofree char *sram_name = NULL;
+g_autofree char *usb_bus = g_strdup_printf("usb-bus.%u", sc->ehcis_num - 
1);
 
 /* Default boot region (SPI memory or ROMs) */
 memory_region_init(&s->spi_boot_container, OBJECT(s),
@@ -472,6 +477,10 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, 
Error **errp)
 
 /* EHCI */
 for (i = 0; i < sc->ehcis_num; i++) {
+if (i == sc->ehcis_num - 1) {
+object_property_set_bool(OBJECT(&s->ehci[i]), "companion-enable",
+ true, &error_fatal);
+}
 if (!sysbus_realize(SYS_BUS_DEVICE(&s->ehci[i]), errp)) {
 return;
 }
@@ -481,6 +490,17 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, 
Error **errp)
aspeed_soc_get_irq(s, ASPEED_DEV_EHCI1 + i));
 }
 
+/* UHCI */
+object_property_set_str(OBJECT(&s->uhci), "masterbus", usb_bus,
+&error_fatal);
+if (!sysbus_realize(SYS_BUS_DEVICE(&s->uhci), errp)) {
+return;
+}
+aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->uhci), 0,
+sc->memmap[ASPEED_DEV_UHCI]);
+sysbus_connect_irq(SYS_BUS_DEVICE(&s->uhci), 0,
+   aspeed_soc_get_irq(s, ASPEED_DEV_UHCI));
+
 /* SDMC - SDRAM Memory Controller */
 if (!sysbus_realize(SYS_BUS_DEVICE(&s->sdmc), errp)) {
 return;
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
index 689f52dae8..e579911ced 100644
--- a/include/hw/arm/aspeed_soc.h
+++ b/include/hw/arm/aspeed_soc.h
@@ -34,6 +34,7 @@
 #include "hw/gpio/aspeed_gpio.h"
 #include "hw/sd/aspeed_sdhci.h"
 #include "hw/usb/hcd-ehci.h"
+#include "hw/usb/hcd-uhci-sysbus.h"
 #include "qom/object.h"
 #include "hw/misc/aspeed_lpc.h"
 #include "hw/misc/unimp.h"
@@ -72,6 +73,7 @@ struct AspeedSoCState {
 AspeedSMCState fmc;
 AspeedSMCState spi[ASPEED_SPIS_NUM];
 EHCISysBusState ehci[ASPEED_EHCIS_NUM];
+ASPEEDUHCIState uhci;
 AspeedSBCState sbc;
 AspeedSLIState sli;
 AspeedSLIState sliio;
@@ -193,6 +195,7 @@ enum {
 ASPEED_DEV_SPI2,
 ASPEED_DEV_EHCI1,
 ASPEED_DEV_EHCI2,
+ASPEED_DEV_UHCI,
 ASPEED_DEV_VIC,
 ASPEED_DEV_INTC,
 ASPEED_DEV_SDMC,
-- 
2.45.2




[PATCH 09/10] usb-hub: Add support for v2.0 hubs

2024-11-12 Thread Guenter Roeck
When adding a high speed USB device to the USB hub supported by qemu,
it is added in full speed mode. Here is an example for a storage device.

/:  Bus 001.Port 001: Dev 001, Class=root_hub, Driver=platform-uhci/2p, 12M
|__ Port 002: Dev 002, If 0, Class=Hub, Driver=hub/8p, 12M
|__ Port 001: Dev 003, If 0, Class=Human Interface Device, 
Driver=usbhid, 12M
|__ Port 002: Dev 004, If 0, Class=Human Interface Device, 
Driver=usbhid, 12M
|__ Port 003: Dev 005, If 0, Class=Mass Storage, Driver=usb-storage, 12M

This also triggers messages such as

usb 1-2.3: new full-speed USB device number 5 using platform-uhci
usb 1-2.3: not running at top speed; connect to a high speed hub

when such devices are instantiated in the host (example from Linux).

Add basic support for USB v2.0 hubs to solve the problem. The usb_version
device parameter configures the USB version; version 1 is default for
compatibility reasons. Example:

-device usb-hub,bus=usb-bus.1,port=1,usb_version=2

This command line parameter can be used to attach devices to the hub in
high speed mode, as seen in the following example.

/:  Bus 002.Port 001: Dev 001, Class=root_hub, Driver=ehci-platform/6p, 480M
|__ Port 001: Dev 002, If 0, Class=Hub, Driver=hub/8p, 480M
|__ Port 002: Dev 004, If 0, Class=Mass Storage, Driver=usb-storage, 
480M

and

usb 2-1.2: new high-speed USB device number 4 using ehci-platform
usb 2-1.2: New USB device found, idVendor=46f4, idProduct=0001, bcdDevice= 0.00

To distinguish v1 from v2 instantiated hubs, the device version is set to
2.01 (from 1.01) if the hub ist instantiated as USB v2 hub. The product
name is set to "QEMU USB v2.0 Hub".

Signed-off-by: Guenter Roeck 
---
Changes since RFC:
- New patch

 hw/usb/dev-hub.c | 84 +++-
 1 file changed, 76 insertions(+), 8 deletions(-)

diff --git a/hw/usb/dev-hub.c b/hw/usb/dev-hub.c
index 06e9537d03..4da91d151c 100644
--- a/hw/usb/dev-hub.c
+++ b/hw/usb/dev-hub.c
@@ -46,6 +46,7 @@ struct USBHubState {
 USBDevice dev;
 USBEndpoint *intr;
 uint32_t num_ports;
+uint32_t usb_version;
 bool port_power;
 QEMUTimer *port_timer;
 USBHubPort ports[MAX_PORTS];
@@ -100,12 +101,14 @@ OBJECT_DECLARE_SIMPLE_TYPE(USBHubState, USB_HUB)
 enum {
 STR_MANUFACTURER = 1,
 STR_PRODUCT,
+STR_PRODUCT_V2,
 STR_SERIALNUMBER,
 };
 
 static const USBDescStrings desc_strings = {
 [STR_MANUFACTURER] = "QEMU",
 [STR_PRODUCT]  = "QEMU USB Hub",
+[STR_PRODUCT_V2]   = "QEMU USB v2.0 Hub",
 [STR_SERIALNUMBER] = "314159",
 };
 
@@ -123,6 +126,20 @@ static const USBDescIface desc_iface_hub = {
 }
 };
 
+static const USBDescIface desc_iface_hub_v2 = {
+.bInterfaceNumber  = 0,
+.bNumEndpoints = 1,
+.bInterfaceClass   = USB_CLASS_HUB,
+.eps = (USBDescEndpoint[]) {
+{
+.bEndpointAddress  = USB_DIR_IN | 0x01,
+.bmAttributes  = USB_ENDPOINT_XFER_INT,
+.wMaxPacketSize= 512,
+.bInterval = 10,
+},
+}
+};
+
 static const USBDescDevice desc_device_hub = {
 .bcdUSB= 0x0110,
 .bDeviceClass  = USB_CLASS_HUB,
@@ -140,6 +157,23 @@ static const USBDescDevice desc_device_hub = {
 },
 };
 
+static const USBDescDevice desc_device_hub_v2 = {
+.bcdUSB= 0x0200,
+.bDeviceClass  = USB_CLASS_HUB,
+.bMaxPacketSize0   = 64,
+.bNumConfigurations= 1,
+.confs = (USBDescConfig[]) {
+{
+.bNumInterfaces= 1,
+.bConfigurationValue   = 1,
+.bmAttributes  = USB_CFG_ATT_ONE | USB_CFG_ATT_SELFPOWER |
+ USB_CFG_ATT_WAKEUP,
+.nif = 1,
+.ifs = &desc_iface_hub_v2,
+},
+},
+};
+
 static const USBDesc desc_hub = {
 .id = {
 .idVendor  = 0x0409,
@@ -153,6 +187,20 @@ static const USBDesc desc_hub = {
 .str  = desc_strings,
 };
 
+static const USBDesc desc_hub_v2 = {
+.id = {
+.idVendor  = 0x0409,
+.idProduct = 0x55aa,
+.bcdDevice = 0x0201,
+.iManufacturer = STR_MANUFACTURER,
+.iProduct  = STR_PRODUCT_V2,
+.iSerialNumber = STR_SERIALNUMBER,
+},
+.full = &desc_device_hub,
+.high = &desc_device_hub_v2,
+.str  = desc_strings,
+};
+
 static const uint8_t qemu_hub_hub_descriptor[] =
 {
 0x00,   /*  u8  bLength; patched in later */
@@ -195,15 +243,20 @@ static bool usb_hub_port_clear(USBHubPort *port, uint16_t 
status)
 return usb_hub_port_change(port, status);
 }
 
-static bool usb_hub_port_update(USBHubPort *port)
+static bool usb_hub_port_update(USBHubState *s, USBHubPort *port)
 {
 bool notify = false;
 
 if (port->port.dev && port-

[PATCH 02/10] usb/uhci: Introduce and use register defines

2024-11-12 Thread Guenter Roeck
Introduce defines for UHCI registers to simplify adding register access
in subsequent patches of the series.

No functional change.

Reviewed-by: Cédric Le Goater 
Signed-off-by: Guenter Roeck 
---
Changes since RFC:
- Rebased to v9.1.0-1673-g134b443512
- Added Reviewed-by: tag

 hw/usb/hcd-uhci.c  | 32 
 include/hw/usb/uhci-regs.h | 11 +++
 2 files changed, 27 insertions(+), 16 deletions(-)

diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
index 50d488d6fb..bdab9ac37e 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -389,7 +389,7 @@ static void uhci_port_write(void *opaque, hwaddr addr,
 trace_usb_uhci_mmio_writew(addr, val);
 
 switch (addr) {
-case 0x00:
+case UHCI_USBCMD:
 if ((val & UHCI_CMD_RS) && !(s->cmd & UHCI_CMD_RS)) {
 /* start frame processing */
 trace_usb_uhci_schedule_start();
@@ -424,7 +424,7 @@ static void uhci_port_write(void *opaque, hwaddr addr,
 }
 }
 break;
-case 0x02:
+case UHCI_USBSTS:
 s->status &= ~val;
 /*
  * XXX: the chip spec is not coherent, so we add a hidden
@@ -435,27 +435,27 @@ static void uhci_port_write(void *opaque, hwaddr addr,
 }
 uhci_update_irq(s);
 break;
-case 0x04:
+case UHCI_USBINTR:
 s->intr = val;
 uhci_update_irq(s);
 break;
-case 0x06:
+case UHCI_USBFRNUM:
 if (s->status & UHCI_STS_HCHALTED) {
 s->frnum = val & 0x7ff;
 }
 break;
-case 0x08:
+case UHCI_USBFLBASEADD:
 s->fl_base_addr &= 0x;
 s->fl_base_addr |= val & ~0xfff;
 break;
-case 0x0a:
+case UHCI_USBFLBASEADD + 2:
 s->fl_base_addr &= 0x;
 s->fl_base_addr |= (val << 16);
 break;
-case 0x0c:
+case UHCI_USBSOF:
 s->sof_timing = val & 0xff;
 break;
-case 0x10 ... 0x1f:
+case UHCI_USBPORTSC1 ... UHCI_USBPORTSC4:
 {
 UHCIPort *port;
 USBDevice *dev;
@@ -493,28 +493,28 @@ static uint64_t uhci_port_read(void *opaque, hwaddr addr, 
unsigned size)
 uint32_t val;
 
 switch (addr) {
-case 0x00:
+case UHCI_USBCMD:
 val = s->cmd;
 break;
-case 0x02:
+case UHCI_USBSTS:
 val = s->status;
 break;
-case 0x04:
+case UHCI_USBINTR:
 val = s->intr;
 break;
-case 0x06:
+case UHCI_USBFRNUM:
 val = s->frnum;
 break;
-case 0x08:
+case UHCI_USBFLBASEADD:
 val = s->fl_base_addr & 0x;
 break;
-case 0x0a:
+case UHCI_USBFLBASEADD + 2:
 val = (s->fl_base_addr >> 16) & 0x;
 break;
-case 0x0c:
+case UHCI_USBSOF:
 val = s->sof_timing;
 break;
-case 0x10 ... 0x1f:
+case UHCI_USBPORTSC1 ... UHCI_USBPORTSC4:
 {
 UHCIPort *port;
 int n;
diff --git a/include/hw/usb/uhci-regs.h b/include/hw/usb/uhci-regs.h
index fd45d29db0..5b81714e5c 100644
--- a/include/hw/usb/uhci-regs.h
+++ b/include/hw/usb/uhci-regs.h
@@ -1,6 +1,17 @@
 #ifndef HW_USB_UHCI_REGS_H
 #define HW_USB_UHCI_REGS_H
 
+#define UHCI_USBCMD   0
+#define UHCI_USBSTS   2
+#define UHCI_USBINTR  4
+#define UHCI_USBFRNUM 6
+#define UHCI_USBFLBASEADD 8
+#define UHCI_USBSOF   0x0c
+#define UHCI_USBPORTSC1   0x10
+#define UHCI_USBPORTSC2   0x12
+#define UHCI_USBPORTSC3   0x14
+#define UHCI_USBPORTSC4   0x16
+
 #define UHCI_CMD_FGR  (1 << 4)
 #define UHCI_CMD_EGSM (1 << 3)
 #define UHCI_CMD_GRESET   (1 << 2)
-- 
2.45.2




[RFC PATCH 0/8] usb/uhci: Add UHCI sysbus support, and enable for AST machines

2024-11-12 Thread Guenter Roeck
Some machines (like Aspeed ARM) only support a sysbus UHCI controller.
The current UHCI implementation in qemu only supports PCI based UHCI
controllers.

This patch series separates basic and PCI functionality from the hcd-uhci
implementation and then adds uhci-sysbus support. This is then used
to implement and enable sysbus based UHCI support for Aspeed machines.

The series is submitted as RFC since I am quite sure that I didn't get
everything right. All code surrounding VMStates deserves special scrutiny,
as well as the changes outside hw/usb/ and hw/arm/.

A side effect of this patch series is that Aspeed AST2400/2500 machines
will now instantiate UHCI, even if the machine does not actually support
it (it also always instantiates both EHCI ports, so that is not really
different). This means that the default USB bus is now the UHCI bus,
not the second EHCI bus. The bus number must therefore now be specified
explicitly when attaching a device unless attaching it to the UHCI port
is ok. I don't know if it is possible to avoid that and to ensure that
the default USB port is still the second EHCI port.

The code was tested on x86 machines to ensure that the existing UHCI
implementation still works. It was also tested on various Aspeed machines
with enabled UHCI ports (ast2500-evb, ast2600-evb, and rainier-bmc).

Changes since RFC:
- Rebased to v9.1.0-1673-g134b443512
- Added Reviewed-by: tags
- Fixed bug in interrupt initialization of vt82c686-uhci-pci.c
  which if instantiated caused a machine crash
- Instantiate UHCI controllers as companion devices on AST2600 machines


Guenter Roeck (10):
  usb/uhci: checkpatch cleanup
  usb/uhci: Introduce and use register defines
  usb/uhci: Move PCI-related code into a separate file
  usb/uhci: enlarge uhci memory space
  usb/uhci: Add support for usb-uhci-sysbus
  usb/uhci: Add aspeed specific read and write functions
  aspeed: Add uhci support for ast2600
  aspeed: Add uhci support for ast2400 and ast2500
  usb-hub: Add support for v2.0 hubs
  usb-hub: Fix handling port power control messages

 hw/arm/Kconfig|   1 +
 hw/arm/aspeed_ast2400.c   |  14 ++
 hw/arm/aspeed_ast2600.c   |  20 +++
 hw/isa/Kconfig|   4 +-
 hw/isa/vt82c686.c |   4 +-
 hw/usb/Kconfig|  10 +-
 hw/usb/dev-hub.c  |  85 ++-
 hw/usb/hcd-uhci-pci.c | 255 
 hw/usb/hcd-uhci-pci.h |  63 
 hw/usb/hcd-uhci-sysbus.c  | 202 +
 hw/usb/hcd-uhci-sysbus.h  |  34 +
 hw/usb/hcd-uhci.c | 337 +-
 hw/usb/hcd-uhci.h |  30 ++--
 hw/usb/meson.build|   2 +
 hw/usb/vt82c686-uhci-pci.c|  18 +--
 include/hw/arm/aspeed_soc.h   |   3 +
 include/hw/southbridge/piix.h |   4 +-
 include/hw/usb/uhci-regs.h|  11 ++
 18 files changed, 822 insertions(+), 275 deletions(-)
 create mode 100644 hw/usb/hcd-uhci-pci.c
 create mode 100644 hw/usb/hcd-uhci-pci.h
 create mode 100644 hw/usb/hcd-uhci-sysbus.c
 create mode 100644 hw/usb/hcd-uhci-sysbus.h



[PATCH 01/10] usb/uhci: checkpatch cleanup

2024-11-12 Thread Guenter Roeck
Fix reported checkpatch issues to prepare for next patches
in the series.

No functional change.

Reviewed-by: Cédric Le Goater 
Signed-off-by: Guenter Roeck 
---
Changes since RFC:
- Rebased to v9.1.0-1673-g134b443512
- Added Reviewed-by: tag

 hw/usb/hcd-uhci.c | 90 +--
 1 file changed, 56 insertions(+), 34 deletions(-)

diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
index 3d0339af7b..50d488d6fb 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -67,7 +67,7 @@ struct UHCIPCIDeviceClass {
 UHCIInfo   info;
 };
 
-/* 
+/*
  * Pending async transaction.
  * 'packet' must be the first field because completion
  * handler does "(UHCIAsync *) pkt" cast.
@@ -220,8 +220,9 @@ static void uhci_async_cancel(UHCIAsync *async)
 uhci_async_unlink(async);
 trace_usb_uhci_packet_cancel(async->queue->token, async->td_addr,
  async->done);
-if (!async->done)
+if (!async->done) {
 usb_cancel_packet(&async->packet);
+}
 uhci_async_free(async);
 }
 
@@ -322,7 +323,7 @@ static void uhci_reset(DeviceState *dev)
 s->fl_base_addr = 0;
 s->sof_timing = 64;
 
-for(i = 0; i < UHCI_PORTS; i++) {
+for (i = 0; i < UHCI_PORTS; i++) {
 port = &s->ports[i];
 port->ctrl = 0x0080;
 if (port->port.dev && port->port.dev->attached) {
@@ -387,7 +388,7 @@ static void uhci_port_write(void *opaque, hwaddr addr,
 
 trace_usb_uhci_mmio_writew(addr, val);
 
-switch(addr) {
+switch (addr) {
 case 0x00:
 if ((val & UHCI_CMD_RS) && !(s->cmd & UHCI_CMD_RS)) {
 /* start frame processing */
@@ -404,7 +405,7 @@ static void uhci_port_write(void *opaque, hwaddr addr,
 int i;
 
 /* send reset on the USB bus */
-for(i = 0; i < UHCI_PORTS; i++) {
+for (i = 0; i < UHCI_PORTS; i++) {
 port = &s->ports[i];
 usb_device_reset(port->port.dev);
 }
@@ -425,10 +426,13 @@ static void uhci_port_write(void *opaque, hwaddr addr,
 break;
 case 0x02:
 s->status &= ~val;
-/* XXX: the chip spec is not coherent, so we add a hidden
-   register to distinguish between IOC and SPD */
-if (val & UHCI_STS_USBINT)
+/*
+ * XXX: the chip spec is not coherent, so we add a hidden
+ * register to distinguish between IOC and SPD
+ */
+if (val & UHCI_STS_USBINT) {
 s->status2 = 0;
+}
 uhci_update_irq(s);
 break;
 case 0x04:
@@ -436,8 +440,9 @@ static void uhci_port_write(void *opaque, hwaddr addr,
 uhci_update_irq(s);
 break;
 case 0x06:
-if (s->status & UHCI_STS_HCHALTED)
+if (s->status & UHCI_STS_HCHALTED) {
 s->frnum = val & 0x7ff;
+}
 break;
 case 0x08:
 s->fl_base_addr &= 0x;
@@ -464,8 +469,8 @@ static void uhci_port_write(void *opaque, hwaddr addr,
 dev = port->port.dev;
 if (dev && dev->attached) {
 /* port reset */
-if ( (val & UHCI_PORT_RESET) &&
- !(port->ctrl & UHCI_PORT_RESET) ) {
+if ((val & UHCI_PORT_RESET) &&
+ !(port->ctrl & UHCI_PORT_RESET)) {
 usb_device_reset(dev);
 }
 }
@@ -487,7 +492,7 @@ static uint64_t uhci_port_read(void *opaque, hwaddr addr, 
unsigned size)
 UHCIState *s = opaque;
 uint32_t val;
 
-switch(addr) {
+switch (addr) {
 case 0x00:
 val = s->cmd;
 break;
@@ -533,12 +538,13 @@ static uint64_t uhci_port_read(void *opaque, hwaddr addr, 
unsigned size)
 }
 
 /* signal resume if controller suspended */
-static void uhci_resume (void *opaque)
+static void uhci_resume(void *opaque)
 {
 UHCIState *s = (UHCIState *)opaque;
 
-if (!s)
+if (!s) {
 return;
+}
 
 if (s->cmd & UHCI_CMD_EGSM) {
 s->cmd |= UHCI_CMD_FGR;
@@ -674,7 +680,8 @@ static int uhci_handle_td_error(UHCIState *s, UHCI_TD *td, 
uint32_t td_addr,
 return ret;
 }
 
-static int uhci_complete_td(UHCIState *s, UHCI_TD *td, UHCIAsync *async, 
uint32_t *int_mask)
+static int uhci_complete_td(UHCIState *s, UHCI_TD *td, UHCIAsync *async,
+uint32_t *int_mask)
 {
 int len = 0, max_len;
 uint8_t pid;
@@ -682,8 +689,9 @@ static int uhci_complete_td(UHCIState *s, UHCI_TD *td, 
UHCIAsync *async, uint32_
 max_len = ((td->token >> 21) + 1) & 0x7ff;
 pid = td->token & 0xff;
 
-if (td->ctrl & TD_CTRL_IOS)
+if (td->ctrl & TD_CTRL_IOS) {
 td->ctrl &= ~TD_CTRL_ACTIVE;
+}
 
 if (async->packet.status != USB_RET_SUCCESS) {
 return uhci_handle_td_error(s, td, async->td_addr,
@@ -693,12 +701,15 @@ static int uhci_complete_td(UHCIState *s, UHCI_TD *td, 
UHCIAsync *async, uint32_
 len = async->packet.actual_length;
 td->ctr

[RFC PATCH 14/14] s390x/cpumodel: gen17 model

2024-11-12 Thread Hendrik Brueckner
This commit introduces the definition of the gen17a/gen17b CPU model.

Signed-off-by: Hendrik Brueckner 
---
 target/s390x/cpu_models.c   |  2 ++
 target/s390x/gen-features.c | 33 +
 2 files changed, 35 insertions(+)

diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c
index c169c080d1..beb50b5300 100644
--- a/target/s390x/cpu_models.c
+++ b/target/s390x/cpu_models.c
@@ -94,6 +94,8 @@ static S390CPUDef s390_cpu_defs[] = {
 CPUDEF_INIT(0x8562, 15, 1, 47, 0x0800U, "gen15b", "IBM z15 T02 GA1"),
 CPUDEF_INIT(0x3931, 16, 1, 47, 0x0800U, "gen16a", "IBM 3931 GA1"),
 CPUDEF_INIT(0x3932, 16, 1, 47, 0x0800U, "gen16b", "IBM 3932 GA1"),
+CPUDEF_INIT(0x9175, 17, 1, 47, 0x0800U, "gen17a", "IBM 9175 GA1"),
+CPUDEF_INIT(0x9176, 17, 1, 47, 0x0800U, "gen17b", "IBM 9176 GA1"),
 };
 
 #define QEMU_MAX_CPU_TYPE 0x8561
diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c
index 58c8708a72..888e0eac4e 100644
--- a/target/s390x/gen-features.c
+++ b/target/s390x/gen-features.c
@@ -558,6 +558,13 @@ static uint16_t base_GEN15_GA1[] = {
 
 #define base_GEN16_GA1 EmptyFeat
 
+static uint16_t base_GEN17_GA1[] = {
+S390_FEAT_MISC_INSTRUCTION_EXT4,
+S390_FEAT_SIF,
+S390_FEAT_GROUP_MSA_EXT_12,
+S390_FEAT_GROUP_PLO_EXT,
+};
+
 /* Full features (in order of release)
  * Automatically includes corresponding base features.
  * Full features are all features this hardware supports even if kvm/QEMU do 
not
@@ -712,6 +719,20 @@ static uint16_t full_GEN16_GA1[] = {
 S390_FEAT_UV_FEAT_AP_INTR,
 };
 
+static uint16_t full_GEN17_GA1[] = {
+S390_FEAT_VECTOR_ENH3,
+S390_FEAT_VECTOR_PACKED_DECIMAL_ENH3,
+S390_FEAT_INEFF_NC_TX,
+S390_FEAT_GROUP_GEN17_PTFF,
+S390_FEAT_GROUP_MSA_EXT_10,
+S390_FEAT_GROUP_MSA_EXT_10_PCKMO,
+S390_FEAT_GROUP_MSA_EXT_11,
+S390_FEAT_GROUP_MSA_EXT_11_PCKMO,
+S390_FEAT_GROUP_MSA_EXT_13,
+S390_FEAT_GROUP_MSA_EXT_13_PCKMO,
+S390_FEAT_GROUP_CONCURRENT_FUNCTIONS,
+};
+
 
 /* Default features (in order of release)
  * Automatically includes corresponding base features.
@@ -807,6 +828,17 @@ static uint16_t default_GEN16_GA1[] = {
 S390_FEAT_PAIE,
 };
 
+static uint16_t default_GEN17_GA1[] = {
+S390_FEAT_VECTOR_ENH3,
+S390_FEAT_VECTOR_PACKED_DECIMAL_ENH3,
+S390_FEAT_GROUP_MSA_EXT_10,
+S390_FEAT_GROUP_MSA_EXT_10_PCKMO,
+S390_FEAT_GROUP_MSA_EXT_11,
+S390_FEAT_GROUP_MSA_EXT_11_PCKMO,
+S390_FEAT_GROUP_MSA_EXT_13,
+S390_FEAT_GROUP_MSA_EXT_13_PCKMO,
+};
+
 /* QEMU (CPU model) features */
 
 static uint16_t qemu_V2_11[] = {
@@ -955,6 +987,7 @@ static CpuFeatDefSpec CpuFeatDef[] = {
 CPU_FEAT_INITIALIZER(GEN14_GA2),
 CPU_FEAT_INITIALIZER(GEN15_GA1),
 CPU_FEAT_INITIALIZER(GEN16_GA1),
+CPU_FEAT_INITIALIZER(GEN17_GA1),
 };
 
 #define FEAT_GROUP_INITIALIZER(_name)  \
-- 
2.43.5




[PATCH 05/10] usb/uhci: Add support for usb-uhci-sysbus

2024-11-12 Thread Guenter Roeck
Signed-off-by: Guenter Roeck 
---
Changes since RFC:
- Rebased to v9.1.0-1673-g134b443512

 hw/arm/Kconfig   |   1 +
 hw/usb/Kconfig   |   4 ++
 hw/usb/hcd-uhci-sysbus.c | 100 +++
 hw/usb/hcd-uhci-sysbus.h |  23 +
 hw/usb/meson.build   |   1 +
 5 files changed, 129 insertions(+)
 create mode 100644 hw/usb/hcd-uhci-sysbus.c
 create mode 100644 hw/usb/hcd-uhci-sysbus.h

diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 1b25e73578..3f92ae429a 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -540,6 +540,7 @@ config ASPEED_SOC
 select MAX31785
 select FSI_APB2OPB_ASPEED
 select AT24C
+select USB_UHCI_SYSBUS
 
 config MPS2
 bool
diff --git a/hw/usb/Kconfig b/hw/usb/Kconfig
index bab4d2d67d..f51aa82370 100644
--- a/hw/usb/Kconfig
+++ b/hw/usb/Kconfig
@@ -11,6 +11,10 @@ config USB_UHCI_PCI
 depends on PCI
 select USB_UHCI
 
+config USB_UHCI_SYSBUS
+bool
+select USB_UHCI
+
 config USB_OHCI
 bool
 select USB
diff --git a/hw/usb/hcd-uhci-sysbus.c b/hw/usb/hcd-uhci-sysbus.c
new file mode 100644
index 00..3a6c56c3df
--- /dev/null
+++ b/hw/usb/hcd-uhci-sysbus.c
@@ -0,0 +1,100 @@
+/*
+ * QEMU USB UHCI Emulation
+ * Copyright (c) 2006 Openedhand Ltd.
+ * Copyright (c) 2010 CodeSourcery
+ * Copyright (c) 2024 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ */
+
+#include "qemu/osdep.h"
+#include "hw/irq.h"
+#include "qapi/error.h"
+#include "qemu/module.h"
+#include "qemu/timer.h"
+#include "hw/usb.h"
+#include "migration/vmstate.h"
+#include "hw/sysbus.h"
+#include "hw/qdev-dma.h"
+#include "hw/qdev-properties.h"
+#include "trace.h"
+#include "hcd-uhci.h"
+#include "hcd-uhci-sysbus.h"
+
+static void uhci_sysbus_reset(UHCIState *uhci)
+{
+uhci_state_reset(uhci);
+}
+
+static void uhci_sysbus_realize(DeviceState *dev, Error **errp)
+{
+UHCISysBusState *s = SYSBUS_UHCI(dev);
+UHCIState *uhci = &s->uhci;
+SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+Error *err = NULL;
+
+uhci->masterbus = s->masterbus;
+uhci->firstport = s->firstport;
+uhci->maxframes = s->maxframes;
+uhci->frame_bandwidth = s->frame_bandwidth;
+uhci->as = &address_space_memory;
+uhci->uhci_reset = uhci_sysbus_reset;
+
+usb_uhci_init(uhci, dev, &err);
+
+if (err) {
+error_propagate(errp, err);
+return;
+}
+sysbus_init_irq(sbd, &uhci->irq);
+sysbus_init_mmio(sbd, &uhci->mem);
+}
+
+static void uhci_sysbus_reset_sysbus(DeviceState *dev)
+{
+UHCISysBusState *s = SYSBUS_UHCI(dev);
+UHCIState *uhci = &s->uhci;
+
+uhci_sysbus_reset(uhci);
+}
+
+static Property uhci_sysbus_properties[] = {
+DEFINE_PROP_STRING("masterbus", UHCISysBusState, masterbus),
+DEFINE_PROP_UINT32("firstport", UHCISysBusState, firstport, 0),
+DEFINE_PROP_UINT32("bandwidth", UHCISysBusState, frame_bandwidth, 1280),
+DEFINE_PROP_UINT32("maxframes", UHCISysBusState, maxframes, 128),
+DEFINE_PROP_END_OF_LIST(),
+};
+
+static void uhci_sysbus_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+dc->realize = uhci_sysbus_realize;
+set_bit(DEVICE_CATEGORY_USB, dc->categories);
+dc->desc = "UHCI USB Controller";
+device_class_set_props(dc, uhci_sysbus_properties);
+device_class_set_legacy_reset(dc, uhci_sysbus_reset_sysbus);
+}
+
+static const TypeInfo uhci_sysbus_types[] = {
+{
+.name  = TYPE_SYSBUS_UHCI,
+.parent= TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(UHCISysBusState),
+.class_init= uhci_sysbus_class_init,
+},
+};
+
+DEFINE_TYPES(uhci_sysbus_types);
diff --git a/hw/usb/hcd-uhci-sysbus.h b/hw/usb/hcd-uhci-sysbus.h
new file mode 100644
index 00..c491b9fc92
--- /dev/null
+++ b/hw/usb/hcd-uhci-sysbus.h
@@ -0,0 +1,23 @@
+#ifndef HW_USB_HCD_UHCI_SYSBUS_H
+#define HW_USB_HCD_UHCI_SYSBUS_H
+
+#include "hcd-uhci.h"
+
+#define TYPE_SYSBUS_UHCI "sysbus-uhci"
+
+OBJECT_DECLARE_SIMPLE_TYPE(UHCISysBusState, SYSBUS_UHCI)
+
+struct UHCISysBusState {
+/*< private >*/
+SysBusDevice parent_obj;
+/*< public >*/
+UHCIState uhci;
+
+char *masterbus;
+uint32_t firstport;
+uint32_t frame_bandwidth;
+uint32_t maxframes;
+uint32_t num_ports;
+};
+
+#endif /* HW_USB_HCD_UHCI_SYSBUS_H */
diff -

Re: [RFC PATCH 0/8] usb/uhci: Add UHCI sysbus support, and enable for AST machines

2024-11-12 Thread Guenter Roeck

Oops, sorry, the subject should have started with "[PATCH 00/10]"

Why do I always see that one second after sending :-(

Guenter

On 11/12/24 08:56, Guenter Roeck wrote:

Some machines (like Aspeed ARM) only support a sysbus UHCI controller.
The current UHCI implementation in qemu only supports PCI based UHCI
controllers.

This patch series separates basic and PCI functionality from the hcd-uhci
implementation and then adds uhci-sysbus support. This is then used
to implement and enable sysbus based UHCI support for Aspeed machines.

The series is submitted as RFC since I am quite sure that I didn't get
everything right. All code surrounding VMStates deserves special scrutiny,
as well as the changes outside hw/usb/ and hw/arm/.

A side effect of this patch series is that Aspeed AST2400/2500 machines
will now instantiate UHCI, even if the machine does not actually support
it (it also always instantiates both EHCI ports, so that is not really
different). This means that the default USB bus is now the UHCI bus,
not the second EHCI bus. The bus number must therefore now be specified
explicitly when attaching a device unless attaching it to the UHCI port
is ok. I don't know if it is possible to avoid that and to ensure that
the default USB port is still the second EHCI port.

The code was tested on x86 machines to ensure that the existing UHCI
implementation still works. It was also tested on various Aspeed machines
with enabled UHCI ports (ast2500-evb, ast2600-evb, and rainier-bmc).

Changes since RFC:
- Rebased to v9.1.0-1673-g134b443512
- Added Reviewed-by: tags
- Fixed bug in interrupt initialization of vt82c686-uhci-pci.c
   which if instantiated caused a machine crash
- Instantiate UHCI controllers as companion devices on AST2600 machines


Guenter Roeck (10):
   usb/uhci: checkpatch cleanup
   usb/uhci: Introduce and use register defines
   usb/uhci: Move PCI-related code into a separate file
   usb/uhci: enlarge uhci memory space
   usb/uhci: Add support for usb-uhci-sysbus
   usb/uhci: Add aspeed specific read and write functions
   aspeed: Add uhci support for ast2600
   aspeed: Add uhci support for ast2400 and ast2500
   usb-hub: Add support for v2.0 hubs
   usb-hub: Fix handling port power control messages

  hw/arm/Kconfig|   1 +
  hw/arm/aspeed_ast2400.c   |  14 ++
  hw/arm/aspeed_ast2600.c   |  20 +++
  hw/isa/Kconfig|   4 +-
  hw/isa/vt82c686.c |   4 +-
  hw/usb/Kconfig|  10 +-
  hw/usb/dev-hub.c  |  85 ++-
  hw/usb/hcd-uhci-pci.c | 255 
  hw/usb/hcd-uhci-pci.h |  63 
  hw/usb/hcd-uhci-sysbus.c  | 202 +
  hw/usb/hcd-uhci-sysbus.h  |  34 +
  hw/usb/hcd-uhci.c | 337 +-
  hw/usb/hcd-uhci.h |  30 ++--
  hw/usb/meson.build|   2 +
  hw/usb/vt82c686-uhci-pci.c|  18 +--
  include/hw/arm/aspeed_soc.h   |   3 +
  include/hw/southbridge/piix.h |   4 +-
  include/hw/usb/uhci-regs.h|  11 ++
  18 files changed, 822 insertions(+), 275 deletions(-)
  create mode 100644 hw/usb/hcd-uhci-pci.c
  create mode 100644 hw/usb/hcd-uhci-pci.h
  create mode 100644 hw/usb/hcd-uhci-sysbus.c
  create mode 100644 hw/usb/hcd-uhci-sysbus.h





[PATCH 4/7 for-9.2] tests/acpi: update expected blobs

2024-11-12 Thread Igor Mammedov
Expected AML return to the state before
  bf1ecc8dad606 (w/acpi: Update ACPI `_STA` method with QOM vCPU ACPI Hotplug 
states)
droping not needed CPRS and _STA logic that broke cpu hotplug

@@ -2887,7 +2887,6 @@ DefinitionBlock ("", "DSDT", 1, "BOCHS ", "BXPC   
 ", 0x0001)
 CRMV,   1,
 CEJ0,   1,
 CEJF,   1,
-CPRS,   1,
 Offset (0x05),
 CCMD,   8
 }
@@ -2922,16 +2921,9 @@ DefinitionBlock ("", "DSDT", 1, "BOCHS ", "BXPC  
  ", 0x0001)
 Acquire (\_SB.PCI0.PRES.CPLK, 0x)
 \_SB.PCI0.PRES.CSEL = Arg0
 Local0 = Zero
-If ((\_SB.PCI0.PRES.CPRS == One))
+If ((\_SB.PCI0.PRES.CPEN == One))
 {
-If ((\_SB.PCI0.PRES.CPEN == One))
-{
-Local0 = 0x0F
-}
-Else
-{
-Local0 = 0x0D
-}
+Local0 = 0x0F
 }

Signed-off-by: Igor Mammedov 
---
 tests/qtest/bios-tables-test-allowed-diff.h   |  41 --
 tests/data/acpi/x86/pc/DSDT   | Bin 8560 -> 8526 bytes
 tests/data/acpi/x86/pc/DSDT.acpierst  | Bin 8471 -> 8437 bytes
 tests/data/acpi/x86/pc/DSDT.acpihmat  | Bin 9885 -> 9851 bytes
 tests/data/acpi/x86/pc/DSDT.bridge| Bin 15431 -> 15397 bytes
 tests/data/acpi/x86/pc/DSDT.cphp  | Bin 9024 -> 8990 bytes
 tests/data/acpi/x86/pc/DSDT.dimmpxm   | Bin 10214 -> 10180 bytes
 tests/data/acpi/x86/pc/DSDT.hpbridge  | Bin 8511 -> 8477 bytes
 tests/data/acpi/x86/pc/DSDT.hpbrroot  | Bin 5067 -> 5033 bytes
 tests/data/acpi/x86/pc/DSDT.ipmikcs   | Bin 8632 -> 8598 bytes
 tests/data/acpi/x86/pc/DSDT.memhp | Bin 9919 -> 9885 bytes
 tests/data/acpi/x86/pc/DSDT.nohpet| Bin 8418 -> 8384 bytes
 tests/data/acpi/x86/pc/DSDT.numamem   | Bin 8566 -> 8532 bytes
 tests/data/acpi/x86/pc/DSDT.roothp| Bin 12353 -> 12319 bytes
 tests/data/acpi/x86/q35/DSDT  | Bin 8389 -> 8355 bytes
 tests/data/acpi/x86/q35/DSDT.acpierst | Bin 8406 -> 8372 bytes
 tests/data/acpi/x86/q35/DSDT.acpihmat | Bin 9714 -> 9680 bytes
 .../acpi/x86/q35/DSDT.acpihmat-noinitiator| Bin 8668 -> 8634 bytes
 tests/data/acpi/x86/q35/DSDT.applesmc | Bin 8435 -> 8401 bytes
 tests/data/acpi/x86/q35/DSDT.bridge   | Bin 12002 -> 11968 bytes
 tests/data/acpi/x86/q35/DSDT.core-count   | Bin 12947 -> 12913 bytes
 tests/data/acpi/x86/q35/DSDT.core-count2  | Bin 33804 -> 33770 bytes
 tests/data/acpi/x86/q35/DSDT.cphp | Bin 8853 -> 8819 bytes
 tests/data/acpi/x86/q35/DSDT.cxl  | Bin 13180 -> 13146 bytes
 tests/data/acpi/x86/q35/DSDT.dimmpxm  | Bin 10043 -> 10009 bytes
 tests/data/acpi/x86/q35/DSDT.ipmibt   | Bin 8464 -> 8430 bytes
 tests/data/acpi/x86/q35/DSDT.ipmismbus| Bin 8477 -> 8443 bytes
 tests/data/acpi/x86/q35/DSDT.ivrs | Bin 8406 -> 8372 bytes
 tests/data/acpi/x86/q35/DSDT.memhp| Bin 9748 -> 9714 bytes
 tests/data/acpi/x86/q35/DSDT.mmio64   | Bin 9519 -> 9485 bytes
 tests/data/acpi/x86/q35/DSDT.multi-bridge | Bin 13242 -> 13208 bytes
 tests/data/acpi/x86/q35/DSDT.noacpihp | Bin 8269 -> 8235 bytes
 tests/data/acpi/x86/q35/DSDT.nohpet   | Bin 8247 -> 8213 bytes
 tests/data/acpi/x86/q35/DSDT.numamem  | Bin 8395 -> 8361 bytes
 tests/data/acpi/x86/q35/DSDT.pvpanic-isa  | Bin 8490 -> 8456 bytes
 tests/data/acpi/x86/q35/DSDT.thread-count | Bin 12947 -> 12913 bytes
 tests/data/acpi/x86/q35/DSDT.thread-count2| Bin 33804 -> 33770 bytes
 tests/data/acpi/x86/q35/DSDT.tis.tpm12| Bin 8995 -> 8961 bytes
 tests/data/acpi/x86/q35/DSDT.tis.tpm2 | Bin 9021 -> 8987 bytes
 tests/data/acpi/x86/q35/DSDT.type4-count  | Bin 18623 -> 18589 bytes
 tests/data/acpi/x86/q35/DSDT.viot | Bin 14646 -> 14612 bytes
 tests/data/acpi/x86/q35/DSDT.xapic| Bin 35752 -> 35718 bytes
 42 files changed, 41 deletions(-)

diff --git a/tests/qtest/bios-tables-test-allowed-diff.h 
b/tests/qtest/bios-tables-test-allowed-diff.h
index 512d40665d..dfb8523c8b 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1,42 +1 @@
 /* List of comma-separated changed AML files to ignore */
-"tests/data/acpi/x86/pc/DSDT",
-"tests/data/acpi/x86/pc/DSDT.acpierst",
-"tests/data/acpi/x86/pc/DSDT.acpihmat",
-"tests/data/acpi/x86/pc/DSDT.bridge",
-"tests/data/acpi/x86/pc/DSDT.cphp",
-"tests/data/acpi/x86/pc/DSDT.dimmpxm",
-"tests/data/acpi/x86

[RESEND PATCH 05/10] usb/uhci: Add support for usb-uhci-sysbus

2024-11-12 Thread Guenter Roeck
Signed-off-by: Guenter Roeck 
---
Changes since RFC:
- Rebased to v9.1.0-1673-g134b443512

 hw/arm/Kconfig   |   1 +
 hw/usb/Kconfig   |   4 ++
 hw/usb/hcd-uhci-sysbus.c | 100 +++
 hw/usb/hcd-uhci-sysbus.h |  23 +
 hw/usb/meson.build   |   1 +
 5 files changed, 129 insertions(+)
 create mode 100644 hw/usb/hcd-uhci-sysbus.c
 create mode 100644 hw/usb/hcd-uhci-sysbus.h

diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 1b25e73578..3f92ae429a 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -540,6 +540,7 @@ config ASPEED_SOC
 select MAX31785
 select FSI_APB2OPB_ASPEED
 select AT24C
+select USB_UHCI_SYSBUS
 
 config MPS2
 bool
diff --git a/hw/usb/Kconfig b/hw/usb/Kconfig
index bab4d2d67d..f51aa82370 100644
--- a/hw/usb/Kconfig
+++ b/hw/usb/Kconfig
@@ -11,6 +11,10 @@ config USB_UHCI_PCI
 depends on PCI
 select USB_UHCI
 
+config USB_UHCI_SYSBUS
+bool
+select USB_UHCI
+
 config USB_OHCI
 bool
 select USB
diff --git a/hw/usb/hcd-uhci-sysbus.c b/hw/usb/hcd-uhci-sysbus.c
new file mode 100644
index 00..3a6c56c3df
--- /dev/null
+++ b/hw/usb/hcd-uhci-sysbus.c
@@ -0,0 +1,100 @@
+/*
+ * QEMU USB UHCI Emulation
+ * Copyright (c) 2006 Openedhand Ltd.
+ * Copyright (c) 2010 CodeSourcery
+ * Copyright (c) 2024 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ */
+
+#include "qemu/osdep.h"
+#include "hw/irq.h"
+#include "qapi/error.h"
+#include "qemu/module.h"
+#include "qemu/timer.h"
+#include "hw/usb.h"
+#include "migration/vmstate.h"
+#include "hw/sysbus.h"
+#include "hw/qdev-dma.h"
+#include "hw/qdev-properties.h"
+#include "trace.h"
+#include "hcd-uhci.h"
+#include "hcd-uhci-sysbus.h"
+
+static void uhci_sysbus_reset(UHCIState *uhci)
+{
+uhci_state_reset(uhci);
+}
+
+static void uhci_sysbus_realize(DeviceState *dev, Error **errp)
+{
+UHCISysBusState *s = SYSBUS_UHCI(dev);
+UHCIState *uhci = &s->uhci;
+SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+Error *err = NULL;
+
+uhci->masterbus = s->masterbus;
+uhci->firstport = s->firstport;
+uhci->maxframes = s->maxframes;
+uhci->frame_bandwidth = s->frame_bandwidth;
+uhci->as = &address_space_memory;
+uhci->uhci_reset = uhci_sysbus_reset;
+
+usb_uhci_init(uhci, dev, &err);
+
+if (err) {
+error_propagate(errp, err);
+return;
+}
+sysbus_init_irq(sbd, &uhci->irq);
+sysbus_init_mmio(sbd, &uhci->mem);
+}
+
+static void uhci_sysbus_reset_sysbus(DeviceState *dev)
+{
+UHCISysBusState *s = SYSBUS_UHCI(dev);
+UHCIState *uhci = &s->uhci;
+
+uhci_sysbus_reset(uhci);
+}
+
+static Property uhci_sysbus_properties[] = {
+DEFINE_PROP_STRING("masterbus", UHCISysBusState, masterbus),
+DEFINE_PROP_UINT32("firstport", UHCISysBusState, firstport, 0),
+DEFINE_PROP_UINT32("bandwidth", UHCISysBusState, frame_bandwidth, 1280),
+DEFINE_PROP_UINT32("maxframes", UHCISysBusState, maxframes, 128),
+DEFINE_PROP_END_OF_LIST(),
+};
+
+static void uhci_sysbus_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+dc->realize = uhci_sysbus_realize;
+set_bit(DEVICE_CATEGORY_USB, dc->categories);
+dc->desc = "UHCI USB Controller";
+device_class_set_props(dc, uhci_sysbus_properties);
+device_class_set_legacy_reset(dc, uhci_sysbus_reset_sysbus);
+}
+
+static const TypeInfo uhci_sysbus_types[] = {
+{
+.name  = TYPE_SYSBUS_UHCI,
+.parent= TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(UHCISysBusState),
+.class_init= uhci_sysbus_class_init,
+},
+};
+
+DEFINE_TYPES(uhci_sysbus_types);
diff --git a/hw/usb/hcd-uhci-sysbus.h b/hw/usb/hcd-uhci-sysbus.h
new file mode 100644
index 00..c491b9fc92
--- /dev/null
+++ b/hw/usb/hcd-uhci-sysbus.h
@@ -0,0 +1,23 @@
+#ifndef HW_USB_HCD_UHCI_SYSBUS_H
+#define HW_USB_HCD_UHCI_SYSBUS_H
+
+#include "hcd-uhci.h"
+
+#define TYPE_SYSBUS_UHCI "sysbus-uhci"
+
+OBJECT_DECLARE_SIMPLE_TYPE(UHCISysBusState, SYSBUS_UHCI)
+
+struct UHCISysBusState {
+/*< private >*/
+SysBusDevice parent_obj;
+/*< public >*/
+UHCIState uhci;
+
+char *masterbus;
+uint32_t firstport;
+uint32_t frame_bandwidth;
+uint32_t maxframes;
+uint32_t num_ports;
+};
+
+#endif /* HW_USB_HCD_UHCI_SYSBUS_H */
diff -

[RESEND PATCH 04/10] usb/uhci: enlarge uhci memory space

2024-11-12 Thread Guenter Roeck
hcd-uhci-sysbus will require more memory than hcd-uhci-pci
since registers for some hardware (specifically Aspeed) don't
map 1:1.

Signed-off-by: Guenter Roeck 
---
Changes since RFC:
- Rebased to v9.1.0-1673-g134b443512

 hw/usb/hcd-uhci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
index 68b72f8d3b..d2993a98b8 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -1212,7 +1212,7 @@ void usb_uhci_init(UHCIState *s, DeviceState *dev, Error 
**errp)
 QTAILQ_INIT(&s->queues);
 
 memory_region_init_io(&s->mem, OBJECT(s), &uhci_ioport_ops, s,
-  "uhci", 0x20);
+  "uhci", 0x100);
 }
 
 void usb_uhci_exit(UHCIState *s)
-- 
2.45.2




[RESEND PATCH 06/10] usb/uhci: Add aspeed specific read and write functions

2024-11-12 Thread Guenter Roeck
Aspeed uses non-standard UHCI register addresses. On top of that,
registers are 32 bit wide instead of 16 bit.

Map Aspeed UHCI addresses to standard UHCI addresses and where needed
combine/split 32 bit accesses to solve the problem.

In addition to that, Aspeed SoCs starting with AST2600 support and use EHCI
companion mode on the second EHCI interface. Support this by moving the
property initialization to the Aspeed class initialization code. Since the
USB ports are part of the SoC and always present, set user_creatable to
false for the Aspeed UHCI controller.

Signed-off-by: Guenter Roeck 
---
Changes since RFC:
- Rebased to v9.1.0-1673-g134b443512
- Added support for EHCI companion mode

 hw/usb/hcd-uhci-sysbus.c | 104 ++-
 hw/usb/hcd-uhci-sysbus.h |  11 +
 2 files changed, 114 insertions(+), 1 deletion(-)

diff --git a/hw/usb/hcd-uhci-sysbus.c b/hw/usb/hcd-uhci-sysbus.c
index 3a6c56c3df..628b6601a1 100644
--- a/hw/usb/hcd-uhci-sysbus.c
+++ b/hw/usb/hcd-uhci-sysbus.c
@@ -20,7 +20,9 @@
 
 #include "qemu/osdep.h"
 #include "hw/irq.h"
+#include "hw/usb/uhci-regs.h"
 #include "qapi/error.h"
+#include "qemu/log.h"
 #include "qemu/module.h"
 #include "qemu/timer.h"
 #include "hw/usb.h"
@@ -84,10 +86,104 @@ static void uhci_sysbus_class_init(ObjectClass *klass, 
void *data)
 dc->realize = uhci_sysbus_realize;
 set_bit(DEVICE_CATEGORY_USB, dc->categories);
 dc->desc = "UHCI USB Controller";
-device_class_set_props(dc, uhci_sysbus_properties);
 device_class_set_legacy_reset(dc, uhci_sysbus_reset_sysbus);
 }
 
+static hwaddr aspeed_uhci_chip_to_uhci(hwaddr addr)
+{
+switch (addr) {
+case 0x00:
+return UHCI_USBCMD;
+case 0x04:
+return UHCI_USBSTS;
+case 0x08:
+return UHCI_USBINTR;
+case 0x0c:
+return UHCI_USBFLBASEADD;
+case 0x80:
+return UHCI_USBFRNUM;
+case 0x84:
+return UHCI_USBSOF;
+case 0x88:
+return UHCI_USBPORTSC1;
+case 0x8c:
+return UHCI_USBPORTSC2;
+case 0x90:
+return UHCI_USBPORTSC3;
+case 0x94:
+return UHCI_USBPORTSC4;
+default:/* unimplemented */
+qemu_log_mask(LOG_UNIMP, "Unimplemented Aspeed UHCI register 0x%lx\n",
+  addr);
+return 0x20;
+}
+}
+
+/*
+ * Aspeed UHCI registers are 32 bit wide.
+ * Convert to 16 bit to access standard UHCI code.
+ */
+static uint64_t aspeed_uhci_port_read(void *opaque, hwaddr addr, unsigned size)
+{
+UHCIState *uhci = opaque;
+MemoryRegion *mr = &uhci->mem;
+hwaddr uaddr = aspeed_uhci_chip_to_uhci(addr);
+
+if (uaddr == UHCI_USBFLBASEADD) {
+return mr->ops->read(opaque, uaddr, 2) |
+   mr->ops->read(opaque, uaddr + 2, 2) << 16;
+}
+return mr->ops->read(opaque, uaddr, 2);
+}
+
+static void aspeed_uhci_port_write(void *opaque, hwaddr addr, uint64_t val,
+   unsigned size)
+{
+UHCIState *uhci = opaque;
+MemoryRegion *mr = &uhci->mem;
+hwaddr uaddr = aspeed_uhci_chip_to_uhci(addr);
+
+if (uaddr == UHCI_USBFLBASEADD) {
+mr->ops->write(opaque, uaddr, val & 0x, 2);
+mr->ops->write(opaque, uaddr + 2, val >> 16, 2);
+} else {
+mr->ops->write(opaque, uaddr, val, 2);
+}
+}
+
+static const MemoryRegionOps aspeed_uhci_mmio_ops = {
+.read = aspeed_uhci_port_read,
+.write = aspeed_uhci_port_write,
+.valid.min_access_size = 4,
+.valid.max_access_size = 4,
+.endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static void uhci_sysbus_aspeed_realize(DeviceState *dev, Error **errp)
+{
+UHCISysBusState *s = SYSBUS_UHCI(dev);
+ASPEEDUHCIState *f = ASPEED_UHCI(dev);
+UHCIState *uhci = &s->uhci;
+
+uhci_sysbus_realize(dev, errp);
+
+memory_region_init_io(&f->mem_aspeed, OBJECT(f), &aspeed_uhci_mmio_ops,
+  uhci, "aspeed", 0x100);
+memory_region_add_subregion(&uhci->mem, 0, &f->mem_aspeed);
+}
+
+static void uhci_sysbus_aspeed_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+dc->realize = uhci_sysbus_aspeed_realize;
+set_bit(DEVICE_CATEGORY_USB, dc->categories);
+dc->desc = "ASPEED UHCI USB Controller";
+device_class_set_legacy_reset(dc, uhci_sysbus_reset_sysbus);
+device_class_set_props(dc, uhci_sysbus_properties);
+dc->user_creatable = false;
+}
+
 static const TypeInfo uhci_sysbus_types[] = {
 {
 .name  = TYPE_SYSBUS_UHCI,
@@ -95,6 +191,12 @@ static const TypeInfo uhci_sysbus_types[] = {
 .instance_size = sizeof(UHCISysBusState),
 .class_init= uhci_sysbus_class_init,
 },
+{
+.name  = TYPE_ASPEED_UHCI,
+.parent= TYPE_SYSBUS_UHCI,
+.instance_size = sizeof(ASPEEDUHCIState),
+.class_init= uhci_sysbus_aspeed_class_init,
+},
 };
 
 DEFINE_TYPES(uhci_sysbus_types);
diff --git a/hw/usb/hcd-uhci-sysbus.h b/hw/usb/hc

[PATCH v3 0/4] Improve Mips target

2024-11-12 Thread Aleksandar Rakic
This patch series adds support for emulation of CRC32 instructions for
the Mips target in QEMU, skips NaN mode check for soft-float, adds a CLI
flag for enabling an MSA feature, and enables the MSA for
MIPS64R2-generic.

There aren't tests for these improvements.

The patch 1/8 "Add CP0 MemoryMapID register implementation" from v2 has
been dropped from v3 since it has been accepted and integrated into the
master branch.

The patch 3/8 "GTM19-448: Fix script to work without realpath" from v2
will be sent separately as it is a fix to a general bug and is intended
for other maintainers.

The patch 5/8 "Add micromips to P5600" from v2 has been dropped from v3
since the latest document for P5600 with eventually updated field
CP0_Config3_ISA that would support microMIPS hasn't been found.

The patch 6/8 "Revert use of clock_gettime for benchmarking" from v2 has
been dropped from v3 because it seems that clock_gettime and
CLOCK_MONOTONIC exist in MinGW headers and that QEMU builds with MinGW.

The patch 7/8 "target/mips: Enable MSA ASE for mips32r6-generic" from v2
has been dropped from v3 since it has been accepted and integrated into
the master branch.

When it comes to the patch 8/8 "target/mips: Enable MSA ASE for
mips64R2-generic" from v2, the cpu Loongson-3A4000 supports both
mips64r2 and the MSA, so I'm not sure whether to drop this patch.

Regarding the DSPRAM for I6500, I heard that the IP for the DSPRAM for
mips64r6 hasn't been published, but in the document "MIPS64® I6500
Multiprocessing System Programmer’s Guide" the DSPRAM is elaborated, so
I don't know whether to add support for the DSPRAM.

Most of the following patches are cherry-picked from the branch
mips_rel/4_1_0/master on the MIPS' repository:
https://github.com/MIPS/gnutools-qemu/
Further details on individual changes are included in the respective
patches. An instance of a pipeline of QEMU CI jobs run with input
variable QEMU_CI=1 for this patch series is available here:
https://gitlab.com/rakicaleksandar1999/qemu/-/pipelines/1533819034
and for the master branch is available here:
https://gitlab.com/rakicaleksandar1999/qemu/-/pipelines/1533465414

We are open for a discussion.



[PATCH] GTM19-448: Fix script to work without realpath

2024-11-12 Thread Aleksandar Rakic
The archive-source.sh script depends on realpath command, which was
introduced in coreutils-8.15. CentOS-6 build systems use coreutils-4.7,
which does not have realpath, so fix the script to use 'readlink -e' to
perform the same action.

Cherry-picked 5d1d5766f0219ce2bec4e41c2467317df920ec0a
and 8003ab4032772a0e5b46e5983fe06268d3469289
from https://github.com/MIPS/gnutools-qemu

An instance of a pipeline of QEMU CI jobs run with input
variable QEMU_CI=1 for this patch is available here:
https://gitlab.com/rakicaleksandar1999/qemu/-/pipelines/1538854588
and for the master branch is available here:
https://gitlab.com/rakicaleksandar1999/qemu/-/pipelines/1533465414

Signed-off-by: Faraz Shahbazker 
Signed-off-by: Chao-ying Fu 
Signed-off-by: Aleksandar Rakic 
---
 scripts/archive-source.sh | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/scripts/archive-source.sh b/scripts/archive-source.sh
index 30677c3ec9..bfaa0c1483 100755
--- a/scripts/archive-source.sh
+++ b/scripts/archive-source.sh
@@ -18,7 +18,13 @@ if test $# -lt 1; then
 error "Usage: $0 "
 fi
 
-tar_file=$(realpath "$1")
+which realpath
+if [ $? -eq 0 ]; then
+tar_file=$(realpath -s "$1")
+else
+d=$(dirname "$1")
+tar_file=$(readlink -e "$d")"/"$(basename "$1")
+fi
 sub_tdir=$(mktemp -d "${tar_file%.tar}.sub.")
 sub_file="${sub_tdir}/submodule.tar"
 
-- 
2.34.1




Re: [PATCH] linux-user: Add missing mmap include

2024-11-12 Thread Alex Bennée
Richard Henderson  writes:

> On 10/28/24 11:18, Patrick Leis wrote:
>> From: Peter Foley 
>> error: use of undeclared identifier 'MAP_FIXED_NOREPLACE'
>> Signed-off-by: Patrick Leis 
>> Signed-off-by: Peter Foley 
>> ---
>>   linux-user/user-mmap.h | 2 ++
>>   1 file changed, 2 insertions(+)
>> diff --git a/linux-user/user-mmap.h b/linux-user/user-mmap.h
>> index b94bcdcf83..de769f9253 100644
>> --- a/linux-user/user-mmap.h
>> +++ b/linux-user/user-mmap.h
>> @@ -18,6 +18,8 @@
>>   #ifndef LINUX_USER_USER_MMAP_H
>>   #define LINUX_USER_USER_MMAP_H
>>   +#include "linux/mman.h"
>> +
>>   /*
>>* Guest parameters for the ADDR_COMPAT_LAYOUT personality
>>* (at present this is the only layout supported by QEMU).
>
> In what context does this appear?
> Both glibc and musl define this in .

I'm going to take a wild guess it's bionic:

🕙16:33:53 alex@draig:bionic.git  on  main 
➜  git grep MAP_FIXED_NOREPLACE
libc/kernel/uapi/asm-generic/mman-common.h:#define MAP_FIXED_NOREPLACE 0x10

>
>
> r~

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



[RFC PATCH 05/14] s390x/cpumodel: Add ptff Query Time-Stamp Event (QTSE) support

2024-11-12 Thread Hendrik Brueckner
Introduce a new PTFF subfunction to query-stamp events.

Signed-off-by: Hendrik Brueckner 
---
 target/s390x/cpu_features.c | 1 +
 target/s390x/cpu_features_def.h.inc | 1 +
 target/s390x/gen-features.c | 9 +
 3 files changed, 11 insertions(+)

diff --git a/target/s390x/cpu_features.c b/target/s390x/cpu_features.c
index ed0266ede1..5a85d24bb8 100644
--- a/target/s390x/cpu_features.c
+++ b/target/s390x/cpu_features.c
@@ -241,6 +241,7 @@ static S390FeatGroupDef s390_feature_groups[] = {
 FEAT_GROUP_INIT("plo", PLO, "Perform-locked-operation facility"),
 FEAT_GROUP_INIT("tods", TOD_CLOCK_STEERING, "Tod-clock-steering facility"),
 FEAT_GROUP_INIT("gen13ptff", GEN13_PTFF, "PTFF enhancements introduced 
with z13"),
+FEAT_GROUP_INIT("gen17ptff", GEN17_PTFF, "PTFF enhancements introduced 
with gen17"),
 FEAT_GROUP_INIT("msa", MSA, "Message-security-assist facility"),
 FEAT_GROUP_INIT("msa1", MSA_EXT_1, "Message-security-assist-extension 1 
facility"),
 FEAT_GROUP_INIT("msa2", MSA_EXT_2, "Message-security-assist-extension 2 
facility"),
diff --git a/target/s390x/cpu_features_def.h.inc 
b/target/s390x/cpu_features_def.h.inc
index 2132837ffe..f96cb5a7d8 100644
--- a/target/s390x/cpu_features_def.h.inc
+++ b/target/s390x/cpu_features_def.h.inc
@@ -181,6 +181,7 @@ DEF_FEAT(PTFF_QSI, "ptff-qsi", PTFF, 2, "PTFF Query 
Steering Information")
 DEF_FEAT(PTFF_QPT, "ptff-qpc", PTFF, 3, "PTFF Query Physical Clock")
 DEF_FEAT(PTFF_QUI, "ptff-qui", PTFF, 4, "PTFF Query UTC Information")
 DEF_FEAT(PTFF_QTOU, "ptff-qtou", PTFF, 5, "PTFF Query TOD Offset User")
+DEF_FEAT(PTFF_QTSE, "ptff-qtse", PTFF, 6, "PTFF Query Time-Stamp Event")
 DEF_FEAT(PTFF_QSIE, "ptff-qsie", PTFF, 10, "PTFF Query Steering Information 
Extended")
 DEF_FEAT(PTFF_QTOUE, "ptff-qtoue", PTFF, 13, "PTFF Query TOD Offset User 
Extended")
 DEF_FEAT(PTFF_STO, "ptff-sto", PTFF, 65, "PTFF Set TOD Offset")
diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c
index 3326e7df43..302b653214 100644
--- a/target/s390x/gen-features.c
+++ b/target/s390x/gen-features.c
@@ -64,6 +64,9 @@
 S390_FEAT_PTFF_STOE, \
 S390_FEAT_PTFF_STOUE
 
+#define S390_FEAT_GROUP_GEN17_PTFF \
+S390_FEAT_PTFF_QTSE
+
 #define S390_FEAT_GROUP_MSA \
 S390_FEAT_MSA, \
 S390_FEAT_KMAC_DEA, \
@@ -318,6 +321,11 @@ static uint16_t group_GEN13_PTFF[] = {
 static uint16_t group_MULTIPLE_EPOCH_PTFF[] = {
 S390_FEAT_GROUP_MULTIPLE_EPOCH_PTFF,
 };
+
+static uint16_t group_GEN17_PTFF[] = {
+S390_FEAT_GROUP_GEN17_PTFF,
+};
+
 static uint16_t group_MSA[] = {
 S390_FEAT_GROUP_MSA,
 };
@@ -918,6 +926,7 @@ static FeatGroupDefSpec FeatGroupDef[] = {
 FEAT_GROUP_INITIALIZER(PLO),
 FEAT_GROUP_INITIALIZER(TOD_CLOCK_STEERING),
 FEAT_GROUP_INITIALIZER(GEN13_PTFF),
+FEAT_GROUP_INITIALIZER(GEN17_PTFF),
 FEAT_GROUP_INITIALIZER(MSA),
 FEAT_GROUP_INITIALIZER(MSA_EXT_1),
 FEAT_GROUP_INITIALIZER(MSA_EXT_2),
-- 
2.43.5




[RFC 6/7] DO NOT MERGE: acpi: cpuhp: use 'realized' status of vCPU to check if CPU is enabled

2024-11-12 Thread Igor Mammedov
it still correct for x86 and other users, and can serve us as simpler to
 [1] cpu_enabled_status() callback that does the same in a roundabout way.

It's still an RFC, and probably there we should add another property
'enabled' instead of abusing 'realized' and/or handle enabled state
using hotplug handlers chain. i.e. in plug handler store enabled state
AcpiCpuStatus and clear it in unplug handler instead of asking cpu from
MMIO handler directly.

1) bf1ecc8dad606 (w/acpi: Update ACPI `_STA` method with QOM vCPU ACPI Hotplug 
states)
Signed-off-by: Igor Mammedov 
---
 hw/acpi/cpu.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
index 67513450f9..992ae5d233 100644
--- a/hw/acpi/cpu.c
+++ b/hw/acpi/cpu.c
@@ -63,7 +63,9 @@ static uint64_t cpu_hotplug_rd(void *opaque, hwaddr addr, 
unsigned size)
 cdev = &cpu_st->devs[cpu_st->selector];
 switch (addr) {
 case ACPI_CPU_FLAGS_OFFSET_RW: /* pack and return is_* fields */
-val |= cdev->cpu ? 1 : 0;
+val |= cdev->cpu ? object_property_get_bool(OBJECT(cdev->cpu),
+"realized", NULL)
+   : 0;
 val |= cdev->is_inserting ? 2 : 0;
 val |= cdev->is_removing  ? 4 : 0;
 val |= cdev->fw_remove  ? 16 : 0;
-- 
2.43.0




[RFC 5/7] DO NOT MERGE: acpi: cpuhp: add option to AML genrator to opt-in to always present vCPUs

2024-11-12 Thread Igor Mammedov
Looking at [1] what 'present' bit would do, it's no necessary as it's
statically defined for VM instance. So instead of introducing new ABI
in cpuhp flags register, add CPUHotplugFeatures::always_present_cpus
config option, that when set change _STA default return value to always
present but not enabled. And the interpose 'enabled' check on top of it,
which would set 'enabled' bit in return value if vCPU is enabled.

Platforms that need the feature can opt in by setting
 CPUHotplugFeatures::always_present_cpus = true
for other plaforms _STA will revert to the behavior before [1]

1)
 bf1ecc8dad606 (w/acpi: Update ACPI `_STA` method with QOM vCPU ACPI Hotplug 
states)
Signed-off-by: Igor Mammedov 
---
 include/hw/acpi/cpu.h | 1 +
 hw/acpi/cpu.c | 9 +++--
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/include/hw/acpi/cpu.h b/include/hw/acpi/cpu.h
index 32654dc274..e9e9c28359 100644
--- a/include/hw/acpi/cpu.h
+++ b/include/hw/acpi/cpu.h
@@ -56,6 +56,7 @@ typedef struct CPUHotplugFeatures {
 bool acpi_1_compatible;
 bool has_legacy_cphp;
 bool fw_unplugs_cpu;
+bool always_present_cpus;
 const char *smi_path;
 } CPUHotplugFeatures;
 
diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
index 5cb60ca8bc..67513450f9 100644
--- a/hw/acpi/cpu.c
+++ b/hw/acpi/cpu.c
@@ -452,15 +452,20 @@ void build_cpus_aml(Aml *table, MachineState *machine, 
CPUHotplugFeatures opts,
 
 method = aml_method(CPU_STS_METHOD, 1, AML_SERIALIZED);
 {
+/*
+ * For always present CPUs set all bits except of 'enabled'
+ * ACPI 1.0b: chapter '6.3.5 _STA'
+ */
+uint8_t default_sta = opts.always_present_cpus ? 0xd : 0;
 Aml *idx = aml_arg(0);
-Aml *sta = aml_local(0);
+Aml *sta = aml_local(default_sta);
 
 aml_append(method, aml_acquire(ctrl_lock, 0x));
 aml_append(method, aml_store(idx, cpu_selector));
 aml_append(method, aml_store(zero, sta));
 ifctx = aml_if(aml_equal(is_enabled, one));
 {
-aml_append(ifctx, aml_store(aml_int(0xF), sta));
+aml_append(ifctx, aml_or(aml_int(0xF), sta, sta));
 }
 aml_append(method, ifctx);
 aml_append(method, aml_release(ctrl_lock));
-- 
2.43.0




[PATCH 0/7 for-9.2] Fix broken cpu hotplug after migration

2024-11-12 Thread Igor Mammedov
1st 4 patches are fixing regression and getting rid of not needed changes
that were merged out of context (ARM CPU hotplug) without proper review,
by simply reverting offendining patches to keep history clean as patches
not 9.2 material to begin with.

The rest [5-7/7] are not tested RFC (not for merging to 9.2) for how problem
could be dealt with and could be adopted/changed for the future ARM CPU hotplug
series. 

Igor Mammedov (6):
  Revert "hw/acpi: Update ACPI `_STA` method with QOM vCPU ACPI Hotplug
states"
  Revert "hw/acpi: Make CPUs ACPI `presence` conditional during vCPU
hot-unplug"
  tests/acpi: update expected blobs
  acpi: cpuhp: add option to AML genrator to opt-in to always present
vCPUs
  acpi: cpuhp: use 'realized' status of vCPU to check if CPU is enabled
  acpi: cpuhp: preserve always present vCPUs on unplug

Salil Mehta (1):
  qtest: allow ACPI DSDT Table changes

 include/hw/acpi/cpu.h |   5 +-
 include/hw/core/cpu.h |   2 -
 hw/acpi/acpi-cpu-hotplug-stub.c   |   3 +-
 hw/acpi/cpu.c |  72 +-
 hw/acpi/cpu_hotplug.c |   2 +-
 hw/acpi/generic_event_device.c|   2 +-
 tests/data/acpi/x86/pc/DSDT   | Bin 8560 -> 8526 bytes
 tests/data/acpi/x86/pc/DSDT.acpierst  | Bin 8471 -> 8437 bytes
 tests/data/acpi/x86/pc/DSDT.acpihmat  | Bin 9885 -> 9851 bytes
 tests/data/acpi/x86/pc/DSDT.bridge| Bin 15431 -> 15397 bytes
 tests/data/acpi/x86/pc/DSDT.cphp  | Bin 9024 -> 8990 bytes
 tests/data/acpi/x86/pc/DSDT.dimmpxm   | Bin 10214 -> 10180 bytes
 tests/data/acpi/x86/pc/DSDT.hpbridge  | Bin 8511 -> 8477 bytes
 tests/data/acpi/x86/pc/DSDT.hpbrroot  | Bin 5067 -> 5033 bytes
 tests/data/acpi/x86/pc/DSDT.ipmikcs   | Bin 8632 -> 8598 bytes
 tests/data/acpi/x86/pc/DSDT.memhp | Bin 9919 -> 9885 bytes
 tests/data/acpi/x86/pc/DSDT.nohpet| Bin 8418 -> 8384 bytes
 tests/data/acpi/x86/pc/DSDT.numamem   | Bin 8566 -> 8532 bytes
 tests/data/acpi/x86/pc/DSDT.roothp| Bin 12353 -> 12319 bytes
 tests/data/acpi/x86/q35/DSDT  | Bin 8389 -> 8355 bytes
 tests/data/acpi/x86/q35/DSDT.acpierst | Bin 8406 -> 8372 bytes
 tests/data/acpi/x86/q35/DSDT.acpihmat | Bin 9714 -> 9680 bytes
 .../acpi/x86/q35/DSDT.acpihmat-noinitiator| Bin 8668 -> 8634 bytes
 tests/data/acpi/x86/q35/DSDT.applesmc | Bin 8435 -> 8401 bytes
 tests/data/acpi/x86/q35/DSDT.bridge   | Bin 12002 -> 11968 bytes
 tests/data/acpi/x86/q35/DSDT.core-count   | Bin 12947 -> 12913 bytes
 tests/data/acpi/x86/q35/DSDT.core-count2  | Bin 33804 -> 33770 bytes
 tests/data/acpi/x86/q35/DSDT.cphp | Bin 8853 -> 8819 bytes
 tests/data/acpi/x86/q35/DSDT.cxl  | Bin 13180 -> 13146 bytes
 tests/data/acpi/x86/q35/DSDT.dimmpxm  | Bin 10043 -> 10009 bytes
 tests/data/acpi/x86/q35/DSDT.ipmibt   | Bin 8464 -> 8430 bytes
 tests/data/acpi/x86/q35/DSDT.ipmismbus| Bin 8477 -> 8443 bytes
 tests/data/acpi/x86/q35/DSDT.ivrs | Bin 8406 -> 8372 bytes
 tests/data/acpi/x86/q35/DSDT.memhp| Bin 9748 -> 9714 bytes
 tests/data/acpi/x86/q35/DSDT.mmio64   | Bin 9519 -> 9485 bytes
 tests/data/acpi/x86/q35/DSDT.multi-bridge | Bin 13242 -> 13208 bytes
 tests/data/acpi/x86/q35/DSDT.noacpihp | Bin 8269 -> 8235 bytes
 tests/data/acpi/x86/q35/DSDT.nohpet   | Bin 8247 -> 8213 bytes
 tests/data/acpi/x86/q35/DSDT.numamem  | Bin 8395 -> 8361 bytes
 tests/data/acpi/x86/q35/DSDT.pvpanic-isa  | Bin 8490 -> 8456 bytes
 tests/data/acpi/x86/q35/DSDT.thread-count | Bin 12947 -> 12913 bytes
 tests/data/acpi/x86/q35/DSDT.thread-count2| Bin 33804 -> 33770 bytes
 tests/data/acpi/x86/q35/DSDT.tis.tpm12| Bin 8995 -> 8961 bytes
 tests/data/acpi/x86/q35/DSDT.tis.tpm2 | Bin 9021 -> 8987 bytes
 tests/data/acpi/x86/q35/DSDT.type4-count  | Bin 18623 -> 18589 bytes
 tests/data/acpi/x86/q35/DSDT.viot | Bin 14646 -> 14612 bytes
 tests/data/acpi/x86/q35/DSDT.xapic| Bin 35752 -> 35718 bytes
 47 files changed, 29 insertions(+), 57 deletions(-)

-- 
2.43.0




Re: [PATCH v2 1/6] target/mips: Introduce decode tree bindings for microMIPS ISA

2024-11-12 Thread Richard Henderson

On 11/12/24 09:20, Philippe Mathieu-Daudé wrote:

From: Philippe Mathieu-Daudé

Introduce the microMIPS decodetree configs for the 16-bit
and 32-bit instructions.

Signed-off-by: Philippe Mathieu-Daudé
---
  target/mips/tcg/translate.h   |  2 ++
  target/mips/tcg/micromips16.decode|  9 +
  target/mips/tcg/micromips32.decode|  9 +
  target/mips/tcg/micromips_translate.c | 14 ++
  target/mips/tcg/micromips_translate.c.inc |  6 ++
  target/mips/tcg/meson.build   |  3 +++
  6 files changed, 43 insertions(+)
  create mode 100644 target/mips/tcg/micromips16.decode
  create mode 100644 target/mips/tcg/micromips32.decode
  create mode 100644 target/mips/tcg/micromips_translate.c


Reviewed-by: Richard Henderson 

r~



[PATCH 13/20] hw/net/xilinx_ethlite: Access TX_LEN register for each port

2024-11-12 Thread Philippe Mathieu-Daudé
Rather than accessing the registers within the mixed RAM/MMIO
region as indexed register, declare a per-port TX_LEN. This
will help to map the RAM as RAM (keeping MMIO as MMIO) in few
commits.

Previous s->regs[R_TX_LEN0] and s->regs[R_TX_LEN1] are now
unused. Not a concern, this array will soon disappear.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/net/xilinx_ethlite.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c
index 4cb4781e70..1a3b295b4b 100644
--- a/hw/net/xilinx_ethlite.c
+++ b/hw/net/xilinx_ethlite.c
@@ -62,6 +62,7 @@
 typedef struct XlnxXpsEthLitePort
 {
 struct {
+uint32_t tx_len;
 uint32_t tx_gie;
 
 uint32_t rx_ctrl;
@@ -133,6 +134,9 @@ eth_read(void *opaque, hwaddr addr, unsigned int size)
 
 case R_TX_LEN0:
 case R_TX_LEN1:
+r = s->port[port_index].reg.tx_len;
+break;
+
 case R_TX_CTRL1:
 case R_TX_CTRL0:
 r = s->regs[addr];
@@ -169,7 +173,7 @@ eth_write(void *opaque, hwaddr addr,
 if ((value & (CTRL_P | CTRL_S)) == CTRL_S) {
 qemu_send_packet(qemu_get_queue(s->nic),
  txbuf_ptr(s, port_index),
- s->regs[base + R_TX_LEN0]);
+ s->port[port_index].reg.tx_len);
 if (s->regs[base + R_TX_CTRL0] & CTRL_I)
 eth_pulse_irq(s);
 } else if ((value & (CTRL_P | CTRL_S)) == (CTRL_P | CTRL_S)) {
@@ -194,7 +198,7 @@ eth_write(void *opaque, hwaddr addr,
 
 case R_TX_LEN0:
 case R_TX_LEN1:
-s->regs[addr] = value;
+s->port[port_index].reg.tx_len = value;
 break;
 
 case R_TX_GIE0:
-- 
2.45.2




[RESEND PATCH 08/10] aspeed: Add uhci support for ast2400 and ast2500

2024-11-12 Thread Guenter Roeck
Add UHCI support for ast2400 and ast2500 SoCs. With this patch,
the UHCI port is successfully enabled on the ast2500-evb machine.

Note that the EHCI controller on AST2400 and AST2500 does not support
companion mode, so the UHCI controller is instantiated as stand-alone
device and creates an additional USB bus.

Reviewed-by: Cédric Le Goater 
Signed-off-by: Guenter Roeck 
---
Changes since RFC:
- Rebased to v9.1.0-1673-g134b443512
- Added Reviewed-by: tag
- Added explanation for not using EHCI companion mode

 hw/arm/aspeed_ast2400.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/hw/arm/aspeed_ast2400.c b/hw/arm/aspeed_ast2400.c
index ecc81ecc79..8a5d21459d 100644
--- a/hw/arm/aspeed_ast2400.c
+++ b/hw/arm/aspeed_ast2400.c
@@ -31,6 +31,7 @@ static const hwaddr aspeed_soc_ast2400_memmap[] = {
 [ASPEED_DEV_FMC]= 0x1E62,
 [ASPEED_DEV_SPI1]   = 0x1E63,
 [ASPEED_DEV_EHCI1]  = 0x1E6A1000,
+[ASPEED_DEV_UHCI]   = 0x1E6B,
 [ASPEED_DEV_VIC]= 0x1E6C,
 [ASPEED_DEV_SDMC]   = 0x1E6E,
 [ASPEED_DEV_SCU]= 0x1E6E2000,
@@ -68,6 +69,7 @@ static const hwaddr aspeed_soc_ast2500_memmap[] = {
 [ASPEED_DEV_SPI2]   = 0x1E631000,
 [ASPEED_DEV_EHCI1]  = 0x1E6A1000,
 [ASPEED_DEV_EHCI2]  = 0x1E6A3000,
+[ASPEED_DEV_UHCI]   = 0x1E6B,
 [ASPEED_DEV_VIC]= 0x1E6C,
 [ASPEED_DEV_SDMC]   = 0x1E6E,
 [ASPEED_DEV_SCU]= 0x1E6E2000,
@@ -107,6 +109,7 @@ static const int aspeed_soc_ast2400_irqmap[] = {
 [ASPEED_DEV_FMC]= 19,
 [ASPEED_DEV_EHCI1]  = 5,
 [ASPEED_DEV_EHCI2]  = 13,
+[ASPEED_DEV_UHCI]   = 14,
 [ASPEED_DEV_SDMC]   = 0,
 [ASPEED_DEV_SCU]= 21,
 [ASPEED_DEV_ADC]= 31,
@@ -199,6 +202,8 @@ static void aspeed_ast2400_soc_init(Object *obj)
 TYPE_PLATFORM_EHCI);
 }
 
+object_initialize_child(obj, "uhci", &s->uhci, TYPE_ASPEED_UHCI);
+
 snprintf(typename, sizeof(typename), "aspeed.sdmc-%s", socname);
 object_initialize_child(obj, "sdmc", &s->sdmc, typename);
 object_property_add_alias(obj, "ram-size", OBJECT(&s->sdmc),
@@ -393,6 +398,15 @@ static void aspeed_ast2400_soc_realize(DeviceState *dev, 
Error **errp)
aspeed_soc_get_irq(s, ASPEED_DEV_EHCI1 + i));
 }
 
+/* UHCI */
+if (!sysbus_realize(SYS_BUS_DEVICE(&s->uhci), errp)) {
+return;
+}
+aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->uhci), 0,
+sc->memmap[ASPEED_DEV_UHCI]);
+sysbus_connect_irq(SYS_BUS_DEVICE(&s->uhci), 0,
+   aspeed_soc_get_irq(s, ASPEED_DEV_UHCI));
+
 /* SDMC - SDRAM Memory Controller */
 if (!sysbus_realize(SYS_BUS_DEVICE(&s->sdmc), errp)) {
 return;
-- 
2.45.2




[RESEND PATCH 02/10] usb/uhci: Introduce and use register defines

2024-11-12 Thread Guenter Roeck
Introduce defines for UHCI registers to simplify adding register access
in subsequent patches of the series.

No functional change.

Reviewed-by: Cédric Le Goater 
Signed-off-by: Guenter Roeck 
---
Changes since RFC:
- Rebased to v9.1.0-1673-g134b443512
- Added Reviewed-by: tag

 hw/usb/hcd-uhci.c  | 32 
 include/hw/usb/uhci-regs.h | 11 +++
 2 files changed, 27 insertions(+), 16 deletions(-)

diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
index 50d488d6fb..bdab9ac37e 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -389,7 +389,7 @@ static void uhci_port_write(void *opaque, hwaddr addr,
 trace_usb_uhci_mmio_writew(addr, val);
 
 switch (addr) {
-case 0x00:
+case UHCI_USBCMD:
 if ((val & UHCI_CMD_RS) && !(s->cmd & UHCI_CMD_RS)) {
 /* start frame processing */
 trace_usb_uhci_schedule_start();
@@ -424,7 +424,7 @@ static void uhci_port_write(void *opaque, hwaddr addr,
 }
 }
 break;
-case 0x02:
+case UHCI_USBSTS:
 s->status &= ~val;
 /*
  * XXX: the chip spec is not coherent, so we add a hidden
@@ -435,27 +435,27 @@ static void uhci_port_write(void *opaque, hwaddr addr,
 }
 uhci_update_irq(s);
 break;
-case 0x04:
+case UHCI_USBINTR:
 s->intr = val;
 uhci_update_irq(s);
 break;
-case 0x06:
+case UHCI_USBFRNUM:
 if (s->status & UHCI_STS_HCHALTED) {
 s->frnum = val & 0x7ff;
 }
 break;
-case 0x08:
+case UHCI_USBFLBASEADD:
 s->fl_base_addr &= 0x;
 s->fl_base_addr |= val & ~0xfff;
 break;
-case 0x0a:
+case UHCI_USBFLBASEADD + 2:
 s->fl_base_addr &= 0x;
 s->fl_base_addr |= (val << 16);
 break;
-case 0x0c:
+case UHCI_USBSOF:
 s->sof_timing = val & 0xff;
 break;
-case 0x10 ... 0x1f:
+case UHCI_USBPORTSC1 ... UHCI_USBPORTSC4:
 {
 UHCIPort *port;
 USBDevice *dev;
@@ -493,28 +493,28 @@ static uint64_t uhci_port_read(void *opaque, hwaddr addr, 
unsigned size)
 uint32_t val;
 
 switch (addr) {
-case 0x00:
+case UHCI_USBCMD:
 val = s->cmd;
 break;
-case 0x02:
+case UHCI_USBSTS:
 val = s->status;
 break;
-case 0x04:
+case UHCI_USBINTR:
 val = s->intr;
 break;
-case 0x06:
+case UHCI_USBFRNUM:
 val = s->frnum;
 break;
-case 0x08:
+case UHCI_USBFLBASEADD:
 val = s->fl_base_addr & 0x;
 break;
-case 0x0a:
+case UHCI_USBFLBASEADD + 2:
 val = (s->fl_base_addr >> 16) & 0x;
 break;
-case 0x0c:
+case UHCI_USBSOF:
 val = s->sof_timing;
 break;
-case 0x10 ... 0x1f:
+case UHCI_USBPORTSC1 ... UHCI_USBPORTSC4:
 {
 UHCIPort *port;
 int n;
diff --git a/include/hw/usb/uhci-regs.h b/include/hw/usb/uhci-regs.h
index fd45d29db0..5b81714e5c 100644
--- a/include/hw/usb/uhci-regs.h
+++ b/include/hw/usb/uhci-regs.h
@@ -1,6 +1,17 @@
 #ifndef HW_USB_UHCI_REGS_H
 #define HW_USB_UHCI_REGS_H
 
+#define UHCI_USBCMD   0
+#define UHCI_USBSTS   2
+#define UHCI_USBINTR  4
+#define UHCI_USBFRNUM 6
+#define UHCI_USBFLBASEADD 8
+#define UHCI_USBSOF   0x0c
+#define UHCI_USBPORTSC1   0x10
+#define UHCI_USBPORTSC2   0x12
+#define UHCI_USBPORTSC3   0x14
+#define UHCI_USBPORTSC4   0x16
+
 #define UHCI_CMD_FGR  (1 << 4)
 #define UHCI_CMD_EGSM (1 << 3)
 #define UHCI_CMD_GRESET   (1 << 2)
-- 
2.45.2




[RESEND PATCH 03/10] usb/uhci: Move PCI-related code into a separate file

2024-11-12 Thread Guenter Roeck
Some machines (like Aspeed ARM) only have a sysbus UHCI controller.
The current UHCI implementation only supports PCI based UHCI controllers.
Move the UHCI-PCI device code into a separate file so that it is possible
to create a sysbus UHCI device without PCI dependency.

Signed-off-by: Guenter Roeck 
---
Changes since RFC:
- Rebased to v9.1.0-1673-g134b443512
- Fixed bug in interrupt initialization

 hw/isa/Kconfig|   4 +-
 hw/isa/vt82c686.c |   4 +-
 hw/usb/Kconfig|   6 +-
 hw/usb/hcd-uhci-pci.c | 255 ++
 hw/usb/hcd-uhci-pci.h |  63 +
 hw/usb/hcd-uhci.c | 221 +
 hw/usb/hcd-uhci.h |  30 ++--
 hw/usb/meson.build|   1 +
 hw/usb/vt82c686-uhci-pci.c|  18 +--
 include/hw/southbridge/piix.h |   4 +-
 10 files changed, 386 insertions(+), 220 deletions(-)
 create mode 100644 hw/usb/hcd-uhci-pci.c
 create mode 100644 hw/usb/hcd-uhci-pci.h

diff --git a/hw/isa/Kconfig b/hw/isa/Kconfig
index 73c6470805..b0e536fad9 100644
--- a/hw/isa/Kconfig
+++ b/hw/isa/Kconfig
@@ -47,7 +47,7 @@ config PIIX
 select IDE_PIIX
 select ISA_BUS
 select MC146818RTC
-select USB_UHCI
+select USB_UHCI_PCI
 
 config VT82C686
 bool
@@ -55,7 +55,7 @@ config VT82C686
 select ISA_SUPERIO
 select ACPI
 select ACPI_SMBUS
-select USB_UHCI
+select USB_UHCI_PCI
 select APM
 select I8254
 select I8257
diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index 6f44b381a5..a47cbd6191 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -26,7 +26,7 @@
 #include "hw/intc/i8259.h"
 #include "hw/irq.h"
 #include "hw/dma/i8257.h"
-#include "hw/usb/hcd-uhci.h"
+#include "hw/usb/hcd-uhci-pci.h"
 #include "hw/timer/i8254.h"
 #include "hw/rtc/mc146818rtc.h"
 #include "migration/vmstate.h"
@@ -600,7 +600,7 @@ struct ViaISAState {
 ViaSuperIOState via_sio;
 MC146818RtcState rtc;
 PCIIDEState ide;
-UHCIState uhci[2];
+UHCIPCIState uhci[2];
 ViaPMState pm;
 ViaAC97State ac97;
 PCIDevice mc97;
diff --git a/hw/usb/Kconfig b/hw/usb/Kconfig
index 5fbecd2f43..bab4d2d67d 100644
--- a/hw/usb/Kconfig
+++ b/hw/usb/Kconfig
@@ -2,10 +2,14 @@ config USB
 bool
 
 config USB_UHCI
+bool
+select USB
+
+config USB_UHCI_PCI
 bool
 default y if PCI_DEVICES
 depends on PCI
-select USB
+select USB_UHCI
 
 config USB_OHCI
 bool
diff --git a/hw/usb/hcd-uhci-pci.c b/hw/usb/hcd-uhci-pci.c
new file mode 100644
index 00..ed9b5f6121
--- /dev/null
+++ b/hw/usb/hcd-uhci-pci.c
@@ -0,0 +1,255 @@
+/*
+ * USB UHCI controller emulation
+ * PCI code
+ *
+ * Copyright (c) 2005 Fabrice Bellard
+ *
+ * Copyright (c) 2008 Max Krasnyansky
+ * Magor rewrite of the UHCI data structures parser and frame processor
+ * Support for fully async operation and multiple outstanding transactions
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/irq.h"
+#include "hw/usb.h"
+#include "migration/vmstate.h"
+#include "hw/pci/pci.h"
+#include "hw/qdev-properties.h"
+#include "qapi/error.h"
+#include "qemu/main-loop.h"
+#include "qemu/module.h"
+#include "qom/object.h"
+#include "hcd-uhci-pci.h"
+
+struct UHCIPCIDeviceClass {
+PCIDeviceClass parent_class;
+UHCIPCIInfo info;
+};
+
+static const VMStateDescription vmstate_uhci = {
+.name = "pci_uhci",
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (const VMStateField[]) {
+VMSTATE_PCI_DEVICE(dev, UHCIPCIState),
+VMSTATE_STRUCT(state, UHCIPCIState, 1, vmstate_uhci_state, UHCIState),
+VMSTATE_END_OF_LIST()
+}
+};
+
+static void uhci_pci_reset(UHCIState *uhci)
+{
+UHCIPCIState *pstate = container_of(uhci, UHCIPCIState, state);
+PCIDevice *d = &pstate->dev;
+
+d->config[0x6a] = 0x01; /* usb clock */
+d->config[0x6b] = 0x00;
+
+   

  1   2   3   >